diff --git a/.discourse-compatibility b/.discourse-compatibility index ff1e994a9c..dc7a63c108 100644 --- a/.discourse-compatibility +++ b/.discourse-compatibility @@ -1,3 +1,4 @@ +< 3.5.0.beta3-dev: 809c097f57bb81a972c53b6e009b0149c45e0965 3.2.0.beta2: 1ee2f7d8babafe32912372fbbfa50c89f5b09ba9 3.1.999: 1f35b80f85e5fd1efb7f4851f0845700432febdc 2.7.99: e07a57e398b6b1676ab42a7e34467556fca5416b diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 7898fbf829..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "eslint-config-discourse" -} diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000000..57f647bc84 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require("@discourse/lint-configs/prettier"); diff --git a/.rubocop.yml b/.rubocop.yml index c092e26535..3290dec708 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,10 @@ inherit_gem: - rubocop-discourse: default.yml + rubocop-discourse: stree-compat.yml + +AllCops: + Exclude: + - 'gems/**/*' + - 'vendor/**/*' RSpec/ContextWording: Enabled: false @@ -12,3 +17,9 @@ Discourse/TimeEqMatcher: Discourse/NoAddReferenceOrAliasesActiveRecordMigration: Enabled: false + +Lint/BooleanSymbol: + Enabled: false + +Discourse/Plugins/NoMonkeyPatching: + Enabled: false diff --git a/.streerc b/.streerc new file mode 100644 index 0000000000..88c01331b5 --- /dev/null +++ b/.streerc @@ -0,0 +1,2 @@ +--print-width=100 +--plugins=plugin/trailing_comma,plugin/disable_auto_ternary \ No newline at end of file diff --git a/.template-lintrc.cjs b/.template-lintrc.cjs new file mode 100644 index 0000000000..5355ea06fb --- /dev/null +++ b/.template-lintrc.cjs @@ -0,0 +1 @@ +module.exports = require("@discourse/lint-configs/template-lint"); diff --git a/.template-lintrc.js b/.template-lintrc.js deleted file mode 100644 index a558b8e32c..0000000000 --- a/.template-lintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - plugins: ["ember-template-lint-plugin-discourse"], - extends: "discourse:recommended", -}; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a204871957..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -services: - - docker - -before_install: - - git clone --depth=1 https://github.com/discourse/discourse-plugin-ci - -install: true - -script: - - discourse-plugin-ci/script.sh diff --git a/Gemfile b/Gemfile index 7da32ec039..c62579adb4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,9 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" group :development do - gem 'rubocop-discourse' + gem "rubocop-discourse" + gem "syntax_tree" + gem "racc" end diff --git a/Gemfile.lock b/Gemfile.lock index 5ab57bb66b..59d33ca6ee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,39 +1,88 @@ GEM remote: https://rubygems.org/ specs: + activesupport (7.2.1) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) ast (2.4.2) - json (2.6.2) - parallel (1.22.1) - parser (3.1.2.1) + base64 (0.2.0) + bigdecimal (3.1.8) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + drb (2.2.1) + i18n (1.14.6) + concurrent-ruby (~> 1.0) + json (2.7.2) + language_server-protocol (3.17.0.3) + logger (1.6.1) + minitest (5.25.1) + parallel (1.26.3) + parser (3.3.5.0) ast (~> 2.4.1) + racc + prettier_print (1.2.1) + racc (1.8.1) + rack (3.1.7) rainbow (3.1.1) - regexp_parser (2.6.0) - rexml (3.2.5) - rubocop (1.36.0) + regexp_parser (2.9.2) + rubocop (1.66.1) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.1.2.1) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.20.1, < 2.0) + regexp_parser (>= 2.4, < 3.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.22.0) - parser (>= 3.1.1.0) - rubocop-discourse (3.0) - rubocop (>= 1.1.0) - rubocop-rspec (>= 2.0.0) - rubocop-rspec (2.13.2) - rubocop (~> 1.33) - ruby-progressbar (1.11.0) - unicode-display_width (2.3.0) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.32.3) + parser (>= 3.3.1.0) + rubocop-capybara (2.21.0) + rubocop (~> 1.41) + rubocop-discourse (3.8.1) + activesupport (>= 6.1) + rubocop (>= 1.59.0) + rubocop-capybara (>= 2.0.0) + rubocop-factory_bot (>= 2.0.0) + rubocop-rails (>= 2.25.0) + rubocop-rspec (>= 3.0.1) + rubocop-rspec_rails (>= 2.30.0) + rubocop-factory_bot (2.26.1) + rubocop (~> 1.61) + rubocop-rails (2.26.2) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.52.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.5) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) + ruby-progressbar (1.13.0) + securerandom (0.3.1) + syntax_tree (6.2.0) + prettier_print (>= 1.2.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) PLATFORMS + arm64-darwin-23 ruby DEPENDENCIES + racc rubocop-discourse + syntax_tree BUNDLED WITH - 2.2.16 + 2.5.18 diff --git a/app/controllers/custom_wizard/admin/admin.rb b/app/controllers/custom_wizard/admin/admin.rb index 2b950b23e9..53fff92035 100644 --- a/app/controllers/custom_wizard/admin/admin.rb +++ b/app/controllers/custom_wizard/admin/admin.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class CustomWizard::AdminController < ::Admin::AdminController before_action :ensure_admin + requires_plugin "discourse-custom-wizard" private diff --git a/app/controllers/custom_wizard/admin/api.rb b/app/controllers/custom_wizard/admin/api.rb index e4ac31e973..e31234bbc6 100644 --- a/app/controllers/custom_wizard/admin/api.rb +++ b/app/controllers/custom_wizard/admin/api.rb @@ -1,23 +1,31 @@ # frozen_string_literal: true class CustomWizard::AdminApiController < CustomWizard::AdminController skip_before_action :check_xhr, only: [:redirect] + requires_plugin "discourse-custom-wizard" def list - serializer = ActiveModel::ArraySerializer.new(CustomWizard::Api.list, - each_serializer: CustomWizard::BasicApiSerializer - ) + serializer = + ActiveModel::ArraySerializer.new( + CustomWizard::Api.list, + each_serializer: CustomWizard::BasicApiSerializer, + ) render json: MultiJson.dump(serializer) end def find - render_serialized(CustomWizard::Api.get(api_params[:name]), CustomWizard::ApiSerializer, root: false) + render_serialized( + CustomWizard::Api.get(api_params[:name]), + CustomWizard::ApiSerializer, + root: false, + ) end def save current = CustomWizard::Api.get(api_params[:name]) if api_params[:new] && current - raise Discourse::InvalidParameters, "An API with that name already exists: '#{current.title || current.name}'" + raise Discourse::InvalidParameters, + "An API with that name already exists: '#{current.title || current.name}'" end unless subscription.includes?(:api, :all) @@ -28,28 +36,28 @@ def save CustomWizard::Api.set(api_params[:name], title: api_params[:title]) if auth_data.present? - auth_data['auth_params'] = auth_data['auth_params'] || [] + auth_data["auth_params"] = auth_data["auth_params"] || [] CustomWizard::Api::Authorization.set(api_params[:name], auth_data) end if api_params[:endpoints].is_a? String begin endpoints = JSON.parse(api_params[:endpoints]) - endpoints.each do |endpoint| - CustomWizard::Api::Endpoint.set(api_params[:name], endpoint) - end + endpoints.each { |endpoint| CustomWizard::Api::Endpoint.set(api_params[:name], endpoint) } rescue => e puts e end end end - render json: success_json.merge( - api: CustomWizard::ApiSerializer.new( - CustomWizard::Api.get(api_params[:name]), - root: false - ) - ) + render json: + success_json.merge( + api: + CustomWizard::ApiSerializer.new( + CustomWizard::Api.get(api_params[:name]), + root: false, + ), + ) end def remove @@ -67,14 +75,16 @@ def authorize result = CustomWizard::Api::Authorization.get_token(api_params[:name]) if result.instance_variable_defined?(:@error) - render json: failed_json.merge(message: result['error_description'] || result['error']) + render json: failed_json.merge(message: result["error_description"] || result["error"]) else - render json: success_json.merge( - api: CustomWizard::ApiSerializer.new( - CustomWizard::Api.get(api_params[:name]), - root: false - ) - ) + render json: + success_json.merge( + api: + CustomWizard::ApiSerializer.new( + CustomWizard::Api.get(api_params[:name]), + root: false, + ), + ) end end @@ -90,7 +100,7 @@ def redirect CustomWizard::Api::Authorization.set(params[:name], code: params[:code]) CustomWizard::Api::Authorization.get_token(params[:name]) - redirect_to path('/admin/wizards/apis/' + params[:name]) + redirect_to path("/admin/wizards/apis/" + params[:name]) end private @@ -98,20 +108,21 @@ def redirect def api_params params.require(:name) - data = params.permit( - :name, - :title, - :auth_type, - :auth_url, - :token_url, - :client_id, - :client_secret, - :username, - :password, - :auth_params, - :endpoints, - :new - ).to_h + data = + params.permit( + :name, + :title, + :auth_type, + :auth_url, + :token_url, + :client_id, + :client_secret, + :username, + :password, + :auth_params, + :endpoints, + :new, + ).to_h data[:name] = data[:name].underscore @@ -119,18 +130,21 @@ def api_params end def auth_data - auth_data = api_params.slice( - :auth_type, - :auth_url, - :token_url, - :client_id, - :client_secret, - :username, - :password, - :auth_params - ) + auth_data = + api_params.slice( + :auth_type, + :auth_url, + :token_url, + :client_id, + :client_secret, + :username, + :password, + :auth_params, + ) - auth_data[:auth_params] = JSON.parse(auth_data[:auth_params]) if auth_data[:auth_params].present? + auth_data[:auth_params] = JSON.parse(auth_data[:auth_params]) if auth_data[ + :auth_params + ].present? @auth_data ||= auth_data end diff --git a/app/controllers/custom_wizard/admin/custom_fields.rb b/app/controllers/custom_wizard/admin/custom_fields.rb index 111e9faf80..9cbadeb8ba 100644 --- a/app/controllers/custom_wizard/admin/custom_fields.rb +++ b/app/controllers/custom_wizard/admin/custom_fields.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController + requires_plugin "discourse-custom-wizard" + def index - render_json_dump( - custom_fields: custom_field_list - ) + render_json_dump(custom_fields: custom_field_list) end def update @@ -12,23 +12,24 @@ def update field_data = {} if saved_field = CustomWizard::CustomField.find(field_params[:id].to_i) - CustomWizard::CustomField::ATTRS.each do |attr| - field_data[attr] = saved_field.send(attr) - end + CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = saved_field.send(attr) } field_id = saved_field.id end - CustomWizard::CustomField::ATTRS.each do |attr| - field_data[attr] = field_params[attr] - end + CustomWizard::CustomField::ATTRS.each { |attr| field_data[attr] = field_params[attr] } field = CustomWizard::CustomField.new(field_id, field_data) PluginStoreRow.transaction do unless field.save - field_errors = field.errors.any? ? - field.errors.full_messages.join("\n\n") : - I18n.t("wizard.custom_field.error.save_default", name: field.name) + field_errors = + ( + if field.errors.any? + field.errors.full_messages.join("\n\n") + else + I18n.t("wizard.custom_field.error.save_default", name: field.name) + end + ) errors << field_errors raise ActiveRecord::Rollback.new end @@ -54,13 +55,6 @@ def destroy private def field_params - params.required(:custom_field) - .permit( - :id, - :name, - :klass, - :type, - serializers: [] - ) + params.required(:custom_field).permit(:id, :name, :klass, :type, serializers: []) end end diff --git a/app/controllers/custom_wizard/admin/logs.rb b/app/controllers/custom_wizard/admin/logs.rb index 7ca37bb206..38303fe7b7 100644 --- a/app/controllers/custom_wizard/admin/logs.rb +++ b/app/controllers/custom_wizard/admin/logs.rb @@ -1,44 +1,48 @@ # frozen_string_literal: true class CustomWizard::AdminLogsController < CustomWizard::AdminController before_action :find_wizard, except: [:index] + requires_plugin "discourse-custom-wizard" def index - render json: ActiveModel::ArraySerializer.new( - CustomWizard::Wizard.list(current_user), - each_serializer: CustomWizard::BasicWizardSerializer - ) + render json: + ActiveModel::ArraySerializer.new( + CustomWizard::Wizard.list(current_user), + each_serializer: CustomWizard::BasicWizardSerializer, + ) end def show render_json_dump( wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), - logs: ActiveModel::ArraySerializer.new( - log_list.logs, - each_serializer: CustomWizard::LogSerializer - ), - total: log_list.total + logs: + ActiveModel::ArraySerializer.new( + log_list.logs, + each_serializer: CustomWizard::LogSerializer, + ), + total: log_list.total, ) end protected def log_list - @log_list ||= begin - list = CustomWizard::Log.list(params[:page].to_i, params[:limit].to_i, params[:wizard_id]) + @log_list ||= + begin + list = CustomWizard::Log.list(params[:page].to_i, params[:limit].to_i, params[:wizard_id]) - if list.logs.any? && (usernames = list.logs.map(&:username)).present? - user_map = User.where(username: usernames) - .reduce({}) do |result, user| - result[user.username] = user - result - end + if list.logs.any? && (usernames = list.logs.map(&:username)).present? + user_map = + User + .where(username: usernames) + .reduce({}) do |result, user| + result[user.username] = user + result + end - list.logs.each do |log_item| - log_item.user = user_map[log_item.username] + list.logs.each { |log_item| log_item.user = user_map[log_item.username] } end - end - list - end + list + end end end diff --git a/app/controllers/custom_wizard/admin/manager.rb b/app/controllers/custom_wizard/admin/manager.rb index 7dcc662c13..b8a06011dc 100644 --- a/app/controllers/custom_wizard/admin/manager.rb +++ b/app/controllers/custom_wizard/admin/manager.rb @@ -2,6 +2,7 @@ class CustomWizard::AdminManagerController < CustomWizard::AdminController skip_before_action :check_xhr, only: [:export] before_action :get_wizard_ids, except: [:import] + requires_plugin "discourse-custom-wizard" def export templates = [] @@ -12,38 +13,32 @@ def export end end - if templates.empty? - return render_error(I18n.t('wizard.export.error.invalid_wizards')) - end + return render_error(I18n.t("wizard.export.error.invalid_wizards")) if templates.empty? - basename = SiteSetting.title.parameterize || 'discourse' + basename = SiteSetting.title.parameterize || "discourse" time = Time.now.to_i filename = "#{basename}-wizards-#{time}.json" send_data templates.to_json, - type: "application/json", - disposition: 'attachment', - filename: filename + type: "application/json", + disposition: "attachment", + filename: filename end def import - file = File.read(params['file'].tempfile) + file = File.read(params["file"].tempfile) - if file.nil? - return render_error(I18n.t('wizard.export.error.no_file')) - end + return render_error(I18n.t("wizard.export.error.no_file")) if file.nil? file_size = file.size max_file_size = 512 * 1024 - if max_file_size < file_size - return render_error(I18n.t('wizard.import.error.file_large')) - end + return render_error(I18n.t("wizard.import.error.file_large")) if max_file_size < file_size begin template_json = JSON.parse(file) rescue JSON::ParserError - return render_error(I18n.t('wizard.import.error.invalid_json')) + return render_error(I18n.t("wizard.import.error.invalid_json")) end imported = [] @@ -55,22 +50,13 @@ def import template.save(skip_jobs: true, create: true) if template.errors.any? - failures.push( - id: template.data['id'], - messages: template.errors.full_messages.join(', ') - ) + failures.push(id: template.data["id"], messages: template.errors.full_messages.join(", ")) else - imported.push( - id: template.data['id'], - name: template.data['name'] - ) + imported.push(id: template.data["id"], name: template.data["name"]) end end - render json: success_json.merge( - imported: imported, - failures: failures - ) + render json: success_json.merge(imported: imported, failures: failures) end def destroy @@ -81,44 +67,34 @@ def destroy template = CustomWizard::Template.find(wizard_id) if template && CustomWizard::Template.remove(wizard_id) - destroyed.push( - id: wizard_id, - name: template['name'] - ) + destroyed.push(id: wizard_id, name: template["name"]) else failures.push( id: wizard_id, - messages: I18n.t("wizard.destroy.error.#{template ? 'default' : 'no_template'}") + messages: I18n.t("wizard.destroy.error.#{template ? "default" : "no_template"}"), ) end end - render json: success_json.merge( - destroyed: destroyed, - failures: failures - ) + render json: success_json.merge(destroyed: destroyed, failures: failures) end private def get_wizard_ids - if params['wizard_ids'].blank? - return render_error(I18n.t('wizard.export.error.select_one')) - end + return render_error(I18n.t("wizard.export.error.select_one")) if params["wizard_ids"].blank? wizard_ids = [] - params['wizard_ids'].each do |wizard_id| + params["wizard_ids"].each do |wizard_id| begin wizard_ids.push(wizard_id.underscore) - rescue + rescue StandardError # end end - if wizard_ids.empty? - return render_error(I18n.t('wizard.export.error.invalid_wizards')) - end + return render_error(I18n.t("wizard.export.error.invalid_wizards")) if wizard_ids.empty? @wizard_ids = wizard_ids end diff --git a/app/controllers/custom_wizard/admin/submissions.rb b/app/controllers/custom_wizard/admin/submissions.rb index d5994c96f0..50aff42e29 100644 --- a/app/controllers/custom_wizard/admin/submissions.rb +++ b/app/controllers/custom_wizard/admin/submissions.rb @@ -2,35 +2,39 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController skip_before_action :preload_json, :check_xhr, only: [:download] before_action :find_wizard, except: [:index] + requires_plugin "discourse-custom-wizard" def index - render json: ActiveModel::ArraySerializer.new( - CustomWizard::Wizard.list(current_user), - each_serializer: CustomWizard::BasicWizardSerializer - ) + render json: + ActiveModel::ArraySerializer.new( + CustomWizard::Wizard.list(current_user), + each_serializer: CustomWizard::BasicWizardSerializer, + ) end def show render_json_dump( wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), - submissions: ActiveModel::ArraySerializer.new( - submission_list.submissions, - each_serializer: CustomWizard::SubmissionSerializer - ), - total: submission_list.total + submissions: + ActiveModel::ArraySerializer.new( + submission_list.submissions, + each_serializer: CustomWizard::SubmissionSerializer, + ), + total: submission_list.total, ) end def download - content = ActiveModel::ArraySerializer.new( - CustomWizard::Submission.list(@wizard).submissions, - each_serializer: CustomWizard::SubmissionSerializer - ) + content = + ActiveModel::ArraySerializer.new( + CustomWizard::Submission.list(@wizard).submissions, + each_serializer: CustomWizard::SubmissionSerializer, + ) send_data content.to_json, - filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", - content_type: "application/json", - disposition: "attachment" + filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", + content_type: "application/json", + disposition: "attachment" end protected diff --git a/app/controllers/custom_wizard/admin/subscription.rb b/app/controllers/custom_wizard/admin/subscription.rb index 7b596ec66f..a055b44a23 100644 --- a/app/controllers/custom_wizard/admin/subscription.rb +++ b/app/controllers/custom_wizard/admin/subscription.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class CustomWizard::SubscriptionController < ::Admin::AdminController before_action :ensure_admin + requires_plugin "discourse-custom-wizard" def index if params[:update_from_remote] diff --git a/app/controllers/custom_wizard/admin/user.rb b/app/controllers/custom_wizard/admin/user.rb new file mode 100644 index 0000000000..77452c6b80 --- /dev/null +++ b/app/controllers/custom_wizard/admin/user.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +class CustomWizard::UserController < ::Admin::AdminController + before_action :ensure_admin + requires_plugin "discourse-custom-wizard" + + def clear_redirect + user = User.find_by(id: params[:id]) + + if user + user.custom_fields["redirect_to_wizard"] = nil + user.save_custom_fields(true) + render json: success_json + else + render json: failed_json + end + end +end diff --git a/app/controllers/custom_wizard/admin/wizard.rb b/app/controllers/custom_wizard/admin/wizard.rb index 08e7b6d01d..9c297b3654 100644 --- a/app/controllers/custom_wizard/admin/wizard.rb +++ b/app/controllers/custom_wizard/admin/wizard.rb @@ -1,16 +1,18 @@ # frozen_string_literal: true class CustomWizard::AdminWizardController < CustomWizard::AdminController - before_action :find_wizard, only: [:show, :remove] + before_action :find_wizard, only: %i[show remove] + requires_plugin "discourse-custom-wizard" def index render_json_dump( - wizard_list: ActiveModel::ArraySerializer.new( - CustomWizard::Wizard.list(current_user), - each_serializer: CustomWizard::BasicWizardSerializer - ), + wizard_list: + ActiveModel::ArraySerializer.new( + CustomWizard::Wizard.list(current_user), + each_serializer: CustomWizard::BasicWizardSerializer, + ), field_types: CustomWizard::Field.types, realtime_validations: CustomWizard::RealtimeValidation.types, - custom_fields: custom_field_list + custom_fields: custom_field_list, ) end @@ -37,7 +39,10 @@ def save wizard_id = template.save(create: params[:create]) if template.errors.any? - render json: failed_json.merge(backend_validation_error: template.errors.full_messages.join("\n\n")) + render json: + failed_json.merge( + backend_validation_error: template.errors.full_messages.join("\n\n"), + ) else render json: success_json.merge(wizard_id: wizard_id) end @@ -52,16 +57,7 @@ def mapped_params :output, :output_type, :output_connector, - pairs: [ - :index, - :key, - :key_type, - :value, - :value_type, - :connector, - value: [], - key: [], - ], + pairs: [:index, :key, :key_type, :value, :value_type, :connector, value: [], key: []], output: [], ] end @@ -82,6 +78,7 @@ def save_wizard_params :resume_on_revisit, :theme_id, permitted: mapped_params, + after_time_groups: [], steps: [ :id, :index, @@ -115,13 +112,15 @@ def save_wizard_params :preview_template, :placeholder, :can_create_tag, + :category, prefill: mapped_params, content: mapped_params, condition: mapped_params, index: mapped_params, - validations: {}, + validations: { + }, tag_groups: [], - ] + ], ], actions: [ :id, @@ -144,6 +143,8 @@ def save_wizard_params custom_fields: mapped_params, visible: mapped_params, required: mapped_params, + poster: mapped_params, + guest_email: mapped_params, recipient: mapped_params, categories: mapped_params, mute_remainder: mapped_params, @@ -166,8 +167,8 @@ def save_wizard_params visibility_level: mapped_params, members_visibility_level: mapped_params, add_event: mapped_params, - add_location: mapped_params - ] + add_location: mapped_params, + ], ) end end diff --git a/app/controllers/custom_wizard/realtime_validations.rb b/app/controllers/custom_wizard/realtime_validations.rb index 5a4c71b6ce..d78c81ff1b 100644 --- a/app/controllers/custom_wizard/realtime_validations.rb +++ b/app/controllers/custom_wizard/realtime_validations.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class CustomWizard::RealtimeValidationsController < ::ApplicationController + requires_plugin "discourse-custom-wizard" + def validate klass_str = "CustomWizard::RealtimeValidation::#{validation_params[:type].camelize}" result = klass_str.constantize.new(current_user).perform(validation_params) diff --git a/app/controllers/custom_wizard/steps.rb b/app/controllers/custom_wizard/steps.rb index 2a4305c7f1..d02fecd545 100644 --- a/app/controllers/custom_wizard/steps.rb +++ b/app/controllers/custom_wizard/steps.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class CustomWizard::StepsController < ::CustomWizard::WizardClientController before_action :ensure_can_update + requires_plugin "discourse-custom-wizard" def update update = update_params.to_h @@ -8,9 +9,7 @@ def update update[:fields] = {} if params[:fields] field_ids = @builder.wizard.field_ids - params[:fields].each do |k, v| - update[:fields][k] = v if field_ids.include? k - end + params[:fields].each { |k, v| update[:fields][k] = v if field_ids.include? k } end @builder.build @@ -34,16 +33,15 @@ def update if current_step.final? builder.template.actions.each do |action_template| - if action_template['run_after'] === 'wizard_completion' - action_result = CustomWizard::Action.new( - action: action_template, - wizard: @wizard, - submission: current_submission - ).perform - - if action_result.success? - current_submission = action_result.submission - end + if action_template["run_after"] === "wizard_completion" + action_result = + CustomWizard::Action.new( + action: action_template, + wizard: @wizard, + submission: current_submission, + ).perform + + current_submission = action_result.submission if action_result.success? end end @@ -68,14 +66,14 @@ def update result[:wizard] = ::CustomWizard::WizardSerializer.new( @wizard, scope: Guardian.new(current_user), - root: false + root: false, ).as_json render json: result else errors = [] updater.errors.messages.each do |field, msg| - errors << { field: field, description: msg.join(',') } + errors << { field: field, description: msg.join(",") } end render json: { errors: errors }, status: 422 end @@ -87,26 +85,25 @@ def ensure_can_update raise Discourse::InvalidParameters.new(:wizard_id) if @builder.template.nil? raise Discourse::InvalidAccess.new if !@builder.wizard || !@builder.wizard.can_access? - @step_template = @builder.template.steps.select do |s| - s['id'] == update_params[:step_id] - end.first + @step_template = @builder.template.steps.select { |s| s["id"] == update_params[:step_id] }.first raise Discourse::InvalidParameters.new(:step_id) if !@step_template raise Discourse::InvalidAccess.new if !@builder.check_condition(@step_template) end def update_params - @update_params || begin - params.require(:step_id) - params.require(:wizard_id) - params.permit(:wizard_id, :step_id).transform_values { |v| v.underscore } - end + @update_params || + begin + params.require(:step_id) + params.require(:wizard_id) + params.permit(:wizard_id, :step_id).transform_values { |v| v.underscore } + end end def get_redirect return @result[:redirect_on_next] if @result[:redirect_on_next].present? submission = @wizard.current_submission - return nil unless submission.present? + return nil if submission.blank? ## route_to set by actions, redirect_on_complete set by actions, redirect_to set at wizard entry submission.route_to || submission.redirect_on_complete || submission.redirect_to end diff --git a/app/controllers/custom_wizard/wizard.rb b/app/controllers/custom_wizard/wizard.rb index dd4ea4ca3b..dcd55b3bcb 100644 --- a/app/controllers/custom_wizard/wizard.rb +++ b/app/controllers/custom_wizard/wizard.rb @@ -1,10 +1,13 @@ # frozen_string_literal: true class CustomWizard::WizardController < ::CustomWizard::WizardClientController + requires_plugin "discourse-custom-wizard" + def show if wizard.present? - render json: CustomWizard::WizardSerializer.new(wizard, scope: guardian, root: false).as_json, status: 200 + render json: CustomWizard::WizardSerializer.new(wizard, scope: guardian, root: false).as_json, + status: 200 else - render json: { error: I18n.t('wizard.none') } + render json: { error: I18n.t("wizard.none") } end end @@ -12,10 +15,10 @@ def skip params.require(:wizard_id) if wizard.required && !wizard.completed? && wizard.permitted? - return render json: { error: I18n.t('wizard.no_skip') } + return render json: { error: I18n.t("wizard.no_skip") } end - result = { success: 'OK' } + result = { success: "OK" } if current_user && wizard.can_access? if redirect_to = wizard.current_submission&.redirect_to @@ -31,9 +34,10 @@ def skip protected def wizard - @wizard ||= begin - return nil unless @builder.present? - @builder.build({ reset: params[:reset] }, params) - end + @wizard ||= + begin + return nil if @builder.blank? + @builder.build({ reset: params[:reset] }, params) + end end end diff --git a/app/controllers/custom_wizard/wizard_client.rb b/app/controllers/custom_wizard/wizard_client.rb index e898852ab3..ed94270ee6 100644 --- a/app/controllers/custom_wizard/wizard_client.rb +++ b/app/controllers/custom_wizard/wizard_client.rb @@ -2,13 +2,12 @@ class CustomWizard::WizardClientController < ::ApplicationController before_action :ensure_plugin_enabled before_action :set_builder + requires_plugin "discourse-custom-wizard" private def ensure_plugin_enabled - unless SiteSetting.custom_wizard_enabled - redirect_to path("/") - end + redirect_to path("/") unless SiteSetting.custom_wizard_enabled end def guest_id diff --git a/app/jobs/regular/set_after_time_wizard.rb b/app/jobs/regular/set_after_time_wizard.rb index a8935c8a12..15077e0e08 100644 --- a/app/jobs/regular/set_after_time_wizard.rb +++ b/app/jobs/regular/set_after_time_wizard.rb @@ -3,22 +3,32 @@ module Jobs class SetAfterTimeWizard < ::Jobs::Base def execute(args) if SiteSetting.custom_wizard_enabled - wizard = CustomWizard::Wizard.create(args[:wizard_id]) + @wizard = CustomWizard::Wizard.create(args[:wizard_id]) - if wizard && wizard.after_time + if @wizard && @wizard.after_time user_ids = [] - User.human_users.each do |user| - if CustomWizard::Wizard.set_user_redirect(wizard.id, user) - user_ids.push(user.id) - end + target_users.each do |user| + user_ids.push(user.id) if CustomWizard::Wizard.set_after_time_redirect(@wizard.id, user) end CustomWizard::Template.clear_cache_keys - MessageBus.publish "/redirect_to_wizard", wizard.id, user_ids: user_ids + MessageBus.publish "/redirect_to_wizard", @wizard.id, user_ids: user_ids end end end + + def target_users + users = [] + + if @wizard.after_time_groups.exists? + @wizard.after_time_groups.each { |group| users += group.users } + else + users = User.human_users + end + + users + end end end diff --git a/app/serializers/custom_wizard/api/basic_endpoint_serializer.rb b/app/serializers/custom_wizard/api/basic_endpoint_serializer.rb index 2c81f9e8d8..65ee0f679b 100644 --- a/app/serializers/custom_wizard/api/basic_endpoint_serializer.rb +++ b/app/serializers/custom_wizard/api/basic_endpoint_serializer.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true class CustomWizard::Api::BasicEndpointSerializer < ::ApplicationSerializer - attributes :id, - :name + attributes :id, :name end diff --git a/app/serializers/custom_wizard/api/endpoint_serializer.rb b/app/serializers/custom_wizard/api/endpoint_serializer.rb index 99af63c3ab..67150e3234 100644 --- a/app/serializers/custom_wizard/api/endpoint_serializer.rb +++ b/app/serializers/custom_wizard/api/endpoint_serializer.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true class CustomWizard::Api::EndpointSerializer < ::ApplicationSerializer - attributes :id, - :name, - :method, - :url, - :content_type, - :success_codes + attributes :id, :name, :method, :url, :content_type, :success_codes def method - object.send('method') + object.send("method") end end diff --git a/app/serializers/custom_wizard/api_serializer.rb b/app/serializers/custom_wizard/api_serializer.rb index 0bf5707d93..8296c22c01 100644 --- a/app/serializers/custom_wizard/api_serializer.rb +++ b/app/serializers/custom_wizard/api_serializer.rb @@ -1,35 +1,25 @@ # frozen_string_literal: true class CustomWizard::ApiSerializer < ::ApplicationSerializer - attributes :name, - :title, - :authorization, - :endpoints, - :log + attributes :name, :title, :authorization, :endpoints, :log def authorization if authorization = CustomWizard::Api::Authorization.get(object.name) - CustomWizard::Api::AuthorizationSerializer.new( - authorization, - root: false - ) + CustomWizard::Api::AuthorizationSerializer.new(authorization, root: false) end end def endpoints if endpoints = CustomWizard::Api::Endpoint.list(object.name) ActiveModel::ArraySerializer.new( - endpoints, - each_serializer: CustomWizard::Api::EndpointSerializer + endpoints, + each_serializer: CustomWizard::Api::EndpointSerializer, ) end end def log if log = CustomWizard::Api::LogEntry.list(object.name) - ActiveModel::ArraySerializer.new( - log, - each_serializer: CustomWizard::Api::LogSerializer - ) + ActiveModel::ArraySerializer.new(log, each_serializer: CustomWizard::Api::LogSerializer) end end end diff --git a/app/serializers/custom_wizard/basic_api_serializer.rb b/app/serializers/custom_wizard/basic_api_serializer.rb index 56094b4917..52531552cf 100644 --- a/app/serializers/custom_wizard/basic_api_serializer.rb +++ b/app/serializers/custom_wizard/basic_api_serializer.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true class CustomWizard::BasicApiSerializer < ::ApplicationSerializer - attributes :name, - :title, - :endpoints + attributes :name, :title, :endpoints def endpoints if endpoints = CustomWizard::Api::Endpoint.list(object.name) ActiveModel::ArraySerializer.new( - endpoints, - each_serializer: CustomWizard::Api::BasicEndpointSerializer + endpoints, + each_serializer: CustomWizard::Api::BasicEndpointSerializer, ) end end diff --git a/app/serializers/custom_wizard/log_serializer.rb b/app/serializers/custom_wizard/log_serializer.rb index 56c5fd8f58..da556437f0 100644 --- a/app/serializers/custom_wizard/log_serializer.rb +++ b/app/serializers/custom_wizard/log_serializer.rb @@ -1,10 +1,7 @@ # frozen_string_literal: true class CustomWizard::LogSerializer < ApplicationSerializer - attributes :date, - :action, - :username, - :message + attributes :date, :action, :username, :message has_one :user, serializer: ::BasicUserSerializer, embed: :objects end diff --git a/app/serializers/custom_wizard/submission_serializer.rb b/app/serializers/custom_wizard/submission_serializer.rb index ed9ad411ce..9d329ec810 100644 --- a/app/serializers/custom_wizard/submission_serializer.rb +++ b/app/serializers/custom_wizard/submission_serializer.rb @@ -1,9 +1,6 @@ # frozen_string_literal: true class CustomWizard::SubmissionSerializer < ApplicationSerializer - attributes :id, - :fields, - :submitted_at, - :user + attributes :id, :fields, :submitted_at, :user def include_user? object.wizard.user.present? @@ -14,22 +11,19 @@ def user end def fields - @fields ||= begin - result = {} + @fields ||= + begin + result = {} - object.wizard.template['steps'].each do |step| - step['fields'].each do |field| - if value = object.fields[field['id']] - result[field['id']] = { - value: value, - type: field['type'], - label: field['label'] - } - end - end - end + object.wizard.template["steps"].each do |step| + step["fields"].each do |field| + if value = object.fields[field["id"]] + result[field["id"]] = { value: value, type: field["type"], label: field["label"] } + end + end + end - result - end + result + end end end diff --git a/app/serializers/custom_wizard/wizard_field_serializer.rb b/app/serializers/custom_wizard/wizard_field_serializer.rb index 56e86cc89c..7312595bb7 100644 --- a/app/serializers/custom_wizard/wizard_field_serializer.rb +++ b/app/serializers/custom_wizard/wizard_field_serializer.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class CustomWizard::FieldSerializer < ::ApplicationSerializer - attributes :id, :index, :type, @@ -18,6 +17,7 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer :content, :tag_groups, :can_create_tag, + :category, :validations, :max_length, :char_counter, @@ -108,7 +108,9 @@ def validations object.validations&.each do |type, props| next unless props["status"] validations[props["position"]] ||= {} - validations[props["position"]][type] = props.merge CustomWizard::RealtimeValidation.types[type.to_sym] + validations[props["position"]][type] = props.merge CustomWizard::RealtimeValidation.types[ + type.to_sym + ] end validations diff --git a/app/serializers/custom_wizard/wizard_serializer.rb b/app/serializers/custom_wizard/wizard_serializer.rb index 9741d7af64..9c3c2ac238 100644 --- a/app/serializers/custom_wizard/wizard_serializer.rb +++ b/app/serializers/custom_wizard/wizard_serializer.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer - attributes :start, :background, :submission_last_updated_at, @@ -20,8 +19,8 @@ def completed def include_completed? object.completed? && - (!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) && - !scope.is_admin? + (!object.respond_to?(:multiple_submissions) || !object.multiple_submissions) && + !scope.is_admin? end def permitted diff --git a/app/serializers/custom_wizard/wizard_step_serializer.rb b/app/serializers/custom_wizard/wizard_step_serializer.rb index a2a314a4f5..e5eab4f5e5 100644 --- a/app/serializers/custom_wizard/wizard_step_serializer.rb +++ b/app/serializers/custom_wizard/wizard_step_serializer.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class CustomWizard::StepSerializer < ::ApplicationSerializer - attributes :id, :index, :next, diff --git a/assets/javascripts/discourse/templates/components/custom-field-input.hbs b/assets/javascripts/discourse/components/custom-field-input.hbs similarity index 57% rename from assets/javascripts/discourse/templates/components/custom-field-input.hbs rename to assets/javascripts/discourse/components/custom-field-input.hbs index 4e3fa2f0c2..faca668228 100644 --- a/assets/javascripts/discourse/templates/components/custom-field-input.hbs +++ b/assets/javascripts/discourse/components/custom-field-input.hbs @@ -1,19 +1,19 @@ -{{#if showInputs}} +{{#if this.showInputs}} {{wizard-subscription-selector - value=field.klass + value=this.field.klass feature="custom_field" attribute="klass" - onChange=(action (mut field.klass)) + onChange=(action (mut this.field.klass)) options=(hash none="admin.wizard.custom_field.klass.select") }} {{wizard-subscription-selector - value=field.type + value=this.field.type feature="custom_field" attribute="type" - onChange=(action (mut field.type)) + onChange=(action (mut this.field.type)) options=(hash none="admin.wizard.custom_field.type.select") }} @@ -25,48 +25,52 @@ {{multi-select - value=field.serializers - content=serializerContent - onChange=(action (mut field.serializers)) + value=this.field.serializers + content=this.serializerContent + onChange=(action (mut this.field.serializers)) options=(hash none="admin.wizard.custom_field.serializers.select") }} - {{#if loading}} + {{#if this.loading}} {{loading-spinner size="small"}} {{else}} - {{#if saveIcon}} - {{d-icon saveIcon}} + {{#if this.saveIcon}} + {{d-icon this.saveIcon}} {{/if}} {{/if}} {{d-button action=(action "destroy") - icon="trash-alt" + icon="trash-can" class="destroy" - disabled=destroyDisabled + disabled=this.destroyDisabled }} {{d-button - icon="save" + icon="floppy-disk" action=(action "save") - disabled=saveDisabled + disabled=this.saveDisabled class="save" }} - {{d-button action=(action "close") icon="times" disabled=closeDisabled}} + {{d-button + action=(action "close") + icon="xmark" + disabled=this.closeDisabled + }} {{else}} - - - + + + - {{#if isExternal}} + {{#if this.isExternal}} — {{else}} - {{#each field.serializers as |serializer|}} + {{#each this.field.serializers as |serializer|}} {{/each}} {{/if}} - {{#if isExternal}} + {{#if this.isExternal}}