diff --git a/.discourse-compatibility b/.discourse-compatibility index b53ff04d..01ce2cde 100644 --- a/.discourse-compatibility +++ b/.discourse-compatibility @@ -1,2 +1,3 @@ +3.1.999: 1f35b80f85e5fd1efb7f4851f0845700432febdc 2.7.99: e07a57e398b6b1676ab42a7e34467556fca5416b 2.5.1: bb85b3a0d2c0ab6b59bcb405731c39089ec6731c diff --git a/app/controllers/custom_wizard/admin/submissions.rb b/app/controllers/custom_wizard/admin/submissions.rb index 72f0961a..d5994c96 100644 --- a/app/controllers/custom_wizard/admin/submissions.rb +++ b/app/controllers/custom_wizard/admin/submissions.rb @@ -23,7 +23,7 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController def download content = ActiveModel::ArraySerializer.new( - submission_list.submissions, + CustomWizard::Submission.list(@wizard).submissions, each_serializer: CustomWizard::SubmissionSerializer ) diff --git a/assets/javascripts/discourse/components/modal/admin-wizards-columns.hbs b/assets/javascripts/discourse/components/modal/admin-wizards-columns.hbs new file mode 100644 index 00000000..5e3829da --- /dev/null +++ b/assets/javascripts/discourse/components/modal/admin-wizards-columns.hbs @@ -0,0 +1,34 @@ + + {{#if loading}} + + {{else}} +
+ {{#each @model.columns as |column|}} +
+
+ +
+
+ {{/each}} +
+ {{/if}} + +
\ No newline at end of file diff --git a/assets/javascripts/discourse/components/modal/admin-wizards-columns.js b/assets/javascripts/discourse/components/modal/admin-wizards-columns.js new file mode 100644 index 00000000..d4da771e --- /dev/null +++ b/assets/javascripts/discourse/components/modal/admin-wizards-columns.js @@ -0,0 +1,15 @@ +import Component from "@glimmer/component"; +import { action } from "@ember/object"; +import I18n from "I18n"; + +export default class AdminWizardsColumnComponent extends Component { + title = I18n.t("admin.wizard.edit_columns"); + + @action save() { + this.args.closeModal(); + } + + @action resetToDefault() { + this.args.model.reset(); + } +} diff --git a/assets/javascripts/discourse/components/modal/next-session-scheduled.hbs b/assets/javascripts/discourse/components/modal/next-session-scheduled.hbs new file mode 100644 index 00000000..2bb4a784 --- /dev/null +++ b/assets/javascripts/discourse/components/modal/next-session-scheduled.hbs @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/assets/javascripts/discourse/components/modal/next-session-scheduled.js b/assets/javascripts/discourse/components/modal/next-session-scheduled.js new file mode 100644 index 00000000..446237f0 --- /dev/null +++ b/assets/javascripts/discourse/components/modal/next-session-scheduled.js @@ -0,0 +1,30 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import I18n from "I18n"; + +export default class NextSessionScheduledComponent extends Component { + @tracked bufferedDateTime; + title = I18n.t("admin.wizard.after_time_modal.title"); + + constructor() { + super(...arguments); + this.bufferedDateTime = this.args.model.dateTime + ? moment(this.args.model.dateTime) + : moment(Date.now()); + } + + get submitDisabled() { + return moment().isAfter(this.bufferedDateTime); + } + + @action submit() { + const dateTime = this.bufferedDateTime; + this.args.model.update(moment(dateTime).utc().toISOString()); + this.args.closeModal(); + } + + @action dateTimeChanged(dateTime) { + this.bufferedDateTime = dateTime; + } +} diff --git a/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 index c08e820c..31b91e16 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 @@ -7,8 +7,11 @@ import { selectKitContent } from "../lib/wizard"; import { underscore } from "@ember/string"; import Controller from "@ember/controller"; import I18n from "I18n"; +import { inject as service } from "@ember/service"; export default Controller.extend({ + router: service(), + queryParams: ["refresh_list"], loadingSubscriptions: false, notAuthorized: not("api.authorized"), @@ -248,7 +251,7 @@ export default Controller.extend({ .catch(popupAjaxError) .then((result) => { if (result.success) { - this.transitionToRoute("adminWizardsApis").then(() => { + this.router.transitionTo("adminWizardsApis").then(() => { this.send("refreshModel"); }); } diff --git a/assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6 deleted file mode 100644 index 4754c577..00000000 --- a/assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6 +++ /dev/null @@ -1,14 +0,0 @@ -import Controller from "@ember/controller"; -import ModalFunctionality from "discourse/mixins/modal-functionality"; - -export default Controller.extend(ModalFunctionality, { - actions: { - save() { - this.send("closeModal"); - }, - - resetToDefault() { - this.get("model.reset")(); - }, - }, -}); diff --git a/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6 index 41dabbb4..dfcf3b7e 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6 @@ -2,11 +2,13 @@ import Controller from "@ember/controller"; import { empty } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; import { fmt } from "discourse/lib/computed"; -import showModal from "discourse/lib/show-modal"; +import { inject as service } from "@ember/service"; +import AdminWizardsColumnsModal from "../components/modal/admin-wizards-columns"; import CustomWizardAdmin from "../models/custom-wizard-admin"; import { formatModel } from "../lib/wizard-submission"; export default Controller.extend({ + modal: service(), downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download"), noResults: empty("submissions"), page: 0, @@ -57,7 +59,7 @@ export default Controller.extend({ }, showEditColumnsModal() { - return showModal("admin-wizards-columns", { + return this.modal.show(AdminWizardsColumnsModal, { model: { columns: this.get("fields"), reset: () => { diff --git a/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 index 75ea0ff7..7ae48709 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 @@ -3,7 +3,8 @@ import { observes, } from "discourse-common/utils/decorators"; import { notEmpty } from "@ember/object/computed"; -import showModal from "discourse/lib/show-modal"; +import { inject as service } from "@ember/service"; +import NextSessionScheduledModal from "../components/modal/next-session-scheduled"; import { generateId, wizardFieldList } from "../lib/wizard"; import { dasherize } from "@ember/string"; import { later, scheduleOnce } from "@ember/runloop"; @@ -13,6 +14,7 @@ import I18n from "I18n"; import { filterValues } from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema"; export default Controller.extend({ + modal: service(), hasName: notEmpty("wizard.name"), @observes("currentStep") @@ -126,15 +128,13 @@ export default Controller.extend({ }, setNextSessionScheduled() { - let controller = showModal("next-session-scheduled", { + this.modal.show(NextSessionScheduledModal, { model: { dateTime: this.wizard.after_time_scheduled, update: (dateTime) => this.set("wizard.after_time_scheduled", dateTime), }, }); - - controller.setup(); }, copyUrl() { diff --git a/assets/javascripts/discourse/controllers/custom-wizard-step.js.es6 b/assets/javascripts/discourse/controllers/custom-wizard-step.js.es6 index 2dca2e70..d1a299fd 100644 --- a/assets/javascripts/discourse/controllers/custom-wizard-step.js.es6 +++ b/assets/javascripts/discourse/controllers/custom-wizard-step.js.es6 @@ -1,7 +1,9 @@ import Controller from "@ember/controller"; import getUrl from "discourse-common/lib/get-url"; +import { inject as service } from "@ember/service"; export default Controller.extend({ + router: service(), wizard: null, step: null, @@ -15,12 +17,12 @@ export default Controller.extend({ const wizardId = this.get("wizard.id"); window.location.href = getUrl(`/w/${wizardId}/steps/${nextStepId}`); } else { - this.transitionToRoute("customWizardStep", nextStepId); + this.router.transitionTo("customWizardStep", nextStepId); } }, goBack() { - this.transitionToRoute("customWizardStep", this.get("step.previous")); + this.router.transitionTo("customWizardStep", this.get("step.previous")); }, showMessage(message) { diff --git a/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 b/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 deleted file mode 100644 index b8f51d1f..00000000 --- a/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 +++ /dev/null @@ -1,30 +0,0 @@ -import { default as discourseComputed } from "discourse-common/utils/decorators"; -import Controller from "@ember/controller"; - -export default Controller.extend({ - title: "admin.wizard.after_time_modal.title", - - setup() { - this.set( - "bufferedDateTime", - this.model.dateTime ? moment(this.model.dateTime) : moment(Date.now()) - ); - }, - - @discourseComputed("bufferedDateTime") - submitDisabled(dateTime) { - return moment().isAfter(dateTime); - }, - - actions: { - submit() { - const dateTime = this.get("bufferedDateTime"); - this.get("model.update")(moment(dateTime).utc().toISOString()); - this.send("closeModal"); - }, - - dateTimeChanged(dateTime) { - this.set("bufferedDateTime", dateTime); - }, - }, -}); diff --git a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 index c974fafb..bd3c3d2d 100644 --- a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 +++ b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 @@ -83,6 +83,16 @@ export default { } }, }); + + api.modifyClass("component:category-chooser", { + categoriesByScope(options = {}) { + let categories = this._super(options); + + return categories.filter((category) => { + return !category.custom_fields?.create_topic_wizard; + }); + }, + }); }); }, }; diff --git a/assets/javascripts/discourse/initializers/custom-wizard-redirect.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-redirect.js.es6 index 70676bb0..c02f0f3d 100644 --- a/assets/javascripts/discourse/initializers/custom-wizard-redirect.js.es6 +++ b/assets/javascripts/discourse/initializers/custom-wizard-redirect.js.es6 @@ -30,6 +30,7 @@ export default { .concat(["loading"]); if ( redirectToWizard && + !data.url.includes("ignore_redirect") && data.currentRouteName !== "customWizardStep" && !excludedPaths.find((p) => { return data.currentRouteName.indexOf(p) > -1; diff --git a/assets/javascripts/discourse/routes/admin-wizards-api-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-api-show.js.es6 index bfe90f72..a431e9ae 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-api-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-api-show.js.es6 @@ -1,7 +1,10 @@ import CustomWizardApi from "../models/custom-wizard-api"; import DiscourseRoute from "discourse/routes/discourse"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model(params) { if (params.name === "create") { return CustomWizardApi.create({ isNew: true }); @@ -12,7 +15,7 @@ export default DiscourseRoute.extend({ afterModel(model) { if (model === null) { - return this.transitionTo("adminWizardsApi"); + return this.router.transitionTo("adminWizardsApi"); } }, diff --git a/assets/javascripts/discourse/routes/admin-wizards-api.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-api.js.es6 index 541ab028..2b108460 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-api.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-api.js.es6 @@ -1,7 +1,10 @@ import DiscourseRoute from "discourse/routes/discourse"; import CustomWizardApi from "../models/custom-wizard-api"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model() { return CustomWizardApi.list(); }, @@ -25,11 +28,11 @@ export default DiscourseRoute.extend({ actions: { changeApi(apiName) { this.controllerFor("adminWizardsApi").set("apiName", apiName); - this.transitionTo("adminWizardsApiShow", apiName); + this.router.transitionTo("adminWizardsApiShow", apiName); }, afterDestroy() { - this.transitionTo("adminWizardsApi").then(() => this.refresh()); + this.router.transitionTo("adminWizardsApi").then(() => this.refresh()); }, afterSave(apiName) { @@ -38,7 +41,7 @@ export default DiscourseRoute.extend({ createApi() { this.controllerFor("adminWizardsApi").set("apiName", "create"); - this.transitionTo("adminWizardsApiShow", "create"); + this.router.transitionTo("adminWizardsApiShow", "create"); }, }, }); diff --git a/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6 index e1f53c8f..9c096a1e 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6 @@ -1,15 +1,18 @@ import CustomWizardLogs from "../models/custom-wizard-logs"; import DiscourseRoute from "discourse/routes/discourse"; import { A } from "@ember/array"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model(params) { return CustomWizardLogs.list(params.wizardId); }, afterModel(model) { if (model === null) { - return this.transitionTo("adminWizardsLogs"); + return this.router.transitionTo("adminWizardsLogs"); } }, diff --git a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 index a1575050..6bb5864b 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 @@ -1,7 +1,10 @@ import DiscourseRoute from "discourse/routes/discourse"; import { ajax } from "discourse/lib/ajax"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model() { return ajax(`/admin/wizards/wizard`); }, @@ -18,7 +21,7 @@ export default DiscourseRoute.extend({ actions: { changeWizard(wizardId) { this.controllerFor("adminWizardsLogs").set("wizardId", wizardId); - this.transitionTo("adminWizardsLogsShow", wizardId); + this.router.transitionTo("adminWizardsLogsShow", wizardId); }, }, }); diff --git a/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 index b9dbd90f..e9bad625 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 @@ -2,15 +2,18 @@ import { A } from "@ember/array"; import CustomWizardAdmin from "../models/custom-wizard-admin"; import DiscourseRoute from "discourse/routes/discourse"; import { formatModel } from "../lib/wizard-submission"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model(params) { return CustomWizardAdmin.submissions(params.wizardId); }, afterModel(model) { if (model === null) { - return this.transitionTo("adminWizardsSubmissions"); + return this.router.transitionTo("adminWizardsSubmissions"); } }, diff --git a/assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6 index 9ecb183d..dc0ef5e0 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6 @@ -1,7 +1,10 @@ import DiscourseRoute from "discourse/routes/discourse"; import { ajax } from "discourse/lib/ajax"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model() { return ajax(`/admin/wizards/wizard`); }, @@ -18,7 +21,7 @@ export default DiscourseRoute.extend({ actions: { changeWizard(wizardId) { this.controllerFor("adminWizardsSubmissions").set("wizardId", wizardId); - this.transitionTo("adminWizardsSubmissionsShow", wizardId); + this.router.transitionTo("adminWizardsSubmissionsShow", wizardId); }, }, }); diff --git a/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 index f55ff19e..2ed2627f 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 @@ -2,8 +2,11 @@ import CustomWizardAdmin from "../models/custom-wizard-admin"; import { ajax } from "discourse/lib/ajax"; import DiscourseRoute from "discourse/routes/discourse"; import I18n from "I18n"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model(params) { if (params.wizardId === "create") { return { create: true }; @@ -14,7 +17,7 @@ export default DiscourseRoute.extend({ afterModel(model) { if (model.none) { - return this.transitionTo("adminWizardsWizard"); + return this.router.transitionTo("adminWizardsWizard"); } }, diff --git a/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 index b23b63f6..6ae31e82 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-wizard.js.es6 @@ -4,8 +4,11 @@ import EmberObject, { set } from "@ember/object"; import { A } from "@ember/array"; import { all } from "rsvp"; import { ajax } from "discourse/lib/ajax"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + model() { return ajax("/admin/wizards/wizard"); }, @@ -80,14 +83,14 @@ export default DiscourseRoute.extend({ this.controllerFor("adminWizardsWizard").set("wizardId", wizardId); if (wizardId) { - this.transitionTo("adminWizardsWizardShow", wizardId); + this.router.transitionTo("adminWizardsWizardShow", wizardId); } else { - this.transitionTo("adminWizardsWizard"); + this.router.transitionTo("adminWizardsWizard"); } }, afterDestroy() { - this.transitionTo("adminWizardsWizard").then(() => this.refresh()); + this.router.transitionTo("adminWizardsWizard").then(() => this.refresh()); }, afterSave(wizardId) { @@ -96,7 +99,7 @@ export default DiscourseRoute.extend({ createWizard() { this.controllerFor("adminWizardsWizard").set("wizardId", "create"); - this.transitionTo("adminWizardsWizardShow", "create"); + this.router.transitionTo("adminWizardsWizardShow", "create"); }, }, }); diff --git a/assets/javascripts/discourse/routes/admin-wizards.js.es6 b/assets/javascripts/discourse/routes/admin-wizards.js.es6 index 6fc0d178..a16df9ae 100644 --- a/assets/javascripts/discourse/routes/admin-wizards.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards.js.es6 @@ -1,9 +1,12 @@ import DiscourseRoute from "discourse/routes/discourse"; +import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ + router: service(), + afterModel(model, transition) { if (transition.targetName === "adminWizards.index") { - this.transitionTo("adminWizardsWizard"); + this.router.transitionTo("adminWizardsWizard"); } }, }); diff --git a/assets/javascripts/discourse/routes/custom-wizard-index.js.es6 b/assets/javascripts/discourse/routes/custom-wizard-index.js.es6 index 5ffe83c6..78495607 100644 --- a/assets/javascripts/discourse/routes/custom-wizard-index.js.es6 +++ b/assets/javascripts/discourse/routes/custom-wizard-index.js.es6 @@ -1,11 +1,14 @@ import { getCachedWizard } from "../models/custom-wizard"; import Route from "@ember/routing/route"; +import { inject as service } from "@ember/service"; export default Route.extend({ + router: service(), + beforeModel() { const wizard = getCachedWizard(); if (wizard && wizard.permitted && !wizard.completed && wizard.start) { - this.replaceWith("customWizardStep", wizard.start); + this.router.replaceWith("customWizardStep", wizard.start); } }, diff --git a/assets/javascripts/discourse/routes/custom-wizard-step.js.es6 b/assets/javascripts/discourse/routes/custom-wizard-step.js.es6 index a882340b..963307e7 100644 --- a/assets/javascripts/discourse/routes/custom-wizard-step.js.es6 +++ b/assets/javascripts/discourse/routes/custom-wizard-step.js.es6 @@ -3,14 +3,17 @@ import { getCachedWizard } from "../models/custom-wizard"; import Route from "@ember/routing/route"; import { scrollTop } from "discourse/mixins/scroll-top"; import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; export default Route.extend({ + router: service(), + beforeModel() { const wizard = getCachedWizard(); this.set("wizard", wizard); if (!wizard || !wizard.permitted || wizard.completed) { - this.replaceWith("customWizard"); + this.router.replaceWith("customWizard"); } }, @@ -27,7 +30,7 @@ export default Route.extend({ afterModel(model) { if (model.completed) { - return this.transitionTo("wizard.index"); + return this.router.transitionTo("wizard.index"); } return model.set("wizardId", this.wizard.id); }, diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index e6a4b703..80152674 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -14,7 +14,7 @@
{{wizard-subscription-selector - value=action.type + value=this.action.type feature="action" attribute="type" onChange=(action "changeType") @@ -31,9 +31,9 @@
{{combo-box - value=action.run_after + value=this.action.run_after content=runAfterContent - onChange=(action (mut action.run_after)) + onChange=(action (mut this.action.run_after)) }}
@@ -48,7 +48,7 @@
{{wizard-mapper - inputs=action.title + inputs=this.action.title property="title" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -67,10 +67,10 @@
{{combo-box - value=action.post + value=this.action.post content=wizardFields nameProperty="label" - onChange=(action (mut action.post)) + onChange=(action (mut this.action.post)) options=(hash none="admin.wizard.selector.placeholder.wizard_field" isDisabled=showPostBuilder @@ -84,7 +84,7 @@
- {{#if action.post_builder}} + {{#if this.action.post_builder}}
@@ -92,7 +92,7 @@
{{wizard-text-editor - value=action.post_template + value=this.action.post_template wizardFields=wizardFields }}
@@ -108,7 +108,7 @@
{{wizard-mapper - inputs=action.category + inputs=this.action.category property="category" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -131,7 +131,7 @@
{{wizard-mapper - inputs=action.tags + inputs=this.action.tags property="tags" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -153,7 +153,7 @@
{{wizard-mapper - inputs=action.visible + inputs=this.action.visible property="visible" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -171,7 +171,7 @@
{{wizard-mapper - inputs=action.add_event + inputs=this.action.add_event property="add_event" onUpdate=(action "mappedFieldUpdated") options=(hash wizardFieldSelection=true context="action") @@ -188,7 +188,7 @@
{{wizard-mapper - inputs=action.add_location + inputs=this.action.add_location property="add_location" onUpdate=(action "mappedFieldUpdated") options=(hash wizardFieldSelection=true context="action") @@ -206,7 +206,7 @@
{{wizard-mapper - inputs=action.recipient + inputs=this.action.recipient property="recipient" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -230,7 +230,7 @@
{{wizard-mapper - inputs=action.profile_updates + inputs=this.action.profile_updates property="profile_updates" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -254,11 +254,11 @@
{{combo-box - value=action.api + value=this.action.api content=availableApis - onChange=(action (mut action.api)) + onChange=(action (mut this.action.api)) options=(hash - isDisabled=action.custom_title_enabled + isDisabled=this.action.custom_title_enabled none="admin.wizard.action.send_to_api.select_an_api" ) }} @@ -272,9 +272,9 @@
{{combo-box - value=action.api_endpoint + value=this.action.api_endpoint content=availableEndpoints - onChange=(action (mut action.api_endpoint)) + onChange=(action (mut this.action.api_endpoint)) options=(hash isDisabled=apiEmpty none="admin.wizard.action.send_to_api.select_an_endpoint" @@ -290,7 +290,7 @@
{{wizard-text-editor - value=action.api_body + value=this.action.api_body previewEnabled=false barEnabled=false wizardFields=wizardFields @@ -308,7 +308,7 @@
{{wizard-mapper - inputs=action.group + inputs=this.action.group property="group" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -333,7 +333,7 @@
{{wizard-mapper - inputs=action.url + inputs=this.action.url property="url" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -357,7 +357,7 @@
{{wizard-mapper - inputs=action.categories + inputs=this.action.categories property="categories" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -381,7 +381,7 @@
{{wizard-mapper - inputs=action.mute_remainder + inputs=this.action.mute_remainder property="mute_remainder" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -402,11 +402,11 @@
{{combo-box - value=action.notification_level + value=this.action.notification_level content=availableNotificationLevels - onChange=(action (mut action.notification_level)) + onChange=(action (mut this.action.notification_level)) options=(hash - isDisabled=action.custom_title_enabled + isDisabled=this.action.custom_title_enabled none="admin.wizard.action.watch_x.select_a_notification_level" ) }} @@ -430,7 +430,7 @@
{{wizard-mapper - inputs=action.usernames + inputs=this.action.usernames property="usernames" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -452,7 +452,7 @@
{{wizard-mapper - inputs=action.tags + inputs=this.action.tags property="tags" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -476,11 +476,11 @@
{{combo-box - value=action.notification_level + value=this.action.notification_level content=availableNotificationLevels - onChange=(action (mut action.notification_level)) + onChange=(action (mut this.action.notification_level)) options=(hash - isDisabled=action.custom_title_enabled + isDisabled=this.action.custom_title_enabled none="admin.wizard.action.watch_x.select_a_notification_level" ) }} @@ -504,7 +504,7 @@
{{wizard-mapper - inputs=action.usernames + inputs=this.action.usernames property="usernames" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -526,7 +526,7 @@
{{wizard-mapper - inputs=action.name + inputs=this.action.name property="name" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -545,7 +545,7 @@
{{wizard-mapper - inputs=action.full_name + inputs=this.action.full_name property="full_name" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -564,7 +564,7 @@
{{wizard-mapper - inputs=action.title + inputs=this.action.title property="title" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -583,7 +583,7 @@
{{wizard-mapper - inputs=action.bio_raw + inputs=this.action.bio_raw property="bio_raw" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -602,7 +602,7 @@
{{wizard-mapper - inputs=action.owner_usernames + inputs=this.action.owner_usernames property="owner_usernames" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -622,7 +622,7 @@
{{wizard-mapper - inputs=action.usernames + inputs=this.action.usernames property="usernames" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -644,7 +644,7 @@
{{wizard-mapper - inputs=action.grant_trust_level + inputs=this.action.grant_trust_level property="grant_trust_level" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -665,7 +665,7 @@
{{wizard-mapper - inputs=action.mentionable_level + inputs=this.action.mentionable_level property="mentionable_level" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -686,7 +686,7 @@
{{wizard-mapper - inputs=action.messageable_level + inputs=this.action.messageable_level property="messageable_level" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -707,7 +707,7 @@
{{wizard-mapper - inputs=action.visibility_level + inputs=this.action.visibility_level property="visibility_level" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -728,7 +728,7 @@
{{wizard-mapper - inputs=action.members_visibility_level + inputs=this.action.members_visibility_level property="members_visibility_level" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -750,7 +750,7 @@
{{wizard-mapper - inputs=action.name + inputs=this.action.name property="name" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -770,7 +770,7 @@
{{wizard-mapper - inputs=action.slug + inputs=this.action.slug property="slug" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -790,7 +790,7 @@
{{wizard-mapper - inputs=action.color + inputs=this.action.color property="color" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -810,7 +810,7 @@
{{wizard-mapper - inputs=action.text_color + inputs=this.action.text_color property="text_color" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -832,7 +832,7 @@
{{wizard-mapper - inputs=action.parent_category_id + inputs=this.action.parent_category_id property="parent_category_id" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -853,7 +853,7 @@
{{wizard-mapper - inputs=action.permissions + inputs=this.action.permissions property="permissions" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -878,7 +878,7 @@
{{wizard-mapper - inputs=action.custom_fields + inputs=this.action.custom_fields property="custom_fields" onUpdate=(action "mappedFieldUpdated") options=(hash @@ -903,7 +903,7 @@
{{wizard-mapper - inputs=action.required + inputs=this.action.required property="required" onUpdate=(action "mappedFieldUpdated") options=(hash diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs index 4138a254..d21a90c0 100644 --- a/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-input.hbs @@ -1,23 +1,23 @@ {{wizard-mapper-connector - connector=input.type - connectors=inputTypes + connector=this.input.type + connectors=this.inputTypes inputTypes=true - inputType=inputType + inputType=this.inputType connectorType="type" - options=options - onUpdate=onUpdate + options=this.options + onUpdate=this.onUpdate }} {{#if hasPairs}}
- {{#each input.pairs as |pair|}} + {{#each this.input.pairs as |pair|}} {{wizard-mapper-pair pair=pair last=pair.last - inputType=inputType - options=options + inputType=this.inputType + options=this.options removePair=(action "removePair") - onUpdate=onUpdate + onUpdate=this.onUpdate }} {{/each}} @@ -32,27 +32,27 @@ {{#if hasOutput}} {{#if hasPairs}} {{wizard-mapper-connector - connector=input.output_connector - connectors=connectors + connector=this.input.output_connector + connectors=this.connectors connectorType="output" - inputType=inputType - options=options - onUpdate=onUpdate + inputType=this.inputType + options=this.options + onUpdate=this.onUpdate }} {{/if}}
{{wizard-mapper-selector selectorType="output" - inputType=input.type - value=input.output - activeType=input.output_type - options=options - onUpdate=onUpdate + inputType=this.input.type + value=this.input.output + activeType=this.input.output_type + options=this.options + onUpdate=this.onUpdate }}
{{/if}} - + {{d-icon "times"}} \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs b/assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs deleted file mode 100644 index b37a92bf..00000000 --- a/assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs +++ /dev/null @@ -1,35 +0,0 @@ -{{#d-modal-body title="admin.wizard.edit_columns"}} - {{#if loading}} - {{loading-spinner size="large"}} - {{else}} -
- {{#each model.columns as |column|}} -
-
- -
-
- {{/each}} -
- {{/if}} -{{/d-modal-body}} - - \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs b/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs deleted file mode 100644 index c7e52a56..00000000 --- a/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs +++ /dev/null @@ -1,17 +0,0 @@ -{{#d-modal-body class="next-session-time-modal" title=title}} - {{date-time-input - date=bufferedDateTime - onChange=(action "dateTimeChanged") - showTime=true - clearable=true - }} -{{/d-modal-body}} - - \ No newline at end of file diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index e8ceb44b..9fa23d53 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -55,6 +55,8 @@ en: liquid_syntax_error: "Liquid syntax error in %{attribute}: %{message}" subscription: "%{type} %{property} usage is not supported on your subscription" not_permitted_for_guests: "%{object_id} is not permitted when guests can access the wizard" + error_messages: + wizard_replacing_composer: "Category not allowed for topic creation." site_settings: custom_wizard_enabled: "Enable custom wizards." diff --git a/plugin.rb b/plugin.rb index f50e1e8a..2c2f5215 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. -# version: 2.4.21 +# version: 2.4.24 # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos # url: https://github.com/paviliondev/discourse-custom-wizard # contact_emails: development@pavilion.tech @@ -239,4 +239,13 @@ after_initialize do end DiscourseEvent.trigger(:custom_wizard_ready) + + on(:before_create_topic) do |topic_params, user| + category = topic_params.category + if category&.custom_fields&.[]('create_topic_wizard').present? + raise Discourse::InvalidParameters.new( + I18n.t('wizard.error_messages.wizard_replacing_composer') + ) + end + end end diff --git a/spec/extensions/topic_extension_spec.rb b/spec/extensions/topic_extension_spec.rb new file mode 100644 index 00000000..da4f416e --- /dev/null +++ b/spec/extensions/topic_extension_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +describe Topic, type: :model do + fab!(:category_with_wizard) do + Fabricate(:category, custom_fields: { create_topic_wizard: 'true' }) + end + fab!(:category_without_wizard) { Fabricate(:category) } + fab!(:user) { Fabricate(:user) } + let(:valid_attrs) { Fabricate.attributes_for(:topic) } + + context 'with a create_topic_wizard custom field in the category' do + it 'will not allow creating a topic directly' do + expect do + TopicCreator.create( + user, + Guardian.new(user), + valid_attrs.merge( + title: 'A valid and sufficiently long title for testing', + category: category_with_wizard.id, + raw: 'hello this is a test topic with category with custom fields' + ) + ) + end.to raise_error( + Discourse::InvalidParameters, + 'Category not allowed for topic creation.' + ) + end + end + + context 'without a create_topic_wizard custom field in the category' do + it 'will allow creating a topic directly' do + expect do + TopicCreator.create( + user, + Guardian.new(user), + valid_attrs.merge( + category: category_without_wizard.id, + title: 'Another valid and sufficiently long title for testing', + raw: 'This is the body of a valid topic' + ) + ) + end.not_to raise_error + end + end +end diff --git a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js index 8811c989..fbfa2314 100644 --- a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js +++ b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js @@ -13,7 +13,7 @@ import { } from "../helpers/admin-wizard"; import { Promise } from "rsvp"; -acceptance("Admin | Custom Fields Unsuscribed", function (needs) { +acceptance("Admin | Custom Fields Unsubscribed", function (needs) { needs.user(); needs.settings({ custom_wizard_enabled: true, diff --git a/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js b/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js index 9e2b00e7..52d70e69 100644 --- a/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js +++ b/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js @@ -16,7 +16,7 @@ import { getWizard, } from "../helpers/admin-wizard"; -acceptance("Admin | Custom Wizard Unsuscribed", function (needs) { +acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { needs.user(); needs.settings({ custom_wizard_enabled: true, @@ -257,7 +257,7 @@ acceptance("Admin | Custom Wizard Unsuscribed", function (needs) { ".wizard-custom-step .wizard-text-editor .d-editor button.local-dates" ); assert.ok( - exists(".discourse-local-dates-create-modal.modal-body"), + exists(".discourse-local-dates-create-modal .modal-body"), "Insert date-time modal visible" ); assert.ok( @@ -269,7 +269,7 @@ acceptance("Admin | Custom Wizard Unsuscribed", function (needs) { await click(".modal-footer button.advanced-mode-btn"); assert.ok( exists( - ".discourse-local-dates-create-modal.modal-body .advanced-options" + ".discourse-local-dates-create-modal .modal-body .advanced-options" ), "Advanced mode is visible" ); diff --git a/test/javascripts/acceptance/category-chooser-initializer-test.js b/test/javascripts/acceptance/category-chooser-initializer-test.js new file mode 100644 index 00000000..f7e02bb8 --- /dev/null +++ b/test/javascripts/acceptance/category-chooser-initializer-test.js @@ -0,0 +1,82 @@ +import { click, visit } from "@ember/test-helpers"; +import { acceptance } from "discourse/tests/helpers/qunit-helpers"; +import selectKit from "discourse/tests/helpers/select-kit-helper"; +import { test } from "qunit"; + +acceptance("Category Chooser Initializer", function (needs) { + needs.user(); + needs.settings({ + allow_uncategorized_topics: false, + }); + needs.site({ + can_tag_topics: true, + categories: [ + { + id: 1, + name: "General", + slug: "general", + permission: 1, + topic_template: null, + }, + { + id: 2, + name: "Category with custom field", + slug: "category-custom-field", + permission: 1, + topic_template: "", + custom_fields: { + create_topic_wizard: "21", + }, + }, + { + id: 3, + name: "Category 1", + slug: "category-1", + permission: 1, + topic_template: "", + }, + { + id: 4, + name: "Category 2", + slug: "category-2", + permission: 1, + topic_template: "", + }, + ], + }); + + test("does not display category with create_topic_wizard custom field", async function (assert) { + const categoryChooser = selectKit(".category-chooser"); + + await visit("/"); + await click("#create-topic"); + await categoryChooser.expand(); + let categories = Array.from( + document.querySelectorAll(".category-chooser .category-row") + ).filter((category) => category.getAttribute("data-name")); // Filter elements with a data-name attribute + assert.equal( + categories.length, + 3, + "Correct number of categories are displayed" + ); + const categoryNames = ["General", "Category 1", "Category 2"]; + + categoryNames.forEach((categoryName) => { + assert.ok( + categories.some( + (category) => category.getAttribute("data-name") === categoryName + ), + `Category '${categoryName}' is displayed` + ); + }); + + const categoryNameWithCustomField = "Category with custom field"; + assert.notOk( + categories.some( + (category) => + category.getAttribute("data-name") === categoryNameWithCustomField + ), + `Category '${categoryNameWithCustomField}' is not displayed` + ); + }); +}); diff --git a/test/javascripts/acceptance/wizard-test.js b/test/javascripts/acceptance/wizard-test.js index dd441649..0527cf0f 100644 --- a/test/javascripts/acceptance/wizard-test.js +++ b/test/javascripts/acceptance/wizard-test.js @@ -74,6 +74,15 @@ acceptance("Wizard | Redirect", function (needs) { "pending wizard routing works" ); }); + + test("Don't redirect to pending Wizard when ingore redirect param is supplied", async function (assert) { + sinon.stub(DiscourseURL, "routeTo"); + await visit("/latest?ignore_redirect=1"); + assert.notOk( + DiscourseURL.routeTo.calledWith("/w/wizard"), + "pending wizard routing blocked" + ); + }); }); acceptance("Wizard | Wizard", function (needs) {