import discourseComputed, { observes } from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; import EmberObject from "@ember/object"; import I18n from "I18n"; export const BAR_CHART_TYPE = "bar"; export const PIE_CHART_TYPE = "pie"; export default Controller.extend({ regularPollType: "regular", numberPollType: "number", multiplePollType: "multiple", alwaysPollResult: "always", votePollResult: "on_vote", closedPollResult: "on_close", staffPollResult: "staff_only", pollChartTypes: [ { name: I18n.t("poll.ui_builder.poll_chart_type.bar"), value: BAR_CHART_TYPE, }, { name: I18n.t("poll.ui_builder.poll_chart_type.pie"), value: PIE_CHART_TYPE, }, ], pollType: null, pollResult: null, pollTitle: null, init() { this._super(...arguments); this._setupPoll(); }, @discourseComputed("regularPollType", "numberPollType", "multiplePollType") pollTypes(regularPollType, numberPollType, multiplePollType) { return [ { name: I18n.t("poll.ui_builder.poll_type.regular"), value: regularPollType, }, { name: I18n.t("poll.ui_builder.poll_type.number"), value: numberPollType, }, { name: I18n.t("poll.ui_builder.poll_type.multiple"), value: multiplePollType, }, ]; }, @discourseComputed("chartType", "pollType", "numberPollType") isPie(chartType, pollType, numberPollType) { return pollType !== numberPollType && chartType === PIE_CHART_TYPE; }, @discourseComputed( "alwaysPollResult", "votePollResult", "closedPollResult", "staffPollResult" ) pollResults( alwaysPollResult, votePollResult, closedPollResult, staffPollResult ) { let options = [ { name: I18n.t("poll.ui_builder.poll_result.always"), value: alwaysPollResult, }, { name: I18n.t("poll.ui_builder.poll_result.vote"), value: votePollResult, }, { name: I18n.t("poll.ui_builder.poll_result.closed"), value: closedPollResult, }, ]; if (this.get("currentUser.staff")) { options.push({ name: I18n.t("poll.ui_builder.poll_result.staff"), value: staffPollResult, }); } return options; }, @discourseComputed("site.groups") siteGroups(groups) { return groups .map((g) => { // prevents group "everyone" to be listed if (g.id !== 0) { return { name: g.name }; } }) .filter(Boolean); }, @discourseComputed("pollType", "regularPollType") isRegular(pollType, regularPollType) { return pollType === regularPollType; }, @discourseComputed("pollType", "pollOptionsCount", "multiplePollType") isMultiple(pollType, count, multiplePollType) { return pollType === multiplePollType && count > 0; }, @discourseComputed("pollType", "numberPollType") isNumber(pollType, numberPollType) { return pollType === numberPollType; }, @discourseComputed("isRegular") showMinMax(isRegular) { return !isRegular; }, @discourseComputed("pollOptions") pollOptionsCount(pollOptions) { if (pollOptions.length === 0) { return 0; } let length = 0; pollOptions.split("\n").forEach((option) => { if (option.length !== 0) { length += 1; } }); return length; }, @observes("pollType", "pollOptionsCount") _setPollMax() { const isMultiple = this.isMultiple; const isNumber = this.isNumber; if (!isMultiple && !isNumber) { return; } if (isMultiple) { this.set("pollMax", this.pollOptionsCount); } else if (isNumber) { this.set("pollMax", this.siteSettings.poll_maximum_options); } }, @discourseComputed("isRegular", "isMultiple", "isNumber", "pollOptionsCount") pollMinOptions(isRegular, isMultiple, isNumber, count) { if (isRegular) { return; } if (isMultiple) { return this._comboboxOptions(1, count + 1); } else if (isNumber) { return this._comboboxOptions( 1, this.siteSettings.poll_maximum_options + 1 ); } }, @discourseComputed( "isRegular", "isMultiple", "isNumber", "pollOptionsCount", "pollMin", "pollStep" ) pollMaxOptions(isRegular, isMultiple, isNumber, count, pollMin, pollStep) { if (isRegular) { return; } const pollMinInt = parseInt(pollMin, 10) || 1; if (isMultiple) { return this._comboboxOptions(pollMinInt + 1, count + 1); } else if (isNumber) { let pollStepInt = parseInt(pollStep, 10); if (pollStepInt < 1) { pollStepInt = 1; } return this._comboboxOptions( pollMinInt + 1, pollMinInt + this.siteSettings.poll_maximum_options * pollStepInt ); } }, @discourseComputed("isNumber", "pollMax") pollStepOptions(isNumber, pollMax) { if (!isNumber) { return; } return this._comboboxOptions(1, (parseInt(pollMax, 10) || 1) + 1); }, @discourseComputed( "isNumber", "showMinMax", "pollType", "pollResult", "publicPoll", "pollTitle", "pollOptions", "pollMin", "pollMax", "pollStep", "pollGroups", "autoClose", "chartType", "date", "time" ) pollOutput( isNumber, showMinMax, pollType, pollResult, publicPoll, pollTitle, pollOptions, pollMin, pollMax, pollStep, pollGroups, autoClose, chartType, date, time ) { let pollHeader = "[poll"; let output = ""; const match = this.toolbarEvent .getText() .match(/\[poll(\s+name=[^\s\]]+)*.*\]/gim); if (match) { pollHeader += ` name=poll${match.length + 1}`; } let step = pollStep; if (step < 1) { step = 1; } if (pollType) { pollHeader += ` type=${pollType}`; } if (pollResult) { pollHeader += ` results=${pollResult}`; } if (pollMin && showMinMax) { pollHeader += ` min=${pollMin}`; } if (pollMax) { pollHeader += ` max=${pollMax}`; } if (isNumber) { pollHeader += ` step=${step}`; } if (publicPoll) { pollHeader += ` public=true`; } if (chartType && pollType !== "number") { pollHeader += ` chartType=${chartType}`; } if (pollGroups && pollGroups.length > 0) { pollHeader += ` groups=${pollGroups}`; } if (autoClose) { let closeDate = moment( date + " " + time, "YYYY-MM-DD HH:mm" ).toISOString(); if (closeDate) { pollHeader += ` close=${closeDate}`; } } pollHeader += "]"; output += `${pollHeader}\n`; if (pollTitle) { output += `# ${pollTitle.trim()}\n`; } if (pollOptions.length > 0 && !isNumber) { pollOptions.split("\n").forEach((option) => { if (option.length !== 0) { output += `* ${option}\n`; } }); } output += "[/poll]\n"; return output; }, @discourseComputed( "pollOptionsCount", "isRegular", "isMultiple", "isNumber", "pollMin", "pollMax" ) disableInsert(count, isRegular, isMultiple, isNumber, pollMin, pollMax) { return ( (isRegular && count < 1) || (isMultiple && count < pollMin && pollMin >= pollMax) || (isNumber ? false : count < 1) ); }, @discourseComputed("pollMin", "pollMax") minMaxValueValidation(pollMin, pollMax) { let options = { ok: true }; if (pollMin >= pollMax) { options = { failed: true, reason: I18n.t("poll.ui_builder.help.invalid_values"), }; } return EmberObject.create(options); }, @discourseComputed("pollStep") minStepValueValidation(pollStep) { let options = { ok: true }; if (pollStep < 1) { options = { failed: true, reason: I18n.t("poll.ui_builder.help.min_step_value"), }; } return EmberObject.create(options); }, @discourseComputed("disableInsert") minNumOfOptionsValidation(disableInsert) { let options = { ok: true }; if (disableInsert) { options = { failed: true, reason: I18n.t("poll.ui_builder.help.options_count"), }; } return EmberObject.create(options); }, _comboboxOptions(startIndex, endIndex) { return [...Array(endIndex - startIndex).keys()].map((number) => ({ value: number + startIndex, name: number + startIndex, })); }, _setupPoll() { this.setProperties({ pollType: this.get("pollTypes.firstObject.value"), publicPoll: false, pollOptions: "", pollMin: 1, pollMax: null, pollStep: 1, autoClose: false, chartType: BAR_CHART_TYPE, pollResult: this.alwaysPollResult, pollGroups: null, pollTitle: null, date: moment().add(1, "day").format("YYYY-MM-DD"), time: moment().add(1, "hour").format("HH:mm"), }); }, actions: { insertPoll() { this.toolbarEvent.addText(this.pollOutput); this.send("closeModal"); this._setupPoll(); }, }, });