diff --git a/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 new file mode 100644 index 00000000..72a66137 --- /dev/null +++ b/assets/javascripts/discourse/controllers/admin-wizards-custom-fields.js.es6 @@ -0,0 +1,28 @@ +import Controller from "@ember/controller"; +import EmberObject from '@ember/object'; +import { ajax } from 'discourse/lib/ajax'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; + +export default Controller.extend({ + fieldKeys: ['klass', 'name', 'type'], + classes: ['topic', 'user', 'group'], + + actions: { + addField() { + this.get('customFields').pushObject( + EmberObject.create({ + new: true + }) + ); + }, + + saveFields() { + ajax(`/admin/wizards/custom-fields`, { + type: 'PUT', + data: { + custom_fields: this.customFields + } + }).catch(popupAjaxError) + } + } +}); \ No newline at end of file diff --git a/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 b/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 index c2722816..97157964 100644 --- a/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 +++ b/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 @@ -7,6 +7,8 @@ export default { this.route('adminWizardsWizardShow', { path: '/:wizardId/', resetNamespace: true }); }); + this.route('adminWizardsCustomFields', { path: '/custom-fields', resetNamespace: true }); + this.route('adminWizardsSubmissions', { path: '/submissions', resetNamespace: true }, function() { this.route('adminWizardsSubmissionsShow', { path: '/:wizardId/', resetNamespace: true }); }) diff --git a/assets/javascripts/discourse/routes/admin-wizards-custom-fields.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-custom-fields.js.es6 new file mode 100644 index 00000000..c6775477 --- /dev/null +++ b/assets/javascripts/discourse/routes/admin-wizards-custom-fields.js.es6 @@ -0,0 +1,13 @@ +import DiscourseRoute from "discourse/routes/discourse"; +import { ajax } from 'discourse/lib/ajax'; +import { A } from "@ember/array"; + +export default DiscourseRoute.extend({ + model() { + return ajax('/admin/wizards/custom-fields'); + }, + + setupController(controller, model) { + controller.set('customFields', A(model || [])); + } +}); \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/admin-wizards-custom-fields.hbs b/assets/javascripts/discourse/templates/admin-wizards-custom-fields.hbs new file mode 100644 index 00000000..8dd340f0 --- /dev/null +++ b/assets/javascripts/discourse/templates/admin-wizards-custom-fields.hbs @@ -0,0 +1,33 @@ +
+

{{i18n 'admin.wizard.custom_fields.nav_label'}}

+ + {{d-button + label="add" + icon="plus" + action="addField"}} +
+ +
+ {{#if model}} + + + {{#each fieldKeys as |key|}} + + {{/each}} + + {{#each customFields as |field|}} + + {{#if field.new}} + + + + {{else}} + {{#each-in field as |k v|}} + + {{/each-in}} + {{/if}} + + {{/each}} +
{{i18n (concat "admin.wizard.custom_fields." key)}}
{{combo-box value=field.klass content=classes onChange=(action (mut field.klass))}}{{input value=field.name}}{{combo-box value=field.type content=types onChange=(action (mut field.type))}}{{v}}
+ {{/if}} +
diff --git a/assets/javascripts/discourse/templates/admin-wizards.hbs b/assets/javascripts/discourse/templates/admin-wizards.hbs index c0bd6b27..1e6399ab 100644 --- a/assets/javascripts/discourse/templates/admin-wizards.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards.hbs @@ -1,5 +1,6 @@ {{#admin-nav}} {{nav-item route='adminWizardsWizard' label='admin.wizard.nav_label'}} + {{nav-item route='adminWizardsCustomFields' label='admin.wizard.custom_fields.nav_label'}} {{nav-item route='adminWizardsSubmissions' label='admin.wizard.submissions.nav_label'}} {{#if siteSettings.wizard_apis_enabled}} {{nav-item route='adminWizardsApi' label='admin.wizard.api.nav_label'}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index 272c3155..c212deab 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -731,6 +731,7 @@ options=(hash inputTypes='association' wizardFieldSelection='value' + wizardActionSelection='value' userFieldSelection='value' keyPlaceholder='admin.wizard.action.custom_fields.key' context='action' diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 65e31c96..db02af96 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -274,6 +274,12 @@ en: visibility_level: Visibility Level members_visibility_level: Members Visibility Level + custom_fields: + nav_label: "Custom Fields" + klass: "Class" + name: "Name" + type: "Type" + submissions: nav_label: "Submissions" title: "{{name}} Submissions" diff --git a/controllers/custom_wizard/admin/custom_fields.rb b/controllers/custom_wizard/admin/custom_fields.rb new file mode 100644 index 00000000..24b5310d --- /dev/null +++ b/controllers/custom_wizard/admin/custom_fields.rb @@ -0,0 +1,40 @@ +class CustomWizard::CustomFieldsController < CustomWizard::AdminController + def index + render_custom_field_list + end + + def update + field_data = params[:custom_fields] + + custom_fields = field_data.map { |data| CustomWizard::CustomFields.new(data) } + + custom_fields.each do |field_data| + custom_field.validate + + unless custom_field.valid? + raise Discourse::InvalidParameters, "Invalid field: '#{custom_field.name}'" + end + end + + all_fields_saved = true + + custom_fields.each do |field| + unless field.save + all_fields_saved = false + end + end + + if all_fields_saved + render_custom_field_list + else + render json: error_json + end + end + + def render_custom_field_list + render_serialized( + CustomWizard::CustomFields.list, + CustomWizard::CustomFieldsSerializer + ) + end +end \ No newline at end of file diff --git a/lib/custom_wizard/custom_fields.rb b/lib/custom_wizard/custom_fields.rb new file mode 100644 index 00000000..98c3cc01 --- /dev/null +++ b/lib/custom_wizard/custom_fields.rb @@ -0,0 +1,61 @@ +class ::CustomWizard::CustomFields + include HasErrors + include ActiveModel::Serialization + + CLASSES ||= ["topic", "user", "group", "category"] + ATTRS ||= ["name", "klass", "type"] + KEY ||= "custom_wizard_custom_fields" + + def initialize(data) + data = data.with_indifferent_access + + ATTRS.each do |attr| + self.class.class_eval { attr_accessor attr } + send("#{attr}=", data[attr]) if data[attr].present? + end + end + + def save + validate + + if valid? + data = {} + name = nil + + ATTRS.each do |attr| + value = send(attr) + + if attr == 'name' + name = value + else + data[attr] = value + end + end + + PluginStore.set(KEY, name, data) + else + false + end + end + + def validate + ATTRS.each do |attr| + value = send(attr) + add_error("Attribute required: #{attr}") if value.blank? + add_error("Unsupported class: #{value}") if CLASSES.exclude?(value) + end + end + + def valid? + errors.blank? + end + + def self.list + PluginStoreRow.where(plugin_name: KEY) + .map do |record| + data = JSON.parse(record.value) + data[:name] = record.key + self.new(data) + end + end +end \ No newline at end of file diff --git a/lib/custom_wizard/wizard.rb b/lib/custom_wizard/wizard.rb index 04308a7f..549b0422 100644 --- a/lib/custom_wizard/wizard.rb +++ b/lib/custom_wizard/wizard.rb @@ -320,6 +320,10 @@ class CustomWizard::Wizard Jobs.cancel_scheduled_job(:set_after_time_wizard, wizard_id: wizard[:id]) Jobs.enqueue(:clear_after_time_wizard, wizard_id: wizard[:id]) end + + if serialize_fields.present? + + end end wizard[:id] diff --git a/plugin.rb b/plugin.rb index dfe3d063..01852f63 100644 --- a/plugin.rb +++ b/plugin.rb @@ -42,6 +42,7 @@ after_initialize do ../controllers/custom_wizard/admin/submissions.rb ../controllers/custom_wizard/admin/api.rb ../controllers/custom_wizard/admin/logs.rb + ../controllers/custom_wizard/admin/custom_fields.rb ../controllers/custom_wizard/wizard.rb ../controllers/custom_wizard/steps.rb ../controllers/custom_wizard/transfer.rb @@ -51,6 +52,7 @@ after_initialize do ../lib/custom_wizard/action_result.rb ../lib/custom_wizard/action.rb ../lib/custom_wizard/builder.rb + ../lib/custom_wizard/custom_fields.rb ../lib/custom_wizard/field.rb ../lib/custom_wizard/mapper.rb ../lib/custom_wizard/log.rb @@ -68,6 +70,7 @@ after_initialize do ../serializers/custom_wizard/api_serializer.rb ../serializers/custom_wizard/basic_api_serializer.rb ../serializers/custom_wizard/basic_wizard_serializer.rb + ../serializers/custom_wizard/custom_fields_serializer.rb ../serializers/custom_wizard/wizard_field_serializer.rb ../serializers/custom_wizard/wizard_step_serializer.rb ../serializers/custom_wizard/wizard_serializer.rb @@ -160,5 +163,19 @@ after_initialize do CustomWizard::Wizard.register_styles + CustomWizard::CustomFields.list.each do |field| + add_to_class(field.klass.to_sym, field.name.to_sym) do + custom_fields[field.name] + end + + add_to_serializer(field.klass.to_sym, field.name.to_sym) do + if field.klass === 'topic' + object.topic.send(field.name) + else + object.send(field.name) + end + end + end + DiscourseEvent.trigger(:custom_wizard_ready) end diff --git a/serializers/custom_wizard/custom_fields_serializer.rb b/serializers/custom_wizard/custom_fields_serializer.rb new file mode 100644 index 00000000..fe8c14f6 --- /dev/null +++ b/serializers/custom_wizard/custom_fields_serializer.rb @@ -0,0 +1,3 @@ +class CustomWizard::CustomFieldsSerializer < ApplicationSerializer + attributes :klass, :name, :type +end \ No newline at end of file