From 632493f3630fe854d6110a3241c91be47cacdc10 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Sun, 22 Mar 2020 17:51:20 +1100 Subject: [PATCH 1/7] Update builder.rb --- lib/custom_wizard/builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index ea8bdc01..30feee98 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -415,7 +415,7 @@ class CustomWizard::Builder end end else - value = [*value] + tags if key === 'tags' + value = [*value] + [*tags] if key === 'tags' params[key.to_sym] = value end end From f2d7f57bb65fa83c93ffef77cfde0ede659a508a Mon Sep 17 00:00:00 2001 From: Robert Barrow Date: Mon, 23 Mar 2020 14:49:39 +0000 Subject: [PATCH 2/7] first feature commit --- assets/javascripts/wizard/controllers/custom-step.js.es6 | 1 + .../wizard/templates/components/wizard-field-number.hbs | 1 + lib/custom_wizard/builder.rb | 2 ++ lib/custom_wizard/field.rb | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 assets/javascripts/wizard/templates/components/wizard-field-number.hbs diff --git a/assets/javascripts/wizard/controllers/custom-step.js.es6 b/assets/javascripts/wizard/controllers/custom-step.js.es6 index 1881764c..892f785b 100644 --- a/assets/javascripts/wizard/controllers/custom-step.js.es6 +++ b/assets/javascripts/wizard/controllers/custom-step.js.es6 @@ -4,6 +4,7 @@ import getUrl from 'discourse-common/lib/get-url'; export default StepController.extend({ actions: { goNext(response) { + debugger; const next = this.get('step.next'); if (response.redirect_on_next) { window.location.href = response.redirect_on_next; diff --git a/assets/javascripts/wizard/templates/components/wizard-field-number.hbs b/assets/javascripts/wizard/templates/components/wizard-field-number.hbs new file mode 100644 index 00000000..33fae047 --- /dev/null +++ b/assets/javascripts/wizard/templates/components/wizard-field-number.hbs @@ -0,0 +1 @@ +{{input type='number' step='0.01' id=field.id value=field.value}} \ No newline at end of file diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index ea8bdc01..7298e9ac 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -330,6 +330,7 @@ class CustomWizard::Builder end def validate_field(field, updater, step_template) + byebug value = updater.fields[field['id']] min_length = false label = field['label'] || I18n.t("#{field['key']}.label") @@ -356,6 +357,7 @@ class CustomWizard::Builder validator[:block].call(field, updater, step_template) end end + byebug end def is_text_type(field) diff --git a/lib/custom_wizard/field.rb b/lib/custom_wizard/field.rb index c68379a6..2afc3237 100644 --- a/lib/custom_wizard/field.rb +++ b/lib/custom_wizard/field.rb @@ -1,6 +1,6 @@ class CustomWizard::Field def self.types - @types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'image', 'text', 'textarea', 'text-only', 'upload', 'user-selector'] + @types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'image', 'text', 'textarea', 'text-only', 'number', 'upload', 'user-selector'] end def self.require_assets From ce9373dd911d377060c6a739fece200a1ac6d48a Mon Sep 17 00:00:00 2001 From: Robert Barrow Date: Mon, 23 Mar 2020 18:40:11 +0000 Subject: [PATCH 3/7] working url and number validation --- .../components/wizard-custom-field.js.es6 | 2 +- .../wizard/controllers/custom-step.js.es6 | 1 - .../wizard/initializers/custom.js.es6 | 5 ++++- .../templates/components/wizard-field-url.hbs | 1 + config/locales/server.en.yml | 1 + lib/custom_wizard/builder.rb | 18 ++++++++++++++++-- lib/custom_wizard/field.rb | 2 +- 7 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 assets/javascripts/wizard/templates/components/wizard-field-url.hbs diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index abd9f459..66bcd014 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -14,7 +14,7 @@ export default Ember.Component.extend({ categoryPropertyTypes: generateSelectKitContent(['id', 'slug']), @computed('field.type') - isInput: (type) => type === 'text' || type === 'textarea', + isInput: (type) => type === 'text' || type === 'textarea' || type === 'url', @computed('field.type') isCategoryOrTag: (type) => type === 'tag' || type === 'category', diff --git a/assets/javascripts/wizard/controllers/custom-step.js.es6 b/assets/javascripts/wizard/controllers/custom-step.js.es6 index 892f785b..1881764c 100644 --- a/assets/javascripts/wizard/controllers/custom-step.js.es6 +++ b/assets/javascripts/wizard/controllers/custom-step.js.es6 @@ -4,7 +4,6 @@ import getUrl from 'discourse-common/lib/get-url'; export default StepController.extend({ actions: { goNext(response) { - debugger; const next = this.get('step.next'); if (response.redirect_on_next) { window.location.href = response.redirect_on_next; diff --git a/assets/javascripts/wizard/initializers/custom.js.es6 b/assets/javascripts/wizard/initializers/custom.js.es6 index de336fa7..5797116e 100644 --- a/assets/javascripts/wizard/initializers/custom.js.es6 +++ b/assets/javascripts/wizard/initializers/custom.js.es6 @@ -214,13 +214,14 @@ export default { inputComponentName: function() { const type = this.get('field.type'); const id = this.get('field.id'); - if (type === 'text-only') return false; + if (['text-only'].includes(type)) return false; return (type === 'component') ? Ember.String.dasherize(id) : `wizard-field-${type}`; }.property('field.type', 'field.id') }); const StandardFieldValidation = [ 'text', + 'number', 'textarea', 'dropdown', 'tag', @@ -259,6 +260,8 @@ export default { valid = val && val.id > 0; } else if (StandardFieldValidation.indexOf(type) > -1) { valid = val && val.length > 0; + } else if (type === 'url') { + valid = true } } diff --git a/assets/javascripts/wizard/templates/components/wizard-field-url.hbs b/assets/javascripts/wizard/templates/components/wizard-field-url.hbs new file mode 100644 index 00000000..2c3844af --- /dev/null +++ b/assets/javascripts/wizard/templates/components/wizard-field-url.hbs @@ -0,0 +1 @@ +{{input type='text' id=field.id value=field.value}} \ No newline at end of file diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 8033e4a7..fe3554a3 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -9,6 +9,7 @@ en: field: too_short: "%{label} must be at least %{min} characters" required: "%{label} is required." + not_url: "%{label} must be a valid url" none: "We couldn't find a wizard at that address." no_skip: "Wizard can't be skipped" export: diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index e7f03a66..ba163513 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -1,3 +1,5 @@ +require 'uri' + TagStruct = Struct.new(:id, :name) class CustomWizard::Builder @@ -330,7 +332,6 @@ class CustomWizard::Builder end def validate_field(field, updater, step_template) - byebug value = updater.fields[field['id']] min_length = false label = field['label'] || I18n.t("#{field['key']}.label") @@ -347,6 +348,12 @@ class CustomWizard::Builder updater.errors.add(field['id'].to_s, I18n.t('wizard.field.too_short', label: label, min: min_length.to_i)) end + if is_url_type(field) + if !check_if_url(value) + updater.errors.add(field['id'].to_s, I18n.t('wizard.field.not_url', label: label)) + end + end + ## ensure all checkboxes are booleans if field['type'] === 'checkbox' updater.fields[field['id']] = standardise_boolean(value) @@ -357,13 +364,20 @@ class CustomWizard::Builder validator[:block].call(field, updater, step_template) end end - byebug end def is_text_type(field) ['text', 'textarea'].include? field['type'] end + def is_url_type(field) + ['url'].include? field['type'] + end + + def check_if_url(value) + value =~ URI::regexp + end + def standardise_boolean(value) ActiveRecord::Type::Boolean.new.cast(value) end diff --git a/lib/custom_wizard/field.rb b/lib/custom_wizard/field.rb index 2afc3237..859e47fa 100644 --- a/lib/custom_wizard/field.rb +++ b/lib/custom_wizard/field.rb @@ -1,6 +1,6 @@ class CustomWizard::Field def self.types - @types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'image', 'text', 'textarea', 'text-only', 'number', 'upload', 'user-selector'] + @types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'image', 'text', 'textarea', 'text-only', 'number', 'upload', 'user-selector', 'url'] end def self.require_assets From 3c364c928cb173635d7c455e740be879029b3b72 Mon Sep 17 00:00:00 2001 From: Robert Barrow Date: Wed, 25 Mar 2020 11:30:05 +0000 Subject: [PATCH 4/7] CSS for url entry to bring in line with text fields --- assets/stylesheets/wizard/wizard_custom.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/assets/stylesheets/wizard/wizard_custom.scss b/assets/stylesheets/wizard/wizard_custom.scss index 853d371a..b1a913f2 100644 --- a/assets/stylesheets/wizard/wizard_custom.scss +++ b/assets/stylesheets/wizard/wizard_custom.scss @@ -195,6 +195,14 @@ } } + .url-field input { + width: 100%; + font-size: 1.1487em; + padding: 6px; + border: 1px solid #ccc; + transition: border-color 0.5s; + } + .control-group { display: inline-block; vertical-align: top; From c06af2b0682295b45877f691d53096d61be660ee Mon Sep 17 00:00:00 2001 From: fzngagan Date: Wed, 25 Mar 2020 23:20:25 +0530 Subject: [PATCH 5/7] improved topic custom fields saving mechanism --- lib/custom_wizard/builder.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index ba163513..fb8dea2e 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -408,8 +408,6 @@ class CustomWizard::Builder params[:tags] = tags - topic_custom_fields = {} - if action['add_fields'] action['add_fields'].each do |field| value = field['value_custom'].present? ? field['value_custom'] : data[field['value']] @@ -424,7 +422,9 @@ class CustomWizard::Builder type = keyArr.first if type === 'topic' - topic_custom_fields[custom_key] = value + params[:topic_opts] ||= {} + params[:topic_opts][:custom_fields] ||= {} + params[:topic_opts][:custom_fields][custom_key] = value elsif type === 'post' params[:custom_fields] ||= {} params[:custom_fields][custom_key.to_sym] = value @@ -444,12 +444,6 @@ class CustomWizard::Builder if creator.errors.present? updater.errors.add(:create_topic, creator.errors.full_messages.join(" ")) else - if topic_custom_fields.present? - topic_custom_fields.each do |k, v| - post.topic.custom_fields[k] = v - end - post.topic.save_custom_fields(true) - end unless action['skip_redirect'] data['redirect_on_complete'] = post.topic.url From 906db9269f2fc7c97547686c60513f7496c04395 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 31 Mar 2020 11:13:16 +1100 Subject: [PATCH 6/7] Update wizard-custom.js --- assets/javascripts/wizard-custom.js | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/javascripts/wizard-custom.js b/assets/javascripts/wizard-custom.js index acc1cb3d..e03cf6a8 100644 --- a/assets/javascripts/wizard-custom.js +++ b/assets/javascripts/wizard-custom.js @@ -30,6 +30,7 @@ //= require discourse/lib/show-modal //= require discourse/lib/key-value-store //= require discourse/lib/settings +//= require discourse/lib/user-presence //= require discourse/mixins/singleton From 9b035523440d317def0e539a055da54b3fe39db5 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 31 Mar 2020 14:14:49 +1100 Subject: [PATCH 7/7] Migrate to new Site registration approach --- assets/javascripts/wizard-custom-lib.js | 4 +--- assets/javascripts/wizard-custom.js | 3 +++ .../wizard/initializers/custom.js.es6 | 20 +++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/assets/javascripts/wizard-custom-lib.js b/assets/javascripts/wizard-custom-lib.js index ee775332..8edec114 100644 --- a/assets/javascripts/wizard-custom-lib.js +++ b/assets/javascripts/wizard-custom-lib.js @@ -4,6 +4,4 @@ Wizard.SiteSettings = {}; Wizard.RAW_TEMPLATES = {}; Discourse.__widget_helpers = {}; Discourse.RAW_TEMPLATES = {}; -Discourse.SiteSettings = Wizard.SiteSettings; -Discourse.Model = Ember.Object.extend(); -Discourse.Site = Ember.Object.extend(); \ No newline at end of file +Discourse.SiteSettings = Wizard.SiteSettings; \ No newline at end of file diff --git a/assets/javascripts/wizard-custom.js b/assets/javascripts/wizard-custom.js index e03cf6a8..3a8382e7 100644 --- a/assets/javascripts/wizard-custom.js +++ b/assets/javascripts/wizard-custom.js @@ -31,9 +31,12 @@ //= require discourse/lib/key-value-store //= require discourse/lib/settings //= require discourse/lib/user-presence +//= require discourse/lib/hash //= require discourse/mixins/singleton +//= require discourse/adapters/rest + //= require discourse/models/login-method //= require discourse/models/permission-type //= require discourse/models/archetype diff --git a/assets/javascripts/wizard/initializers/custom.js.es6 b/assets/javascripts/wizard/initializers/custom.js.es6 index 5797116e..9afd9128 100644 --- a/assets/javascripts/wizard/initializers/custom.js.es6 +++ b/assets/javascripts/wizard/initializers/custom.js.es6 @@ -5,7 +5,8 @@ export default { initialize(app) { if (window.location.pathname.indexOf('/w/') < 0) return; - + + const EmberObject = requirejs('@ember/object').default; const Router = requirejs('wizard/router').default; const ApplicationRoute = requirejs('wizard/routes/application').default; const ajax = requirejs('wizard/lib/ajax').ajax; @@ -22,7 +23,10 @@ export default { const Store = requirejs("discourse/models/store").default; const registerRawHelpers = requirejs("discourse-common/lib/raw-handlebars-helpers").registerRawHelpers; const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars").default; + const Site = requirejs("discourse/models/site").default; + const RestAdapter = requirejs("discourse/adapters/rest").default; + Discourse.Model = EmberObject.extend(); Discourse.__container__ = app.__container__; Discourse.getURLWithCDN = getUrl; Discourse.getURL = getUrl; @@ -51,16 +55,16 @@ export default { app.register("service:store", Store); targets.forEach(t => app.inject(t, "store", "service:store")); - - const site = Discourse.Site; - app.register("site:main", site); - targets.forEach(t => app.inject(t, "site", "site:main")); - targets.forEach(t => app.inject(t, "appEvents", "service:app-events")); - site.reopenClass(Singleton); - site.currentProp('can_create_tag', false); + app.register("adapter:rest", RestAdapter); + const site = Site.current(); + app.register("site:main", site, { instantiate: false }); + targets.forEach(t => app.inject(t, "site", "site:main")); + + site.set('can_create_tag', false); + Router.reopen({ rootURL: getUrl('/w/') });