Browse Source

Add prompt completion feature

Angus McLeod 7 years ago
parent
commit
b45d26c143

+ 25 - 0
assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6

@@ -0,0 +1,25 @@
+import { withPluginApi } from 'discourse/lib/plugin-api';
+
+export default {
+  name: 'custom-wizard-edits',
+  initialize() {
+    withPluginApi('0.8.12', api => {
+      api.modifyClass('component:global-notice', {
+        buildBuffer(buffer) {
+          this._super(...arguments);
+          const wizards = this.site.get('complete_custom_wizard');
+          if (wizards) {
+            wizards.forEach((w) => {
+              const text = I18n.t('wizard.complete_custom', {
+                wizard_url: w.url,
+                wizard_name: w.name,
+                site_name: this.siteSettings.title
+              });
+              buffer.push(`<div class='row'><div class='alert alert-info alert-wizard'>${text}</div></div>`);
+            });
+          }
+        }
+      });
+    });
+  }
+};

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

@@ -8,7 +8,8 @@ const wizardProperties = [
   'after_signup',
   'after_time',
   'after_time_scheduled',
-  'required'
+  'required',
+  'prompt_completion'
 ];
 
 const CustomWizard = Discourse.Model.extend({
@@ -235,6 +236,7 @@ CustomWizard.reopenClass({
       props['after_signup'] = false;
       props['after_time'] = false;
       props['required'] = false;
+      props['prompt_completion'] = false;
       props['steps'] = Ember.A();
     };
 

+ 10 - 0
assets/javascripts/discourse/templates/admin-wizard.hbs

@@ -82,6 +82,16 @@
     </div>
   </div>
 
+  <div class="setting">
+    <div class="setting-label">
+      <h3>{{i18n 'admin.wizard.prompt_completion'}}</h3>
+    </div>
+    <div class="setting-value">
+      {{input type='checkbox' checked=model.prompt_completion}}
+      <span for="save">{{i18n 'admin.wizard.prompt_completion_label'}}</span>
+    </div>
+  </div>
+
   <div class="setting full">
     <div class="setting-label">
       <h3>{{i18n 'admin.wizard.url'}}</h3>

+ 40 - 13
assets/stylesheets/wizard/wizard_custom.scss

@@ -1,6 +1,10 @@
 .custom-wizard {
   background-color: initial;
 
+  .wizard-step-contents {
+    position: relative;
+  }
+
   .wizard-step-description {
     line-height: 1.7;
 
@@ -15,7 +19,18 @@
     }
 
     .image-container {
-      margin: 10px 0;
+      margin: 30px 0;
+      padding: 0 40px;
+      display: flex;
+      justify-content: space-between;
+      flex-wrap: wrap;
+
+      &.group {
+        padding: 0;
+        margin: 0;
+        width: 140px;
+        height: 140px;
+      }
     }
 
     img.large {
@@ -27,6 +42,29 @@
       width: 120;
       padding: 10px;
     }
+
+    img.x-small {
+      width: 60px;
+      height: 60px;
+      padding: 3px;
+    }
+
+    label {
+      display: block;
+      text-align: center;
+    }
+
+    .tip {
+      position: absolute;
+      bottom: 0;
+      font-style: italic;
+
+      img {
+        width: 30px;
+        height: 30px;
+        vertical-align: middle;
+      }
+    }
   }
 
   .wizard-column .wizard-step-banner {
@@ -88,6 +126,7 @@
   line-height: 0;
   text-align: center;
   transition: all .2s;
+  z-index: 2;
 
   &.success {
     height: 60px;
@@ -190,15 +229,3 @@
     transform: rotate(360deg);
   }
 }
-
-// 3rd party styles TO BE REMOVED / REFACTORED
-
-#custom-wizard-main.place-petition {
-  .wizard-step.intro .image-container {
-    margin: 30px 0;
-
-    img {
-      padding: 20px 40px;
-    }
-  }
-}

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

@@ -1,4 +1,7 @@
 en:
+  js:
+    wizard:
+      complete_custom: "Welcome to %{site_name}! Get started with <a href='%{wizard_url}' data-auto-route='true'>the %{wizard_name} wizard</a> ✨"
   admin_js:
     admin:
       wizard:
@@ -27,6 +30,8 @@ en:
           clear: "Clear"
         required: "Required"
         required_label: "Users cannot skip the wizard."
+        prompt_completion: "Prompt"
+        prompt_completion_label: "Prompt user to complete wizard."
         save: "Save Changes"
         remove: "Delete Wizard"
         header: "Wizard"

+ 3 - 1
lib/template.rb

@@ -6,6 +6,7 @@ class CustomWizard::Template
               :background,
               :save_submissions,
               :multiple_submissions,
+              :prompt_completion,
               :after_signup,
               :after_time,
               :after_time_scheduled,
@@ -19,9 +20,10 @@ class CustomWizard::Template
     @background = data['background']
     @save_submissions = data['save_submissions'] || false
     @multiple_submissions = data['multiple_submissions'] || false
+    @prompt_completion = data['prompt_completion'] || false
     @after_signup = data['after_signup']
     @after_time = data['after_time']
     @after_time_scheduled = data['after_time_scheduled']
-    @required = data['required']
+    @required = data['required'] || false
   end
 end

+ 18 - 1
lib/wizard.rb

@@ -13,7 +13,8 @@ class CustomWizard::Wizard
                 :multiple_submissions,
                 :after_time,
                 :after_signup,
-                :required
+                :required,
+                :prompt_completion
 
   def initialize(user, attrs = {})
     @steps = []
@@ -116,6 +117,22 @@ class CustomWizard::Wizard
     end
   end
 
+  def self.prompt_completion(user)
+    rows = PluginStoreRow.where(plugin_name: 'custom_wizard')
+    wizards = [*rows].select { |r| r.value['prompt_completion'] }
+    if wizards.any?
+      wizards.reduce([]) do |result, w|
+        data = ::JSON.parse(w.value)
+        id = data['id']
+        name = data['name']
+        wizard = CustomWizard::Wizard.new(user, id: id, name: name)
+        result.push(id: id, name: name) if !wizard.completed?
+      end
+    else
+      false
+    end
+  end
+
   def self.steps(wizard_id)
     wizard = PluginStore.get('custom_wizard', wizard_id)
     wizard ? wizard['steps'] : nil

+ 11 - 1
lib/wizard_edits.rb

@@ -71,7 +71,9 @@ end
   end
 
   def include_completed?
-    object.completed? && !object.multiple_submissions && !scope.current_user.admin?
+    object.completed? &&
+    (!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) &&
+    !scope.current_user.admin?
   end
 
   def include_start?
@@ -89,6 +91,14 @@ end
   def include_required?
     object.respond_to?(:required)
   end
+
+  def prompt_completion
+    object.prompt_completion
+  end
+
+  def include_prompt_completion?
+    object.respond_to?(:prompt_completion)
+  end
 end
 
 ::WizardStepSerializer.class_eval do

+ 12 - 0
plugin.rb

@@ -112,8 +112,20 @@ after_initialize do
 
   ## TODO limit this to the first admin
   SiteSerializer.class_eval do
+    attributes :complete_custom_wizard
+
     def include_wizard_required?
       scope.is_admin? && Wizard.user_requires_completion?(scope.user)
     end
+
+    def complete_custom_wizard
+      if requires_completion = CustomWizard::Wizard.prompt_completion(scope.user)
+        requires_completion.map { |w| { name: w[:name], url: "/w/#{w[:id]}" } }
+      end
+    end
+
+    def include_complete_custom_wizard?
+      complete_custom_wizard.present?
+    end
   end
 end