Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 09:20:29 +01:00
various
Dieser Commit ist enthalten in:
Ursprung
92e61f3f51
Commit
d128565979
21 geänderte Dateien mit 161 neuen und 113 gelöschten Zeilen
|
@ -1,8 +1,15 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
import { default as discourseComputed } from 'discourse-common/utils/decorators';
|
||||||
|
import { wizardFieldList } from '../lib/wizard';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: 'wizard-custom-step',
|
classNames: 'wizard-custom-step',
|
||||||
|
|
||||||
|
@discourseComputed('wizard.steps', 'step.id')
|
||||||
|
descriptionWizardFields(steps, stepId) {
|
||||||
|
return wizardFieldList(steps, { upTo: stepId });
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
bannerUploadDone(upload) {
|
bannerUploadDone(upload) {
|
||||||
this.set("step.banner", upload.url);
|
this.set("step.banner", upload.url);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { default as discourseComputed, on } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed, on } from 'discourse-common/utils/decorators';
|
||||||
|
import { notEmpty } from "@ember/object/computed";
|
||||||
import { userProperties } from '../lib/wizard';
|
import { userProperties } from '../lib/wizard';
|
||||||
import { scheduleOnce } from "@ember/runloop";
|
import { scheduleOnce } from "@ember/runloop";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
|
@ -8,9 +9,11 @@ export default Component.extend({
|
||||||
barEnabled: true,
|
barEnabled: true,
|
||||||
previewEnabled: true,
|
previewEnabled: true,
|
||||||
fieldsEnabled: true,
|
fieldsEnabled: true,
|
||||||
|
hasWizardFields: notEmpty('wizardFieldList'),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
if (!this.barEnabled) {
|
if (!this.barEnabled) {
|
||||||
scheduleOnce('afterRender', () => {
|
scheduleOnce('afterRender', () => {
|
||||||
$(this.element).find('.d-editor-button-bar').addClass('hidden');
|
$(this.element).find('.d-editor-button-bar').addClass('hidden');
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{{#each site.complete_custom_wizard as |wizard|}}
|
||||||
|
<div class='row'>
|
||||||
|
<div class='alert alert-info alert-wizard'>
|
||||||
|
<a href="{{wizard.url}}">{{i18n 'wizard.complete_custom' name=wizard.name}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
shouldRender(_, ctx) {
|
||||||
|
return ctx.siteSettings.custom_wizard_enabled &&
|
||||||
|
ctx.site.complete_custom_wizard;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators';
|
||||||
import { notEmpty, alias } from "@ember/object/computed";
|
import { notEmpty, alias } from "@ember/object/computed";
|
||||||
import showModal from 'discourse/lib/show-modal';
|
import showModal from 'discourse/lib/show-modal';
|
||||||
import { generateId } from '../lib/wizard';
|
import { generateId, wizardFieldList } from '../lib/wizard';
|
||||||
import { buildProperties } from '../lib/wizard-json';
|
import { buildProperties } from '../lib/wizard-json';
|
||||||
import { dasherize } from "@ember/string";
|
import { dasherize } from "@ember/string";
|
||||||
import EmberObject from "@ember/object";
|
import EmberObject from "@ember/object";
|
||||||
|
@ -47,29 +47,11 @@ export default Controller.extend({
|
||||||
|
|
||||||
@discourseComputed('currentStep.id', 'wizard.save_submissions', 'wizard.steps.@each.fields[]')
|
@discourseComputed('currentStep.id', 'wizard.save_submissions', 'wizard.steps.@each.fields[]')
|
||||||
wizardFields(currentStepId, saveSubmissions) {
|
wizardFields(currentStepId, saveSubmissions) {
|
||||||
const allSteps = this.get('wizard.steps');
|
let steps = this.wizard.steps;
|
||||||
let steps = allSteps;
|
|
||||||
let fields = [];
|
|
||||||
|
|
||||||
if (!saveSubmissions) {
|
if (!saveSubmissions) {
|
||||||
steps = [allSteps.findBy('id', currentStepId)];
|
steps = [steps.findBy('id', currentStepId)];
|
||||||
}
|
}
|
||||||
|
return wizardFieldList(steps);
|
||||||
steps.forEach((s) => {
|
|
||||||
if (s.fields && s.fields.length > 0) {
|
|
||||||
let stepFields = s.fields.map((f) => {
|
|
||||||
return EmberObject.create({
|
|
||||||
id: f.id,
|
|
||||||
label: `${f.label} (${s.id}, ${f.id})`,
|
|
||||||
type: f.type
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
fields.push(...stepFields);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return fields;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -7,25 +7,6 @@ export default {
|
||||||
const siteSettings = container.lookup('site-settings:main');
|
const siteSettings = container.lookup('site-settings:main');
|
||||||
|
|
||||||
if (!siteSettings.custom_wizard_enabled) return;
|
if (!siteSettings.custom_wizard_enabled) return;
|
||||||
|
|
||||||
withPluginApi('0.8.12', api => {
|
|
||||||
api.modifyClass('component:global-notice', {
|
|
||||||
buildBuffer(buffer) {
|
|
||||||
this._super(...arguments);
|
|
||||||
const wizards = this.site.get('complete_custom_wizard');
|
|
||||||
if (wizards) {
|
|
||||||
wizards.forEach((w) => {
|
|
||||||
const text = I18n.t('wizard.complete_custom', {
|
|
||||||
wizard_url: w.url,
|
|
||||||
wizard_name: w.name,
|
|
||||||
site_name: this.siteSettings.title
|
|
||||||
});
|
|
||||||
buffer.push(`<div class='row'><div class='alert alert-info alert-wizard'>${text}</div></div>`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const existing = DiscourseURL.routeTo;
|
const existing = DiscourseURL.routeTo;
|
||||||
DiscourseURL.routeTo = function(path, opts) {
|
DiscourseURL.routeTo = function(path, opts) {
|
||||||
|
|
|
@ -137,7 +137,7 @@ function buildProperties(json) {
|
||||||
steps: A(),
|
steps: A(),
|
||||||
actions: A()
|
actions: A()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (present(json)) {
|
if (present(json)) {
|
||||||
props.existingId = true;
|
props.existingId = true;
|
||||||
props = buildBasicProperties(json, 'wizard', props);
|
props = buildBasicProperties(json, 'wizard', props);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import EmberObject from "@ember/object";
|
||||||
|
|
||||||
function selectKitContent(content) {
|
function selectKitContent(content) {
|
||||||
return content.map(i => ({id: i, name: i}));
|
return content.map(i => ({id: i, name: i}));
|
||||||
}
|
}
|
||||||
|
@ -177,9 +179,8 @@ const fieldProperties = {
|
||||||
'content'
|
'content'
|
||||||
],
|
],
|
||||||
advanced: [
|
advanced: [
|
||||||
'prefill',
|
'property',
|
||||||
'content',
|
'key'
|
||||||
'property'
|
|
||||||
],
|
],
|
||||||
required: [
|
required: [
|
||||||
'id',
|
'id',
|
||||||
|
@ -290,6 +291,33 @@ function listProperties(type, objectType = null) {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wizardFieldList(steps = [], opts = {}) {
|
||||||
|
let upToIndex = null;
|
||||||
|
|
||||||
|
if (opts.upTo) {
|
||||||
|
upToIndex = steps.map((s) => (s.id)).indexOf(opts.upTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return steps.reduce((result, step, index) => {
|
||||||
|
let fields = step.fields;
|
||||||
|
|
||||||
|
if (fields && fields.length > 0) {
|
||||||
|
|
||||||
|
if (upToIndex === null || index < upToIndex) {
|
||||||
|
result.push(...fields.map((field) => {
|
||||||
|
return EmberObject.create({
|
||||||
|
id: field.id,
|
||||||
|
label: `${field.label} (${step.id}, ${field.id})`,
|
||||||
|
type: field.type
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
selectKitContent,
|
selectKitContent,
|
||||||
generateName,
|
generateName,
|
||||||
|
@ -298,5 +326,6 @@ export {
|
||||||
snakeCase,
|
snakeCase,
|
||||||
schema,
|
schema,
|
||||||
userProperties,
|
userProperties,
|
||||||
listProperties
|
listProperties,
|
||||||
|
wizardFieldList
|
||||||
};
|
};
|
|
@ -21,7 +21,7 @@ export default DiscourseRoute.extend({
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
const parentModel = this.modelFor('adminWizardsWizard');
|
const parentModel = this.modelFor('adminWizardsWizard');
|
||||||
const wizard = CustomWizard.create((!model || model.create) ? {} : model);
|
const wizard = CustomWizard.create((!model || model.create) ? {} : model);
|
||||||
|
|
||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
wizardList: parentModel.wizard_list,
|
wizardList: parentModel.wizard_list,
|
||||||
fieldTypes: selectKitContent(parentModel.field_types),
|
fieldTypes: selectKitContent(parentModel.field_types),
|
||||||
|
|
|
@ -97,6 +97,34 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if showPrefill}}
|
||||||
|
<div class="setting full field-mapper-setting">
|
||||||
|
<div class="setting-label">
|
||||||
|
<label>{{i18n 'admin.wizard.field.prefill'}}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-value">
|
||||||
|
{{wizard-mapper
|
||||||
|
inputs=field.prefill
|
||||||
|
options=prefillOptions}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if showContent}}
|
||||||
|
<div class="setting full field-mapper-setting">
|
||||||
|
<div class="setting-label">
|
||||||
|
<label>{{i18n 'admin.wizard.field.content'}}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="setting-value">
|
||||||
|
{{wizard-mapper
|
||||||
|
inputs=field.content
|
||||||
|
options=contentOptions}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{wizard-advanced-toggle showAdvanced=field.showAdvanced}}
|
{{wizard-advanced-toggle showAdvanced=field.showAdvanced}}
|
||||||
|
|
||||||
{{#if field.showAdvanced}}
|
{{#if field.showAdvanced}}
|
||||||
|
@ -120,34 +148,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if showPrefill}}
|
|
||||||
<div class="setting full field-mapper-setting">
|
|
||||||
<div class="setting-label">
|
|
||||||
<label>{{i18n 'admin.wizard.field.prefill'}}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-value">
|
|
||||||
{{wizard-mapper
|
|
||||||
inputs=field.prefill
|
|
||||||
options=prefillOptions}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if showContent}}
|
|
||||||
<div class="setting full field-mapper-setting">
|
|
||||||
<div class="setting-label">
|
|
||||||
<label>{{i18n 'admin.wizard.field.content'}}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="setting-value">
|
|
||||||
{{wizard-mapper
|
|
||||||
inputs=field.content
|
|
||||||
options=contentOptions}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<div class="setting-label">
|
<div class="setting-label">
|
||||||
<label>{{i18n 'admin.wizard.translation'}}</label>
|
<label>{{i18n 'admin.wizard.translation'}}</label>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<div class="setting-value">
|
<div class="setting-value">
|
||||||
{{wizard-text-editor
|
{{wizard-text-editor
|
||||||
value=step.raw_description
|
value=step.raw_description
|
||||||
fieldsEnabled=false}}
|
wizardFields=descriptionWizardFields}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,13 @@
|
||||||
{{i18n 'admin.wizard.action.post_builder.user_fields'}}
|
{{i18n 'admin.wizard.action.post_builder.user_fields'}}
|
||||||
{{userFieldList}}
|
{{userFieldList}}
|
||||||
</label>
|
</label>
|
||||||
<label>
|
|
||||||
{{i18n 'admin.wizard.action.post_builder.wizard_fields'}}
|
{{#if hasWizardFields}}
|
||||||
{{wizardFieldList}}
|
<label>
|
||||||
</label>
|
{{i18n 'admin.wizard.action.post_builder.wizard_fields'}}
|
||||||
|
{{wizardFieldList}}
|
||||||
|
</label>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -89,7 +89,13 @@ export default {
|
||||||
|
|
||||||
animateInvalidFields() {
|
animateInvalidFields() {
|
||||||
Ember.run.scheduleOnce('afterRender', () => {
|
Ember.run.scheduleOnce('afterRender', () => {
|
||||||
$('.invalid input[type=text], .invalid textarea, .invalid input[type=checkbox], .invalid .select-kit').wiggle(2, 100);
|
let query = '.invalid input[type=text], .invalid textarea, .invalid input[type=checkbox], .invalid .select-kit';
|
||||||
|
|
||||||
|
$([document.documentElement, document.body]).animate({
|
||||||
|
scrollTop: $(query).offset().top - 200
|
||||||
|
}, 400, function() {
|
||||||
|
$(query).wiggle(2, 100);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -185,6 +191,7 @@ export default {
|
||||||
if (wizardErrors.length) {
|
if (wizardErrors.length) {
|
||||||
this.handleWizardError(wizardErrors.join('\n'));
|
this.handleWizardError(wizardErrors.join('\n'));
|
||||||
}
|
}
|
||||||
|
this.animateInvalidFields();
|
||||||
throw response;
|
throw response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
{{wizard-no-access text=(i18n 'wizard.none') wizardId=wizardId}}
|
{{wizard-no-access text=(i18n 'wizard.none') wizardId=wizardId}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if requiresLogin}}
|
{{#if requiresLogin}}
|
||||||
{{wizard-no-access text=(i18n 'wizard.requires_login' name=name) wizardId=wizardId}}
|
{{wizard-no-access text=(i18n 'wizard.requires_login') wizardId=wizardId}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if notPermitted}}
|
{{#if notPermitted}}
|
||||||
{{wizard-no-access text=(i18n 'wizard.not_permitted' name=name) wizardId=wizardId}}
|
{{wizard-no-access text=(i18n 'wizard.not_permitted') wizardId=wizardId}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if completed}}
|
{{#if completed}}
|
||||||
{{wizard-no-access text=(i18n 'wizard.completed' name=name) wizardId=wizardId}}
|
{{wizard-no-access text=(i18n 'wizard.completed') wizardId=wizardId}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
en:
|
en:
|
||||||
js:
|
js:
|
||||||
wizard:
|
wizard:
|
||||||
complete_custom: "Welcome to %{site_name}! Get started with <a href='%{wizard_url}' data-auto-route='true'>the %{wizard_name} wizard</a> ✨"
|
complete_custom: "Complete the {{name}}"
|
||||||
|
|
||||||
admin_js:
|
admin_js:
|
||||||
admin:
|
admin:
|
||||||
|
@ -337,11 +337,11 @@ en:
|
||||||
other: "Select at least {{count}} items."
|
other: "Select at least {{count}} items."
|
||||||
|
|
||||||
wizard:
|
wizard:
|
||||||
completed: "You have completed the {{name}} wizard."
|
completed: "You have completed this wizard."
|
||||||
not_permitted: "You are not permitted to access the {{name}} wizard."
|
not_permitted: "You are not permitted to access this wizard."
|
||||||
none: "There is no wizard here."
|
none: "There is no wizard here."
|
||||||
return_to_site: "Return to {{siteName}}"
|
return_to_site: "Return to {{siteName}}"
|
||||||
requires_login: "You need to be logged in to access the {{name}} wizard."
|
requires_login: "You need to be logged in to access this wizard."
|
||||||
reset: "Reset this wizard."
|
reset: "Reset this wizard."
|
||||||
step_not_permitted: "You're not permitted to view this step."
|
step_not_permitted: "You're not permitted to view this step."
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
module Jobs
|
module Jobs
|
||||||
class SetAfterTimeWizard < ::Jobs::Base
|
class SetAfterTimeWizard < ::Jobs::Base
|
||||||
def execute(args)
|
def execute(args)
|
||||||
if CustomWizard::Wizard.find(args[:wizard_id])
|
if SiteSetting.custom_wizard_enabled
|
||||||
user_ids = []
|
wizard = CustomWizard::Wizard.find(args[:wizard_id])
|
||||||
|
|
||||||
|
if wizard && wizard.after_time
|
||||||
|
user_ids = []
|
||||||
|
|
||||||
User.human_users.each do |user|
|
User.human_users.each do |user|
|
||||||
if CustomWizard::Wizard.set_wizard_redirect(args[:wizard_id], user)
|
if CustomWizard::Wizard.set_wizard_redirect(wizard.id, user)
|
||||||
user_ids.push(user.id)
|
user_ids.push(user.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
MessageBus.publish "/redirect_to_wizard", args[:wizard_id], user_ids: user_ids
|
MessageBus.publish "/redirect_to_wizard", wizard.id, user_ids: user_ids
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,6 +36,13 @@ class CustomWizard::Builder
|
||||||
sorted_field_validators << { priority: priority, type: type, block: block }
|
sorted_field_validators << { priority: priority, type: type, block: block }
|
||||||
@sorted_field_validators.sort_by! { |h| -h[:priority] }
|
@sorted_field_validators.sort_by! { |h| -h[:priority] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mapper
|
||||||
|
CustomWizard::Mapper.new(
|
||||||
|
user: @wizard.user,
|
||||||
|
data: @submissions.last
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def build(build_opts = {}, params = {})
|
def build(build_opts = {}, params = {})
|
||||||
return nil if !SiteSetting.custom_wizard_enabled || !@wizard
|
return nil if !SiteSetting.custom_wizard_enabled || !@wizard
|
||||||
|
@ -46,8 +53,12 @@ class CustomWizard::Builder
|
||||||
@steps.each do |step_template|
|
@steps.each do |step_template|
|
||||||
@wizard.append_step(step_template['id']) do |step|
|
@wizard.append_step(step_template['id']) do |step|
|
||||||
step.title = step_template['title'] if step_template['title']
|
step.title = step_template['title'] if step_template['title']
|
||||||
step.description = step_template['description'] if step_template['description']
|
|
||||||
step.banner = step_template['banner'] if step_template['banner']
|
step.banner = step_template['banner'] if step_template['banner']
|
||||||
|
|
||||||
|
if step_template['description']
|
||||||
|
step.description = mapper.interpolate(step_template['description'])
|
||||||
|
end
|
||||||
|
|
||||||
step.key = step_template['key'] if step_template['key']
|
step.key = step_template['key'] if step_template['key']
|
||||||
step.permitted = true
|
step.permitted = true
|
||||||
|
|
||||||
|
@ -87,10 +98,7 @@ class CustomWizard::Builder
|
||||||
p['key'] = @submissions.last[p['key']]
|
p['key'] = @submissions.last[p['key']]
|
||||||
end
|
end
|
||||||
|
|
||||||
unless CustomWizard::Mapper.new(
|
unless mapper.validate_pairs(pairs)
|
||||||
user: @wizard.user,
|
|
||||||
data: @submissions.last
|
|
||||||
).validate_pairs(pairs)
|
|
||||||
step.permitted = false
|
step.permitted = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,17 +13,23 @@ class CustomWizard::StepUpdater
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
return false if !SiteSetting.custom_wizard_enabled
|
byebug
|
||||||
|
|
||||||
@step.updater.call(self) if @step.present? && @step.updater.present?
|
|
||||||
|
|
||||||
if success?
|
if SiteSetting.custom_wizard_enabled &&
|
||||||
|
@step.present? &&
|
||||||
|
@step.updater.present? &&
|
||||||
|
success?
|
||||||
|
|
||||||
|
@step.updater.call(self)
|
||||||
|
|
||||||
UserHistory.create(
|
UserHistory.create(
|
||||||
action: UserHistory.actions[:custom_wizard_step],
|
action: UserHistory.actions[:custom_wizard_step],
|
||||||
acting_user_id: @current_user.id,
|
acting_user_id: @current_user.id,
|
||||||
context: @wizard.id,
|
context: @wizard.id,
|
||||||
subject: @step.id
|
subject: @step.id
|
||||||
)
|
)
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,14 @@ class CustomWizard::Validator
|
||||||
wizard = CustomWizard::Wizard.create(@params[:id]) if !@opts[:create]
|
wizard = CustomWizard::Wizard.create(@params[:id]) if !@opts[:create]
|
||||||
current_time = wizard.present? ? wizard.after_time_scheduled : nil
|
current_time = wizard.present? ? wizard.after_time_scheduled : nil
|
||||||
new_time = @params[:after_time_scheduled]
|
new_time = @params[:after_time_scheduled]
|
||||||
|
|
||||||
|
begin
|
||||||
|
active_time = Time.parse(new_time.present? ? new_time : current_time).utc
|
||||||
|
rescue ArgumentError
|
||||||
|
invalid_time = true
|
||||||
|
end
|
||||||
|
|
||||||
if (new_time.blank? && current_time.blank?) ||
|
if invalid_time || active_time.blank? || active_time < Time.now.utc
|
||||||
(new_time !~ /^([01]?[0-9]|2[0-3])\:[0-5][0-9]$/) ||
|
|
||||||
(Time.parse(new_time).utc < Time.now.utc)
|
|
||||||
|
|
||||||
@error = { type: 'after_time' }
|
@error = { type: 'after_time' }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -172,9 +172,7 @@ class CustomWizard::Wizard
|
||||||
|
|
||||||
def can_access?
|
def can_access?
|
||||||
return true if user.admin
|
return true if user.admin
|
||||||
return false if multiple_submissions && completed?
|
return permitted? && (multiple_submissions || !completed?)
|
||||||
return false if !permitted?
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset
|
def reset
|
||||||
|
@ -230,7 +228,11 @@ class CustomWizard::Wizard
|
||||||
if (records = filter_records('prompt_completion')).any?
|
if (records = filter_records('prompt_completion')).any?
|
||||||
records.reduce([]) do |result, record|
|
records.reduce([]) do |result, record|
|
||||||
wizard = CustomWizard::Wizard.new(::JSON.parse(record.value), user)
|
wizard = CustomWizard::Wizard.new(::JSON.parse(record.value), user)
|
||||||
result.push(id: wizard.id, name: wizard.name) if !wizard.completed?
|
|
||||||
|
if wizard.permitted? && !wizard.completed?
|
||||||
|
result.push(id: wizard.id, name: wizard.name)
|
||||||
|
end
|
||||||
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -15,7 +15,7 @@ module CustomWizardSiteSerializerExtension
|
||||||
|
|
||||||
def complete_custom_wizard
|
def complete_custom_wizard
|
||||||
if scope.user && requires_completion = CustomWizard::Wizard.prompt_completion(scope.user)
|
if scope.user && requires_completion = CustomWizard::Wizard.prompt_completion(scope.user)
|
||||||
requires_completion.map {|w| {name: w[:name], url: "/w/#{w[:id]}"}}
|
requires_completion.map {|w| { name: w[:name], url: "/w/#{w[:id]}"} }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Laden …
In neuem Issue referenzieren