From 2678ee153d8905b925167df86bc57532d8ec6f37 Mon Sep 17 00:00:00 2001 From: Faizaan Gagan Date: Wed, 22 Sep 2021 13:52:05 +0530 Subject: [PATCH] FEATURE: add resume wizard popup (#146) * FEATURE: add resume wizard popup * code cleanup, copy edits * FIX: address functionality, setting and copy issues @fzngagan a few issues fixed 1. The resume button wasn't working (old reference to ``resumeDialog`` remained in callback. 2. This needs a wizard setting 3. It's not necessary to serialize the first step separately. We have all the steps in ``steps`` and steps have indexes. 4. Button copy * Fix linting * Ensure aa submission exists * Apply prettier Co-authored-by: angusmcleod --- .../discourse/lib/wizard-schema.js.es6 | 1 + .../templates/admin-wizards-wizard-show.hbs | 10 +++++ .../javascripts/wizard/models/custom.js.es6 | 10 +++++ .../javascripts/wizard/routes/custom.js.es6 | 43 +++++++++++++++++++ config/locales/client.en.yml | 6 +++ controllers/custom_wizard/admin/wizard.rb | 1 + lib/custom_wizard/wizard.rb | 2 + plugin.rb | 2 +- .../custom_wizard/wizard_serializer.rb | 8 +++- 9 files changed, 81 insertions(+), 2 deletions(-) diff --git a/assets/javascripts/discourse/lib/wizard-schema.js.es6 b/assets/javascripts/discourse/lib/wizard-schema.js.es6 index 8b8200b0..5445223a 100644 --- a/assets/javascripts/discourse/lib/wizard-schema.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-schema.js.es6 @@ -14,6 +14,7 @@ const wizard = { required: null, prompt_completion: null, restart_on_revisit: null, + resume_on_revisit: null, theme_id: null, permitted: null, }, diff --git a/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs b/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs index 7e5b0ee0..c5ed70a7 100644 --- a/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards-wizard-show.hbs @@ -151,6 +151,16 @@ +
+
+ +
+
+ {{input type="checkbox" checked=wizard.resume_on_revisit}} + {{i18n "admin.wizard.resume_on_revisit_label"}} +
+
+ {{/if}} diff --git a/assets/javascripts/wizard/models/custom.js.es6 b/assets/javascripts/wizard/models/custom.js.es6 index 31a403da..a17233b2 100644 --- a/assets/javascripts/wizard/models/custom.js.es6 +++ b/assets/javascripts/wizard/models/custom.js.es6 @@ -15,6 +15,10 @@ const CustomWizard = EmberObject.extend({ } CustomWizard.skip(this.id); }, + + restart() { + CustomWizard.restart(this.id); + }, }); CustomWizard.reopenClass({ @@ -24,6 +28,12 @@ CustomWizard.reopenClass({ }); }, + restart(wizardId) { + ajax({ url: `/w/${wizardId}/skip`, type: "PUT" }).then(() => { + window.location.href = `/w/${wizardId}`; + }); + }, + finished(result) { let url = "/"; if (result.redirect_on_complete) { diff --git a/assets/javascripts/wizard/routes/custom.js.es6 b/assets/javascripts/wizard/routes/custom.js.es6 index 367fa36b..a312db3a 100644 --- a/assets/javascripts/wizard/routes/custom.js.es6 +++ b/assets/javascripts/wizard/routes/custom.js.es6 @@ -2,6 +2,7 @@ import { findCustomWizard, updateCachedWizard } from "../models/custom"; import { ajax } from "wizard/lib/ajax"; +import WizardI18n from "../lib/wizard-i18n"; export default Ember.Route.extend({ beforeModel(transition) { @@ -12,6 +13,48 @@ export default Ember.Route.extend({ return findCustomWizard(params.wizard_id, this.get("queryParams")); }, + renderTemplate() { + this.render("custom"); + const wizardModel = this.modelFor("custom"); + const stepModel = this.modelFor("custom.step"); + + if ( + wizardModel.resume_on_revisit && + wizardModel.submission_last_updated_at && + stepModel.index > 0 + ) { + this.showDialog(wizardModel); + } + }, + + showDialog(wizardModel) { + const title = WizardI18n("wizard.incomplete_submission.title", { + date: moment(wizardModel.submission_last_updated_at).format( + "MMMM Do YYYY" + ), + }); + + const buttons = [ + { + label: WizardI18n("wizard.incomplete_submission.restart"), + class: "btn btn-default", + callback: () => { + wizardModel.restart(); + }, + }, + { + label: WizardI18n("wizard.incomplete_submission.resume"), + class: "btn btn-primary", + }, + ]; + + const options = { + onEscape: false, + }; + + bootbox.dialog(title, buttons, options); + }, + afterModel(model) { updateCachedWizard(model); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index ef826cab..d9b34a87 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -35,6 +35,8 @@ en: prompt_completion_label: "Prompt user to complete wizard." restart_on_revisit: "Restart" restart_on_revisit_label: "Clear submissions on each visit." + resume_on_revisit: "Resume" + resume_on_revisit_label: "Ask the user if they want to resume on each visit." theme_id: "Theme" no_theme: "Select a Theme (optional)" save: "Save Changes" @@ -496,6 +498,10 @@ en: requires_login: "You need to be logged in to access this wizard." reset: "Reset this wizard." step_not_permitted: "You're not permitted to view this step." + incomplete_submission: + title: "Continue editing your draft submission from %{date}?" + resume: "Continue" + restart: "Start over" x_characters: one: "%{count} Character" other: "%{count} Characters" diff --git a/controllers/custom_wizard/admin/wizard.rb b/controllers/custom_wizard/admin/wizard.rb index 8da64fac..e2edfba0 100644 --- a/controllers/custom_wizard/admin/wizard.rb +++ b/controllers/custom_wizard/admin/wizard.rb @@ -79,6 +79,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :required, :prompt_completion, :restart_on_revisit, + :resume_on_revisit, :theme_id, permitted: mapped_params, steps: [ diff --git a/lib/custom_wizard/wizard.rb b/lib/custom_wizard/wizard.rb index 8f5a897f..ebae615e 100644 --- a/lib/custom_wizard/wizard.rb +++ b/lib/custom_wizard/wizard.rb @@ -21,6 +21,7 @@ class CustomWizard::Wizard :required, :prompt_completion, :restart_on_revisit, + :resume_on_revisit, :permitted, :needs_categories, :needs_groups, @@ -47,6 +48,7 @@ class CustomWizard::Wizard @multiple_submissions = cast_bool(attrs['multiple_submissions']) @prompt_completion = cast_bool(attrs['prompt_completion']) @restart_on_revisit = cast_bool(attrs['restart_on_revisit']) + @resume_on_revisit = cast_bool(attrs['resume_on_revisit']) @after_signup = cast_bool(attrs['after_signup']) @after_time = cast_bool(attrs['after_time']) @after_time_scheduled = attrs['after_time_scheduled'] diff --git a/plugin.rb b/plugin.rb index 05e5fe9a..51adcba6 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Create custom wizards -# version: 1.13.34 +# version: 1.14.0 # authors: Angus McLeod # url: https://github.com/paviliondev/discourse-custom-wizard # contact emails: angus@thepavilion.io diff --git a/serializers/custom_wizard/wizard_serializer.rb b/serializers/custom_wizard/wizard_serializer.rb index 7a162ba5..f23ff7e1 100644 --- a/serializers/custom_wizard/wizard_serializer.rb +++ b/serializers/custom_wizard/wizard_serializer.rb @@ -4,12 +4,14 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer attributes :start, :background, + :submission_last_updated_at, :theme_id, :completed, :required, :permitted, :uncategorized_category_id, - :categories + :categories, + :resume_on_revisit has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects has_one :user, serializer: ::BasicUserSerializer, embed: :objects @@ -37,6 +39,10 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer include_steps? && object.start.present? end + def submission_last_updated_at + object.current_submission.updated_at + end + def include_steps? !include_completed? end