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..3bccad2a 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..7605d8a4 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..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="wizard-step" + 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 ad4623c2..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="wizard-banner" + type="wizard-step-banner" 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..4163a1f7 100644 --- a/lib/custom_wizard/template.rb +++ b/lib/custom_wizard/template.rb @@ -29,6 +29,7 @@ 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 @@ -52,11 +53,16 @@ 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 @@ -123,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 @@ -176,4 +194,19 @@ class CustomWizard::Template object.delete(:index) end end + + def ensure_wizard_upload_references! + 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 = 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 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 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