From 2cec01ba2c4ac550546349e53c93cfe65e5e514b Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 2 Aug 2022 12:39:56 +0100 Subject: [PATCH 1/4] WIP Example --- app/controllers/custom_wizard/admin/wizard.rb | 2 ++ .../components/wizard-custom-field.js.es6 | 10 ++++-- .../components/wizard-custom-step.js.es6 | 10 ++++-- .../discourse/lib/wizard-schema.js.es6 | 2 ++ .../components/wizard-custom-field.hbs | 2 +- .../components/wizard-custom-step.hbs | 2 +- lib/custom_wizard/field.rb | 1 + lib/custom_wizard/step.rb | 1 + lib/custom_wizard/template.rb | 31 +++++++++++++++++++ plugin.rb | 16 ++++++++++ 10 files changed, 71 insertions(+), 6 deletions(-) diff --git a/app/controllers/custom_wizard/admin/wizard.rb b/app/controllers/custom_wizard/admin/wizard.rb index 0a59e02b..71a5623b 100644 --- a/app/controllers/custom_wizard/admin/wizard.rb +++ b/app/controllers/custom_wizard/admin/wizard.rb @@ -88,6 +88,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :title, :key, :banner, + :banner_upload_id, :raw_description, :required_data_message, :force_final, @@ -99,6 +100,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :index, :label, :image, + :image_upload_id, :description, :required, :key, diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 8efb7f0c..6966020c 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -144,11 +144,17 @@ export default Component.extend(UndoChanges, { actions: { imageUploadDone(upload) { - this.set("field.image", upload.url); + this.setProperties({ + "field.image": upload.url, + "field.image_upload_id": upload.id + }); }, imageUploadDeleted() { - this.set("field.image", null); + this.setProperties({ + "field.image": null, + "field.image_upload_id": null + }); }, }, }); diff --git a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 index 2a07dd65..034931ce 100644 --- a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 @@ -24,11 +24,17 @@ export default Component.extend({ actions: { bannerUploadDone(upload) { - this.set("step.banner", upload.url); + this.setProperties({ + "step.banner": upload.url, + "step.banner_upload_id": upload.id + }); }, bannerUploadDeleted() { - this.set("step.banner", null); + this.setProperties({ + "step.banner": null, + "step.banner_upload_id": null + }); }, }, }); diff --git a/assets/javascripts/discourse/lib/wizard-schema.js.es6 b/assets/javascripts/discourse/lib/wizard-schema.js.es6 index 5445223a..b47df7e6 100644 --- a/assets/javascripts/discourse/lib/wizard-schema.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-schema.js.es6 @@ -43,6 +43,7 @@ const step = { title: null, key: null, banner: null, + banner_upload_id: null, raw_description: null, required_data: null, required_data_message: null, @@ -68,6 +69,7 @@ const field = { index: null, label: null, image: null, + image_upload_id: null, description: null, required: null, key: null, diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index 6866f3ef..bc47b50f 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -44,7 +44,7 @@ imageUrl=field.image onUploadDone=(action "imageUploadDone") onUploadDeleted=(action "imageUploadDeleted") - type="wizard-step" + type=(concat "wizard-" wizard.id) class="no-repeat contain-image" id=(concat "wizard-field-" field.id "-image-upload")}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs index ad4623c2..64afa703 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs @@ -18,7 +18,7 @@ imageUrl=step.banner onUploadDone=(action "bannerUploadDone") onUploadDeleted=(action "bannerUploadDeleted") - type="wizard-banner" + type=(concat "wizard-" wizard.id) class="no-repeat contain-image" id=(concat "wizard-step-" step.id "-banner-upload")}} diff --git a/lib/custom_wizard/field.rb b/lib/custom_wizard/field.rb index 65f29504..12c46623 100644 --- a/lib/custom_wizard/field.rb +++ b/lib/custom_wizard/field.rb @@ -11,6 +11,7 @@ class CustomWizard::Field :label, :description, :image, + :image_upload_id, :key, :validations, :min_length, diff --git a/lib/custom_wizard/step.rb b/lib/custom_wizard/step.rb index 5ffd8024..b6ba5910 100644 --- a/lib/custom_wizard/step.rb +++ b/lib/custom_wizard/step.rb @@ -16,6 +16,7 @@ class CustomWizard::Step :next, :previous, :banner, + :banner_upload_id, :disabled, :description_vars, :last_step, diff --git a/lib/custom_wizard/template.rb b/lib/custom_wizard/template.rb index b57ebbd8..9bd75307 100644 --- a/lib/custom_wizard/template.rb +++ b/lib/custom_wizard/template.rb @@ -32,6 +32,7 @@ class CustomWizard::Template end self.class.clear_cache_keys + remove_unused_wizard_upload_references @data[:id] end @@ -62,6 +63,7 @@ class CustomWizard::Template end clear_cache_keys + remove_wizard_upload_references true end @@ -176,4 +178,33 @@ class CustomWizard::Template object.delete(:index) end end + + def collect_upload_ids + upload_ids = [] + + @data[:steps].each do |step| + upload_ids << step[:banner_upload_id] if step[:banner_upload_id] + + step[:fields].each do |field| + upload_ids << field[:image_upload_id] if field[:image_upload_id] + end + end + + upload_ids + end + + def wizard_upload_references + @wizard_upload_references ||= begin + record = PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: @data[:id]) + UploadReference.where(target_type: "CustomWizard", target_id: custom_wizard_record.id) + end + end + + def remove_unused_wizard_upload_references + wizard_upload_references.where.not(upload_id: collect_upload_ids).delete_all + end + + def remove_wizard_upload_references + wizard_upload_references.delete_all + end end diff --git a/plugin.rb b/plugin.rb index b05911f7..c15ad19a 100644 --- a/plugin.rb +++ b/plugin.rb @@ -226,5 +226,21 @@ after_initialize do ::DiscourseTagging.singleton_class.prepend CustomWizardDiscourseTagging end + on(:after_upload_creation) do |upload, opts| + from_wizard = opts[:type].include?("wizard-") + wizard_id = opts[:type].split("wizard-").last + wizard_record = PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: wizard_id) + + if wizard_record + UploadReference.create( + upload_id: upload.id, + target_type: "CustomWizard", + target_id: wizard_record.id, + created_at: Time.zone.now, + updated_at: Time.zone.now + ) + end + end + DiscourseEvent.trigger(:custom_wizard_ready) end From 1e8b667e3f409e125b8a436086d86d545197e111 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 2 Aug 2022 13:54:57 +0100 Subject: [PATCH 2/4] Working version contained within template model --- .../components/wizard-custom-field.hbs | 2 +- .../components/wizard-custom-step.hbs | 2 +- lib/custom_wizard/template.rb | 40 ++++++----- plugin.rb | 16 ----- .../components/custom_wizard/template_spec.rb | 69 +++++++++++++++++++ 5 files changed, 92 insertions(+), 37 deletions(-) diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index bc47b50f..dbf59e32 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -44,7 +44,7 @@ imageUrl=field.image onUploadDone=(action "imageUploadDone") onUploadDeleted=(action "imageUploadDeleted") - type=(concat "wizard-" wizard.id) + type="wizard-field-image" class="no-repeat contain-image" id=(concat "wizard-field-" field.id "-image-upload")}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs index 64afa703..9d7ae5af 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-step.hbs @@ -18,7 +18,7 @@ imageUrl=step.banner onUploadDone=(action "bannerUploadDone") onUploadDeleted=(action "bannerUploadDeleted") - type=(concat "wizard-" wizard.id) + type="wizard-step-banner" class="no-repeat contain-image" id=(concat "wizard-step-" step.id "-banner-upload")}} diff --git a/lib/custom_wizard/template.rb b/lib/custom_wizard/template.rb index 9bd75307..4163a1f7 100644 --- a/lib/custom_wizard/template.rb +++ b/lib/custom_wizard/template.rb @@ -29,10 +29,10 @@ class CustomWizard::Template ActiveRecord::Base.transaction do schedule_save_jobs unless opts[:skip_jobs] PluginStore.set(CustomWizard::PLUGIN_NAME, @data[:id], @data) + ensure_wizard_upload_references! end self.class.clear_cache_keys - remove_unused_wizard_upload_references @data[:id] end @@ -53,17 +53,21 @@ class CustomWizard::Template PluginStore.get(CustomWizard::PLUGIN_NAME, wizard_id) end + def self.find_record(wizard_id) + PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: wizard_id) + end + def self.remove(wizard_id) wizard = CustomWizard::Wizard.create(wizard_id) return false if !wizard ActiveRecord::Base.transaction do + ensure_wizard_upload_references!(wizard_id) PluginStore.remove(CustomWizard::PLUGIN_NAME, wizard.id) clear_user_wizard_redirect(wizard_id, after_time: !!wizard.after_time) end clear_cache_keys - remove_wizard_upload_references true end @@ -125,6 +129,18 @@ class CustomWizard::Template CustomWizard::Cache.new(AFTER_TIME_CACHE_KEY).delete end + def self.ensure_wizard_upload_references!(wizard_id, wizard_upload_ids = []) + wizard_record = find_record(wizard_id) + + if wizard_record + UploadReference.ensure_exist!( + upload_ids: wizard_upload_ids, + target_type: "PluginStoreRow", + target_id: wizard_record.id + ) + end + end + private def normalize_data @@ -179,7 +195,7 @@ class CustomWizard::Template end end - def collect_upload_ids + def ensure_wizard_upload_references! upload_ids = [] @data[:steps].each do |step| @@ -190,21 +206,7 @@ class CustomWizard::Template end end - upload_ids - end - - def wizard_upload_references - @wizard_upload_references ||= begin - record = PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: @data[:id]) - UploadReference.where(target_type: "CustomWizard", target_id: custom_wizard_record.id) - end - end - - def remove_unused_wizard_upload_references - wizard_upload_references.where.not(upload_id: collect_upload_ids).delete_all - end - - def remove_wizard_upload_references - wizard_upload_references.delete_all + upload_ids = upload_ids.select { |upload_id| Upload.exists?(upload_id) } + self.class.ensure_wizard_upload_references!(@data[:id], upload_ids) end end diff --git a/plugin.rb b/plugin.rb index c15ad19a..b05911f7 100644 --- a/plugin.rb +++ b/plugin.rb @@ -226,21 +226,5 @@ after_initialize do ::DiscourseTagging.singleton_class.prepend CustomWizardDiscourseTagging end - on(:after_upload_creation) do |upload, opts| - from_wizard = opts[:type].include?("wizard-") - wizard_id = opts[:type].split("wizard-").last - wizard_record = PluginStoreRow.find_by(plugin_name: CustomWizard::PLUGIN_NAME, key: wizard_id) - - if wizard_record - UploadReference.create( - upload_id: upload.id, - target_type: "CustomWizard", - target_id: wizard_record.id, - created_at: Time.zone.now, - updated_at: Time.zone.now - ) - end - end - DiscourseEvent.trigger(:custom_wizard_ready) end diff --git a/spec/components/custom_wizard/template_spec.rb b/spec/components/custom_wizard/template_spec.rb index 06a7bcb7..9a7b3777 100644 --- a/spec/components/custom_wizard/template_spec.rb +++ b/spec/components/custom_wizard/template_spec.rb @@ -2,6 +2,7 @@ describe CustomWizard::Template do fab!(:user) { Fabricate(:user) } + fab!(:upload) { Fabricate(:upload) } let(:template_json) { JSON.parse(File.open( @@ -54,6 +55,74 @@ describe CustomWizard::Template do ).to eq(true) end + context "upload references" do + it "are added if a wizard has a step banner" do + template_json['steps'][0]['banner'] = upload.url + template_json['steps'][0]['banner_upload_id'] = upload.id + CustomWizard::Template.save(template_json, skip_jobs: true) + wizard_record = CustomWizard::Template.find_record(template_json["id"]) + expect( + UploadReference.exists?( + upload_id: upload.id, + target_type: "PluginStoreRow", + target_id: wizard_record.id + ) + ).to eq(true) + end + + it "are added if a wizard has a field image" do + template_json['steps'][0]["fields"][0]['image'] = upload.url + template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id + CustomWizard::Template.save(template_json, skip_jobs: true) + wizard_record = CustomWizard::Template.find_record(template_json["id"]) + expect( + UploadReference.exists?( + upload_id: upload.id, + target_type: "PluginStoreRow", + target_id: wizard_record.id + ) + ).to eq(true) + end + + it "are removed if a wizard step banner is removed" do + template_json['steps'][0]['banner'] = upload.url + template_json['steps'][0]['banner_upload_id'] = upload.id + CustomWizard::Template.save(template_json, skip_jobs: true) + + template_json['steps'][0]['banner'] = nil + template_json['steps'][0]['banner_upload_id'] = nil + CustomWizard::Template.save(template_json, skip_jobs: true) + wizard_record = CustomWizard::Template.find_record(template_json["id"]) + expect( + UploadReference.exists?(target_type: "PluginStoreRow") + ).to eq(false) + end + + it "are removed if a wizard field image is removed" do + template_json['steps'][0]["fields"][0]['image'] = upload.url + template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id + CustomWizard::Template.save(template_json, skip_jobs: true) + + template_json['steps'][0]["fields"][0]['image'] = nil + template_json['steps'][0]["fields"][0]['image_upload_id'] = nil + CustomWizard::Template.save(template_json, skip_jobs: true) + wizard_record = CustomWizard::Template.find_record(template_json["id"]) + expect( + UploadReference.exists?(target_type: "PluginStoreRow") + ).to eq(false) + end + + it "are removed if a wizard is removed" do + template_json['steps'][0]["fields"][0]['image'] = upload.url + template_json['steps'][0]["fields"][0]['image_upload_id'] = upload.id + CustomWizard::Template.save(template_json, skip_jobs: true) + CustomWizard::Template.remove(template_json["id"]) + expect( + UploadReference.exists?(target_type: "PluginStoreRow") + ).to eq(false) + end + end + context "wizard template list" do before do template_json_2 = template_json.dup From 5acff01708df2b805327076f9696a4048d10bcf8 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 2 Aug 2022 13:57:19 +0100 Subject: [PATCH 3/4] Apply prettier --- .../discourse/components/wizard-custom-field.js.es6 | 4 ++-- .../discourse/components/wizard-custom-step.js.es6 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index 6966020c..3bccad2a 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -146,14 +146,14 @@ export default Component.extend(UndoChanges, { imageUploadDone(upload) { this.setProperties({ "field.image": upload.url, - "field.image_upload_id": upload.id + "field.image_upload_id": upload.id, }); }, imageUploadDeleted() { this.setProperties({ "field.image": null, - "field.image_upload_id": null + "field.image_upload_id": null, }); }, }, diff --git a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 index 034931ce..7605d8a4 100644 --- a/assets/javascripts/discourse/components/wizard-custom-step.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-step.js.es6 @@ -26,14 +26,14 @@ export default Component.extend({ bannerUploadDone(upload) { this.setProperties({ "step.banner": upload.url, - "step.banner_upload_id": upload.id + "step.banner_upload_id": upload.id, }); }, bannerUploadDeleted() { this.setProperties({ "step.banner": null, - "step.banner_upload_id": null + "step.banner_upload_id": null, }); }, }, From c3c87852b89e6df8f775a907586ae8c5d1865abe Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Tue, 2 Aug 2022 13:57:44 +0100 Subject: [PATCH 4/4] Bump version --- plugin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.rb b/plugin.rb index b05911f7..bb978b26 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.22.2 +# version: 1.22.3 # authors: Angus McLeod # url: https://github.com/paviliondev/discourse-custom-wizard # contact emails: angus@pavilion.tech