Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-25 18:50:27 +01:00
add permitted setting
Dieser Commit ist enthalten in:
Ursprung
b212eaa2f3
Commit
ee61c1deb3
28 geänderte Dateien mit 589 neuen und 524 gelöschten Zeilen
|
@ -46,11 +46,11 @@ export default Ember.Component.extend({
|
|||
return options;
|
||||
},
|
||||
|
||||
canFilter: or('isCategory', 'isTag', 'isGroup'),
|
||||
contentEnabled: or('isCategory', 'isTag', 'isGroup'),
|
||||
|
||||
@computed('field.type')
|
||||
filterOptions(fieldType) {
|
||||
if (!this.canFilter) return {};
|
||||
contentOptions(fieldType) {
|
||||
if (!this.contentEnabled) return {};
|
||||
|
||||
let options = {
|
||||
hasOutput: true,
|
||||
|
|
|
@ -23,9 +23,14 @@ export default Ember.Component.extend({
|
|||
if (!this.type) this.set('type', defaultInputType(this.options));
|
||||
},
|
||||
|
||||
@discourseComputed
|
||||
inputTypes() {
|
||||
return ['conditional', 'assignment'].map((type) => {
|
||||
@discourseComputed('options.allowedInputs')
|
||||
allowedInputs(option) {
|
||||
return option || 'conditional,assignment';
|
||||
},
|
||||
|
||||
@discourseComputed('allowedInputs')
|
||||
inputTypes(allowedInputs) {
|
||||
return allowedInputs.split(',').map((type) => {
|
||||
return {
|
||||
id: type,
|
||||
name: I18n.t(`admin.wizard.input.${type}.prefix`)
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||
import { on } from 'discourse-common/utils/decorators';
|
||||
import { newInput } from '../lib/custom-wizard';
|
||||
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: 'field-mapper',
|
||||
|
||||
@discourseComputed('inputs.[]', 'options.singular')
|
||||
canAdd(inputs, singular) {
|
||||
return !singular || !inputs || inputs.length < 1;
|
||||
},
|
||||
|
||||
actions: {
|
||||
add() {
|
||||
|
|
|
@ -10,16 +10,15 @@ function generateName(id) {
|
|||
|
||||
const profileFields = [
|
||||
'name',
|
||||
'user_avatar',
|
||||
'username',
|
||||
'email',
|
||||
'date_of_birth',
|
||||
'title',
|
||||
'locale',
|
||||
'location',
|
||||
'website',
|
||||
'bio_raw',
|
||||
'profile_background',
|
||||
'card_background',
|
||||
'theme_id'
|
||||
'trust_level'
|
||||
];
|
||||
|
||||
const connectors = [
|
||||
|
@ -69,7 +68,10 @@ const inputTypes = [
|
|||
]
|
||||
|
||||
function defaultInputType(options = {}) {
|
||||
return options.hasOutput ? 'conditional' : 'pair';
|
||||
if (!options.hasOutput) return 'pair';
|
||||
const allowedInputs = options.allowedInputs;
|
||||
if (!allowedInputs) return 'conditional';
|
||||
return allowedInputs.split(',')[0];
|
||||
}
|
||||
|
||||
function defaultSelectionType(inputType, options = {}) {
|
||||
|
|
|
@ -12,8 +12,8 @@ const wizardProperties = [
|
|||
'required',
|
||||
'prompt_completion',
|
||||
'restart_on_revisit',
|
||||
'min_trust',
|
||||
'theme_id'
|
||||
'theme_id',
|
||||
'permitted'
|
||||
];
|
||||
|
||||
const CustomWizard = EmberObject.extend({
|
||||
|
@ -267,7 +267,7 @@ CustomWizard.reopenClass({
|
|||
props['required'] = false;
|
||||
props['prompt_completion'] = false;
|
||||
props['restart_on_revisit'] = false;
|
||||
props['min_trust'] = 0;
|
||||
props['permitted'] = null;
|
||||
props['steps'] = Ember.A();
|
||||
};
|
||||
|
||||
|
|
|
@ -22,13 +22,7 @@
|
|||
placeholderKey="admin.wizard.name_placeholder"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wizard-header medium">
|
||||
{{i18n 'admin.wizard.label'}}
|
||||
</div>
|
||||
|
||||
<div class="wizard-settings">
|
||||
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.background'}}</label>
|
||||
|
@ -40,7 +34,13 @@
|
|||
placeholderKey="admin.wizard.background_placeholder"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wizard-header medium">
|
||||
{{i18n 'admin.wizard.label'}}
|
||||
</div>
|
||||
|
||||
<div class="wizard-settings">
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.save_submissions'}}</label>
|
||||
|
@ -106,16 +106,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.min_trust'}}</label>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
<span>{{i18n 'admin.wizard.min_trust_label'}}</span>
|
||||
{{input type='number' value=model.min_trust class='input-small'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.theme_id'}}</label>
|
||||
|
@ -144,17 +134,17 @@
|
|||
|
||||
<div class="setting full field-mapper-setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.group'}}</label>
|
||||
<label>{{i18n 'admin.wizard.permitted'}}</label>
|
||||
</div>
|
||||
<div class="setting-value">
|
||||
{{wizard-field-mapper
|
||||
inputs=model.group
|
||||
inputs=model.permitted
|
||||
options=(hash
|
||||
hasOutput=true
|
||||
enableConnectors=true
|
||||
userFieldSelection='key,value'
|
||||
groupSelection=true
|
||||
groupSelection='output'
|
||||
textDisabled='output'
|
||||
allowedInputs='assignment'
|
||||
singular=true
|
||||
)}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -170,17 +170,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{#if canFilter}}
|
||||
{{#if contentEnabled}}
|
||||
<div class="setting full field-mapper-setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n 'admin.wizard.field.filter'}}</label>
|
||||
<label>{{i18n 'admin.wizard.field.content'}}</label>
|
||||
</div>
|
||||
|
||||
<div class="setting-value">
|
||||
{{wizard-field-mapper
|
||||
inputs=field.filters
|
||||
inputs=field.content
|
||||
wizardFields=wizardFields
|
||||
options=filterOptions}}
|
||||
options=contentOptions}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
remove=(action 'remove')}}
|
||||
{{/each}}
|
||||
|
||||
<div class="add-custom-input">
|
||||
{{d-button action='add' label='admin.wizard.add' icon='plus'}}
|
||||
</div>
|
||||
{{#if canAdd}}
|
||||
<div class="add-custom-input">
|
||||
{{d-button action='add' label='admin.wizard.add' icon='plus'}}
|
||||
</div>
|
||||
{{/if}}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
export default Ember.Component.extend({
|
||||
didInsertElement() {
|
||||
console.log(this.field)
|
||||
}
|
||||
})
|
|
@ -2,11 +2,16 @@ import ComboBox from 'select-kit/components/combo-box';
|
|||
import { computed } from "@ember/object";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
|
||||
export default ComboBox.extend({
|
||||
content: computed("groups.[]", "whitelist.[]", function() {
|
||||
const whitelist = makeArray(this.whitelist);
|
||||
export default ComboBox.extend({
|
||||
content: computed("groups.[]", "field.content.[]", function() {
|
||||
const whitelist = makeArray(this.field.content);
|
||||
return this.groups.filter(group => {
|
||||
return !whitelist.length || whitelist.indexOf(group.id) > -1;
|
||||
}).map(g => {
|
||||
return {
|
||||
id: g.id,
|
||||
name: g.name
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
|
@ -14,7 +14,6 @@ export default Ember.Route.extend({
|
|||
if (model) {
|
||||
const completed = model.get('completed');
|
||||
const permitted = model.get('permitted');
|
||||
const minTrust = model.get('min_trust');
|
||||
const wizardId = model.get('id');
|
||||
const user = model.get('user');
|
||||
const name = model.get('name');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{wizard-category-selector
|
||||
categories=categories
|
||||
whitelist=field.filter
|
||||
whitelist=field.content
|
||||
maximum=field.limit
|
||||
onChange=(action (mut categories))}}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{{wizard-group-selector
|
||||
groups=wizard.groups
|
||||
whitelist=field.filter
|
||||
field=field
|
||||
whitelist=field.content
|
||||
value=field.value
|
||||
onChange=(action (mut field.value))
|
||||
options=(hash
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{{wizard-no-access text=(i18n 'wizard.requires_login' name=name) wizardId=wizardId}}
|
||||
{{else}}
|
||||
{{#if notPermitted}}
|
||||
{{wizard-no-access text=(i18n 'wizard.not_permitted' name=name level=minTrust) wizardId=wizardId}}
|
||||
{{wizard-no-access text=(i18n 'wizard.not_permitted' name=name) wizardId=wizardId}}
|
||||
{{else}}
|
||||
{{#if completed}}
|
||||
{{wizard-no-access text=(i18n 'wizard.completed' name=name) wizardId=wizardId}}
|
||||
|
|
|
@ -61,10 +61,6 @@ $setting-background: dark-light-diff($primary, $secondary, 96%, -65%);
|
|||
}
|
||||
}
|
||||
|
||||
.wizard-basic-details {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.content-list + .content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@ en:
|
|||
prompt_completion_label: "Prompt user to complete wizard."
|
||||
restart_on_revisit: "Restart"
|
||||
restart_on_revisit_label: "Restart the the wizard whenever the user revisits, regardless of prior progress."
|
||||
min_trust: "Trust"
|
||||
min_trust_label: "Trust level required to access wizard."
|
||||
theme_id: "Theme"
|
||||
no_theme: "Select a Theme (optional)"
|
||||
save: "Save Changes"
|
||||
|
@ -61,6 +59,7 @@ en:
|
|||
submission_key: 'submission key'
|
||||
param_key: 'param'
|
||||
group: "Group"
|
||||
permitted: "Permitted"
|
||||
|
||||
editor:
|
||||
show: "Show"
|
||||
|
@ -125,7 +124,7 @@ en:
|
|||
limit: "Limit"
|
||||
property: "Property"
|
||||
prefill: "Prefill"
|
||||
filter: "Content"
|
||||
content: "Content"
|
||||
|
||||
action:
|
||||
header: "Actions"
|
||||
|
@ -306,12 +305,12 @@ en:
|
|||
|
||||
wizard:
|
||||
completed: "You have completed the {{name}} wizard."
|
||||
not_permitted: "You need to be trust level {{level}} or higher to access the {{name}} wizard."
|
||||
not_permitted: "You are not permitted to access the {{name}} wizard."
|
||||
none: "There is no wizard here."
|
||||
return_to_site: "Return to {{siteName}}"
|
||||
requires_login: "You need to be logged in to access the {{name}} wizard."
|
||||
reset: "Reset this wizard."
|
||||
step_not_permitted: "You're not allowed to view this step."
|
||||
step_not_permitted: "You're not permitted to view this step."
|
||||
|
||||
wizard_composer:
|
||||
show_preview: "Preview Post"
|
||||
|
|
|
@ -33,8 +33,6 @@ fr:
|
|||
required_label: "Les utilisatrices doivent compléter l'assistant."
|
||||
prompt_completion: "Invitation"
|
||||
prompt_completion_label: "Inviter l'utilisatrice à compléter l'assistant."
|
||||
min_trust: "Confiance"
|
||||
min_trust_label: "Niveau de confiance requis pour accéder à l'assistant."
|
||||
theme_id: "Thème"
|
||||
no_theme: "Choisir un thème (optionnel)"
|
||||
save: "Sauvegarder"
|
||||
|
|
|
@ -14,11 +14,8 @@ class CustomWizard::AdminController < ::ApplicationController
|
|||
params.require(:wizard)
|
||||
|
||||
wizard = ::JSON.parse(params[:wizard])
|
||||
|
||||
existing = PluginStore.get('custom_wizard', wizard['id']) || {}
|
||||
|
||||
new_time = false
|
||||
|
||||
error = nil
|
||||
|
||||
if wizard["id"].blank?
|
||||
|
|
289
lib/custom_wizard/actions.rb
Normale Datei
289
lib/custom_wizard/actions.rb
Normale Datei
|
@ -0,0 +1,289 @@
|
|||
class CustomWizard::Action
|
||||
attr_accessor :data,
|
||||
:action,
|
||||
:user,
|
||||
:updater
|
||||
|
||||
def initialize(params)
|
||||
@action = params[:action]
|
||||
@user = params[:user]
|
||||
@data = params[:data]
|
||||
@updater = params[:updater]
|
||||
end
|
||||
|
||||
def perform
|
||||
ActiveRecord::Base.transaction { self.send(action['type'].to_sym) }
|
||||
end
|
||||
|
||||
def mapper
|
||||
@mapper ||= CustomWizard::Mapper.new(user: user, data: data)
|
||||
end
|
||||
|
||||
def create_topic
|
||||
if action['custom_title_enabled']
|
||||
title = mapper.interpolate(action['custom_title'])
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
if action['post_builder']
|
||||
post = mapper.interpolate(action['post_template'])
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
if title
|
||||
params = {
|
||||
title: title,
|
||||
raw: post,
|
||||
skip_validations: true
|
||||
}
|
||||
|
||||
params[:category] = action_category_id(action, data)
|
||||
tags = action_tags(action, data)
|
||||
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']]
|
||||
key = field['key']
|
||||
|
||||
if key && (value.present? || value === false)
|
||||
if key.include?('custom_fields')
|
||||
keyArr = key.split('.')
|
||||
|
||||
if keyArr.length === 3
|
||||
custom_key = keyArr.last
|
||||
type = keyArr.first
|
||||
|
||||
if type === 'topic'
|
||||
topic_custom_fields[custom_key] = value
|
||||
elsif type === 'post'
|
||||
params[:custom_fields] ||= {}
|
||||
params[:custom_fields][custom_key.to_sym] = value
|
||||
end
|
||||
end
|
||||
else
|
||||
value = [*value] + tags if key === 'tags'
|
||||
params[key.to_sym] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
creator = PostCreator.new(user, params)
|
||||
post = creator.create
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_message
|
||||
if action['required'].present? && data[action['required']].blank?
|
||||
return
|
||||
end
|
||||
|
||||
if action['custom_title_enabled']
|
||||
title = mapper.interpolate(action['custom_title'])
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
if action['post_builder']
|
||||
post = mapper.interpolate(action['post_template'])
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
if title && post
|
||||
creator = PostCreator.new(user,
|
||||
title: title,
|
||||
raw: post,
|
||||
archetype: Archetype.private_message,
|
||||
target_usernames: action['username']
|
||||
)
|
||||
|
||||
post = creator.create
|
||||
|
||||
if creator.errors.present?
|
||||
updater.errors.add(:send_message, creator.errors.full_messages.join(" "))
|
||||
else
|
||||
unless action['skip_redirect']
|
||||
data['redirect_on_complete'] = post.topic.url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_profile
|
||||
return unless action['profile_updates'].length
|
||||
|
||||
attributes = {}
|
||||
custom_fields = {}
|
||||
|
||||
action['profile_updates'].each do |pu|
|
||||
value = pu['value']
|
||||
key = pu['key']
|
||||
|
||||
return if data[key].blank?
|
||||
|
||||
if user_field || custom_field
|
||||
custom_fields[user_field || custom_field] = data[key]
|
||||
else
|
||||
updater_key = value
|
||||
if ['profile_background', 'card_background'].include?(value)
|
||||
updater_key = "#{value}_upload_url"
|
||||
end
|
||||
attributes[updater_key.to_sym] = data[key] if updater_key
|
||||
end
|
||||
|
||||
if ['user_avatar'].include?(value)
|
||||
this_upload_id = data[key][:id]
|
||||
user.create_user_avatar unless user.user_avatar
|
||||
user.user_avatar.custom_upload_id = this_upload_id
|
||||
user.uploaded_avatar_id = this_upload_id
|
||||
user.save!
|
||||
user.user_avatar.save!
|
||||
end
|
||||
end
|
||||
|
||||
if custom_fields.present?
|
||||
attributes[:custom_fields] = custom_fields
|
||||
end
|
||||
|
||||
if attributes.present?
|
||||
user_updater = UserUpdater.new(user, user)
|
||||
user_updater.update(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def send_to_api
|
||||
api_body = nil
|
||||
|
||||
if action['api_body'] != ""
|
||||
begin
|
||||
api_body_parsed = JSON.parse(action['api_body'])
|
||||
rescue JSON::ParserError
|
||||
raise Discourse::InvalidParameters, "Invalid API body definition: #{action['api_body']} for #{action['title']}"
|
||||
end
|
||||
api_body = JSON.parse(mapper.interpolate(JSON.generate(api_body_parsed)))
|
||||
end
|
||||
|
||||
result = CustomWizard::Api::Endpoint.request(user, action['api'], action['api_endpoint'], api_body)
|
||||
|
||||
if error = result['error'] || (result[0] && result[0]['error'])
|
||||
error = error['message'] || error
|
||||
updater.errors.add(:send_to_api, error)
|
||||
else
|
||||
## add validation callback
|
||||
end
|
||||
end
|
||||
|
||||
def open_composer
|
||||
if action['custom_title_enabled']
|
||||
title = mapper.interpolate(action['custom_title'])
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
url = "/new-topic?title=#{title}"
|
||||
|
||||
if action['post_builder']
|
||||
post = mapper.interpolate(action['post_template'])
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
url += "&body=#{post}"
|
||||
|
||||
if category_id = action_category_id(action, data)
|
||||
if category = Category.find(category_id)
|
||||
url += "&category=#{category.full_slug('/')}"
|
||||
end
|
||||
end
|
||||
|
||||
if tags = action_tags(action, data)
|
||||
url += "&tags=#{tags.join(',')}"
|
||||
end
|
||||
|
||||
data['redirect_on_complete'] = Discourse.base_uri + URI.encode(url)
|
||||
end
|
||||
|
||||
def add_to_group
|
||||
groups = CustomWizard::Mapper.new(
|
||||
inputs: action['inputs'],
|
||||
data: data,
|
||||
user: user,
|
||||
opts: {
|
||||
multiple: true
|
||||
}
|
||||
).output
|
||||
|
||||
groups = groups.flatten.reduce([]) do |result, g|
|
||||
begin
|
||||
result.push(Integer(g))
|
||||
rescue ArgumentError
|
||||
group = Group.find_by(name: g)
|
||||
result.push(group.id) if group
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
if groups.present?
|
||||
groups.each do |group_id|
|
||||
group = Group.find(group_id) if group_id
|
||||
group.add(user) if group
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def route_to
|
||||
url = mapper.interpolate(action['url'])
|
||||
if action['code']
|
||||
data[action['code']] = SecureRandom.hex(8)
|
||||
url += "&#{action['code']}=#{data[action['code']]}"
|
||||
end
|
||||
data['route_to'] = URI.encode(url)
|
||||
end
|
||||
|
||||
def action_category_id
|
||||
if action['custom_category_enabled']
|
||||
if action['custom_category_wizard_field']
|
||||
data[action['category_id']]
|
||||
elsif action['custom_category_user_field_key']
|
||||
if action['custom_category_user_field_key'].include?('custom_fields')
|
||||
field = action['custom_category_user_field_key'].split('.').last
|
||||
user.custom_fields[field]
|
||||
else
|
||||
user.send(action['custom_category_user_field_key'])
|
||||
end
|
||||
end
|
||||
else
|
||||
action['category_id']
|
||||
end
|
||||
end
|
||||
|
||||
def action_tags
|
||||
if action['custom_tag_enabled']
|
||||
data[action['custom_tag_field']]
|
||||
else
|
||||
action['tags']
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,4 @@
|
|||
TagStruct = Struct.new(:id, :name)
|
||||
|
||||
class CustomWizard::Builder
|
||||
|
||||
attr_accessor :wizard, :updater, :submissions
|
||||
|
||||
def initialize(user=nil, wizard_id)
|
||||
|
@ -10,10 +7,7 @@ class CustomWizard::Builder
|
|||
|
||||
@steps = data['steps']
|
||||
@wizard = CustomWizard::Wizard.new(user, data)
|
||||
|
||||
if user
|
||||
@submissions = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id))
|
||||
end
|
||||
@submissions = Array.wrap(PluginStore.get("#{wizard_id}_submissions", user.id)) if user
|
||||
end
|
||||
|
||||
def self.sorted_handlers
|
||||
|
@ -42,47 +36,6 @@ class CustomWizard::Builder
|
|||
@sorted_field_validators.sort_by! { |h| -h[:priority] }
|
||||
end
|
||||
|
||||
USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale']
|
||||
PROFILE_FIELDS = ['location', 'website', 'bio_raw', 'profile_background', 'card_background']
|
||||
OPERATORS = {
|
||||
'eq': '==',
|
||||
'gt': '>',
|
||||
'lt': '<',
|
||||
'gte': '>=',
|
||||
'lte': '<='
|
||||
}
|
||||
|
||||
def self.fill_placeholders(string, user, data)
|
||||
result = string.gsub(/u\{(.*?)\}/) do |match|
|
||||
result = ''
|
||||
result = user.send($1) if USER_FIELDS.include?($1)
|
||||
result = user.user_profile.send($1) if PROFILE_FIELDS.include?($1)
|
||||
result
|
||||
end
|
||||
|
||||
result = result.gsub(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split('.')]) }
|
||||
|
||||
result.gsub(/v\{(.*?)\}/) do |match|
|
||||
attrs = $1.split(':')
|
||||
key = attrs.first
|
||||
format = attrs.length > 1 ? attrs.last : nil
|
||||
v = nil
|
||||
|
||||
if key == 'time'
|
||||
time_format = format.present? ? format : "%B %-d, %Y"
|
||||
v = Time.now.strftime(time_format)
|
||||
end
|
||||
|
||||
v
|
||||
end
|
||||
end
|
||||
|
||||
def self.recurse(data, keys)
|
||||
k = keys.shift
|
||||
result = data[k]
|
||||
keys.empty? ? result : self.recurse(result, keys)
|
||||
end
|
||||
|
||||
def build(build_opts = {}, params = {})
|
||||
|
||||
return @wizard if !SiteSetting.custom_wizard_enabled ||
|
||||
|
@ -135,13 +88,24 @@ class CustomWizard::Builder
|
|||
step.permitted = false
|
||||
else
|
||||
required_data.each do |required|
|
||||
pairs = required['pairs'].map { |p| p['value'] = @submissions.last[p['value']] }
|
||||
step.permitted = false unless validate_pairs(pairs)
|
||||
pairs = required['pairs'].map do |p|
|
||||
p['key'] = @submissions.last[p['key']]
|
||||
end
|
||||
|
||||
unless CustomWizard::Mapper.new(
|
||||
user: @wizard.user,
|
||||
data: @submissions.last
|
||||
).validate_pairs(pairs)
|
||||
step.permitted = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !step.permitted
|
||||
step.permitted_message = step_template['required_data_message'] if step_template['required_data_message']
|
||||
if step_template['required_data_message']
|
||||
step.permitted_message = step_template['required_data_message']
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
end
|
||||
|
@ -183,7 +147,12 @@ class CustomWizard::Builder
|
|||
|
||||
if step_template['actions'] && step_template['actions'].length && data
|
||||
step_template['actions'].each do |action|
|
||||
self.send(action['type'].to_sym, user, action, data)
|
||||
CustomWizard::Action.new(
|
||||
action: action,
|
||||
user: user,
|
||||
data: data,
|
||||
updater: updater
|
||||
).perform
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -237,6 +206,10 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
params[:value] = prefill_field(field_template, step_template) || params[:value]
|
||||
|
||||
if field_template['type'] === 'group'
|
||||
params[:value] = params[:value].first
|
||||
end
|
||||
|
||||
if field_template['type'] === 'checkbox'
|
||||
params[:value] = standardise_boolean(params[:value])
|
||||
|
@ -262,8 +235,12 @@ class CustomWizard::Builder
|
|||
@wizard.needs_groups = true
|
||||
end
|
||||
|
||||
if (prefill = field_template['filters']).present?
|
||||
params[:filter] = get_output(field_template['filters'])
|
||||
if (content = field_template['content']).present?
|
||||
params[:content] = CustomWizard::Mapper.new(
|
||||
inputs: content,
|
||||
user: @wizard.user,
|
||||
data: @submissions.last
|
||||
).output
|
||||
end
|
||||
|
||||
field = step.add_field(params)
|
||||
|
@ -275,76 +252,11 @@ class CustomWizard::Builder
|
|||
|
||||
def prefill_field(field_template, step_template)
|
||||
if (prefill = field_template['prefill']).present?
|
||||
get_output(prefill)
|
||||
end
|
||||
end
|
||||
|
||||
def get_output(inputs, opts = {})
|
||||
output = opts[:multiple] ? [] : nil
|
||||
|
||||
inputs.each do |input|
|
||||
if input['type'] === 'conditional' && validate_pairs(input['pairs'])
|
||||
if opts[:multiple]
|
||||
output.push(get_field(input['output'], input['output_type'], opts))
|
||||
else
|
||||
output = get_field(input['output'], input['output_type'], opts)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if input['type'] === 'assignment'
|
||||
value = get_field(input['output'], input['output_type'], opts)
|
||||
|
||||
if opts[:multiple]
|
||||
output.push(value)
|
||||
else
|
||||
output = value
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
|
||||
def validate_pairs(pairs)
|
||||
failed = false
|
||||
|
||||
pairs.each do |pair|
|
||||
key = get_field(pair['key'], pair['key_type'])
|
||||
value = get_field(pair['value'], pair['value_type'])
|
||||
failed = true unless key.public_send(get_operator(pair['connector']), value)
|
||||
end
|
||||
|
||||
!failed
|
||||
end
|
||||
|
||||
def get_operator(connector)
|
||||
OPERATORS[connector] || '=='
|
||||
end
|
||||
|
||||
def get_field(value, type, opts = {})
|
||||
method = "get_#{type}_field"
|
||||
|
||||
if self.respond_to?(method)
|
||||
self.send(method, value, opts)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def get_wizard_field(value, opts = {})
|
||||
data = opts[:data] || @submissions.last
|
||||
data && !data.key?("submitted_at") && data[value]
|
||||
end
|
||||
|
||||
def get_user_field(value, opts = {})
|
||||
if value.include?('user_field_')
|
||||
UserCustomField.where(user_id: @wizard.user.id, name: value).pluck(:value).first
|
||||
elsif UserProfile.column_names.include? value
|
||||
UserProfile.find_by(user_id: @wizard.user.id).send(value)
|
||||
elsif User.column_names.include? value
|
||||
User.find(@wizard.user.id).send(value)
|
||||
CustomWizard::Mapper.new(
|
||||
inputs: prefill,
|
||||
user: @wizard.user,
|
||||
data: @submissions.last
|
||||
).output
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -382,7 +294,10 @@ class CustomWizard::Builder
|
|||
end
|
||||
|
||||
if min_length && value.is_a?(String) && value.strip.length < min_length.to_i
|
||||
updater.errors.add(field['id'].to_s, I18n.t('wizard.field.too_short', label: label, min: min_length.to_i))
|
||||
updater.errors.add(
|
||||
field['id'].to_s,
|
||||
I18n.t('wizard.field.too_short', label: label, min: min_length.to_i)
|
||||
)
|
||||
end
|
||||
|
||||
## ensure all checkboxes are booleans
|
||||
|
@ -405,245 +320,6 @@ class CustomWizard::Builder
|
|||
ActiveRecord::Type::Boolean.new.cast(value)
|
||||
end
|
||||
|
||||
def create_topic(user, action, data)
|
||||
if action['custom_title_enabled']
|
||||
title = CustomWizard::Builder.fill_placeholders(action['custom_title'], user, data)
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
if action['post_builder']
|
||||
post = CustomWizard::Builder.fill_placeholders(action['post_template'], user, data)
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
if title
|
||||
params = {
|
||||
title: title,
|
||||
raw: post,
|
||||
skip_validations: true
|
||||
}
|
||||
|
||||
params[:category] = action_category_id(action, data)
|
||||
|
||||
tags = action_tags(action, data)
|
||||
|
||||
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']]
|
||||
key = field['key']
|
||||
|
||||
if key && (value.present? || value === false)
|
||||
if key.include?('custom_fields')
|
||||
keyArr = key.split('.')
|
||||
|
||||
if keyArr.length === 3
|
||||
custom_key = keyArr.last
|
||||
type = keyArr.first
|
||||
|
||||
if type === 'topic'
|
||||
topic_custom_fields[custom_key] = value
|
||||
elsif type === 'post'
|
||||
params[:custom_fields] ||= {}
|
||||
params[:custom_fields][custom_key.to_sym] = value
|
||||
end
|
||||
end
|
||||
else
|
||||
value = [*value] + tags if key === 'tags'
|
||||
params[key.to_sym] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
creator = PostCreator.new(user, params)
|
||||
post = creator.create
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_message(user, action, data)
|
||||
|
||||
if action['required'].present? && data[action['required']].blank?
|
||||
return
|
||||
end
|
||||
|
||||
if action['custom_title_enabled']
|
||||
title = CustomWizard::Builder.fill_placeholders(action['custom_title'], user, data)
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
if action['post_builder']
|
||||
post = CustomWizard::Builder.fill_placeholders(action['post_template'], user, data)
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
if title && post
|
||||
creator = PostCreator.new(user,
|
||||
title: title,
|
||||
raw: post,
|
||||
archetype: Archetype.private_message,
|
||||
target_usernames: action['username']
|
||||
)
|
||||
|
||||
post = creator.create
|
||||
|
||||
if creator.errors.present?
|
||||
updater.errors.add(:send_message, creator.errors.full_messages.join(" "))
|
||||
else
|
||||
unless action['skip_redirect']
|
||||
data['redirect_on_complete'] = post.topic.url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_profile(user, action, data)
|
||||
return unless action['profile_updates'].length
|
||||
|
||||
attributes = {}
|
||||
custom_fields = {}
|
||||
|
||||
action['profile_updates'].each do |pu|
|
||||
value = pu['value']
|
||||
key = pu['key']
|
||||
|
||||
return if data[key].blank?
|
||||
|
||||
if user_field || custom_field
|
||||
custom_fields[user_field || custom_field] = data[key]
|
||||
else
|
||||
updater_key = value
|
||||
if ['profile_background', 'card_background'].include?(value)
|
||||
updater_key = "#{value}_upload_url"
|
||||
end
|
||||
attributes[updater_key.to_sym] = data[key] if updater_key
|
||||
end
|
||||
|
||||
if ['user_avatar'].include?(value)
|
||||
this_upload_id = data[key][:id]
|
||||
user.create_user_avatar unless user.user_avatar
|
||||
user.user_avatar.custom_upload_id = this_upload_id
|
||||
user.uploaded_avatar_id = this_upload_id
|
||||
user.save!
|
||||
user.user_avatar.save!
|
||||
end
|
||||
end
|
||||
|
||||
if custom_fields.present?
|
||||
attributes[:custom_fields] = custom_fields
|
||||
end
|
||||
|
||||
if attributes.present?
|
||||
user_updater = UserUpdater.new(user, user)
|
||||
user_updater.update(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def send_to_api(user, action, data)
|
||||
api_body = nil
|
||||
|
||||
if action['api_body'] != ""
|
||||
begin
|
||||
api_body_parsed = JSON.parse(action['api_body'])
|
||||
rescue JSON::ParserError
|
||||
raise Discourse::InvalidParameters, "Invalid API body definition: #{action['api_body']} for #{action['title']}"
|
||||
end
|
||||
api_body = JSON.parse(CustomWizard::Builder.fill_placeholders(JSON.generate(api_body_parsed), user, data))
|
||||
end
|
||||
|
||||
result = CustomWizard::Api::Endpoint.request(user, action['api'], action['api_endpoint'], api_body)
|
||||
|
||||
if error = result['error'] || (result[0] && result[0]['error'])
|
||||
error = error['message'] || error
|
||||
updater.errors.add(:send_to_api, error)
|
||||
else
|
||||
## add validation callback
|
||||
end
|
||||
end
|
||||
|
||||
def open_composer(user, action, data)
|
||||
if action['custom_title_enabled']
|
||||
title = CustomWizard::Builder.fill_placeholders(action['custom_title'], user, data)
|
||||
else
|
||||
title = data[action['title']]
|
||||
end
|
||||
|
||||
url = "/new-topic?title=#{title}"
|
||||
|
||||
if action['post_builder']
|
||||
post = CustomWizard::Builder.fill_placeholders(action['post_template'], user, data)
|
||||
else
|
||||
post = data[action['post']]
|
||||
end
|
||||
|
||||
url += "&body=#{post}"
|
||||
|
||||
if category_id = action_category_id(action, data)
|
||||
if category = Category.find(category_id)
|
||||
url += "&category=#{category.full_slug('/')}"
|
||||
end
|
||||
end
|
||||
|
||||
if tags = action_tags(action, data)
|
||||
url += "&tags=#{tags.join(',')}"
|
||||
end
|
||||
|
||||
data['redirect_on_complete'] = Discourse.base_uri + URI.encode(url)
|
||||
end
|
||||
|
||||
def add_to_group(user, action, data)
|
||||
groups = get_output(action['inputs'], multiple: true, data: data)
|
||||
|
||||
groups = groups.flatten.reduce([]) do |result, g|
|
||||
begin
|
||||
result.push(Integer(g))
|
||||
rescue ArgumentError
|
||||
group = Group.find_by(name: g)
|
||||
result.push(group.id) if group
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
if groups.present?
|
||||
groups.each do |group_id|
|
||||
group = Group.find(group_id) if group_id
|
||||
group.add(user) if group
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def route_to(user, action, data)
|
||||
url = CustomWizard::Builder.fill_placeholders(action['url'], user, data)
|
||||
if action['code']
|
||||
data[action['code']] = SecureRandom.hex(8)
|
||||
url += "&#{action['code']}=#{data[action['code']]}"
|
||||
end
|
||||
data['route_to'] = URI.encode(url)
|
||||
end
|
||||
|
||||
def save_submissions(data, final_step)
|
||||
if final_step
|
||||
data['submitted_at'] = Time.now.iso8601
|
||||
|
@ -661,29 +337,4 @@ class CustomWizard::Builder
|
|||
PluginStore.set("#{@wizard.id}_submissions", @wizard.user.id, @submissions)
|
||||
@wizard.reset
|
||||
end
|
||||
|
||||
def action_category_id(action, data)
|
||||
if action['custom_category_enabled']
|
||||
if action['custom_category_wizard_field']
|
||||
data[action['category_id']]
|
||||
elsif action['custom_category_user_field_key']
|
||||
if action['custom_category_user_field_key'].include?('custom_fields')
|
||||
field = action['custom_category_user_field_key'].split('.').last
|
||||
user.custom_fields[field]
|
||||
else
|
||||
user.send(action['custom_category_user_field_key'])
|
||||
end
|
||||
end
|
||||
else
|
||||
action['category_id']
|
||||
end
|
||||
end
|
||||
|
||||
def action_tags(action, data)
|
||||
if action['custom_tag_enabled']
|
||||
data[action['custom_tag_field']]
|
||||
else
|
||||
action['tags']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
114
lib/custom_wizard/mapper.rb
Normale Datei
114
lib/custom_wizard/mapper.rb
Normale Datei
|
@ -0,0 +1,114 @@
|
|||
class CustomWizard::Mapper
|
||||
attr_accessor :inputs, :data, :user
|
||||
|
||||
USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale', 'trust_level']
|
||||
PROFILE_FIELDS = ['location', 'website', 'bio_raw']
|
||||
OPERATORS = { 'eq': '==', 'gt': '>', 'lt': '<', 'gte': '>=', 'lte': '<=' }
|
||||
|
||||
def initialize(params)
|
||||
@inputs = params[:inputs] || {}
|
||||
@data = params[:data] || {}
|
||||
@user = params[:user]
|
||||
@opts = params[:opts] || {}
|
||||
end
|
||||
|
||||
def output
|
||||
multiple = @opts[:multiple]
|
||||
output = multiple ? [] : nil
|
||||
|
||||
inputs.each do |input|
|
||||
if input['type'] === 'conditional' && validate_pairs(input['pairs'])
|
||||
if multiple
|
||||
output.push(map_field(input['output'], input['output_type']))
|
||||
else
|
||||
output = map_field(input['output'], input['output_type'])
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if input['type'] === 'assignment'
|
||||
value = map_field(input['output'], input['output_type'])
|
||||
|
||||
if @opts[:multiple]
|
||||
output.push(value)
|
||||
else
|
||||
output = value
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
|
||||
def validate_pairs(pairs)
|
||||
failed = false
|
||||
|
||||
pairs.each do |pair|
|
||||
key = map_field(pair['key'], pair['key_type'])
|
||||
value = map_field(pair['value'], pair['value_type'])
|
||||
failed = true unless key.public_send(operator(pair['connector']), value)
|
||||
end
|
||||
|
||||
!failed
|
||||
end
|
||||
|
||||
def operator(connector)
|
||||
OPERATORS[connector] || '=='
|
||||
end
|
||||
|
||||
def map_field(value, type)
|
||||
method = "#{type}_field"
|
||||
|
||||
if self.respond_to?(method)
|
||||
self.send(method, value)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def wizard_field(value)
|
||||
data && !data.key?("submitted_at") && data[value]
|
||||
end
|
||||
|
||||
def user_field(value)
|
||||
if value.include?('user_field_')
|
||||
UserCustomField.where(user_id: user.id, name: value).pluck(:value).first
|
||||
elsif PROFILE_FIELDS.include?(value)
|
||||
UserProfile.find_by(user_id: user.id).send(value)
|
||||
elsif USER_FIELDS.include?(value)
|
||||
User.find(user.id).send(value)
|
||||
end
|
||||
end
|
||||
|
||||
def interpolate(string)
|
||||
result = string.gsub(/u\{(.*?)\}/) do |match|
|
||||
result = ''
|
||||
result = user.send($1) if USER_FIELDS.include?($1)
|
||||
result = user.user_profile.send($1) if PROFILE_FIELDS.include?($1)
|
||||
result
|
||||
end
|
||||
|
||||
result = result.gsub(/w\{(.*?)\}/) { |match| recurse(data, [*$1.split('.')]) }
|
||||
|
||||
result.gsub(/v\{(.*?)\}/) do |match|
|
||||
attrs = $1.split(':')
|
||||
key = attrs.first
|
||||
format = attrs.length > 1 ? attrs.last : nil
|
||||
val = nil
|
||||
|
||||
if key == 'time'
|
||||
time_format = format.present? ? format : "%B %-d, %Y"
|
||||
val = Time.now.strftime(time_format)
|
||||
end
|
||||
|
||||
val
|
||||
end
|
||||
end
|
||||
|
||||
def recurse(data, keys)
|
||||
k = keys.shift
|
||||
result = data[k]
|
||||
keys.empty? ? result : self.recurse(result, keys)
|
||||
end
|
||||
end
|
|
@ -8,12 +8,12 @@ class CustomWizard::Template
|
|||
:multiple_submissions,
|
||||
:prompt_completion,
|
||||
:restart_on_revisit,
|
||||
:min_trust,
|
||||
:after_signup,
|
||||
:after_time,
|
||||
:after_time_scheduled,
|
||||
:required,
|
||||
:theme_id
|
||||
:theme_id,
|
||||
:permitted
|
||||
|
||||
def initialize(data)
|
||||
data = data.is_a?(String) ? ::JSON.parse(data) : data
|
||||
|
@ -28,12 +28,12 @@ class CustomWizard::Template
|
|||
@multiple_submissions = data['multiple_submissions'] || false
|
||||
@prompt_completion = data['prompt_completion'] || false
|
||||
@restart_on_revisit = data['restart_on_revisit'] || false
|
||||
@min_trust = data['min_trust'] || 0
|
||||
@after_signup = data['after_signup']
|
||||
@after_time = data['after_time']
|
||||
@after_time_scheduled = data['after_time_scheduled']
|
||||
@required = data['required'] || false
|
||||
@theme_id = data['theme_id']
|
||||
@permitted = data['permitted'] || nil
|
||||
|
||||
if data['theme']
|
||||
theme = Theme.find_by(name: data['theme'])
|
||||
|
|
|
@ -14,13 +14,13 @@ class CustomWizard::Wizard
|
|||
:background,
|
||||
:save_submissions,
|
||||
:multiple_submissions,
|
||||
:min_trust,
|
||||
:after_time,
|
||||
:after_time_scheduled,
|
||||
:after_signup,
|
||||
:required,
|
||||
:prompt_completion,
|
||||
:restart_on_revisit,
|
||||
:permitted,
|
||||
:needs_categories,
|
||||
:needs_groups
|
||||
|
||||
|
@ -127,7 +127,10 @@ class CustomWizard::Wizard
|
|||
end
|
||||
|
||||
def permitted?
|
||||
user && (user.staff? || user.trust_level.to_i >= min_trust.to_i)
|
||||
return false unless user
|
||||
return true if user.admin? || permitted.blank?
|
||||
group_ids = permitted.first['output']
|
||||
return GroupUser.exists?(group_id: group_ids, user_id: user.id)
|
||||
end
|
||||
|
||||
def reset
|
||||
|
@ -146,22 +149,37 @@ class CustomWizard::Wizard
|
|||
def groups
|
||||
@groups ||= ::Site.new(Guardian.new(@user)).groups
|
||||
end
|
||||
|
||||
def self.templates(filter = nil)
|
||||
rows = [*PluginStoreRow.where(plugin_name: 'custom_wizard')]
|
||||
rows = rows.select { |r| r.value[filter] } if filter
|
||||
rows
|
||||
end
|
||||
|
||||
def self.after_signup
|
||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizard')
|
||||
wizards = [*rows].select { |r| r.value['after_signup'] }
|
||||
if wizards.any?
|
||||
wizards.first.key
|
||||
def self.after_signup(user)
|
||||
if (temps = templates('after_signup')).any?
|
||||
wizard = nil
|
||||
|
||||
temps
|
||||
.sort_by { |t| template.value['permitted'].present? }
|
||||
.each do |template|
|
||||
wizard = CustomWizard::Wizard.new(user, template)
|
||||
|
||||
if wizard.permitted?
|
||||
wizard = wizard
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
wizard
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def self.prompt_completion(user)
|
||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizard')
|
||||
wizards = [*rows].select { |r| r.value['prompt_completion'] }
|
||||
if wizards.any?
|
||||
wizards.reduce([]) do |result, w|
|
||||
if (temps = templates('prompt_completion')).any?
|
||||
temps.reduce([]) do |result, w|
|
||||
data = ::JSON.parse(w.value)
|
||||
id = data['id']
|
||||
name = data['name']
|
||||
|
@ -175,10 +193,8 @@ class CustomWizard::Wizard
|
|||
end
|
||||
|
||||
def self.restart_on_revisit
|
||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizard')
|
||||
wizards = [*rows].select { |r| r.value['restart_on_revisit'] }
|
||||
if wizards.any?
|
||||
wizards.first.key
|
||||
if (temps = templates('restart_on_revisit')).any?
|
||||
temps.first.key
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module CustomWizardFieldExtension
|
|||
:file_types,
|
||||
:limit,
|
||||
:property,
|
||||
:filter
|
||||
:content
|
||||
|
||||
attr_accessor :dropdown_none
|
||||
|
||||
|
@ -26,7 +26,7 @@ module CustomWizardFieldExtension
|
|||
@file_types = attrs[:file_types]
|
||||
@limit = attrs[:limit]
|
||||
@property = attrs[:property]
|
||||
@filter = attrs[:filter]
|
||||
@content = attrs[:content]
|
||||
end
|
||||
|
||||
def label
|
||||
|
|
82
plugin.rb
82
plugin.rb
|
@ -37,42 +37,44 @@ if respond_to?(:register_svg_icon)
|
|||
end
|
||||
|
||||
after_initialize do
|
||||
[
|
||||
'../lib/custom_wizard/engine.rb',
|
||||
'../config/routes.rb',
|
||||
'../controllers/custom_wizard/wizard.rb',
|
||||
'../controllers/custom_wizard/steps.rb',
|
||||
'../controllers/custom_wizard/admin.rb',
|
||||
'../controllers/custom_wizard/transfer.rb',
|
||||
'../controllers/custom_wizard/api.rb',
|
||||
'../controllers/application_controller.rb',
|
||||
'../controllers/extra_locales_controller.rb',
|
||||
'../controllers/invites_controller.rb',
|
||||
'../jobs/clear_after_time_wizard.rb',
|
||||
'../jobs/refresh_api_access_token.rb',
|
||||
'../jobs/set_after_time_wizard.rb',
|
||||
'../lib/custom_wizard/builder.rb',
|
||||
'../lib/custom_wizard/field.rb',
|
||||
'../lib/custom_wizard/step_updater.rb',
|
||||
'../lib/custom_wizard/template.rb',
|
||||
'../lib/custom_wizard/wizard.rb',
|
||||
'../lib/custom_wizard/api/api.rb',
|
||||
'../lib/custom_wizard/api/authorization.rb',
|
||||
'../lib/custom_wizard/api/endpoint.rb',
|
||||
'../lib/custom_wizard/api/log_entry.rb',
|
||||
'../lib/wizard/choice.rb',
|
||||
'../lib/wizard/field.rb',
|
||||
'../lib/wizard/step.rb',
|
||||
'../serializers/custom_wizard/api/authorization_serializer.rb',
|
||||
'../serializers/custom_wizard/api/basic_endpoint_serializer.rb',
|
||||
'../serializers/custom_wizard/api/endpoint_serializer.rb',
|
||||
'../serializers/custom_wizard/api/log_serializer.rb',
|
||||
'../serializers/custom_wizard/api_serializer.rb',
|
||||
'../serializers/custom_wizard/basic_api_serializer.rb',
|
||||
'../serializers/custom_wizard/wizard_field_serializer.rb',
|
||||
'../serializers/custom_wizard/wizard_step_serializer.rb',
|
||||
'../serializers/custom_wizard/wizard_serializer.rb',
|
||||
'../serializers/site_serializer.rb'
|
||||
%w[
|
||||
../lib/custom_wizard/engine.rb
|
||||
../config/routes.rb
|
||||
../controllers/custom_wizard/wizard.rb
|
||||
../controllers/custom_wizard/steps.rb
|
||||
../controllers/custom_wizard/admin.rb
|
||||
../controllers/custom_wizard/transfer.rb
|
||||
../controllers/custom_wizard/api.rb
|
||||
../controllers/application_controller.rb
|
||||
../controllers/extra_locales_controller.rb
|
||||
../controllers/invites_controller.rb
|
||||
../jobs/clear_after_time_wizard.rb
|
||||
../jobs/refresh_api_access_token.rb
|
||||
../jobs/set_after_time_wizard.rb
|
||||
../lib/custom_wizard/actions.rb
|
||||
../lib/custom_wizard/builder.rb
|
||||
../lib/custom_wizard/field.rb
|
||||
../lib/custom_wizard/mapper.rb
|
||||
../lib/custom_wizard/step_updater.rb
|
||||
../lib/custom_wizard/template.rb
|
||||
../lib/custom_wizard/wizard.rb
|
||||
../lib/custom_wizard/api/api.rb
|
||||
../lib/custom_wizard/api/authorization.rb
|
||||
../lib/custom_wizard/api/endpoint.rb
|
||||
../lib/custom_wizard/api/log_entry.rb
|
||||
../lib/wizard/choice.rb
|
||||
../lib/wizard/field.rb
|
||||
../lib/wizard/step.rb
|
||||
../serializers/custom_wizard/api/authorization_serializer.rb
|
||||
../serializers/custom_wizard/api/basic_endpoint_serializer.rb
|
||||
../serializers/custom_wizard/api/endpoint_serializer.rb
|
||||
../serializers/custom_wizard/api/log_serializer.rb
|
||||
../serializers/custom_wizard/api_serializer.rb
|
||||
../serializers/custom_wizard/basic_api_serializer.rb
|
||||
../serializers/custom_wizard/wizard_field_serializer.rb
|
||||
../serializers/custom_wizard/wizard_step_serializer.rb
|
||||
../serializers/custom_wizard/wizard_serializer.rb
|
||||
../serializers/site_serializer.rb
|
||||
].each do |path|
|
||||
load File.expand_path(path, __FILE__)
|
||||
end
|
||||
|
@ -85,13 +87,11 @@ after_initialize do
|
|||
|
||||
if user &&
|
||||
user.first_seen_at.blank? &&
|
||||
wizard_id = CustomWizard::Wizard.after_signup
|
||||
|
||||
wizard = CustomWizard::Wizard.create(user, wizard_id)
|
||||
wizard = CustomWizard::Wizard.after_signup(user)
|
||||
|
||||
if !wizard.completed? && wizard.permitted?
|
||||
if !wizard.completed?
|
||||
custom_redirect = true
|
||||
CustomWizard::Wizard.set_wizard_redirect(user, wizard_id)
|
||||
CustomWizard::Wizard.set_wizard_redirect(user, wizard.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ class CustomWizardFieldSerializer < ::WizardFieldSerializer
|
|||
:file_types,
|
||||
:limit,
|
||||
:property,
|
||||
:filter
|
||||
:content
|
||||
|
||||
has_many :choices, serializer: WizardFieldChoiceSerializer, embed: :objects
|
||||
|
||||
|
@ -49,7 +49,7 @@ class CustomWizardFieldSerializer < ::WizardFieldSerializer
|
|||
object.property
|
||||
end
|
||||
|
||||
def filter
|
||||
object.filter
|
||||
def content
|
||||
object.content
|
||||
end
|
||||
end
|
|
@ -7,7 +7,6 @@ class CustomWizardSerializer < ::WizardSerializer
|
|||
:background,
|
||||
:completed,
|
||||
:required,
|
||||
:min_trust,
|
||||
:permitted,
|
||||
:uncategorized_category_id
|
||||
|
||||
|
|
Laden …
In neuem Issue referenzieren