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