diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 93d5143a..c4094a75 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -16,7 +16,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-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 fa6717c3..308f9c92 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/') }); @@ -214,13 +218,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', @@ -253,15 +258,15 @@ export default { } else { const val = this.get('value'); const type = this.get('type'); - - console.log(val, type) - + if (type === 'checkbox') { valid = val; } else if (type === 'upload') { valid = val && val.id > 0; } else if (StandardFieldValidation.indexOf(type) > -1) { valid = val && val.toString().length > 0; + } else if (type === 'url') { + valid = true; } } 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/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/assets/stylesheets/wizard/wizard_custom.scss b/assets/stylesheets/wizard/wizard_custom.scss index e83450e6..5c05598c 100644 --- a/assets/stylesheets/wizard/wizard_custom.scss +++ b/assets/stylesheets/wizard/wizard_custom.scss @@ -181,6 +181,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; 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 af07de50..8d7686f7 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -300,6 +300,12 @@ class CustomWizard::Builder ) 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) @@ -316,6 +322,14 @@ class CustomWizard::Builder ['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 9fcf3cc5..c7725f1b 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', 'group', 'image', 'text', 'textarea', 'text-only', 'upload', 'user-selector'] + @types ||= ['checkbox', 'composer', 'dropdown', 'tag', 'category', 'group', 'image', 'text', 'textarea', 'text-only', 'number', 'upload', 'user-selector', 'url'] end def self.require_assets