FEATURE: Poll breakdown 2.0 (#10345)
The poll breakdown modal replaces the grouped pie charts feature.
Includes:
* MODAL: Untangle `onSelectPanel`
Previously modal-tab component would call on click the onSelectPanel callback with itself (modal-tab) as `this` which severely limited its usefulness. Now showModal binds the callback to its controller.
"The PR includes a fix/change to d-modal (b7f6ec6) that hasn't been extracted to a separate PR because it's not currently possible to test a change like this in abstract, i.e. with dynamically created controllers/components in tests. The percentage/count toggle test for the poll breakdown feature is essentially a test for that d-modal modification."
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import I18n from "I18n";
|
||||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { classify } from "@ember/string";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
model: null,
|
||||
charts: null,
|
||||
groupedBy: null,
|
||||
highlightedOption: null,
|
||||
displayMode: "percentage",
|
||||
|
||||
@discourseComputed("model.groupableUserFields")
|
||||
groupableUserFields(fields) {
|
||||
return fields.map(field => {
|
||||
const transformed = field.split("_").filter(Boolean);
|
||||
|
||||
if (transformed.length > 1) {
|
||||
transformed[0] = classify(transformed[0]);
|
||||
}
|
||||
|
||||
return { id: field, label: transformed.join(" ") };
|
||||
});
|
||||
},
|
||||
|
||||
@discourseComputed("model.poll.options")
|
||||
totalVotes(options) {
|
||||
return options.reduce((sum, option) => sum + option.votes, 0);
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.set("charts", null);
|
||||
this.set("displayMode", "percentage");
|
||||
this.set("groupedBy", this.model.groupableUserFields[0]);
|
||||
|
||||
loadScript("/javascripts/Chart.min.js")
|
||||
.then(() => loadScript("/javascripts/chartjs-plugin-datalabels.min.js"))
|
||||
.then(() => {
|
||||
window.Chart.plugins.unregister(window.ChartDataLabels);
|
||||
this.fetchGroupedPollData();
|
||||
});
|
||||
},
|
||||
|
||||
fetchGroupedPollData() {
|
||||
return ajax("/polls/grouped_poll_results.json", {
|
||||
data: {
|
||||
post_id: this.model.post.id,
|
||||
poll_name: this.model.poll.name,
|
||||
user_field_name: this.groupedBy
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (error) {
|
||||
popupAjaxError(error);
|
||||
} else {
|
||||
bootbox.alert(I18n.t("poll.error_while_fetching_voters"));
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
if (this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.set("charts", result.grouped_results);
|
||||
});
|
||||
},
|
||||
|
||||
@action
|
||||
setGrouping(value) {
|
||||
this.set("groupedBy", value);
|
||||
this.fetchGroupedPollData();
|
||||
},
|
||||
|
||||
@action
|
||||
onSelectPanel(panel) {
|
||||
this.set("displayMode", panel.id);
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import I18n from "I18n";
|
||||
import Controller from "@ember/controller";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import EmberObject from "@ember/object";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export const BAR_CHART_TYPE = "bar";
|
||||
export const PIE_CHART_TYPE = "pie";
|
||||
|
||||
Reference in New Issue
Block a user