diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 0da2cb31..cc9d56eb 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -31,7 +31,7 @@ export default Component.extend(UndoChanges, { validations(type) { const applicableToField = []; for(let validation in wizardSchema.field.validations) { - if (wizardSchema.field.validations[validation]["type"] === type) { + if ((wizardSchema.field.validations[validation]["types"]).includes(type)) { applicableToField.push(validation) } } diff --git a/assets/javascripts/discourse/templates/components/realtime-validation-settings.hbs b/assets/javascripts/discourse/templates/components/realtime-validation-settings.hbs index 7ca7b502..487c4de6 100644 --- a/assets/javascripts/discourse/templates/components/realtime-validation-settings.hbs +++ b/assets/javascripts/discourse/templates/components/realtime-validation-settings.hbs @@ -3,8 +3,8 @@ {{#each-in field.validations as |name props|}} - {{i18n (concat 'admin.wizard.field.validations.' name)}} {{input type="checkbox" checked=props.status }} + {{i18n (concat 'admin.wizard.field.validations.' name)}}
{{radio-button name=(concat name field.id) value="above" selection=props.position}} {{i18n 'admin.wizard.field.validations.above'}} diff --git a/assets/javascripts/wizard/components/alpha-validator.js.es6 b/assets/javascripts/wizard/components/alpha-validator.js.es6 deleted file mode 100644 index dfa16406..00000000 --- a/assets/javascripts/wizard/components/alpha-validator.js.es6 +++ /dev/null @@ -1,13 +0,0 @@ -import WizardFieldValidator from "../../wizard/components/validator"; - -export default WizardFieldValidator.extend({ - validMessageKey: 'hello', - invalidMessageKey: 'world', - validate() { - if(this.field.value) { - this.field.value.length > 0 ? this.set('isValid', true) : this.set('isValid', false); - } else { - this.set('isValid', false); - } - } -}); \ No newline at end of file diff --git a/assets/javascripts/wizard/components/suggested-validator.js.es6 b/assets/javascripts/wizard/components/suggested-validator.js.es6 new file mode 100644 index 00000000..953acfa1 --- /dev/null +++ b/assets/javascripts/wizard/components/suggested-validator.js.es6 @@ -0,0 +1,20 @@ +import WizardFieldValidator from "../../wizard/components/validator"; +import { ajax } from "discourse/lib/ajax"; +import { getToken } from "wizard/lib/ajax"; +import { getOwner } from "discourse-common/lib/get-owner"; +import discourseComputed from "discourse-common/utils/decorators"; + +export default WizardFieldValidator.extend({ + validMessageKey: 'hello', + invalidMessageKey: 'world', + validate() { + this.backendValidate({title: this.get("field.value")}).then(response => { + console.log(response) + }) + }, + + init() { + this._super(...arguments); + + } +}); \ No newline at end of file diff --git a/assets/javascripts/wizard/components/validator.js.es6 b/assets/javascripts/wizard/components/validator.js.es6 index 68b6fb35..f46b8319 100644 --- a/assets/javascripts/wizard/components/validator.js.es6 +++ b/assets/javascripts/wizard/components/validator.js.es6 @@ -1,6 +1,7 @@ import Component from "@ember/component"; import { not } from "@ember/object/computed"; -import { observes } from "discourse-common/utils/decorators"; +import { ajax } from "discourse/lib/ajax"; +import { getToken } from "wizard/lib/ajax"; export default Component.extend({ classNameBindings: ['isValid', 'isInvalid'], @@ -9,11 +10,35 @@ export default Component.extend({ isValid: null, isInvalid: not('isValid'), layoutName: 'components/validator', // useful for sharing the template with extending components + init() { + this._super(...arguments); + + if (this.get('validation.backend')) { + // set a function that can be called as often as it need to + // from the derived component + this.backendValidate = (params) => { + return ajax('/w/realtime_validation', { + type: 'put', + data: { + validation: this.get('name'), + authenticity_token: getToken(), + ...params + } + }); + } + + } + }, + didInsertElement() { - this.appEvents.on('custom-wizard:validate', this, this.validate); + this.appEvents.on('custom-wizard:validate', this, this.checkIsValid); }, willDestroyElement() { - this.appEvents.off('custom-wizard:validate', this, this.validate); + this.appEvents.off('custom-wizard:validate', this, this.checkIsValid); + }, + + checkIsValid() { + this.set('isValid', this.validate()); } }); \ No newline at end of file diff --git a/assets/javascripts/wizard/templates/components/field-validators.hbs b/assets/javascripts/wizard/templates/components/field-validators.hbs index fd5872b7..a732c3e2 100644 --- a/assets/javascripts/wizard/templates/components/field-validators.hbs +++ b/assets/javascripts/wizard/templates/components/field-validators.hbs @@ -1,12 +1,12 @@ {{#if field.validations}} {{#each-in field.validations.above as |name validation|}} - {{component validation.component field=field}} + {{component validation.component field=field name=name validation=validation}} {{/each-in}} {{yield (hash perform=(action 'perform'))}} {{#each-in field.validations.below as |name validation|}} - {{component validation.component field=field}} + {{component validation.component field=field name=name validation=validation}} {{/each-in}} {{else}} {{yield}} diff --git a/assets/javascripts/wizard/templates/components/suggested-validator.hbs b/assets/javascripts/wizard/templates/components/suggested-validator.hbs new file mode 100644 index 00000000..e69de29b diff --git a/config/routes.rb b/config/routes.rb index 764c0fdd..7f30e311 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,7 @@ CustomWizard::Engine.routes.draw do get ':wizard_id/steps' => 'wizard#index' get ':wizard_id/steps/:step_id' => 'wizard#index' put ':wizard_id/steps/:step_id' => 'steps#update' + put 'realtime_validation' => 'realtime_validation#validate' end Discourse::Application.routes.append do diff --git a/controllers/custom_wizard/realtime_validation.rb b/controllers/custom_wizard/realtime_validation.rb new file mode 100644 index 00000000..a2e0dac1 --- /dev/null +++ b/controllers/custom_wizard/realtime_validation.rb @@ -0,0 +1,8 @@ +class CustomWizard::RealtimeValidationController < ::ApplicationController + def validate + params.require(:validation) + params.require(::CustomWizard::RealtimeValidation.types[params[:validation].to_sym][:required_params]) + + render_json_dump(::CustomWizard::RealtimeValidation.send(params[:validation], params, current_user)) + end +end diff --git a/lib/custom_wizard/realtime_validation.rb b/lib/custom_wizard/realtime_validation.rb index 422211d3..f015d3fb 100644 --- a/lib/custom_wizard/realtime_validation.rb +++ b/lib/custom_wizard/realtime_validation.rb @@ -1,7 +1,31 @@ class CustomWizard::RealtimeValidation cattr_accessor :types @@types ||= { - suggested_topics: {type: :text, component: "alpha-validator"} + suggested_topics: { types: [:text], component: "suggested-validator", backend: true, required_params: [] } } - end - \ No newline at end of file + + class SimilarTopic + def initialize(topic) + @topic = topic + end + + attr_reader :topic + + def blurb + Search::GroupedSearchResults.blurb_for(cooked: @topic.try(:blurb)) + end + end + + def self.suggested_topics(params, current_user) + title = params[:title] + raw = params[:raw] + + if title.length < SiteSetting.min_title_similar_length || !Topic.count_exceeds_minimum? + return [] + end + + topics = Topic.similar_to(title, raw, current_user).to_a + topics.map! { |t| SimilarTopic.new(t) } + ::ActiveModel::ArraySerializer.new(topics, each_serializer: SimilarTopicSerializer, root: :similar_topics, rest_serializer: true, scope: ::Guardian.new(current_user)) + end +end diff --git a/plugin.rb b/plugin.rb index 0521cc10..83699751 100644 --- a/plugin.rb +++ b/plugin.rb @@ -47,6 +47,7 @@ after_initialize do ../controllers/custom_wizard/admin/custom_fields.rb ../controllers/custom_wizard/wizard.rb ../controllers/custom_wizard/steps.rb + ../controllers/custom_wizard/realtime_validation.rb ../jobs/clear_after_time_wizard.rb ../jobs/refresh_api_access_token.rb ../jobs/set_after_time_wizard.rb