diff --git a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 index 7d9b0bbd..8a2ae9ce 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 @@ -24,6 +24,8 @@ const customFieldActionMap = { user: ["update_profile"], }; +const values = ["present", "true", "false"]; + export default Component.extend({ classNameBindings: [":mapper-selector", "activeType"], @@ -60,6 +62,9 @@ export default Component.extend({ showCustomField: computed("activeType", function () { return this.showInput("customField"); }), + showValue: computed("activeType", function () { + return this.showInput("value"); + }), textEnabled: computed("options.textSelection", "inputType", function () { return this.optionEnabled("textSelection"); }), @@ -117,6 +122,9 @@ export default Component.extend({ listEnabled: computed("options.listSelection", "inputType", function () { return this.optionEnabled("listSelection"); }), + valueEnabled: computed("connector", function () { + return this.connector === "is"; + }), groups: alias("site.groups"), categories: alias("site.categories"), @@ -125,7 +133,8 @@ export default Component.extend({ "showWizardAction", "showUserField", "showUserFieldOptions", - "showCustomField" + "showCustomField", + "showValue" ), showMultiSelect: or("showCategory", "showGroup"), hasTypes: gt("selectorTypes.length", 1), @@ -157,7 +166,7 @@ export default Component.extend({ } }, - @discourseComputed + @discourseComputed("connector") selectorTypes() { return selectionTypes .filter((type) => this[`${type}Enabled`]) @@ -268,6 +277,13 @@ export default Component.extend({ })); } + if (activeType === "value") { + content = values.map((value) => ({ + id: value, + name: value, + })); + } + return content; }, @@ -337,7 +353,7 @@ export default Component.extend({ resetActiveType() { this.set( "activeType", - defaultSelectionType(this.selectorType, this.options) + defaultSelectionType(this.selectorType, this.options, this.connector) ); }, diff --git a/assets/javascripts/discourse/lib/wizard-mapper.js.es6 b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 index 29315b9c..c398eaf4 100644 --- a/assets/javascripts/discourse/lib/wizard-mapper.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 @@ -105,13 +105,18 @@ const selectionTypes = [ "tag", "user", "customField", + "value", ]; -function defaultSelectionType(inputType, options = {}) { +function defaultSelectionType(inputType, options = {}, connector = null) { if (options[`${inputType}DefaultSelection`]) { return options[`${inputType}DefaultSelection`]; } + if (connector === "is") { + return "value"; + } + let type = selectionTypes[0]; for (let t of selectionTypes) { diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs index ffb9eaf2..c4c15907 100644 --- a/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-pair.hbs @@ -23,7 +23,8 @@ value=pair.value activeType=pair.value_type options=options - onUpdate=onUpdate}} + onUpdate=onUpdate + connector=pair.connector}} {{#if showJoin}} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d9b34a87..b07fd84a 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -124,6 +124,7 @@ en: group: "group" list: "list" custom_field: "custom field" + value: "value" placeholder: text: "Enter text" @@ -138,7 +139,8 @@ en: group: "Select group" list: "Enter item" custom_field: "Select field" - + value: "Select value" + error: failed: "failed to save wizard" required: "{{type}} requires {{property}}" diff --git a/lib/custom_wizard/mapper.rb b/lib/custom_wizard/mapper.rb index 3ba52cb0..0ded76cf 100644 --- a/lib/custom_wizard/mapper.rb +++ b/lib/custom_wizard/mapper.rb @@ -143,7 +143,7 @@ class CustomWizard::Mapper if value == "present" result = key.public_send(operator) elsif ["true", "false"].include?(value) - result = key.public_send(operator, ActiveRecord::Type::Boolean.new.cast(value)) + result = bool(key).public_send(operator, bool(value)) end elsif [key, value, operator].all? { |i| !i.nil? } result = key.public_send(operator, value) @@ -265,4 +265,8 @@ class CustomWizard::Mapper result = data[k] keys.empty? ? result : self.recurse(result, keys) end + + def bool(value) + ActiveRecord::Type::Boolean.new.cast(value) + end end diff --git a/plugin.rb b/plugin.rb index 10fed93b..da28bd3e 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Create custom wizards -# version: 1.15.1 +# version: 1.15.2 # authors: Angus McLeod # url: https://github.com/paviliondev/discourse-custom-wizard # contact emails: angus@thepavilion.io diff --git a/spec/components/custom_wizard/builder_spec.rb b/spec/components/custom_wizard/builder_spec.rb index 8e80d806..def54fc4 100644 --- a/spec/components/custom_wizard/builder_spec.rb +++ b/spec/components/custom_wizard/builder_spec.rb @@ -47,6 +47,14 @@ describe CustomWizard::Builder do ) } + let(:boolean_field_condition_json) { + JSON.parse( + File.open( + "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/condition/boolean_field_condition.json" + ).read + ) + } + before do Group.refresh_automatic_group!(:trust_level_3) CustomWizard::Template.save( @@ -322,6 +330,7 @@ describe CustomWizard::Builder do context "with condition" do before do @template[:steps][0][:fields][0][:condition] = user_condition_json['condition'] + @template[:steps][2][:fields][5][:condition] = boolean_field_condition_json['condition'] CustomWizard::Template.save(@template.as_json) end @@ -334,6 +343,16 @@ describe CustomWizard::Builder do wizard = CustomWizard::Builder.new(@template[:id], user).build expect(wizard.steps.first.fields.first.id).to eq(@template[:steps][0][:fields][1]['id']) end + + it "works if a field condition uses 'is true/false'" do + builder = CustomWizard::Builder.new(@template[:id], user) + wizard = builder.build + wizard.create_updater('step_2', step_2_field_5: 'true').update + + builder = CustomWizard::Builder.new(@template[:id], user) + wizard = builder.build + expect(wizard.steps.last.fields.last.id).to eq(@template[:steps][2][:fields][5]['id']) + end end end diff --git a/spec/fixtures/condition/boolean_field_condition.json b/spec/fixtures/condition/boolean_field_condition.json new file mode 100644 index 00000000..6a264e71 --- /dev/null +++ b/spec/fixtures/condition/boolean_field_condition.json @@ -0,0 +1,17 @@ +{ + "condition": [ + { + "type": "validation", + "pairs": [ + { + "index": 0, + "key": "step_2_field_5", + "key_type": "wizard_field", + "value": "true", + "value_type": "text", + "connector": "is" + } + ] + } + ] +} \ No newline at end of file diff --git a/spec/fixtures/wizard.json b/spec/fixtures/wizard.json index a505c0d3..4727c7a8 100644 --- a/spec/fixtures/wizard.json +++ b/spec/fixtures/wizard.json @@ -157,6 +157,12 @@ "label": "User Selector", "description": "", "type": "user_selector" + }, + { + "id": "step_3_field_6", + "label": "Conditional User Selector", + "description": "Shown when checkbox in step_2_field_5 is true", + "type": "user_selector" } ], "description": "Unfortunately not the edible type :sushi: "