added backend validation mechanism and refined code
Dieser Commit ist enthalten in:
Ursprung
fa57bb8a5b
Commit
ffd2101a30
11 geänderte Dateien mit 89 neuen und 23 gelöschten Zeilen
|
@ -31,7 +31,7 @@ export default Component.extend(UndoChanges, {
|
||||||
validations(type) {
|
validations(type) {
|
||||||
const applicableToField = [];
|
const applicableToField = [];
|
||||||
for(let validation in wizardSchema.field.validations) {
|
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)
|
applicableToField.push(validation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
</div>
|
</div>
|
||||||
{{#each-in field.validations as |name props|}}
|
{{#each-in field.validations as |name props|}}
|
||||||
<span class="setting-title">
|
<span class="setting-title">
|
||||||
{{i18n (concat 'admin.wizard.field.validations.' name)}}
|
|
||||||
{{input type="checkbox" checked=props.status }}
|
{{input type="checkbox" checked=props.status }}
|
||||||
|
{{i18n (concat 'admin.wizard.field.validations.' name)}}
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
{{radio-button name=(concat name field.id) value="above" selection=props.position}} {{i18n 'admin.wizard.field.validations.above'}}
|
{{radio-button name=(concat name field.id) value="above" selection=props.position}} {{i18n 'admin.wizard.field.validations.above'}}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
20
assets/javascripts/wizard/components/suggested-validator.js.es6
Normale Datei
20
assets/javascripts/wizard/components/suggested-validator.js.es6
Normale Datei
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { not } from "@ember/object/computed";
|
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({
|
export default Component.extend({
|
||||||
classNameBindings: ['isValid', 'isInvalid'],
|
classNameBindings: ['isValid', 'isInvalid'],
|
||||||
|
@ -9,11 +10,35 @@ export default Component.extend({
|
||||||
isValid: null,
|
isValid: null,
|
||||||
isInvalid: not('isValid'),
|
isInvalid: not('isValid'),
|
||||||
layoutName: 'components/validator', // useful for sharing the template with extending components
|
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() {
|
didInsertElement() {
|
||||||
this.appEvents.on('custom-wizard:validate', this, this.validate);
|
this.appEvents.on('custom-wizard:validate', this, this.checkIsValid);
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
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());
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,12 +1,12 @@
|
||||||
{{#if field.validations}}
|
{{#if field.validations}}
|
||||||
{{#each-in field.validations.above as |name validation|}}
|
{{#each-in field.validations.above as |name validation|}}
|
||||||
{{component validation.component field=field}}
|
{{component validation.component field=field name=name validation=validation}}
|
||||||
{{/each-in}}
|
{{/each-in}}
|
||||||
|
|
||||||
{{yield (hash perform=(action 'perform'))}}
|
{{yield (hash perform=(action 'perform'))}}
|
||||||
|
|
||||||
{{#each-in field.validations.below as |name validation|}}
|
{{#each-in field.validations.below as |name validation|}}
|
||||||
{{component validation.component field=field}}
|
{{component validation.component field=field name=name validation=validation}}
|
||||||
{{/each-in}}
|
{{/each-in}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{yield}}
|
{{yield}}
|
||||||
|
|
|
@ -4,6 +4,7 @@ CustomWizard::Engine.routes.draw do
|
||||||
get ':wizard_id/steps' => 'wizard#index'
|
get ':wizard_id/steps' => 'wizard#index'
|
||||||
get ':wizard_id/steps/:step_id' => 'wizard#index'
|
get ':wizard_id/steps/:step_id' => 'wizard#index'
|
||||||
put ':wizard_id/steps/:step_id' => 'steps#update'
|
put ':wizard_id/steps/:step_id' => 'steps#update'
|
||||||
|
put 'realtime_validation' => 'realtime_validation#validate'
|
||||||
end
|
end
|
||||||
|
|
||||||
Discourse::Application.routes.append do
|
Discourse::Application.routes.append do
|
||||||
|
|
8
controllers/custom_wizard/realtime_validation.rb
Normale Datei
8
controllers/custom_wizard/realtime_validation.rb
Normale Datei
|
@ -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
|
|
@ -1,7 +1,31 @@
|
||||||
class CustomWizard::RealtimeValidation
|
class CustomWizard::RealtimeValidation
|
||||||
cattr_accessor :types
|
cattr_accessor :types
|
||||||
@@types ||= {
|
@@types ||= {
|
||||||
suggested_topics: {type: :text, component: "alpha-validator"}
|
suggested_topics: { types: [:text], component: "suggested-validator", backend: true, required_params: [] }
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -47,6 +47,7 @@ after_initialize do
|
||||||
../controllers/custom_wizard/admin/custom_fields.rb
|
../controllers/custom_wizard/admin/custom_fields.rb
|
||||||
../controllers/custom_wizard/wizard.rb
|
../controllers/custom_wizard/wizard.rb
|
||||||
../controllers/custom_wizard/steps.rb
|
../controllers/custom_wizard/steps.rb
|
||||||
|
../controllers/custom_wizard/realtime_validation.rb
|
||||||
../jobs/clear_after_time_wizard.rb
|
../jobs/clear_after_time_wizard.rb
|
||||||
../jobs/refresh_api_access_token.rb
|
../jobs/refresh_api_access_token.rb
|
||||||
../jobs/set_after_time_wizard.rb
|
../jobs/set_after_time_wizard.rb
|
||||||
|
|
Laden …
In neuem Issue referenzieren