mirror of
https://github.com/discourse/discourse.git
synced 2024-12-03 15:44:21 +08:00
cd4f251891
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."
84 lines
2.2 KiB
JavaScript
84 lines
2.2 KiB
JavaScript
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);
|
|
}
|
|
});
|