diff --git a/app/controllers/custom_wizard/admin/wizard.rb b/app/controllers/custom_wizard/admin/wizard.rb index 08e7b6d0..955deb3f 100644 --- a/app/controllers/custom_wizard/admin/wizard.rb +++ b/app/controllers/custom_wizard/admin/wizard.rb @@ -115,6 +115,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :preview_template, :placeholder, :can_create_tag, + :category, prefill: mapped_params, content: mapped_params, condition: mapped_params, diff --git a/app/serializers/custom_wizard/wizard_field_serializer.rb b/app/serializers/custom_wizard/wizard_field_serializer.rb index 56e86cc8..af4514ae 100644 --- a/app/serializers/custom_wizard/wizard_field_serializer.rb +++ b/app/serializers/custom_wizard/wizard_field_serializer.rb @@ -18,6 +18,7 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer :content, :tag_groups, :can_create_tag, + :category, :validations, :max_length, :char_counter, diff --git a/assets/javascripts/discourse/components/custom-wizard-field-topic.js.es6 b/assets/javascripts/discourse/components/custom-wizard-field-topic.js.es6 new file mode 100644 index 00000000..ac28aee0 --- /dev/null +++ b/assets/javascripts/discourse/components/custom-wizard-field-topic.js.es6 @@ -0,0 +1,21 @@ +import Component from "@ember/component"; + +export default Component.extend({ + topics: [], + + didInsertElement() { + const value = this.field.value; + + if (value) { + this.set("topics", value); + } + }, + + actions: { + setValue(_, topics) { + if (topics.length) { + this.set("field.value", topics); + } + }, + }, +}); diff --git a/assets/javascripts/discourse/components/custom-wizard-topic-selector.js.es6 b/assets/javascripts/discourse/components/custom-wizard-topic-selector.js.es6 new file mode 100644 index 00000000..b3d9cc57 --- /dev/null +++ b/assets/javascripts/discourse/components/custom-wizard-topic-selector.js.es6 @@ -0,0 +1,73 @@ +import MultiSelectComponent from "select-kit/components/multi-select"; +import { isEmpty } from "@ember/utils"; +import { searchForTerm } from "discourse/lib/search"; +import { makeArray } from "discourse-common/lib/helpers"; + +export default MultiSelectComponent.extend({ + classNames: ["topic-selector", "wizard-topic-selector"], + topics: null, + value: [], + content: [], + nameProperty: "fancy_title", + labelProperty: "title", + titleProperty: "title", + + selectKitOptions: { + clearable: true, + filterable: true, + filterPlaceholder: "choose_topic.title.placeholder", + allowAny: false, + }, + + didReceiveAttrs() { + if (this.topics && !this.selectKit.hasSelection) { + const values = makeArray(this.topics.map((t) => t.id)); + const content = makeArray(this.topics); + this.selectKit.change(values, content); + } + this._super(...arguments); + }, + + modifyComponentForRow() { + return "topic-row"; + }, + + search(filter) { + if (isEmpty(filter)) { + return []; + } + + const searchParams = {}; + searchParams.typeFilter = "topic"; + searchParams.restrictToArchetype = "regular"; + searchParams.searchForId = true; + + if (this.category) { + searchParams.searchContext = { + type: "category", + id: this.category, + }; + } + + return searchForTerm(filter, searchParams).then((results) => { + if (results?.posts?.length > 0) { + return results.posts.mapBy("topic"); + } + }); + }, + + actions: { + onChange(value, items) { + const content = items.map((t) => { + return { + id: t.id, + title: t.title, + fancy_title: t.fancy_title, + url: t.url, + }; + }); + this.setProperties({ value, content }); + this.onChange(value, content); + }, + }, +}); diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index b19667ad..5aff7f6e 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -15,15 +15,23 @@ export default Component.extend(UndoChanges, { isDropdown: equal("field.type", "dropdown"), isUpload: equal("field.type", "upload"), isCategory: equal("field.type", "category"), + isTopic: equal("field.type", "topic"), isGroup: equal("field.type", "group"), isTag: equal("field.type", "tag"), isText: equal("field.type", "text"), isTextarea: equal("field.type", "textarea"), isUrl: equal("field.type", "url"), isComposer: equal("field.type", "composer"), - showPrefill: or("isText", "isCategory", "isTag", "isGroup", "isDropdown"), - showContent: or("isCategory", "isTag", "isGroup", "isDropdown"), - showLimit: or("isCategory", "isTag"), + showPrefill: or( + "isText", + "isCategory", + "isTag", + "isGroup", + "isDropdown", + "isTopic" + ), + showContent: or("isCategory", "isTag", "isGroup", "isDropdown", "isTopic"), + showLimit: or("isCategory", "isTag", "isTopic"), isTextType: or("isText", "isTextarea", "isComposer"), isComposerPreview: equal("field.type", "composer_preview"), categoryPropertyTypes: selectKitContent(["id", "slug"]), @@ -156,5 +164,9 @@ export default Component.extend(UndoChanges, { "field.image_upload_id": null, }); }, + + changeCategory(category) { + this.set("field.category", category?.id); + }, }, }); diff --git a/assets/javascripts/discourse/components/wizard-table-field.js.es6 b/assets/javascripts/discourse/components/wizard-table-field.js.es6 index 93859f1f..363648c2 100644 --- a/assets/javascripts/discourse/components/wizard-table-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-table-field.js.es6 @@ -18,6 +18,7 @@ export default Component.extend({ isDropdown: equal("value.type", "dropdown"), isTag: equal("value.type", "tag"), isCategory: equal("value.type", "category"), + isTopic: equal("value.type", "topic"), isGroup: equal("value.type", "group"), isUserSelector: equal("value.type", "user_selector"), isSubmittedAt: equal("field", "submitted_at"), diff --git a/assets/javascripts/discourse/lib/wizard-schema.js.es6 b/assets/javascripts/discourse/lib/wizard-schema.js.es6 index 959185da..710a3594 100644 --- a/assets/javascripts/discourse/lib/wizard-schema.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-schema.js.es6 @@ -73,6 +73,7 @@ const field = { type: null, condition: null, tag_groups: null, + category: null, }, types: {}, mapped: ["prefill", "content", "condition", "index"], @@ -227,6 +228,7 @@ const filters = { "dropdown", "tag", "category", + "topic", "group", "user_selector", ], diff --git a/assets/javascripts/discourse/models/custom-wizard-field.js.es6 b/assets/javascripts/discourse/models/custom-wizard-field.js.es6 index 9dbbb8f4..03c0d847 100644 --- a/assets/javascripts/discourse/models/custom-wizard-field.js.es6 +++ b/assets/javascripts/discourse/models/custom-wizard-field.js.es6 @@ -14,6 +14,7 @@ const StandardFieldValidation = [ "text_only", "composer", "category", + "topic", "group", "date", "time", diff --git a/assets/javascripts/discourse/models/custom-wizard-step.js.es6 b/assets/javascripts/discourse/models/custom-wizard-step.js.es6 index 5c3ce3ab..24733950 100644 --- a/assets/javascripts/discourse/models/custom-wizard-step.js.es6 +++ b/assets/javascripts/discourse/models/custom-wizard-step.js.es6 @@ -63,7 +63,8 @@ export default EmberObject.extend(ValidState, { return ajax({ url: `/w/${wizardId}/steps/${this.get("id")}`, type: "PUT", - data: { fields }, + contentType: "application/json", + data: JSON.stringify({ fields }), }).catch((response) => { if (response.jqXHR) { response = response.jqXHR; diff --git a/assets/javascripts/discourse/templates/components/custom-wizard-field-topic.hbs b/assets/javascripts/discourse/templates/components/custom-wizard-field-topic.hbs new file mode 100644 index 00000000..fbaf016b --- /dev/null +++ b/assets/javascripts/discourse/templates/components/custom-wizard-field-topic.hbs @@ -0,0 +1,6 @@ +{{custom-wizard-topic-selector + topics=topics + category=field.category + onChange=(action "setValue") + options=(hash maximum=field.limit) +}} \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index c4d297ff..33a4400d 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -245,6 +245,25 @@ {{/if}} +{{#if isTopic}} +
Topic
", + file_types: null, + format: null, + limit: null, + property: null, + content: null, + validations: {}, + max_length: null, + char_counter: null, + preview_template: null, + tabindex: 7, + wizardId: "super_mega_fun_wizard", + stepId: "step_3", + _validState: 0, + }, ], _validState: 0, wizardId: "super_mega_fun_wizard",