Angus McLeod 7 years ago
parent
commit
dd26ac63af

+ 1 - 1
app/controllers/admin.rb

@@ -7,7 +7,7 @@ class CustomWizard::AdminController < ::ApplicationController
   end
 
   def field_types
-    render json: { types: CustomWizard::FieldTypes.all }
+    render json: { types: CustomWizard::Field.types }
   end
 
   def save

+ 4 - 0
app/views/layouts/custom_wizard.html.erb

@@ -2,15 +2,19 @@
   <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(mobile_view? ? :mobile : :desktop) %>
     <%= preload_script "ember_jquery" %>
     <%= preload_script "wizard-vendor" %>
     <%= preload_script "wizard-application" %>
     <%= preload_script "wizard-custom" %>
+    <%= preload_script "wizard-plugin" %>
     <%= preload_script "locales/#{I18n.locale}" %>
     <%= render partial: "common/special_font_face" %>
     <script src="<%= Discourse.base_uri %>/extra-locales/wizard"></script>
     <%= csrf_meta_tags %>
 
+    <%= server_plugin_outlet "custom_wizard" %>
+
     <meta name="discourse-base-uri" content="<%= Discourse.base_uri %>">
 
     <%= render partial: "layouts/head" %>

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

@@ -123,6 +123,7 @@ CustomWizard.reopenClass({
       props['id'] = w.id;
       props['name'] = w.name;
       props['background'] = w.background;
+      props['save_submissions'] = w.save_submissions;
 
       if (w.steps) {
         w.steps.forEach((s) => {

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

@@ -6,7 +6,7 @@ export default Discourse.Route.extend({
     if (params.wizard_id === 'new') {
       this.set('newWizard', true);
       return CustomWizard.create();
-    }
+    };
     this.set('newWizard', false);
 
     const wizard = this.modelFor('admin-wizards-custom').findBy('id', params.wizard_id.underscore());

+ 7 - 0
assets/javascripts/wizard-custom.js

@@ -1,6 +1,13 @@
 //= require ./wizard/custom-wizard
+//= require_tree ./wizard/components
 //= require_tree ./wizard/controllers
+//= require_tree ./wizard/helpers
 //= require_tree ./wizard/initializers
 //= require_tree ./wizard/models
 //= require_tree ./wizard/routes
 //= require_tree ./wizard/templates
+
+//= require lodash.js
+
+window.Wizard = {};
+Wizard.SiteSettings = {};

+ 17 - 0
assets/javascripts/wizard-plugin.js.erb

@@ -0,0 +1,17 @@
+// loads files for plugins that have been added via CustomWizard::Field
+<%
+Discourse.unofficial_plugins.each do |plugin|
+  plugin_name = plugin.metadata.name
+  if require_plugin_assets = CustomWizard::Field.require_assets[plugin_name]
+    plugin.each_globbed_asset do |f, is_dir|
+      if require_plugin_assets.any? { |dir| f.include?(dir) }
+        if is_dir
+          depend_on(f)
+        else
+          require_asset(f)
+        end
+      end
+    end
+  end
+end
+%>

+ 28 - 0
assets/javascripts/wizard/components/wizard-field-composer.js.es6

@@ -0,0 +1,28 @@
+import { observes } from 'ember-addons/ember-computed-decorators';
+
+export default Ember.Component.extend({
+  classNames: 'wizard-field-composer',
+
+  keyPress(e) {
+    e.stopPropagation();
+  },
+
+  @observes('field.value')
+  validate() {
+    const minLength = Wizard.SiteSettings.min_post_length;
+    const post = this.get('field.value');
+    const field = this.get('field');
+
+    field.set('customValidation', true);
+
+    if (!post) {
+      return field.setValid(false);
+    }
+
+    if (minLength && post.length < minLength) {
+      return field.setValid(false, I18n.t('wizard.validation.too_short', { min: minLength }));
+    }
+
+    field.setValid(true);
+  }
+});

+ 15 - 0
assets/javascripts/wizard/helpers/loading-spinner.es6

@@ -0,0 +1,15 @@
+import { htmlHelper } from 'discourse-common/lib/helpers';
+
+function renderSpinner(cssClass) {
+  var html = "<div class='spinner";
+  if (cssClass) { html += ' ' + cssClass; }
+  return html + "'></div>";
+}
+var spinnerHTML = renderSpinner();
+
+export default htmlHelper(params => {
+  const hash = params.hash;
+  return renderSpinner((hash && hash.size) ? hash.size : undefined);
+});
+
+export { spinnerHTML, renderSpinner };

+ 34 - 6
assets/javascripts/wizard/initializers/custom.js.es6

@@ -12,6 +12,7 @@ export default {
     const StepModel = requirejs('wizard/models/step').default;
     const WizardStep = requirejs('wizard/components/wizard-step').default;
     const getUrl = requirejs('discourse-common/lib/get-url').default;
+    const FieldModel = requirejs('wizard/models/wizard-field').default;
 
     Router.map(function() {
       this.route('custom', { path: '/custom/:id' }, function() {
@@ -26,16 +27,23 @@ export default {
       },
 
       afterModel(model) {
-        return ajax({
-          url: `/site/basic-info`,
-          type: 'GET',
-        }).then((result) => {
-          return model.set('siteInfo', result);
+        return Ember.RSVP.hash({
+          info: ajax({
+            url: `/site/basic-info`,
+            type: 'GET',
+          }).then((result) => {
+            return model.set('siteInfo', result);
+          }),
+          settings: ajax({
+            url: `/site/settings`,
+            type: 'GET',
+          }).then((result) => {
+            Object.assign(Wizard.SiteSettings, result);
+          })
         });
       },
 
       setupController(controller, model) {
-        console.log(model)
         Ember.run.scheduleOnce('afterRender', this, function(){
           $('body.custom-wizard').css('background', model.get('background'));
         });
@@ -106,5 +114,25 @@ export default {
         }
       }
     });
+
+    FieldModel.reopen({
+      check() {
+        let valid = this.get('valid');
+
+        if (!this.get('required')) {
+          this.setValid(true);
+          return true;
+        }
+
+        if (!this.get('customValidation')) {
+          const val = this.get('value');
+          valid = val && val.length > 0;
+
+          this.setValid(valid);
+        }
+
+        return valid;
+      }
+    });
   }
 };

+ 1 - 0
assets/javascripts/wizard/templates/components/wizard-field-composer.hbs

@@ -0,0 +1 @@
+{{textarea elementId=field.id value=field.value placeholder=field.placeholder tabindex="9"}}

+ 5 - 0
assets/stylesheets/custom_wizard.scss

@@ -81,3 +81,8 @@
   display: inline-block;
   overflow: scroll;
 }
+
+.wizard-field-composer textarea {
+  width: 100%;
+  min-height: 150px;
+}

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

@@ -18,6 +18,7 @@ en:
         add: "Add"
         url: "Url"
         translation: "Translation"
+
         step:
           header: "Steps"
           title: "Title"
@@ -27,6 +28,7 @@ en:
           description: "Description"
           description_placeholder: "Overrides description translation"
           translation_placeholder: "Translation key for step"
+
         field:
           header: "Fields"
           label: "Label"
@@ -37,6 +39,7 @@ en:
           required: "Required"
           required_label: "Field is Required"
           translation_placeholder: "Translation key for field"
+
         action:
           header: "Actions"
           label: "Label"
@@ -56,3 +59,8 @@ en:
             field: "Profile Field"
           save_input:
             label: "Save Input"
+
+  wizard_js:
+    wizard:
+      validation:
+        too_short: "Post must be at least {{min}} characters"

+ 1 - 1
lib/builder.rb

@@ -56,7 +56,7 @@ class CustomWizard::Builder
           input = updater.fields
           user = @wizard.user
 
-          if @wizard.save_submissions
+          if @wizard.save_submissions && input
             store_key = @wizard.id
             submissions = Array.wrap(PluginStore.get("custom_wizard_submissions", store_key))
             submission = {}

+ 19 - 0
lib/field.rb

@@ -0,0 +1,19 @@
+class CustomWizard::Field
+  def self.types
+    @types ||= ['dropdown', 'image', 'radio', 'text', 'textarea', 'composer']
+  end
+
+  def self.require_assets
+    @require_assets ||= {}
+  end
+
+  def self.add_assets(type, plugin = nil, asset_paths = [])
+    if type
+      types.push(*type)
+    end
+
+    if plugin && asset_paths
+      require_assets[plugin] = asset_paths
+    end
+  end
+end

+ 3 - 1
lib/wizard.rb

@@ -1,11 +1,13 @@
 class CustomWizard::Wizard
 
-  attr_reader :id, :name, :steps, :custom
+  attr_reader :id, :name, :steps, :background, :save_submissions, :custom
 
   def initialize(data)
     data = data.is_a?(String) ? ::JSON.parse(data) : data
     @id = data['id']
     @name = data['name']
+    @background = data['background']
+    @save_submissions = data['save_submissions']
     @steps = data['steps']
     @custom = true
   end

+ 1 - 10
plugin.rb

@@ -18,6 +18,7 @@ after_initialize do
   end
 
   load File.expand_path('../lib/builder.rb', __FILE__)
+  load File.expand_path('../lib/field.rb', __FILE__)
   load File.expand_path('../lib/wizard.rb', __FILE__)
   load File.expand_path('../app/controllers/wizard.rb', __FILE__)
   load File.expand_path('../app/controllers/steps.rb', __FILE__)
@@ -51,16 +52,6 @@ after_initialize do
     end
   end
 
-  class CustomWizard::FieldTypes
-    def self.all
-      @types ||= ['dropdown', 'image', 'radio', 'text', 'textarea']
-    end
-
-    def self.add(type)
-      all.push(*type)
-    end
-  end
-
   class ::Wizard
     attr_accessor :id, :background, :save_submissions
   end