Angus McLeod 7 years ago
parent
commit
a43f4b1344

+ 2 - 2
app/controllers/admin.rb

@@ -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

+ 1 - 1
app/controllers/steps.rb

@@ -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
 

+ 1 - 1
app/controllers/wizard.rb

@@ -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 {}

+ 0 - 1
assets/javascripts/discourse/components/wizard-custom-field.js.es6

@@ -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());
     }

+ 17 - 13
assets/javascripts/discourse/components/wizard-custom-step.js.es6

@@ -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);

+ 14 - 11
assets/javascripts/discourse/controllers/admin-wizard.js.es6

@@ -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) {

+ 5 - 0
assets/javascripts/discourse/helpers/custom-wizard.js.es6

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

+ 41 - 13
assets/javascripts/discourse/models/custom-wizard.js.es6

@@ -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);

+ 11 - 8
assets/javascripts/discourse/routes/admin-wizard.js.es6

@@ -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();
     }
   }

+ 8 - 8
assets/javascripts/discourse/routes/admin-wizards-custom.js.es6

@@ -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') {
-        this.refresh();
-      }
+    refreshAllWizards() {
+      this.set('transitionToWizard', 'last');
+      this.refresh();
     }
   }
 });

+ 1 - 5
assets/javascripts/discourse/routes/admin-wizards.js.es6

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

+ 14 - 3
assets/javascripts/discourse/templates/admin-wizard.hbs

@@ -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>
 
-  {{wizard-custom-step step=currentStep fieldTypes=model.fieldTypes}}
+  {{#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>

+ 2 - 2
assets/javascripts/discourse/templates/admin-wizards-custom.hbs

@@ -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>

+ 1 - 1
assets/javascripts/discourse/templates/admin-wizards-submissions.hbs

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

+ 9 - 0
assets/javascripts/discourse/templates/components/wizard-custom-field.hbs

@@ -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>

+ 10 - 1
assets/javascripts/discourse/templates/components/wizard-custom-step.hbs

@@ -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>
 

+ 0 - 12
assets/javascripts/wizard/application.hbs

@@ -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>

+ 10 - 1
assets/javascripts/wizard/initializers/custom.js.es6

@@ -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}`);

+ 10 - 5
assets/stylesheets/custom_wizard.scss

@@ -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;
-      }
     }
   }
 }

+ 7 - 2
config/locales/client.en.yml

@@ -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"

+ 8 - 0
config/locales/server.en.yml

@@ -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"

+ 14 - 5
lib/builder.rb

@@ -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'],
-                                 type: f['type'],
-                                 label: f['label'],
-                                 description: f['description'],
-                                 required: f['required'])
+          params = {
+            id: f['id'],
+            type: f['type'],
+            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|

+ 30 - 19
plugin.rb

@@ -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: '')
-      end
+      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

+ 10 - 1
public/desktop.css

@@ -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;
 }