diff --git a/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 b/assets/javascripts/discourse/initializers/custom-wizard-edits.js.es6 new file mode 100644 index 00000000..dc5d1a02 --- /dev/null +++ b/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(`
${text}
`); + }); + } + } + }); + }); + } +}; diff --git a/assets/javascripts/discourse/models/custom-wizard.js.es6 b/assets/javascripts/discourse/models/custom-wizard.js.es6 index 7c5e06e3..0c4a9107 100644 --- a/assets/javascripts/discourse/models/custom-wizard.js.es6 +++ b/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(); }; diff --git a/assets/javascripts/discourse/templates/admin-wizard.hbs b/assets/javascripts/discourse/templates/admin-wizard.hbs index 1bbb6107..af7bd902 100644 --- a/assets/javascripts/discourse/templates/admin-wizard.hbs +++ b/assets/javascripts/discourse/templates/admin-wizard.hbs @@ -82,6 +82,16 @@ +
+
+

{{i18n 'admin.wizard.prompt_completion'}}

+
+
+ {{input type='checkbox' checked=model.prompt_completion}} + {{i18n 'admin.wizard.prompt_completion_label'}} +
+
+

{{i18n 'admin.wizard.url'}}

diff --git a/assets/stylesheets/wizard/wizard_custom.scss b/assets/stylesheets/wizard/wizard_custom.scss index f8c00a62..ac973745 100644 --- a/assets/stylesheets/wizard/wizard_custom.scss +++ b/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; - } - } -} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 42d12b62..5b08f7f1 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1,4 +1,7 @@ en: + js: + wizard: + complete_custom: "Welcome to %{site_name}! Get started with the %{wizard_name} wizard ✨" 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" diff --git a/lib/template.rb b/lib/template.rb index 3f0da153..5532f61f 100644 --- a/lib/template.rb +++ b/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 diff --git a/lib/wizard.rb b/lib/wizard.rb index 5946a355..b1aff727 100644 --- a/lib/wizard.rb +++ b/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 diff --git a/lib/wizard_edits.rb b/lib/wizard_edits.rb index eb7b51ed..96b934de 100644 --- a/lib/wizard_edits.rb +++ b/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 diff --git a/plugin.rb b/plugin.rb index 46f4f2fa..a3d755bf 100644 --- a/plugin.rb +++ b/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