Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 09:20:29 +01:00
Custom forms display steps, just don't save data yet
Dieser Commit ist enthalten in:
Ursprung
3fa2735c63
Commit
f8848d2b93
31 geänderte Dateien mit 338 neuen und 110 gelöschten Zeilen
|
@ -1,6 +1,6 @@
|
||||||
class CustomWizard::AdminController < ::ApplicationController
|
class CustomWizard::AdminController < ::ApplicationController
|
||||||
before_filter :ensure_logged_in
|
before_action :ensure_logged_in
|
||||||
before_filter :ensure_admin
|
before_action :ensure_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render nothing: true
|
render nothing: true
|
||||||
|
@ -11,9 +11,20 @@ class CustomWizard::AdminController < ::ApplicationController
|
||||||
|
|
||||||
wizard = ::JSON.parse(params[:wizard])
|
wizard = ::JSON.parse(params[:wizard])
|
||||||
|
|
||||||
wizard["id"] = SecureRandom.hex(8) if !wizard["id"]
|
saved = false
|
||||||
|
if wizard["existing_id"] && rows = PluginStoreRow.where(plugin_name: 'custom_wizard').order(:id)
|
||||||
|
rows.each do |r, i|
|
||||||
|
wizard = CustomWizard::Wizard.new(r.value)
|
||||||
|
if wizard.id = wizard["existing_id"]
|
||||||
|
r.update_all(key: wizard['id'], value: wizard)
|
||||||
|
saved = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
PluginStore.set('custom_wizards', wizard["id"], wizard)
|
unless saved
|
||||||
|
PluginStore.set('custom_wizard', wizard["id"], wizard)
|
||||||
|
end
|
||||||
|
|
||||||
render json: success_json
|
render json: success_json
|
||||||
end
|
end
|
||||||
|
@ -21,7 +32,7 @@ class CustomWizard::AdminController < ::ApplicationController
|
||||||
def remove
|
def remove
|
||||||
params.require(:id)
|
params.require(:id)
|
||||||
|
|
||||||
PluginStore.remove('custom_wizards', params[:id])
|
PluginStore.remove('custom_wizard', params[:id])
|
||||||
|
|
||||||
render json: success_json
|
render json: success_json
|
||||||
end
|
end
|
||||||
|
@ -29,13 +40,13 @@ class CustomWizard::AdminController < ::ApplicationController
|
||||||
def find
|
def find
|
||||||
params.require(:id)
|
params.require(:id)
|
||||||
|
|
||||||
wizard = PluginStore.get('custom_wizards', params[:id])
|
wizard = PluginStore.get('custom_wizard', params[:id])
|
||||||
|
|
||||||
render json: success_json.merge(wizard: wizard)
|
render json: success_json.merge(wizard: wizard)
|
||||||
end
|
end
|
||||||
|
|
||||||
def all
|
def all
|
||||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizards').order(:id)
|
rows = PluginStoreRow.where(plugin_name: 'custom_wizard').order(:id)
|
||||||
|
|
||||||
wizards = rows ? [*rows].map do |r|
|
wizards = rows ? [*rows].map do |r|
|
||||||
CustomWizard::Wizard.new(r.value)
|
CustomWizard::Wizard.new(r.value)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
class StepsController < ApplicationController
|
class CustomWizard::StepsController < ApplicationController
|
||||||
before_filter :ensure_logged_in
|
before_action :ensure_logged_in
|
||||||
|
|
||||||
def update
|
def update
|
||||||
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id]).build
|
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id]).build
|
||||||
updater = wizard.create_updater(params[:id], params[:fields])
|
updater = wizard.create_updater(params[:step_id], params[:fields])
|
||||||
updater.update
|
updater.update
|
||||||
|
|
||||||
if updater.success?
|
if updater.success?
|
||||||
|
@ -18,5 +18,4 @@ class StepsController < ApplicationController
|
||||||
render json: { errors: errors }, status: 422
|
render json: { errors: errors }, status: 422
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ class CustomWizard::WizardController < ::ApplicationController
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
wizard = CustomWizard::Builder.new(current_user, params[:name]).build
|
wizard = CustomWizard::Builder.new(current_user, params[:wizard_id]).build
|
||||||
render_serialized(wizard, WizardSerializer)
|
render_serialized(wizard, WizardSerializer)
|
||||||
end
|
end
|
||||||
format.html {}
|
format.html {}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<link href="<%= Discourse.base_uri %>/plugins/discourse-custom-wizard/desktop.css" media="all" rel="stylesheet" data-target="desktop" type="text/css" />
|
||||||
<%= discourse_stylesheet_link_tag :wizard, theme_key: nil %>
|
<%= discourse_stylesheet_link_tag :wizard, theme_key: nil %>
|
||||||
<%= preload_script "ember_jquery" %>
|
<%= preload_script "ember_jquery" %>
|
||||||
<%= preload_script "wizard-vendor" %>
|
<%= preload_script "wizard-vendor" %>
|
||||||
|
@ -16,12 +17,12 @@
|
||||||
<title><%= t 'custom_wizard.title' %></title>
|
<title><%= t 'custom_wizard.title' %></title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class='wizard'>
|
<body class='custom-wizard'>
|
||||||
<div id='wizard-main'></div>
|
<div id='custom-wizard-main'></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var wizard = require('wizard/wizard').default.create();
|
var wizard = require('discourse/plugins/discourse-custom-wizard/wizard/custom-wizard').default.create();
|
||||||
wizard.start();
|
wizard.start();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,17 +4,15 @@ export default Ember.Component.extend({
|
||||||
classNames: 'wizard-custom-step',
|
classNames: 'wizard-custom-step',
|
||||||
|
|
||||||
@computed('step.fields.@each.id')
|
@computed('step.fields.@each.id')
|
||||||
allowAddAction(stepFields) {
|
allowAddAction: stepFields => stepFields.get('firstObject.id'),
|
||||||
return stepFields.get('firstObject.id');
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
addField() {
|
addField() {
|
||||||
this.get('step.fields').pushObject(Ember.Object.create());
|
this.get('step.fields').pushObject(Ember.Object.create({ id: '', label: '' }));
|
||||||
},
|
},
|
||||||
|
|
||||||
addAction() {
|
addAction() {
|
||||||
this.get('step.actions').pushObject(Ember.Object.create());
|
this.get('step.actions').pushObject(Ember.Object.create({ id: '', label: '' }));
|
||||||
},
|
},
|
||||||
|
|
||||||
removeField(field) {
|
removeField(field) {
|
||||||
|
|
|
@ -13,10 +13,10 @@ export default Ember.Controller.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
addStep() {
|
addStep() {
|
||||||
this.get('model.steps').pushObject({
|
this.get('model.steps').pushObject(Ember.Object.create({
|
||||||
fields: Ember.A(),
|
fields: Ember.A(),
|
||||||
actions: Ember.A()
|
actions: Ember.A()
|
||||||
});
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
removeStep(step) {
|
removeStep(step) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ export default {
|
||||||
map() {
|
map() {
|
||||||
this.route('adminWizards', { path: '/wizards', resetNamespace: true }, function() {
|
this.route('adminWizards', { path: '/wizards', resetNamespace: true }, function() {
|
||||||
this.route('adminWizardsCustom', { path: '/custom', resetNamespace: true }, function() {
|
this.route('adminWizardsCustom', { path: '/custom', resetNamespace: true }, function() {
|
||||||
this.route('adminWizard', { path: '/:name', resetNamespace: true });
|
this.route('adminWizard', { path: '/:wizard_id', resetNamespace: true });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
export default {
|
|
||||||
name: 'wizard-edits',
|
|
||||||
initialize() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,22 +1,55 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
|
||||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
|
|
||||||
const CustomWizard = Discourse.Model.extend({
|
const CustomWizard = Discourse.Model.extend({
|
||||||
steps: Ember.A(),
|
init() {
|
||||||
|
const id = this.get('id');
|
||||||
|
if (id) this.set('existingId', id);
|
||||||
|
},
|
||||||
|
|
||||||
@computed('name')
|
@computed('name')
|
||||||
dasherizedName(name) {
|
id(name) {
|
||||||
return Ember.String.dasherize(name);
|
return name ? Ember.String.dasherize(name) : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
const wizard = {
|
const stepsObj = this.get('steps');
|
||||||
id: this.get('id'),
|
let steps = [];
|
||||||
steps: this.get('steps').toArray(),
|
|
||||||
name: this.get('name')
|
stepsObj.forEach((s) => {
|
||||||
|
let step = {
|
||||||
|
id: Ember.String.dasherize(s.title),
|
||||||
|
title: s.title,
|
||||||
|
banner: s.banner,
|
||||||
|
description: s.description,
|
||||||
|
fields: [],
|
||||||
|
actions: []
|
||||||
};
|
};
|
||||||
|
|
||||||
return ajax(`/admin/wizards/custom/save`, {
|
const fields = s.get('fields');
|
||||||
|
fields.forEach((f) => {
|
||||||
|
f.set('id', Ember.String.dasherize(f.get('label')));
|
||||||
|
step['fields'].push(f);
|
||||||
|
});
|
||||||
|
|
||||||
|
s.actions.forEach((a) => {
|
||||||
|
a['id'] = Ember.String.dasherize(a.label);
|
||||||
|
step['actions'].push(a);
|
||||||
|
});
|
||||||
|
|
||||||
|
steps.push(step);
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = this.get('id');
|
||||||
|
const name = this.get('name');
|
||||||
|
let wizard = { id, name, steps };
|
||||||
|
|
||||||
|
const existingId = this.get('existingId');
|
||||||
|
if (existingId && existingId !== id) {
|
||||||
|
wizard['existing_id'] = existingId;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ajax("/admin/wizards/custom/save", {
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: {
|
data: {
|
||||||
wizard: JSON.stringify(wizard)
|
wizard: JSON.stringify(wizard)
|
||||||
|
@ -25,7 +58,7 @@ const CustomWizard = Discourse.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
return ajax(`/admin/wizards/custom/remove`, {
|
return ajax("/admin/wizards/custom/remove", {
|
||||||
type: 'DELETE',
|
type: 'DELETE',
|
||||||
data: {
|
data: {
|
||||||
id: this.get('id')
|
id: this.get('id')
|
||||||
|
@ -36,21 +69,54 @@ const CustomWizard = Discourse.Model.extend({
|
||||||
|
|
||||||
CustomWizard.reopenClass({
|
CustomWizard.reopenClass({
|
||||||
findAll() {
|
findAll() {
|
||||||
return ajax("/admin/wizards/custom/all").then(result => {
|
return ajax("/admin/wizards/custom/all", {
|
||||||
|
type: 'GET'
|
||||||
|
}).then(result => {
|
||||||
return result.wizards.map(w => CustomWizard.create(w));
|
return result.wizards.map(w => CustomWizard.create(w));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
create() {
|
create(w) {
|
||||||
const wizard = this._super.apply(this, arguments);
|
const wizard = this._super.apply(this);
|
||||||
const steps = wizard.get('steps');
|
|
||||||
|
|
||||||
steps.forEach((s) => {
|
let steps = Ember.A();
|
||||||
s.fields = Ember.A(s.fields);
|
let props = { steps };
|
||||||
s.fields.forEach((f) => f.choices = Ember.A(f.choices));
|
|
||||||
s.actions = Ember.A(s.actions);
|
if (w) {
|
||||||
|
props['id'] = w.id; props['name'] = w.name;
|
||||||
|
|
||||||
|
if (w.steps) {
|
||||||
|
w.steps.forEach((s) => {
|
||||||
|
let fields = Ember.A();
|
||||||
|
|
||||||
|
s.fields.forEach((f) => {
|
||||||
|
let choices = Ember.A();
|
||||||
|
|
||||||
|
f.choices.forEach((c) => {
|
||||||
|
choices.pushObject(Ember.Object.create(c));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fields.pushObject(Ember.Object.create(f));
|
||||||
|
});
|
||||||
|
|
||||||
|
let actions = Ember.A();
|
||||||
|
s.actions.forEach((a) => {
|
||||||
|
actions.pushObject(Ember.Object.create(a));
|
||||||
|
});
|
||||||
|
|
||||||
|
steps.pushObject(Ember.Object.create({
|
||||||
|
id: s.id,
|
||||||
|
title: s.title,
|
||||||
|
description: s.description,
|
||||||
|
fields,
|
||||||
|
actions
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
wizard.setProperties(props);
|
||||||
|
|
||||||
return wizard;
|
return wizard;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,15 +2,13 @@ import CustomWizard from '../models/custom-wizard';
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model(params) {
|
model(params) {
|
||||||
if (params.name === 'new') {
|
if (params.wizard_id === 'new') {
|
||||||
this.set('new', true);
|
this.set('new', true);
|
||||||
return CustomWizard.create({ name: '', steps: []});
|
return CustomWizard.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('new', false);
|
this.set('new', false);
|
||||||
|
|
||||||
const wizard = this.modelFor('admin-wizards-custom').findBy('dasherizedName', params.name);
|
const wizard = this.modelFor('admin-wizards-custom').findBy('id', params.wizard_id);
|
||||||
|
|
||||||
if (!wizard) return this.transitionTo('adminWizardsCustom.index');
|
if (!wizard) return this.transitionTo('adminWizardsCustom.index');
|
||||||
|
|
||||||
return wizard;
|
return wizard;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="name">{{i18n 'admin.wizard.name'}}</label>
|
<label for="name">{{i18n 'admin.wizard.name'}}</label>
|
||||||
{{text-field name="name" value=model.name placeholderKey="admin.wizard.name_placeholder"}}
|
{{text-field name="name" value=model.name placeholderKey="admin.wizard.name_placeholder"}}
|
||||||
|
@ -21,5 +20,4 @@
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
<span class="saving {{unless savingStatus 'hidden'}}">{{savingStatus}}</span>
|
<span class="saving {{unless savingStatus 'hidden'}}">{{savingStatus}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{{#each model as |w|}}
|
{{#each model as |w|}}
|
||||||
<li>
|
<li>
|
||||||
{{#link-to "adminWizard" w.dasherizedName}}{{w.name}}{{/link-to}}
|
{{#link-to "adminWizard" w.id}}{{w.name}}{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{{input type='text' value=choice.label}}
|
|
@ -14,7 +14,7 @@
|
||||||
{{#if isDropdown}}
|
{{#if isDropdown}}
|
||||||
<span>{{i18n 'admin.wizard.field.choices_label'}}</span>
|
<span>{{i18n 'admin.wizard.field.choices_label'}}</span>
|
||||||
{{#each field.choices as |c|}}
|
{{#each field.choices as |c|}}
|
||||||
{{input type='text' value=c.label}}
|
{{wizard-custom-choice choice=c}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{d-button action='addChoice' label='admin.wizard.field.add_choice'}}
|
{{d-button action='addChoice' label='admin.wizard.field.add_choice'}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
//= require ./wizard/custom-wizard
|
||||||
|
//= require_tree ./wizard/controllers
|
||||||
//= require_tree ./wizard/initializers
|
//= require_tree ./wizard/initializers
|
||||||
//= require_tree ./wizard/models
|
//= require_tree ./wizard/models
|
||||||
//= require_tree ./wizard/routes
|
//= require_tree ./wizard/routes
|
||||||
|
//= require_tree ./wizard/templates
|
||||||
|
|
12
assets/javascripts/wizard/application.hbs
Normale Datei
12
assets/javascripts/wizard/application.hbs
Normale Datei
|
@ -0,0 +1,12 @@
|
||||||
|
{{#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>
|
20
assets/javascripts/wizard/controllers/custom-step.js.es6
Normale Datei
20
assets/javascripts/wizard/controllers/custom-step.js.es6
Normale Datei
|
@ -0,0 +1,20 @@
|
||||||
|
import StepController from 'wizard/controllers/step';
|
||||||
|
import getUrl from 'discourse-common/lib/get-url';
|
||||||
|
|
||||||
|
export default StepController.extend({
|
||||||
|
actions: {
|
||||||
|
goNext(response) {
|
||||||
|
const next = this.get('step.next');
|
||||||
|
if (response.refresh_required) {
|
||||||
|
const id = this.get('wizard.id');
|
||||||
|
document.location = getUrl(`/wizard/custom/${id}/steps/${next}`);
|
||||||
|
} else {
|
||||||
|
this.transitionToRoute('custom.step', next);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
goBack() {
|
||||||
|
this.transitionToRoute('custom.step', this.get('step.previous'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
5
assets/javascripts/wizard/custom-wizard.js.es6
Normale Datei
5
assets/javascripts/wizard/custom-wizard.js.es6
Normale Datei
|
@ -0,0 +1,5 @@
|
||||||
|
import WizardApplication from 'wizard/wizard';
|
||||||
|
|
||||||
|
export default WizardApplication.extend({
|
||||||
|
rootElement: '#custom-wizard-main'
|
||||||
|
});
|
|
@ -1,13 +1,66 @@
|
||||||
import Router from 'wizard/router';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'custom-routes',
|
name: 'custom-routes',
|
||||||
|
|
||||||
initialize() {
|
initialize(container, app) {
|
||||||
|
if (app.get('rootElement') !== '#custom-wizard-main') return;
|
||||||
|
|
||||||
|
const WizardApplicationRoute = requirejs('wizard/routes/application').default;
|
||||||
|
const findCustomWizard = requirejs('discourse/plugins/discourse-custom-wizard/wizard/models/custom').findCustomWizard;
|
||||||
|
const Router = requirejs('wizard/router').default;
|
||||||
|
const ajax = requirejs('wizard/lib/ajax').ajax;
|
||||||
|
const StepRoute = requirejs('wizard/routes/step').default;
|
||||||
|
const StepModel = requirejs('wizard/models/step').default;
|
||||||
|
|
||||||
Router.map(function() {
|
Router.map(function() {
|
||||||
this.route('custom', { path: '/custom/:name' }, function() {
|
this.route('custom', { path: '/custom/:id' }, function() {
|
||||||
this.route('step', { path: '/steps/:step_id' });
|
this.route('step', { path: '/steps/:step_id' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
WizardApplicationRoute.reopen({
|
||||||
|
model() {
|
||||||
|
const customParams = this.paramsFor('custom');
|
||||||
|
return findCustomWizard(customParams.id);
|
||||||
|
},
|
||||||
|
|
||||||
|
afterModel(model) {
|
||||||
|
return ajax({
|
||||||
|
url: `/site/basic-info`,
|
||||||
|
type: 'GET',
|
||||||
|
}).then((result) => {
|
||||||
|
return model.set('siteInfo', result);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
controller.setProperties({
|
||||||
|
customWizard: true,
|
||||||
|
siteInfo: model.get('siteInfo')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StepModel.reopen({
|
||||||
|
save() {
|
||||||
|
const fields = {};
|
||||||
|
this.get('fields').forEach(f => fields[f.id] = f.value);
|
||||||
|
return ajax({
|
||||||
|
url: `/wizard/custom/${this.get('wizardId')}/steps/${this.get('id')}`,
|
||||||
|
type: 'PUT',
|
||||||
|
data: { fields }
|
||||||
|
}).catch(response => {
|
||||||
|
response.responseJSON.errors.forEach(err => this.fieldError(err.field, err.description));
|
||||||
|
throw response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StepRoute.reopen({
|
||||||
|
afterModel(model) {
|
||||||
|
const wizard = this.modelFor('application');
|
||||||
|
return model.set("wizardId", wizard.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
import Step from 'wizard/models/step';
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
import WizardField from 'wizard/models/wizard-field';
|
import WizardField from 'wizard/models/wizard-field';
|
||||||
import { ajax } from 'wizard/lib/ajax';
|
import { ajax } from 'wizard/lib/ajax';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import Step from 'wizard/models/step';
|
||||||
|
|
||||||
const CustomWizard = Ember.Object.extend({
|
const CustomWizard = Ember.Object.extend({
|
||||||
@computed('steps.length')
|
@computed('steps.length')
|
||||||
totalSteps: length => length
|
totalSteps: length => length
|
||||||
});
|
});
|
||||||
|
|
||||||
export function findCustomWizard(name) {
|
export function findCustomWizard(wizardId) {
|
||||||
return ajax({ url: `/wizard/custom/${name}.json` }).then(response => {
|
return ajax({ url: `/wizard/custom/${wizardId}` }).then(result => {
|
||||||
const wizard = response.wizard;
|
const wizard = result.wizard;
|
||||||
wizard.steps = wizard.steps.map(step => {
|
wizard.steps = wizard.steps.map(step => {
|
||||||
const stepObj = Step.create(step);
|
const stepObj = Step.create(step);
|
||||||
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
||||||
return stepObj;
|
return stepObj;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(wizard)
|
||||||
|
|
||||||
return CustomWizard.create(wizard);
|
return CustomWizard.create(wizard);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default CustomWizard;
|
|
@ -1,7 +0,0 @@
|
||||||
import { findCustomWizard } from '../models/custom-wizard';
|
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
|
||||||
model(params) {
|
|
||||||
return findCustomWizard(params.name);
|
|
||||||
}
|
|
||||||
});
|
|
8
assets/javascripts/wizard/routes/custom-index.js.es6
Normale Datei
8
assets/javascripts/wizard/routes/custom-index.js.es6
Normale Datei
|
@ -0,0 +1,8 @@
|
||||||
|
import IndexRoute from 'wizard/routes/index';
|
||||||
|
|
||||||
|
export default IndexRoute.extend({
|
||||||
|
beforeModel() {
|
||||||
|
const appModel = this.modelFor('application');
|
||||||
|
this.replaceWith('custom.step', appModel.start);
|
||||||
|
}
|
||||||
|
});
|
3
assets/javascripts/wizard/routes/custom-step.js.es6
Normale Datei
3
assets/javascripts/wizard/routes/custom-step.js.es6
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
import StepRoute from 'wizard/routes/step';
|
||||||
|
|
||||||
|
export default StepRoute.extend();
|
|
@ -1,11 +0,0 @@
|
||||||
import { findCustomWizard } from '../models/custom-wizard';
|
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
|
||||||
model(params) {
|
|
||||||
return findCustomWizard(params.name);
|
|
||||||
},
|
|
||||||
|
|
||||||
afterModel(model) {
|
|
||||||
this.replaceWith('step', model.start);
|
|
||||||
}
|
|
||||||
});
|
|
16
assets/javascripts/wizard/templates/application.hbs
Normale Datei
16
assets/javascripts/wizard/templates/application.hbs
Normale Datei
|
@ -0,0 +1,16 @@
|
||||||
|
{{#if showCanvas}}
|
||||||
|
{{wizard-canvas}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class='wizard-column'>
|
||||||
|
<div class='wizard-column-contents'>
|
||||||
|
{{outlet}}
|
||||||
|
</div>
|
||||||
|
<div class='wizard-footer'>
|
||||||
|
{{#if customWizard}}
|
||||||
|
<img src="{{siteInfo.logo_small_url}}" style="background-image: initial; width: 33px; height: 33px;"/>
|
||||||
|
{{else}}
|
||||||
|
<div class='discourse-logo'></div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
1
assets/javascripts/wizard/templates/custom.step.hbs
Normale Datei
1
assets/javascripts/wizard/templates/custom.step.hbs
Normale Datei
|
@ -0,0 +1 @@
|
||||||
|
{{wizard-step step=step wizard=wizard goNext="goNext" goBack="goBack"}}
|
|
@ -1,31 +1,27 @@
|
||||||
class CustomWizard::Builder
|
class CustomWizard::Builder
|
||||||
def initialize(user, wizard_name)
|
def initialize(user, wizard_id)
|
||||||
rows = PluginStoreRow.where(plugin_name: 'custom_wizards')
|
data = PluginStore.get('custom_wizard', wizard_id)
|
||||||
return if !rows
|
@custom_wizard = CustomWizard::Wizard.new(data)
|
||||||
|
|
||||||
[*rows].each do |r|
|
|
||||||
wizard = CustomWizard::Wizard.new(r.value)
|
|
||||||
@template = wizard if wizard.name.dasherize.downcase == wizard_name
|
|
||||||
end
|
|
||||||
|
|
||||||
@wizard = Wizard.new(user)
|
@wizard = Wizard.new(user)
|
||||||
|
@wizard.id = wizard_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def build
|
def build
|
||||||
@template.steps.each do |s|
|
@custom_wizard.steps.each do |s|
|
||||||
@wizard.append_step(s['title']) do |step|
|
@wizard.append_step(s['id']) do |step|
|
||||||
|
step.title = s['title'] if s['title']
|
||||||
step.banner = s['banner'] if s['banner']
|
step.banner = s['banner'] if s['banner']
|
||||||
|
|
||||||
s['fields'].each do |f|
|
s['fields'].each do |f|
|
||||||
field = step.add_field(id: f['id'],
|
field = step.add_field(id: f['id'],
|
||||||
type: f['type'],
|
type: f['type'],
|
||||||
required: f['required'],
|
label: f['label'],
|
||||||
value: f['value'])
|
description: f['description'],
|
||||||
|
required: f['required'])
|
||||||
|
|
||||||
if f['type'] == 'dropdown'
|
if f['type'] == 'dropdown'
|
||||||
f['choices'].each do |c|
|
f['choices'].each do |c|
|
||||||
field.add_choice(c)
|
field.add_choice(c['id'], label: c['label'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
class CustomWizard::Wizard
|
class CustomWizard::Wizard
|
||||||
|
|
||||||
attr_reader :name, :steps
|
attr_reader :id, :name, :steps, :custom
|
||||||
|
|
||||||
def initialize(data)
|
def initialize(data)
|
||||||
parsed = ::JSON.parse(data)
|
data = data.is_a?(String) ? ::JSON.parse(data) : data
|
||||||
@id = parsed['id']
|
@id = data['id']
|
||||||
@name = parsed['name']
|
@name = data['name']
|
||||||
@steps = parsed['steps']
|
@steps = data['steps']
|
||||||
|
@custom = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
67
plugin.rb
67
plugin.rb
|
@ -3,7 +3,7 @@
|
||||||
# version: 0.1
|
# version: 0.1
|
||||||
# authors: Angus McLeod
|
# authors: Angus McLeod
|
||||||
|
|
||||||
register_asset 'stylesheets/custom-wizard.scss'
|
register_asset 'stylesheets/custom_wizard.scss'
|
||||||
|
|
||||||
config = Rails.application.config
|
config = Rails.application.config
|
||||||
config.assets.paths << Rails.root.join("plugins", "discourse-custom-wizard", "assets", "javascripts")
|
config.assets.paths << Rails.root.join("plugins", "discourse-custom-wizard", "assets", "javascripts")
|
||||||
|
@ -24,10 +24,10 @@ after_initialize do
|
||||||
load File.expand_path('../app/controllers/admin.rb', __FILE__)
|
load File.expand_path('../app/controllers/admin.rb', __FILE__)
|
||||||
|
|
||||||
CustomWizard::Engine.routes.draw do
|
CustomWizard::Engine.routes.draw do
|
||||||
get ':name' => 'wizard#index'
|
get ':wizard_id' => 'wizard#index'
|
||||||
get ':name/steps' => 'steps#index'
|
get ':wizard_id/steps' => 'steps#index'
|
||||||
get ':name/steps/:id' => 'wizard#index'
|
get ':wizard_id/steps/:step_id' => 'wizard#index'
|
||||||
put ':name/steps/:id' => 'steps#update'
|
put ':wizard_id/steps/:step_id' => 'steps#update'
|
||||||
end
|
end
|
||||||
|
|
||||||
require_dependency 'admin_constraint'
|
require_dependency 'admin_constraint'
|
||||||
|
@ -40,9 +40,64 @@ after_initialize do
|
||||||
get 'admin/wizards/custom' => 'admin#index'
|
get 'admin/wizards/custom' => 'admin#index'
|
||||||
get 'admin/wizards/custom/new' => 'admin#index'
|
get 'admin/wizards/custom/new' => 'admin#index'
|
||||||
get 'admin/wizards/custom/all' => 'admin#all'
|
get 'admin/wizards/custom/all' => 'admin#all'
|
||||||
get 'admin/wizards/custom/:id' => 'admin#find'
|
get 'admin/wizards/custom/:wizard_id' => 'admin#find'
|
||||||
put 'admin/wizards/custom/save' => 'admin#save'
|
put 'admin/wizards/custom/save' => 'admin#save'
|
||||||
delete 'admin/wizards/custom/remove' => 'admin#remove'
|
delete 'admin/wizards/custom/remove' => 'admin#remove'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ::Wizard
|
||||||
|
attr_accessor :id
|
||||||
|
end
|
||||||
|
|
||||||
|
class ::Wizard::Step
|
||||||
|
attr_accessor :title
|
||||||
|
end
|
||||||
|
|
||||||
|
::Wizard::Field.class_eval do
|
||||||
|
attr_reader :label, :description
|
||||||
|
|
||||||
|
def initialize(attrs)
|
||||||
|
attrs = attrs || {}
|
||||||
|
|
||||||
|
@id = attrs[:id]
|
||||||
|
@type = attrs[:type]
|
||||||
|
@required = !!attrs[:required]
|
||||||
|
@label = attrs[:label]
|
||||||
|
@description = attrs[:description]
|
||||||
|
@value = attrs[:value]
|
||||||
|
@choices = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
add_to_serializer(:wizard, :id) { object.id }
|
||||||
|
|
||||||
|
::WizardStepSerializer.class_eval do
|
||||||
|
def title
|
||||||
|
if object.title
|
||||||
|
object.title
|
||||||
|
else
|
||||||
|
I18n.t("#{i18n_key}.title", default: '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
::WizardFieldSerializer.class_eval do
|
||||||
|
def label
|
||||||
|
puts "LABEL: #{object.label}"
|
||||||
|
if object.label
|
||||||
|
object.label
|
||||||
|
else
|
||||||
|
I18n.t("#{i18n_key}.label", default: '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
if object.description
|
||||||
|
object.description
|
||||||
|
else
|
||||||
|
I18n.t("#{i18n_key}.description", default: '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
3
public/desktop.css
Normale Datei
3
public/desktop.css
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
.custom-wizard {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
Laden …
In neuem Issue referenzieren