Angus McLeod 7 anni fa
parent
commit
9f40821db0
20 ha cambiato i file con 520 aggiunte e 151 eliminazioni
  1. 2 5
      assets/javascripts/discourse/components/wizard-custom-action.js.es6
  2. 9 6
      assets/javascripts/discourse/components/wizard-custom-field.js.es6
  3. 86 9
      assets/javascripts/discourse/components/wizard-custom-step.js.es6
  4. 48 6
      assets/javascripts/discourse/controllers/admin-wizard.js.es6
  5. 4 4
      assets/javascripts/discourse/models/custom-wizard.js.es6
  6. 10 2
      assets/javascripts/discourse/routes/admin-wizard.js.es6
  7. 6 0
      assets/javascripts/discourse/routes/admin-wizards-custom.js.es6
  8. 6 0
      assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6
  9. 16 14
      assets/javascripts/discourse/templates/admin-wizard-submissions.hbs
  10. 36 13
      assets/javascripts/discourse/templates/admin-wizard.hbs
  11. 1 7
      assets/javascripts/discourse/templates/admin-wizards-custom-index.hbs
  12. 6 1
      assets/javascripts/discourse/templates/admin-wizards-custom.hbs
  13. 1 1
      assets/javascripts/discourse/templates/admin-wizards-submissions.hbs
  14. 90 20
      assets/javascripts/discourse/templates/components/wizard-custom-action.hbs
  15. 0 1
      assets/javascripts/discourse/templates/components/wizard-custom-choice.hbs
  16. 44 18
      assets/javascripts/discourse/templates/components/wizard-custom-field.hbs
  17. 42 20
      assets/javascripts/discourse/templates/components/wizard-custom-step.hbs
  18. 11 0
      assets/javascripts/wizard/initializers/custom.js.es6
  19. 75 0
      assets/stylesheets/custom_wizard.scss
  20. 27 24
      config/locales/client.en.yml

+ 2 - 5
assets/javascripts/discourse/components/wizard-custom-action.js.es6

@@ -1,11 +1,8 @@
 export default Ember.Component.extend({
+  classNames: 'wizard-custom-action',
   types: ['create_topic', 'update_profile', 'send_message'],
   profileFields: ['name', 'username', 'email'],
   createTopic: Ember.computed.equal('action.type', 'create_topic'),
   updateProfile: Ember.computed.equal('action.type', 'update_profile'),
-  sendMessage: Ember.computed.equal('action.type', 'send_message'),
-
-  test: function() {
-    console.log(this.get('stepFields'));
-  }.observes('stepFields.[]')
+  sendMessage: Ember.computed.equal('action.type', 'send_message')
 });

+ 9 - 6
assets/javascripts/discourse/components/wizard-custom-field.js.es6

@@ -1,9 +1,11 @@
-import { observes } from 'ember-addons/ember-computed-decorators';
+import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
 
 export default Ember.Component.extend({
   classNames: 'wizard-custom-field',
   isDropdown: Ember.computed.equal('field.type', 'dropdown'),
 
+  @on('init')
+  @observes('field.id')
   init() {
     this._super(...arguments);
 
@@ -12,15 +14,16 @@ export default Ember.Component.extend({
     }
   },
 
-  @observes('field.label')
-  setFieldId() {
-    const label = this.get('field.label');
-    this.set('field.id', Ember.String.underscore(label));
-  },
+  @computed('field.choices.[]')
+  dropdownChoices: choices => choices,
 
   actions: {
     addChoice() {
       this.get('field.choices').pushObject(Ember.Object.create());
+    },
+
+    removeChoice(c) {
+      this.get('field.choices').removeObject(c);
     }
   }
 });

+ 86 - 9
assets/javascripts/discourse/components/wizard-custom-step.js.es6

@@ -1,26 +1,103 @@
-import { default as computed } from 'ember-addons/ember-computed-decorators';
+import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
 
 export default Ember.Component.extend({
   classNames: 'wizard-custom-step',
+  currentField: null,
+  currentAction: null,
 
-  @computed('step.fields.@each.id')
-  allowAddAction: stepFields => stepFields.get('firstObject.id'),
+  @on('init')
+  @observes('step.id')
+  setup() {
+    this._super(...arguments);
+    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) {
+    return fields.map((f) => {
+      if (f) {
+        let link = {
+          id: f.get('id'),
+          label: f.get('label')
+        };
+
+        let classes = 'btn';
+        if (current && f.get('id') === current.get('id')) {
+          classes += ' btn-primary';
+        };
+
+        link['classes'] = classes;
+
+        return link;
+      }
+    });
+  },
+
+  @computed('step.actions.[]', 'currentAction')
+  actionLinks(actions, current) {
+    return actions.map((a) => {
+      if (a) {
+        let link = {
+          id: a.get('id'),
+          label: a.get('label')
+        };
+
+        let classes = 'btn';
+        if (current && a.get('id') === current.get('id')) {
+          classes += ' btn-primary';
+        };
+
+        link['classes'] = classes;
+
+        return link;
+      }
+    });
+  },
 
   actions: {
     addField() {
-      this.get('step.fields').pushObject(Ember.Object.create({ id: '', label: '' }));
+      const fields = this.get('step.fields');
+      const newNum = fields.length + 1;
+      const field = Ember.Object.create({
+        id: `field-${newNum}`, label: `Field ${newNum}`
+      });
+      fields.pushObject(field);
+      this.set('currentField', field);
     },
 
     addAction() {
-      this.get('step.actions').pushObject(Ember.Object.create({ id: '', label: '' }));
+      const actions = this.get('step.actions');
+      const newNum = actions.length + 1;
+      const action = Ember.Object.create({
+        id: `action-${newNum}`, label: `Action ${newNum}`
+      });
+      actions.pushObject(action);
+      this.set('currentAction', action);
+    },
+
+    removeField(fieldId) {
+      const fields = this.get('step.fields');
+      fields.removeObject(fields.findBy('id', fieldId));
+      this.set('currentField', fields[fields.length - 1]);
+    },
+
+    removeAction(actionId) {
+      const actions = this.get('step.actions');
+      actions.removeObject(actions.findBy('id', actionId));
+      this.set('currentAction', actions[actions.length - 1]);
     },
 
-    removeField(field) {
-      this.get('step.fields').removeObject(field);
+    changeField(fieldId) {
+      const fields = this.get('step.fields');
+      this.set('currentField', fields.findBy('id', fieldId));
     },
 
-    removeAction(action) {
-      this.get('step.actions').removeObject(action);
+    changeAction(actionId) {
+      const actions = this.get('step.actions');
+      this.set('currentAction', actions.findBy('id', actionId));
     }
   }
 });

+ 48 - 6
assets/javascripts/discourse/controllers/admin-wizard.js.es6

@@ -1,8 +1,37 @@
+import { default as computed } from 'ember-addons/ember-computed-decorators';
+
 export default Ember.Controller.extend({
+
+  @computed('model.steps.[]', 'currentStep')
+  stepLinks(steps, currentStep) {
+    return steps.map((s) => {
+      if (s) {
+        let link = {
+          id: s.get('id'),
+          title: s.get('title')
+        };
+
+        let classes = 'btn';
+        if (currentStep && s.get('id') === currentStep.get('id')) {
+          classes += ' btn-primary';
+        };
+
+        link['classes'] = classes;
+
+        return link;
+      }
+    });
+  },
+
+  @computed('model.id')
+  wizardUrl(wizardId) {
+    return window.location.origin + '/wizard/custom/' + wizardId;
+  },
+
   actions: {
     save() {
       this.get('model').save().then(() => {
-        this.transitionToRoute('adminWizardsCustom');
+        this.send("refreshRoute");
       });
     },
 
@@ -13,14 +42,27 @@ export default Ember.Controller.extend({
     },
 
     addStep() {
-      this.get('model.steps').pushObject(Ember.Object.create({
+      const steps = this.get('model.steps');
+      const newNum = steps.length + 1;
+      const step = Ember.Object.create({
         fields: Ember.A(),
-        actions: Ember.A()
-      }));
+        actions: Ember.A(),
+        title: `Step ${newNum}`,
+        id: `step-${newNum}`
+      });
+
+      steps.pushObject(step);
+      this.set('currentStep', step);
+    },
+
+    removeStep(stepId) {
+      const steps = this.get('model.steps');
+      steps.removeObject(steps.findBy('id', stepId));
     },
 
-    removeStep(step) {
-      this.get('model.steps').removeObject(step);
+    changeStep(stepId) {
+      const steps = this.get('model.steps');
+      this.set('currentStep', steps.findBy('id', stepId));
     }
   }
 });

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

@@ -8,9 +8,7 @@ const CustomWizard = Discourse.Model.extend({
   },
 
   @computed('name')
-  id(name) {
-    return name ? Ember.String.dasherize(name) : null;
-  },
+  id: (name) => name ? Ember.String.dasherize(name) : null,
 
   save() {
     const stepsObj = this.get('steps');
@@ -36,11 +34,12 @@ const CustomWizard = Discourse.Model.extend({
             c.set('id', c.get('label'));
           });
         }
+
         step['fields'].push(f);
       });
 
       s.actions.forEach((a) => {
-        a['id'] = Ember.String.dasherize(a.label);
+        a.set('id', Ember.String.dasherize(a.get('label')));
         step['actions'].push(a);
       });
 
@@ -128,6 +127,7 @@ CustomWizard.reopenClass({
             id: s.id,
             title: s.title,
             description: s.description,
+            banner: s.banner,
             fields,
             actions
           }));

+ 10 - 2
assets/javascripts/discourse/routes/admin-wizard.js.es6

@@ -21,7 +21,15 @@ export default Discourse.Route.extend({
   },
 
   setupController(controller, model) {
-    controller.set("new", this.get('new'));
-    controller.set("model", model);
+    let props = { new: this.get('new'), model };
+    const steps = model.get('steps');
+    if (steps[0]) props['currentStep'] = steps[0];
+    controller.setProperties(props);
+  },
+
+  actions: {
+    refreshRoute() {
+      this.refresh();
+    }
   }
 });

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

@@ -5,6 +5,12 @@ 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);
+    }
+  },
+
   setupController(controller, model){
     controller.set("model", model.toArray());
   },

+ 6 - 0
assets/javascripts/discourse/routes/admin-wizards-submissions.js.es6

@@ -5,6 +5,12 @@ export default Discourse.Route.extend({
     return CustomWizard.findAllSubmissions();
   },
 
+  afterModel(model, transition) {
+    if (transition.intent.name !== 'adminWizardSubmissions' && model.length > 0) {
+      this.transitionTo('adminWizardSubmissions', model[0].id);
+    }
+  },
+
   setupController(controller, model){
     controller.set("model", model);
   }

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

@@ -1,14 +1,16 @@
-<table>
-  {{#each model.submissions as |s|}}
-    <tr>
-      {{#each-in s as |k v|}}
-        <th>{{k}}</th>
-      {{/each-in}}
-    </tr>
-    <tr>
-      {{#each-in s as |k v|}}
-        <td>{{v}}</td>
-      {{/each-in}}
-    </tr>
-  {{/each}}
-</table>
+<div class="wizard-submissions">
+  <table>
+    {{#each model.submissions as |s|}}
+      <tr>
+        {{#each-in s as |k v|}}
+          <th>{{k}}</th>
+        {{/each-in}}
+      </tr>
+      <tr>
+        {{#each-in s as |k v|}}
+          <td>{{v}}</td>
+        {{/each-in}}
+      </tr>
+    {{/each}}
+  </table>
+</div>

+ 36 - 13
assets/javascripts/discourse/templates/admin-wizard.hbs

@@ -1,22 +1,45 @@
-<div class="form-horizontal">
-  <div>
-    <label for="name">{{i18n 'admin.wizard.name'}}</label>
-    {{text-field name="name" value=model.name placeholderKey="admin.wizard.name_placeholder"}}
+<div class="admin-wizard settings">
+
+  <div class="wizard-header">
+    {{i18n 'admin.wizard.header'}}
+  </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"}}
+    </div>
   </div>
 
-  <div>
-    {{input type='checkbox' checked=model.save_submissions}}
-    <span for="save">{{i18n 'admin.wizard.save_submissions'}}</span>
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n 'admin.wizard.save_submissions'}}</h3>
+    </div>
+    <div class="setting-value">
+      {{input type='checkbox' checked=model.save_submissions}}
+      <span for="save">{{i18n 'admin.wizard.save_submissions_label'}}</span>
+    </div>
   </div>
 
-  {{#if model.steps}}
-    {{#each model.steps as |s|}}
-      {{wizard-custom-step step=s fieldTypes=model.fieldTypes}}
-      {{d-button action='removeStep' actionParam=s label='admin.wizard.step.remove'}}
+  <div class="setting full">
+    <div class="setting-label">
+      <h3>{{i18n 'admin.wizard.url'}}</h3>
+    </div>
+    <a href="{{wizardUrl}}" target="_blank">{{wizardUrl}}</a>
+  </div>
+
+  <div class="wizard-links">
+    <div class="wizard-header">{{i18n 'admin.wizard.step.header'}}</div>
+    {{#each stepLinks as |s|}}
+      {{d-button action="changeStep" actionParam=s.id translatedLabel=s.title class=s.classes}}
+      {{d-button action="removeStep" actionParam=s.id icon='times' class='remove'}}
     {{/each}}
-  {{/if}}
+    {{d-button action='addStep' label='admin.wizard.add' icon='plus'}}
+  </div>
 
-  {{d-button action='addStep' label='admin.wizard.step.add'}}
+  {{wizard-custom-step step=currentStep fieldTypes=model.fieldTypes}}
 
   <div class='buttons'>
     <button {{action "save"}} disabled={{disableSave}} class='btn btn-primary'>{{i18n 'admin.wizard.save'}}</button>

+ 1 - 7
assets/javascripts/discourse/templates/admin-wizards-custom-index.hbs

@@ -1,7 +1 @@
-<div class="groups-type-index">
-  <div>
-    {{#link-to 'adminWizard' 'new' class="btn"}}
-      {{d-icon "plus"}} {{i18n 'admin.wizard.new'}}
-    {{/link-to}}
-  </div>
-</div>
+<div class="groups-type-index"></div>

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

@@ -7,9 +7,14 @@
         </li>
       {{/each}}
     </ul>
+    <div class="new-wizard">
+      {{#link-to 'adminWizard' 'new' class="btn"}}
+        {{d-icon "plus"}} {{i18n 'admin.wizard.new'}}
+      {{/link-to}}
+    </div>
   </div>
 
-  <div class="span13">
+  <div class="content">
     {{outlet}}
   </div>
 </div>

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

@@ -9,7 +9,7 @@
     </ul>
   </div>
 
-  <div class="span13">
+  <div class="content">
     {{outlet}}
   </div>
 </div>

+ 90 - 20
assets/javascripts/discourse/templates/components/wizard-custom-action.hbs

@@ -1,26 +1,96 @@
-{{combo-box value=action.type content=types}}
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n "admin.wizard.action.label"}}</h3>
+  </div>
+  <div class="setting-value">
+    {{input value=action.label}}
+  </div>
+</div>
+
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n "admin.wizard.action.type"}}</h3>
+  </div>
+  <div class="setting-value">
+    {{combo-box value=action.type content=types}}
+  </div>
+</div>
+
+
 {{#if createTopic}}
-  <label>{{i18n "admin.wizard.action.create_topic.category"}}</label>
-  {{category-select-box value=action.category_id}}
-  <label>{{i18n "admin.wizard.action.create_topic.title"}}</label>
-  {{combo-box value=action.title content=stepFields nameProperty="label"}}
-  <label>{{i18n "admin.wizard.action.create_topic.post"}}</label>
-  {{combo-box value=action.post content=stepFields nameProperty="label"}}
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.create_topic.category"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{category-select-box value=action.category_id}}
+    </div>
+  </div>
+
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.create_topic.title"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.title content=stepFields nameProperty="label"}}
+    </div>
+  </div>
+
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.create_topic.post"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.post content=stepFields nameProperty="label"}}
+    </div>
+  </div>
 {{/if}}
+
 {{#if sendMessage}}
-  <label>{{i18n "admin.wizard.action.send_message.title"}}</label>
-  {{combo-box value=action.title content=stepFields nameProperty="label"}}
-  <label>{{i18n "admin.wizard.action.send_message.post"}}</label>
-  {{combo-box value=action.post content=stepFields nameProperty="label"}}
-  <label>{{i18n "admin.wizard.action.send_message.recipient"}}</label>
-  {{user-selector single="true"
-                  includeMentionableGroups="true"
-                  usernames=action.username
-                  allowedUsers="true"}}
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.send_message.title"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.title content=stepFields nameProperty="label"}}
+    </div>
+  </div>
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.send_message.post"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.post content=stepFields nameProperty="label"}}
+    </div>
+  </div>
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.send_message.recipient"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{user-selector single="true"
+                      includeMentionableGroups="true"
+                      usernames=action.username
+                      allowedUsers="true"}}
+    </div>
+  </div>
 {{/if}}
+
 {{#if updateProfile}}
-  <label>{{i18n "admin.wizard.action.source"}}</label>
-  {{combo-box value=action.source content=stepFields nameProperty="label"}}
-  <label>{{i18n "admin.wizard.action.profile_field"}}</label>
-  {{combo-box value=action.profile_field content=profileFields}}
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.source"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.source content=stepFields nameProperty="label"}}
+    </div>
+  </div>
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n "admin.wizard.action.profile_field"}}</h3>
+    </div>
+    <div class="setting-value">
+      {{combo-box value=action.profile_field content=profileFields}}
+    </div>
+  </div>
 {{/if}}

+ 0 - 1
assets/javascripts/discourse/templates/components/wizard-custom-choice.hbs

@@ -1 +0,0 @@
-{{input type='text' value=choice.label}}

+ 44 - 18
assets/javascripts/discourse/templates/components/wizard-custom-field.hbs

@@ -1,25 +1,51 @@
-<div for={{field.id}}>
-  <div>
-    <span>{{i18n 'admin.wizard.field.label'}}</span>
-    {{text-field name="label" value=field.label}}
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.field.label'}}</h3>
   </div>
-  <div>
-    <span>{{i18n 'admin.wizard.field.description'}}</span>
-    {{text-field name="description" value=field.description}}
+  <div class="setting-value">
+    {{input name="label" value=field.label}}
   </div>
-  <div>
-    <span>{{i18n 'admin.wizard.field.type'}}</span>
+</div>
+
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.field.description'}}</h3>
+  </div>
+  <div class="setting-value">
+    {{textarea name="description" value=field.description}}
+  </div>
+</div>
+
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.field.type'}}</h3>
+  </div>
+  <div class="setting-value">
     {{combo-box value=field.type content=types}}
   </div>
-  {{#if isDropdown}}
-    <span>{{i18n 'admin.wizard.field.choices_label'}}</span>
-    {{#each field.choices as |c|}}
-      {{wizard-custom-choice choice=c}}
-    {{/each}}
-    {{d-button action='addChoice' label='admin.wizard.field.add_choice'}}
-  {{/if}}
-  <div>
-    <span>{{i18n 'admin.wizard.field.required'}}</span>
+</div>
+
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.field.required'}}</h3>
+  </div>
+  <div class="setting-value">
     {{input type='checkbox' checked=field.required}}
+    <span>{{i18n 'admin.wizard.field.required_label'}}</span>
   </div>
 </div>
+
+{{#if isDropdown}}
+  <div class="wizard-dropdown-choices">
+    <div class="wizard-header small">
+      {{i18n 'admin.wizard.field.choices_label'}}
+    </div>
+    {{#each dropdownChoices as |c|}}
+      <span class='wizard-dropdown-choice'>
+        {{input type='text' value=c.label}}
+      </span>
+      {{d-button action='removeChoice' actionParam=c icon='times'}}
+    {{/each}}
+    {{d-button action='addChoice' label='admin.wizard.add' icon='plus'}}
+  </div>
+{{/if}}

+ 42 - 20
assets/javascripts/discourse/templates/components/wizard-custom-step.hbs

@@ -1,30 +1,52 @@
-<div>
-  <label for="title">{{i18n 'admin.wizard.step.title'}}</label>
-  {{text-field name="title" value=step.title placeholderKey="admin.wizard.step.title_placeholder"}}
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.step.title'}}</h3>
+  </div>
+  <div class="setting-value">
+    {{input name="title" value=step.title placeholderKey="admin.wizard.step.title_placeholder"}}
+  </div>
 </div>
 
-<div>
-  <label for="banner">{{i18n 'admin.wizard.step.banner'}}</label>
-  {{input name="banner" value=step.banner placeholderKey="admin.wizard.step.banner_placeholder"}}
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.step.banner'}}</h3>
+  </div>
+  <div class="setting-value">
+    {{input name="banner" value=step.banner placeholderKey="admin.wizard.step.banner_placeholder"}}
+  </div>
 </div>
 
-<div>
-  <label for="description">{{i18n 'admin.wizard.step.description'}}</label>
-  {{input name="description" value=step.description placeholderKey="admin.wizard.step.description_placeholder"}}
+<div class="setting">
+  <div class="setting-label">
+    <h3>{{i18n 'admin.wizard.step.description'}}</h3>
+  </div>
+  <div class="setting-value">
+    {{textarea name="description" value=step.description placeholderKey="admin.wizard.step.description_placeholder"}}
+  </div>
 </div>
 
-{{#each step.fields as |f|}}
-  {{wizard-custom-field field=f types=fieldTypes}}
-  {{d-button action='removeField' actionParam=f label="admin.wizard.field.remove"}}
-{{/each}}
+<div class="wizard-links">
+  <div class="wizard-header medium">{{i18n 'admin.wizard.field.header'}}</div>
+  {{#each fieldLinks as |f|}}
+    {{d-button action="changeField" actionParam=f.id translatedLabel=f.label class=f.classes}}
+    {{d-button action='removeField' actionParam=f.id icon='times' class='remove'}}
+  {{/each}}
+  {{d-button action='addField' label='admin.wizard.add' icon='plus'}}
+</div>
 
-{{d-button action='addField' label='admin.wizard.field.add'}}
+{{#if currentField}}
+  {{wizard-custom-field field=currentField types=fieldTypes removeField="removeField"}}
+{{/if}}
 
-{{#each step.actions as |a|}}
-  {{wizard-custom-action action=a stepFields=step.fields}}
-  {{d-button action='removeAction' actionParam=a label="admin.wizard.action.remove"}}
-{{/each}}
+<div class="wizard-links">
+  <div class="wizard-header medium">{{i18n 'admin.wizard.action.header'}}</div>
+  {{#each actionLinks as |a|}}
+    {{d-button action="changeAction" actionParam=a.id translatedLabel=a.label class=a.classes}}
+    {{d-button action='removeAction' actionParam=a.id icon='times' class='remove'}}
+  {{/each}}
+  {{d-button action='addAction' label='admin.wizard.add' icon='plus'}}
+</div>
 
-{{#if allowAddAction}}
-  {{d-button action='addAction' label='admin.wizard.action.add'}}
+{{#if currentAction}}
+  {{wizard-custom-action action=currentAction stepFields=step.fields removeAction="removeAction"}}
 {{/if}}

+ 11 - 0
assets/javascripts/wizard/initializers/custom.js.es6

@@ -65,6 +65,17 @@ export default {
     });
 
     WizardStep.reopen({
+      bannerImage: function() {
+        const src = this.get('step.banner');
+        if (!src) return;
+
+        if (src.indexOf('/uploads/') > -1) {
+          return getUrl(src);
+        } else {
+          return getUrl(`/images/wizard/${src}`);
+        };
+      }.property('step.banner'),
+
       advance() {
         this.set('saving', true);
         this.get('step').save()

+ 75 - 0
assets/stylesheets/custom_wizard.scss

@@ -1,3 +1,78 @@
 .wizards-nav-button {
   @extend .nav-pills;
+  float: left;
+}
+
+.new-wizard {
+  margin-top: 15px;
+}
+
+.wizard-header {
+  font-size: 1.3em;
+  margin-bottom: 15px;
+
+  &.medium {
+    font-size: 1.1em;
+  }
+
+  &.small {
+    font-size: 0.97em;
+  }
+}
+
+.content-list + .content {
+  overflow: hidden;
+}
+
+.admin-wizard.settings {
+  margin-left: 30px;
+  margin-right: 30px;
+
+  .setting {
+    display: inline-block;
+    vertical-align: top;
+    min-width: 49%;
+
+    .setting-label {
+      width: 20%;
+    }
+
+    &.full {
+      width: 100%;
+
+      .setting-label {
+        width: 75px;
+      }
+    }
+  }
+}
+
+.wizard-links {
+  margin-bottom: 20px;
+
+  .remove {
+    margin-right: 10px;
+  }
+}
+
+.wizard-custom-step {
+  display: inline-block;
+  width: 100%;
+  margin-bottom: 20px;
+  padding: 15px;
+  background-color: dark-light-diff($primary, $secondary, 96%, -65%);
+}
+
+.wizard-dropdown-choices {
+  margin-bottom: 25px;
+}
+
+.wizard-dropdown-choice {
+  display: inline-block;
+}
+
+.wizard-submissions {
+  padding: 0 20px;
+  display: inline-block;
+  overflow: scroll;
 }

+ 27 - 24
config/locales/client.en.yml

@@ -8,41 +8,44 @@ en:
         submissions_label: "Submissions"
         name: "Name"
         name_placeholder: "name of the wizard"
-        save_submissions: "Save wizard submissions"
-        save: "Save Wizard"
+        save_submissions: "Save"
+        save_submissions_label: "Save wizard submissions"
+        save: "Save Changes"
         remove: "Delete Wizard"
+        header: "Wizard"
+        add: "Add"
+        url: "Url"
         step:
-          title: "Step Title"
+          header: "Steps"
+          title: "Title"
           title_placeholder: "This will appear at the top of the step"
-          banner: "Step Banner"
-          banner_placeholder: "This image will appear under the title"
-          description: "Step Description"
+          banner: "Banner"
+          banner_placeholder: "Image url"
+          description: "Description"
           description_placeholder: "This will appear underneath the title and / or title"
-          add: "Add Step"
-          remove: "Remove Step"
         field:
-          add: "Add Field"
-          remove: "Remove Field"
-          label: "Field Name"
-          description: "Field Description"
-          type: "Field Type"
+          header: "Fields"
+          label: "Label"
+          description: "Description"
+          type: "Type"
           choices_label: "Dropdown Choices"
-          add_choice: "Add Choice"
-          required: "Field Required"
+          add_choice: "Add"
+          required: "Required"
+          required_label: "Field is Required"
         action:
-          add: "Add Action"
-          remove: "Remove Action"
-          source: "Source"
+          header: "Actions"
+          label: "Label"
+          type: "Type"
           send_message:
             label: "Send Message"
-            title: "Message Title"
-            post: "Message Post"
-            recipient: "Message Recipient"
+            title: "Title"
+            post: "Post"
+            recipient: "Recipient"
           create_topic:
             label: "Create Topic"
-            title: "Topic Title"
-            post: "Topic Post"
-            category: "Topic Category"
+            title: "Title"
+            post: "Post"
+            category: "Category"
           update_profile:
             label: "Update Profile"
             field: "Profile Field"