0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-09-19 15:21:11 +02:00
Dieser Commit ist enthalten in:
Angus McLeod 2017-10-07 10:27:38 +08:00
Ursprung 9f40821db0
Commit a43f4b1344
24 geänderte Dateien mit 226 neuen und 115 gelöschten Zeilen

Datei anzeigen

@ -44,7 +44,7 @@ class CustomWizard::AdminController < ::ApplicationController
def find_wizard
params.require(:wizard_id)
wizard = PluginStore.get('custom_wizard', params[:wizard_id])
wizard = PluginStore.get('custom_wizard', params[:wizard_id].underscore)
render json: success_json.merge(wizard: wizard)
end
@ -60,7 +60,7 @@ class CustomWizard::AdminController < ::ApplicationController
def find_submissions
params.require(:wizard_id)
wizard = PluginStore.get('custom_wizard_submissions', params[:wizard_id])
wizard = PluginStore.get('custom_wizard_submissions', params[:wizard_id].underscore)
render json: success_json.merge(submissions: submissions)
end

Datei anzeigen

@ -2,7 +2,7 @@ class CustomWizard::StepsController < ApplicationController
before_action :ensure_logged_in
def update
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id]).build
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id].underscore).build
updater = wizard.create_updater(params[:step_id], params[:fields])
updater.update

Datei anzeigen

@ -6,7 +6,7 @@ class CustomWizard::WizardController < ::ApplicationController
def index
respond_to do |format|
format.json do
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id]).build
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id].underscore).build
render_serialized(wizard, WizardSerializer)
end
format.html {}

Datei anzeigen

@ -8,7 +8,6 @@ export default Ember.Component.extend({
@observes('field.id')
init() {
this._super(...arguments);
if (!this.get('field.choices')) {
this.set('field.choices', Ember.A());
}

Datei anzeigen

@ -6,23 +6,25 @@ export default Ember.Component.extend({
currentAction: null,
@on('init')
@observes('step.id')
@observes('step')
setup() {
this._super(...arguments);
const fields = this.get('step.fields');
const actions = this.get('step.actions');
const fields = this.get('step.fields') || [];
const actions = this.get('step.actions') || [];
this.set('currentField', fields[0]);
this.set('currentAction', actions[0]);
},
@computed('step.fields.[]', 'currentField')
fieldLinks(fields, current) {
if (!fields) return;
return fields.map((f) => {
if (f) {
let link = {
id: f.get('id'),
label: f.get('label')
};
const id = f.get('id');
const label = f.get('label');
let link = { id, label: label || id };
let classes = 'btn';
if (current && f.get('id') === current.get('id')) {
@ -38,12 +40,14 @@ export default Ember.Component.extend({
@computed('step.actions.[]', 'currentAction')
actionLinks(actions, current) {
if (!actions) return;
return actions.map((a) => {
if (a) {
let link = {
id: a.get('id'),
label: a.get('label')
};
const id = a.get('id');
const label = a.get('label');
let link = { id, label: label || id };
let classes = 'btn';
if (current && a.get('id') === current.get('id')) {
@ -62,7 +66,7 @@ export default Ember.Component.extend({
const fields = this.get('step.fields');
const newNum = fields.length + 1;
const field = Ember.Object.create({
id: `field-${newNum}`, label: `Field ${newNum}`
id: `field-${newNum}`
});
fields.pushObject(field);
this.set('currentField', field);
@ -72,7 +76,7 @@ export default Ember.Component.extend({
const actions = this.get('step.actions');
const newNum = actions.length + 1;
const action = Ember.Object.create({
id: `action-${newNum}`, label: `Action ${newNum}`
id: `action-${newNum}`
});
actions.pushObject(action);
this.set('currentAction', action);

Datei anzeigen

@ -6,13 +6,13 @@ export default Ember.Controller.extend({
stepLinks(steps, currentStep) {
return steps.map((s) => {
if (s) {
let link = {
id: s.get('id'),
title: s.get('title')
};
const id = s.get('id');
const title = s.get('title');
let link = { id, title: title || id };
let classes = 'btn';
if (currentStep && s.get('id') === currentStep.get('id')) {
if (currentStep && id === currentStep.get('id')) {
classes += ' btn-primary';
};
@ -23,21 +23,25 @@ export default Ember.Controller.extend({
});
},
@computed('model.id')
@computed('model.id', 'model.name')
wizardUrl(wizardId) {
return window.location.origin + '/wizard/custom/' + wizardId;
return window.location.origin + '/wizard/custom/' + Ember.String.dasherize(wizardId);
},
actions: {
save() {
this.get('model').save().then(() => {
this.send("refreshRoute");
if (this.get('newWizard')) {
this.send("refreshAllWizards");
} else {
this.send("refreshWizard");
}
});
},
remove() {
this.get('model').remove().then(() => {
this.transitionToRoute('adminWizardsCustom');
this.send("refreshAllWizards");
});
},
@ -47,10 +51,8 @@ export default Ember.Controller.extend({
const step = Ember.Object.create({
fields: Ember.A(),
actions: Ember.A(),
title: `Step ${newNum}`,
id: `step-${newNum}`
});
steps.pushObject(step);
this.set('currentStep', step);
},
@ -58,6 +60,7 @@ export default Ember.Controller.extend({
removeStep(stepId) {
const steps = this.get('model.steps');
steps.removeObject(steps.findBy('id', stepId));
this.set('currentStep', steps[steps.length - 1]);
},
changeStep(stepId) {

Datei anzeigen

@ -0,0 +1,5 @@
import { registerUnbound } from 'discourse-common/lib/helpers';
registerUnbound('dasherize', function(string) {
return Ember.String.dasherize(string);
});

Datei anzeigen

@ -1,37 +1,57 @@
import { default as computed } from 'ember-addons/ember-computed-decorators';
import { observes, on } from 'ember-addons/ember-computed-decorators';
import { ajax } from 'discourse/lib/ajax';
const CustomWizard = Discourse.Model.extend({
init() {
@on('init')
setup() {
const id = this.get('id');
if (id) this.set('existingId', id);
},
@computed('name')
id: (name) => name ? Ember.String.dasherize(name) : null,
@observes('name')
updateId() {
const name = this.get('name');
this.set('id', name.underscore());
},
save() {
const stepsObj = this.get('steps');
let steps = [];
stepsObj.forEach((s) => {
if (!s.title && !s.translation_key) return;
let step = {
id: Ember.String.dasherize(s.title),
title: s.title,
banner: s.banner,
description: s.description,
id: (s.title || s.translation_key.split('.').pop()).underscore(),
fields: [],
actions: []
};
if (s.title) step['title'] = s.title;
if (s.translation_key) step['translation_key'] = s.translation_key;
if (s.banner) step['banner'] = s.banner;
if (s.description) step['description'] = s.description;
const fields = s.get('fields');
fields.forEach((f) => {
f.set('id', Ember.String.dasherize(f.get('label')));
const fl = f.get('label');
const fkey = f.get('translation_key');
if (!fl && !fkey) return;
f.set('id', (fl || fkey.split('.').pop()).underscore());
if (f.get('type') === 'dropdown') {
const choices = f.get('choices');
choices.forEach((c) => {
c.set('id', c.get('label'));
const cl = c.get('label');
const ckey = c.get('translation_key');
if (!cl && !ckey) return;
c.set('id', (cl || ckey.split('.').pop()).underscore());
});
}
@ -39,7 +59,9 @@ const CustomWizard = Discourse.Model.extend({
});
s.actions.forEach((a) => {
a.set('id', Ember.String.dasherize(a.get('label')));
const al = a.get('label');
if (!al) return;
a.set('id', al.underscore());
step['actions'].push(a);
});
@ -48,8 +70,9 @@ const CustomWizard = Discourse.Model.extend({
const id = this.get('id');
const name = this.get('name');
const background = this.get('background');
const save_submissions = this.get('save_submissions');
let wizard = { id, name, save_submissions, steps };
let wizard = { id, name, background, save_submissions, steps };
const existingId = this.get('existingId');
if (existingId && existingId !== id) {
@ -93,13 +116,13 @@ CustomWizard.reopenClass({
create(w) {
const wizard = this._super.apply(this);
let steps = Ember.A();
let props = { steps };
if (w) {
props['id'] = w.id;
props['name'] = w.name;
props['background'] = w.background;
if (w.steps) {
w.steps.forEach((s) => {
@ -125,6 +148,7 @@ CustomWizard.reopenClass({
steps.pushObject(Ember.Object.create({
id: s.id,
translation_key: s.translation_key,
title: s.title,
description: s.description,
banner: s.banner,
@ -134,7 +158,11 @@ CustomWizard.reopenClass({
});
};
} else {
props['id'] = '';
props['name'] = '';
props['background'] = '';
props['save_submissions'] = true;
props['steps'] = Ember.A();
};
wizard.setProperties(props);

Datei anzeigen

@ -4,12 +4,12 @@ import { ajax } from 'discourse/lib/ajax';
export default Discourse.Route.extend({
model(params) {
if (params.wizard_id === 'new') {
this.set('new', true);
this.set('newWizard', true);
return CustomWizard.create();
}
this.set('new', false);
this.set('newWizard', false);
const wizard = this.modelFor('admin-wizards-custom').findBy('id', params.wizard_id);
const wizard = this.modelFor('admin-wizards-custom').findBy('id', params.wizard_id.underscore());
if (!wizard) return this.transitionTo('adminWizardsCustom.index');
return wizard;
@ -21,14 +21,17 @@ export default Discourse.Route.extend({
},
setupController(controller, model) {
let props = { new: this.get('new'), model };
const steps = model.get('steps');
if (steps[0]) props['currentStep'] = steps[0];
controller.setProperties(props);
const newWizard = this.get('newWizard');
const steps = model.get('steps') || [];
controller.setProperties({
newWizard,
model,
currentStep: steps[0]
});
},
actions: {
refreshRoute() {
refreshWizard() {
this.refresh();
}
}

Datei anzeigen

@ -5,10 +5,11 @@ export default Discourse.Route.extend({
return CustomWizard.findAll();
},
afterModel(model, transition) {
if (transition.intent.name !== 'adminWizard' && model.length > 0) {
this.transitionTo('adminWizard', model[0].id);
}
afterModel(model) {
const transitionToWizard = this.get('transitionToWizard');
if (transitionToWizard === 'last' && model.length) {
this.transitionTo('adminWizard', model[model.length - 1].id);
};
},
setupController(controller, model){
@ -16,10 +17,9 @@ export default Discourse.Route.extend({
},
actions: {
willTransition(transition) {
if (transition.intent.name === 'adminWizardsCustom') {
refreshAllWizards() {
this.set('transitionToWizard', 'last');
this.refresh();
}
}
}
});

Datei anzeigen

@ -1,5 +1 @@
export default Discourse.Route.extend({
redirect() {
this.transitionTo('adminWizardsCustom');
}
});
export default Discourse.Route.extend();

Datei anzeigen

@ -4,12 +4,21 @@
{{i18n 'admin.wizard.header'}}
</div>
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.background'}}</h3>
</div>
<div class="setting-value">
{{input name="background" value=model.background placeholderKey="admin.wizard.background_placeholder"}}
</div>
</div>
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.name'}}</h3>
</div>
<div class="setting-value">
{{text-field name="name" value=model.name placeholderKey="admin.wizard.name_placeholder"}}
{{input name="name" value=model.name placeholderKey="admin.wizard.name_placeholder"}}
</div>
</div>
@ -39,11 +48,13 @@
{{d-button action='addStep' label='admin.wizard.add' icon='plus'}}
</div>
{{#if currentStep}}
{{wizard-custom-step step=currentStep fieldTypes=model.fieldTypes}}
{{/if}}
<div class='buttons'>
<button {{action "save"}} disabled={{disableSave}} class='btn btn-primary'>{{i18n 'admin.wizard.save'}}</button>
{{#unless new}}
{{#unless newWizard}}
<button {{action "remove"}} class='btn btn-danger'>{{d-icon "trash-o"}}{{i18n 'admin.wizard.remove'}}</button>
{{/unless}}
<span class="saving {{unless savingStatus 'hidden'}}">{{savingStatus}}</span>

Datei anzeigen

@ -1,9 +1,9 @@
<div class='row'>
<div class='content-list span6'>
<div class='content-list wizard-list'>
<ul>
{{#each model as |w|}}
<li>
{{#link-to "adminWizard" w.id}}{{w.name}}{{/link-to}}
{{#link-to "adminWizard" (dasherize w.id)}}{{w.name}}{{/link-to}}
</li>
{{/each}}
</ul>

Datei anzeigen

@ -1,5 +1,5 @@
<div class='row'>
<div class='content-list span6'>
<div class='wizard-list'>
<ul>
{{#each model as |s|}}
<li>

Datei anzeigen

@ -1,3 +1,12 @@
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.translation'}}</h3>
</div>
<div class="setting-value">
{{input name="translation_key" value=field.translation_key placeholderKey="admin.wizard.field.translation_placeholder"}}
</div>
</div>
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.field.label'}}</h3>

Datei anzeigen

@ -1,3 +1,12 @@
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.translation'}}</h3>
</div>
<div class="setting-value">
{{input name="translation_key" value=step.translation_key placeholderKey="admin.wizard.step.translation_placeholder"}}
</div>
</div>
<div class="setting">
<div class="setting-label">
<h3>{{i18n 'admin.wizard.step.title'}}</h3>
@ -21,7 +30,7 @@
<h3>{{i18n 'admin.wizard.step.description'}}</h3>
</div>
<div class="setting-value">
{{textarea name="description" value=step.description placeholderKey="admin.wizard.step.description_placeholder"}}
{{textarea name="description" value=step.description placeholder=(i18n "admin.wizard.step.description_placeholder")}}
</div>
</div>

Datei anzeigen

@ -1,12 +0,0 @@
{{#if showCanvas}}
{{wizard-canvas}}
{{/if}}
<div class='wizard-column'>
<div class='wizard-column-contents'>
{{outlet}}
</div>
<div class='wizard-footer'>
<div class='discourse-logo'></div>
</div>
</div>

Datei anzeigen

@ -35,6 +35,11 @@ export default {
},
setupController(controller, model) {
console.log(model)
Ember.run.scheduleOnce('afterRender', this, function(){
$('body.custom-wizard').css('background', model.get('background'));
});
controller.setProperties({
customWizard: true,
siteInfo: model.get('siteInfo')
@ -59,6 +64,10 @@ export default {
StepRoute.reopen({
afterModel(model) {
if (!model) {
return document.location = getUrl("/");
}
const wizard = this.modelFor('application');
return model.set("wizardId", wizard.id);
}
@ -69,7 +78,7 @@ export default {
const src = this.get('step.banner');
if (!src) return;
if (src.indexOf('/uploads/') > -1) {
if (src.indexOf('/uploads/') > -1 || src.indexOf('/images/') > -1) {
return getUrl(src);
} else {
return getUrl(`/images/wizard/${src}`);

Datei anzeigen

@ -3,6 +3,11 @@
float: left;
}
.wizard-list {
float: left;
width: 250px;
}
.new-wizard {
margin-top: 15px;
}
@ -34,15 +39,15 @@
min-width: 49%;
.setting-label {
width: 20%;
width: 90px;
}
.setting-value span {
font-size: 0.929em;
}
&.full {
width: 100%;
.setting-label {
width: 75px;
}
}
}
}

Datei anzeigen

@ -8,6 +8,8 @@ en:
submissions_label: "Submissions"
name: "Name"
name_placeholder: "name of the wizard"
background: "Background"
background_placeholder: "Background css property"
save_submissions: "Save"
save_submissions_label: "Save wizard submissions"
save: "Save Changes"
@ -15,14 +17,16 @@ en:
header: "Wizard"
add: "Add"
url: "Url"
translation: "Translation"
step:
header: "Steps"
title: "Title"
title_placeholder: "This will appear at the top of the step"
title_placeholder: "Overrides title translation"
banner: "Banner"
banner_placeholder: "Image url"
description: "Description"
description_placeholder: "This will appear underneath the title and / or title"
description_placeholder: "Overrides description translation"
translation_placeholder: "Translation key for step"
field:
header: "Fields"
label: "Label"
@ -32,6 +36,7 @@ en:
add_choice: "Add"
required: "Required"
required_label: "Field is Required"
translation_placeholder: "Translation key for field"
action:
header: "Actions"
label: "Label"

Datei anzeigen

@ -1,3 +1,11 @@
en:
custom_wizard:
title: "Wizard"
new_wizard:
step_1:
title: "Translated title"
description: "Translated description"
field_1:
label: "Translated field title"
description: "Translated field description"

Datei anzeigen

@ -6,6 +6,7 @@ class CustomWizard::Builder
@wizard = Wizard.new(user)
@wizard.id = wizard_id
@wizard.save_submissions = data['save_submissions']
@wizard.background = data["background"]
end
def self.sorted_handlers
@ -25,14 +26,22 @@ class CustomWizard::Builder
@custom_wizard.steps.each do |s|
@wizard.append_step(s['id']) do |step|
step.title = s['title'] if s['title']
step.description = s['description'] if s['description']
step.banner = s['banner'] if s['banner']
step.translation_key = s['translation_key'] if s['translation_key']
s['fields'].each do |f|
field = step.add_field(id: f['id'],
params = {
id: f['id'],
type: f['type'],
label: f['label'],
description: f['description'],
required: f['required'])
required: f['required']
}
params[:label] = f['label'] if f['label']
params[:description] = f['description'] if f['description']
params[:translation_key] = f['translation_key'] if f['translation_key']
field = step.add_field(params)
if f['type'] == 'dropdown'
f['choices'].each do |c|

Datei anzeigen

@ -62,11 +62,11 @@ after_initialize do
end
class ::Wizard
attr_accessor :id, :save_submissions
attr_accessor :id, :background, :save_submissions
end
class ::Wizard::Step
attr_accessor :title
attr_accessor :title, :description, :translation_key
end
class ::Wizard::StepUpdater
@ -75,7 +75,7 @@ after_initialize do
require_dependency 'wizard/field'
Wizard::Field.class_eval do
attr_reader :label, :description
attr_reader :label, :description, :translation_key
def initialize(attrs)
attrs = attrs || {}
@ -85,38 +85,49 @@ after_initialize do
@required = !!attrs[:required]
@label = attrs[:label]
@description = attrs[:description]
@translation_key = attrs[:translation_key]
@value = attrs[:value]
@choices = []
end
end
add_to_serializer(:wizard, :id) { object.id }
::WizardSerializer.class_eval do
attributes :id, :background
def id
object.id
end
def background
object.background
end
def include_start?
object.start
end
end
::WizardStepSerializer.class_eval do
def title
if object.title
object.title
else
I18n.t("#{i18n_key}.title", default: '')
return object.title if object.title
I18n.t("#{object.translation_key || i18n_key}.title", default: '')
end
def description
return object.description if object.description
I18n.t("#{object.translation_key || i18n_key}.description", default: '')
end
end
::WizardFieldSerializer.class_eval do
def label
if object.label
object.label
else
I18n.t("#{i18n_key}.label", default: '')
end
return object.label if object.label
I18n.t("#{object.translation_key || i18n_key}.label", default: '')
end
def description
if object.description
object.description
else
I18n.t("#{i18n_key}.description", default: '')
end
return object.description if object.description
I18n.t("#{object.translation_key || i18n_key}.description", default: '')
end
end
end

Datei anzeigen

@ -1,3 +1,12 @@
.custom-wizard {
background-color: #f4f4f4;
background-color: initial;
}
.custom-wizard .wizard-step-description {
line-height: 1.7;
}
.custom-wizard .wizard-column .wizard-step-banner {
width: initial;
max-width: 660px;
}