FEATURE: Add export poll button (#8370)

This PR aims to make poll results easily exportable to staff in a CSV format, so they can be analyzed in external software.

It also makes the export data easily customizable by allowing users to leverage any data explorer query to generate the report. By default, we use a query that ships with data explorer, but user can change the ID in settings or use 0 to disable this feature.

One potential upgrade is using the recent work that allows arbitrary group to run data explorer and allow all the groups with access to the configured query to also export polls, but that can be added later.

Co-Authored-By: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
Rafael dos Santos Silva
2019-11-22 16:06:39 -03:00
committed by GitHub
parent c498780479
commit fd0025a735
5 changed files with 70 additions and 0 deletions

View File

@ -425,7 +425,9 @@ createWidget("discourse-poll-buttons", {
const closed = attrs.isClosed;
const staffOnly = poll.results === "staff_only";
const isStaff = this.currentUser && this.currentUser.staff;
const dataExplorerEnabled = this.siteSettings.data_explorer_enabled;
const hideResultsDisabled = !staffOnly && (closed || topicArchived);
const exportQueryID = this.siteSettings.poll_export_data_explorer_query_id;
if (attrs.isMultiple && !hideResultsDisabled) {
const castVotesDisabled = !attrs.canCastVotes;
@ -475,6 +477,19 @@ createWidget("discourse-poll-buttons", {
}
}
if (isStaff && dataExplorerEnabled && poll.voters > 0 && exportQueryID) {
contents.push(
this.attach("button", {
className: "btn btn-default export-results",
label: "poll.export-results.label",
title: "poll.export-results.title",
icon: "download",
disabled: poll.voters === 0,
action: "exportResults"
})
);
}
if (poll.get("close")) {
const closeDate = moment.utc(poll.get("close"));
if (closeDate.isValid()) {
@ -685,6 +700,47 @@ export default createWidget("discourse-poll", {
this.state.showResults = !this.state.showResults;
},
exportResults() {
const { attrs } = this;
const queryID = this.siteSettings.poll_export_data_explorer_query_id;
// This uses the Data Explorer plugin export as CSV route
// There is detection to check if the plugin is enabled before showing the button
ajax(`/admin/plugins/explorer/queries/${queryID}/run.csv`, {
type: "POST",
data: {
// needed for data-explorer route compatibility
params: JSON.stringify({
poll_name: attrs.poll.name,
post_id: attrs.post.id.toString() // needed for data-explorer route compatibility
}),
explain: false,
limit: 1000000,
download: 1
}
})
.then(csvContent => {
const downloadLink = document.createElement("a");
const blob = new Blob([csvContent], {
type: "text/csv;charset=utf-8;"
});
downloadLink.href = URL.createObjectURL(blob);
downloadLink.setAttribute(
"download",
`poll-export-${attrs.poll.name}-${attrs.post.id}.csv`
);
downloadLink.click();
downloadLink.remove();
})
.catch(error => {
if (error) {
popupAjaxError(error);
} else {
bootbox.alert(I18n.t("poll.error_while_exporting_results"));
}
});
},
showLogin() {
this.register.lookup("route:application").send("showLogin");
},