FIX: two-column poll

This commit is contained in:
Régis Hanol 2015-05-04 22:29:45 +02:00
parent a2d8cd501c
commit 90c05ff045
6 changed files with 191 additions and 85 deletions

View File

@ -4,9 +4,6 @@ export default Em.Controller.extend({
isRandom : Em.computed.equal("poll.order", "random"), isRandom : Em.computed.equal("poll.order", "random"),
isClosed: Em.computed.equal("poll.status", "closed"), isClosed: Em.computed.equal("poll.status", "closed"),
// immediately shows the results when the user has already voted
showResults: Em.computed.gt("vote.length", 0),
// shows the results when // shows the results when
// - poll is closed // - poll is closed
// - topic is archived/closed // - topic is archived/closed
@ -50,6 +47,20 @@ export default Em.Controller.extend({
return max; return max;
}.property("poll.max", "poll.options.length"), }.property("poll.max", "poll.options.length"),
votersText: function() {
return I18n.t("poll.voters", { count: this.get("poll.voters") });
}.property("poll.voters"),
totalVotes: function() {
return _.reduce(this.get("poll.options"), function(total, o) {
return total + parseInt(o.get("votes"), 10);
}, 0);
}.property("poll.options.@each.votes"),
totalVotesText: function() {
return I18n.t("poll.total_votes", { count: this.get("totalVotes") });
}.property("totalVotes"),
multipleHelpText: function() { multipleHelpText: function() {
const options = this.get("poll.options.length"), const options = this.get("poll.options.length"),
min = this.get("min"), min = this.get("min"),

View File

@ -1,13 +1,11 @@
<tbody> {{#each option in options}}
{{#each option in options}} <tr>
<tr> <td class="option">{{{option.html}}}</td>
<td class="option">{{{option.html}}}</td> <td class="percentage">{{option.percentage}}%</td>
<td class="percentage">{{option.percentage}}%</td> </tr>
</tr> <tr>
<tr> <td colspan="2" class="bar-back">
<td colspan="2" class="bar-back"> <div class="bar" {{bind-attr style=option.style}}></div>
<div class="bar" {{bind-attr style=option.style}}></div> </td>
</td> </tr>
</tr> {{/each}}
{{/each}}
</tbody>

View File

@ -1,34 +1,53 @@
<div class="poll-container"> <div>
{{#if showingResults}} <div class="poll-info">
{{#if isNumber}} <p>
{{poll-results-number poll=poll}} <span class="info-number">{{poll.voters}}</span>
{{else}} <span class="info-text">{{votersText}}</span>
{{poll-results-standard poll=poll}} </p>
{{#if isMultiple}}
{{#if showingResults}}
<p>
<span class="info-number">{{totalVotes}}</span>
<span class="info-text">{{totalVotesText}}</span>
</p>
{{else}}
<p>{{{multipleHelpText}}}</p>
{{/if}}
{{/if}} {{/if}}
{{else}} </div>
<ul> <div class="poll-container">
{{#each option in poll.options}} {{#if showingResults}}
{{poll-option option=option color=poll.color background=poll.background toggle="toggleOption"}} {{#if isNumber}}
{{/each}} {{poll-results-number poll=poll}}
</ul> {{else}}
{{/if}} {{poll-results-standard poll=poll}}
{{/if}}
{{else}}
<ul>
{{#each option in poll.options}}
{{poll-option option=option color=poll.color background=poll.background toggle="toggleOption"}}
{{/each}}
</ul>
{{/if}}
</div>
</div> </div>
{{#if isMultiple}} <div class="poll-buttons">
<p>{{multipleHelpText}}</p> {{#if isMultiple}}
{{d-button class="cast-votes" title="poll.cast-votes.title" label="poll.cast-votes.label" disabled=castVotesDisabled action="castVotes"}} {{d-button class="cast-votes" title="poll.cast-votes.title" label="poll.cast-votes.label" disabled=castVotesDisabled action="castVotes"}}
{{/if}}
{{#if showingResults}}
{{d-button class="toggle-results" title="poll.hide-results.title" label="poll.hide-results.label" icon="eye-slash" disabled=hideResultsDisabled action="toggleResults"}}
{{else}}
{{d-button class="toggle-results" title="poll.show-results.title" label="poll.show-results.label" icon="eye" disabled=showResultsDisabled action="toggleResults"}}
{{/if}}
{{#if canToggleStatus}}
{{#if isClosed}}
{{d-button class="toggle-status" title="poll.open.title" label="poll.open.label" icon="unlock-alt" action="toggleStatus"}}
{{else}}
{{d-button class="toggle-status btn-danger" title="poll.close.title" label="poll.close.label" icon="lock" action="toggleStatus"}}
{{/if}} {{/if}}
{{/if}}
{{#if showingResults}}
{{d-button class="toggle-results" title="poll.hide-results.title" label="poll.hide-results.label" icon="eye-slash" disabled=hideResultsDisabled action="toggleResults"}}
{{else}}
{{d-button class="toggle-results" title="poll.show-results.title" label="poll.show-results.label" icon="eye" disabled=showResultsDisabled action="toggleResults"}}
{{/if}}
{{#if canToggleStatus}}
{{#if isClosed}}
{{d-button class="toggle-status" title="poll.open.title" label="poll.open.label" icon="unlock-alt" action="toggleStatus"}}
{{else}}
{{d-button class="toggle-status btn-danger" title="poll.close.title" label="poll.close.label" icon="lock" action="toggleStatus"}}
{{/if}}
{{/if}}
</div>

View File

@ -97,11 +97,25 @@
contents[0][o].splice(1, 0, attr); contents[0][o].splice(1, 0, attr);
} }
// that's our poll! // // add some information when type is "multiple"
var pollContainer = ["div", { "class": "poll-container" }].concat(contents); // if (attributes[DATA_PREFIX + "type"] === "multiple") {
var result = ["div", attributes, pollContainer];
// add some information when type is "multiple"
// }
var result = ["div", attributes],
poll = ["div"];
// 1 - POLL INFO
var info = ["div", { "class": "poll-info" }];
// # of voters
info.push(["p",
["span", { "class": "info-number" }, "0"],
["span", { "class": "info-text"}, I18n.t("poll.voters", { count: 0 })]
]);
// multiple help text
if (attributes[DATA_PREFIX + "type"] === "multiple") { if (attributes[DATA_PREFIX + "type"] === "multiple") {
var optionCount = contents[0].length - 1; var optionCount = contents[0].length - 1;
@ -128,23 +142,40 @@
} }
} }
if (help) { result.push(["p", help]); } if (help) { info.push(["p", help]); }
}
// add "cast-votes" button poll.push(info);
result.push(["a", { "class": "button cast-votes", "title": I18n.t("poll.cast-votes.title") }, I18n.t("poll.cast-votes.label")]);
// 2 - POLL CONTAINER
var container = ["div", { "class": "poll-container" }].concat(contents);
poll.push(container);
// 3 - BUTTONS
var buttons = ["div", { "class": "poll-buttons" }];
// add "cast-votes" button
if (attributes[DATA_PREFIX + "type"] === "multiple") {
buttons.push(["a", { "class": "button cast-votes", "title": I18n.t("poll.cast-votes.title") }, I18n.t("poll.cast-votes.label")]);
} }
// add "toggle-results" button // add "toggle-results" button
result.push(["a", { "class": "button toggle-results", "title": I18n.t("poll.show-results.title") }, I18n.t("poll.show-results.label")]); buttons.push(["a", { "class": "button toggle-results", "title": I18n.t("poll.show-results.title") }, I18n.t("poll.show-results.label")]);
// 4 - MIX IT ALL UP
result.push(poll);
result.push(buttons)
return result; return result;
} }
}); });
Discourse.Markdown.whiteListTag("div", "class", "poll"); Discourse.Markdown.whiteListTag("div", "class", "poll");
Discourse.Markdown.whiteListTag("div", "class", "poll-container"); Discourse.Markdown.whiteListTag("div", "class", /^poll-(info|container|buttons)/);
Discourse.Markdown.whiteListTag("div", "data-*"); Discourse.Markdown.whiteListTag("div", "data-*");
Discourse.Markdown.whiteListTag("span", "class", /^info-(number|text)/);
Discourse.Markdown.whiteListTag("a", "class", /^button (cast-votes|toggle-results)/); Discourse.Markdown.whiteListTag("a", "class", /^button (cast-votes|toggle-results)/);
Discourse.Markdown.whiteListTag("li", "data-*"); Discourse.Markdown.whiteListTag("li", "data-*");

View File

@ -1,11 +1,22 @@
$border-color: rgb(219,219,219);
$text-color: #9E9E9E;
$option-foreground: $primary;
$option-background: dark-light-diff($primary, $secondary, 90%, -65%);
$option-shadow: dark-light-diff($option-background, $primary, 10%, -10%);
div.poll { div.poll {
display: table;
border: 1px solid $border-color;
width: 500px;
ul, ol { ul, ol {
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
display: inline-block; display: inline-block;
max-width: 90%; width: 100%;
} }
li, .option { li, .option {
@ -15,31 +26,29 @@ div.poll {
} }
li[data-poll-option-id] { li[data-poll-option-id] {
color: $secondary; position: relative;
background: $primary; color: $option-foreground;
background: $option-background;
box-shadow: 0 6px $option-shadow;
padding: 0 .8em; padding: 0 .8em;
margin-bottom: .7em; margin-bottom: .7em;
border-radius: .25rem; border-radius: 4px;
box-shadow: inset 0 -.2em 0 0 rgba(0,0,0,.2),
inset 0 0 0 100px rgba(0,0,0,0),
0 .2em 0 0 rgba(0,0,0,.2);
&:hover { &:hover {
box-shadow: inset 0 -.2em 0 0 rgba(0,0,0,.25), top: 2px;
inset 0 0 0 100px rgba(0,0,0,.1), box-shadow: 0 4px $option-shadow;
0 .2em 0 0 rgba(0,0,0,.2);
} }
&:active { &:active {
-webkit-transform: translate(0,2px); top: 6px;
transform: translate(0,2px); box-shadow: 0 0 $option-shadow;
box-shadow: inset 0 -.1em 0 0 rgba(0,0,0,.25),
inset 0 0 0 100px rgba(0,0,0,.1),
0 .1em 0 0 rgba(0,0,0,.2);
} }
&[data-poll-selected="selected"] { &[data-poll-selected="selected"] {
background: green !important; background: $success !important;
box-shadow: 0 6px darken($success, 10%);
&:hover { box-shadow: 0 4px darken($success, 10%); }
&:active { box-shadow: 0 0 darken($success, 10%); }
} }
} }
@ -58,11 +67,45 @@ div.poll {
} }
} }
.poll-info {
color: $text-color;
width: 150px;
display: table-cell;
text-align: center;
vertical-align: middle;
border-right: 1px solid $border-color;
p {
margin: 40px 20px;
}
.info-number {
font-size: 3.5em;
}
.info-text {
display: block;
font-size: 1.7em;
}
}
.poll-container { .poll-container {
margin: 0 0 5px; display: table-cell;
vertical-align: middle;
padding: 10px;
width: 330px;
span { span {
font-size: 1.125em; font-size: 2em;
line-height: 2 }
}
.poll-buttons {
border-top: 1px solid $border-color;
padding: 10px;
.toggle-status {
float: right;
} }
} }
@ -80,16 +123,16 @@ div.poll {
font-size: 1.7em; font-size: 1.7em;
text-align: right; text-align: right;
vertical-align: middle; vertical-align: middle;
color: #9E9E9E; color: $text-color;
} }
.bar-back { .bar-back {
background: rgb(219,219,219); background: $border-color;
} }
.bar { .bar {
height: 10px; height: 10px;
background: $primary; background: $option-foreground;
} }
} }
@ -98,7 +141,7 @@ div.poll {
li { li {
display: inline-block; display: inline-block;
margin-right: .7em; margin: 0 12px 15px 5px;
} }
} }

View File

@ -9,18 +9,22 @@ en:
js: js:
poll: poll:
voters: voters:
zero: "No votes yet. Want to be the first?" zero: "voters"
one: "There's only 1 vote." one: "voter"
other: "There are %{count} total votes." other: "voters"
total_votes:
zero: "total votes"
one: "total vote"
other: "total votes"
average_rating: "Average rating: <strong>%{average}</strong>." average_rating: "Average rating: <strong>%{average}</strong>."
multiple: multiple:
help: help:
at_least_min_options: "You may choose at least %{count} options." at_least_min_options: "You may choose at least <strong>%{count}</strong> options."
up_to_max_options: "You may choose up to %{count} options." up_to_max_options: "You may choose up to <strong>%{count}</strong> options."
x_options: "You may choose %{count} options." x_options: "You may choose <strong>%{count}</strong> options."
between_min_and_max_options: "You may choose between %{min} and %{max} options." between_min_and_max_options: "You may choose between <strong>%{min}</strong> and <strong>%{max}</strong> options."
cast-votes: cast-votes:
title: "Cast your votes" title: "Cast your votes"