From 04198339caf64923f4254bb8d8adeba281bb235a Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Wed, 15 Apr 2020 10:46:44 +1000 Subject: [PATCH] Action logging and submissions bugixs --- .../components/wizard-custom-action.js.es6 | 3 +- .../controllers/admin-wizards-logs.js.es6 | 52 +++++++++++++++++ .../custom-wizard-admin-route-map.js.es6 | 2 + .../templates/admin-wizards-logs.hbs | 28 +++++++++ .../discourse/templates/admin-wizards.hbs | 1 + .../components/wizard-custom-action.hbs | 6 +- .../components/wizard-mapper-selector.hbs | 2 +- assets/stylesheets/common/wizard-admin.scss | 10 ++-- config/locales/client.en.yml | 3 + config/locales/server.en.yml | 3 +- config/routes.rb | 2 + config/settings.yml | 2 - controllers/custom_wizard/admin/logs.rb | 8 +++ .../custom_wizard/admin/submissions.rb | 8 ++- lib/custom_wizard/{actions.rb => action.rb} | 58 +++++++++++-------- lib/custom_wizard/builder.rb | 1 + lib/custom_wizard/log.rb | 38 ++++++++++++ plugin.rb | 5 +- serializers/custom_wizard/log_serializer.rb | 3 + 19 files changed, 193 insertions(+), 42 deletions(-) create mode 100644 assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 create mode 100644 assets/javascripts/discourse/templates/admin-wizards-logs.hbs create mode 100644 controllers/custom_wizard/admin/logs.rb rename lib/custom_wizard/{actions.rb => action.rb} (84%) create mode 100644 lib/custom_wizard/log.rb create mode 100644 serializers/custom_wizard/log_serializer.rb diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 index 8f5a6103..dbb55f8f 100644 --- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 @@ -1,5 +1,5 @@ import { default as discourseComputed, observes, on } from 'discourse-common/utils/decorators'; -import { equal, empty, or } from "@ember/object/computed"; +import { equal, empty, or, notEmpty } from "@ember/object/computed"; import { generateName, selectKitContent, schema } from '../lib/wizard'; import Component from "@ember/component"; @@ -20,6 +20,7 @@ export default Component.extend({ basicTopicFields: or('createTopic', 'sendMessage', 'openComposer'), publicTopicFields: or('createTopic', 'openComposer'), showSkipRedirect: or('createTopic', 'sendMessage'), + showPostBuilder: notEmpty('action.post_template'), @discourseComputed('wizard.steps') runAfterContent(steps) { diff --git a/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 new file mode 100644 index 00000000..aebc5d00 --- /dev/null +++ b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 @@ -0,0 +1,52 @@ +import { default as computed } from 'discourse-common/utils/decorators'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; +import { ajax } from 'discourse/lib/ajax'; +import { notEmpty } from "@ember/object/computed"; + +export default Ember.Controller.extend({ + refreshing: false, + hasLogs: notEmpty("logs"), + page: 0, + canLoadMore: true, + logs: [], + + loadLogs() { + if (!this.canLoadMore) return; + + this.set("refreshing", true); + + ajax('/admin/wizards/logs', { + data: { + page: this.page + } + }).catch(popupAjaxError) + .then(result => { + if (!result || result.length === 0) { + this.set('canLoadMore', false); + } + this.set("logs", this.logs.concat(result)); + }) + .finally(() => this.set("refreshing", false)); + }, + + @computed('hasLogs', 'refreshing') + noResults(hasLogs, refreshing) { + return !hasLogs && !refreshing; + }, + + actions: { + loadMore() { + this.set('page', this.page += 1); + this.loadLogs(); + }, + + refresh() { + this.setProperties({ + canLoadMore: true, + page: 0, + logs: [] + }) + this.loadLogs(); + } + } +}); \ No newline at end of file diff --git a/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 b/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 index 66cdacea..c2722816 100644 --- a/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 +++ b/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6 @@ -14,6 +14,8 @@ export default { this.route('adminWizardsApi', { path: '/api', resetNamespace: true }, function() { this.route('adminWizardsApiShow', { path: '/:name', resetNamespace: true }); }); + + this.route('adminWizardsLogs', { path: '/logs', resetNamespace: true }); this.route('adminWizardsTransfer', { path: '/transfer', resetNamespace: true }); }); diff --git a/assets/javascripts/discourse/templates/admin-wizards-logs.hbs b/assets/javascripts/discourse/templates/admin-wizards-logs.hbs new file mode 100644 index 00000000..5843bb7b --- /dev/null +++ b/assets/javascripts/discourse/templates/admin-wizards-logs.hbs @@ -0,0 +1,28 @@ +
+ {{d-button label="refresh" icon="refresh" action="refresh"}} +
+ +{{#load-more selector=".log-list tr" action=(action "loadMore")}} + {{#if noResults}} +

{{i18n 'search.no_results'}}

+ {{else}} + + + + + + + + + {{#each logs as |log|}} + + + + + {{/each}} + +
MessageDate
{{log.message}}{{bound-date log.date}}
+ {{/if}} + + {{conditional-loading-spinner condition=refreshing}} +{{/load-more}} \ No newline at end of file diff --git a/assets/javascripts/discourse/templates/admin-wizards.hbs b/assets/javascripts/discourse/templates/admin-wizards.hbs index 102ffcde..c5e8a0d4 100644 --- a/assets/javascripts/discourse/templates/admin-wizards.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards.hbs @@ -4,6 +4,7 @@ {{#if siteSettings.wizard_api_features}} {{nav-item route='adminWizardsApis' label='admin.wizard.api.nav_label'}} {{/if}} + {{nav-item route='adminWizardsLogs' label='admin.wizard.log.nav_label'}} {{nav-item route='adminWizardsTransfer' label='admin.wizard.transfer.nav_label'}} {{/admin-nav}} diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index 32083f03..87a16589 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -57,17 +57,17 @@ onChange=(action (mut action.post)) options=(hash none='admin.wizard.selector.placeholder.wizard_field' - isDisabled=action.post_builder + isDisabled=showPostBuilder )}}
- {{input type='checkbox' checked=action.post_builder}} + {{input type='checkbox' checked=showPostBuilder}} {{i18n 'admin.wizard.action.post_builder.checkbox'}}
- {{#if action.post_builder}} + {{#if showPostBuilder}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-mapper-selector.hbs b/assets/javascripts/discourse/templates/components/wizard-mapper-selector.hbs index b0c0d8fd..7b71756b 100644 --- a/assets/javascripts/discourse/templates/components/wizard-mapper-selector.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-mapper-selector.hbs @@ -54,9 +54,9 @@ {{#if showTag}} {{tag-chooser tags=value - filterable=true options=(hash none=placeholderKey + filterable=true )}} {{/if}} diff --git a/assets/stylesheets/common/wizard-admin.scss b/assets/stylesheets/common/wizard-admin.scss index 750957a5..d165d9e8 100644 --- a/assets/stylesheets/common/wizard-admin.scss +++ b/assets/stylesheets/common/wizard-admin.scss @@ -24,12 +24,10 @@ .admin-wizard-container { margin-top: 20px; - - .row > .content table { - margin-top: 0; - min-width: 100%; - width: auto; - } +} + +.wizard-submissions { + overflow: scroll; } .wizard-settings-parent { diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index e4074ea4..68e5da9a 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -260,6 +260,9 @@ en: log: label: "Logs" + + log: + nav_label: "Logs" transfer: nav_label: "Transfer" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 8932633a..58332e3c 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -30,5 +30,4 @@ en: wizard_redirect_exclude_paths: "Routes excluded from wizard redirects." wizard_recognised_image_upload_formats: "File types which will result in upload displaying an image preview" wizard_step_advanced: "Enable advanced settings for wizard steps (experimental)." - wizard_api_features: "Enable API features (experimental)." - wizard_action_debug: "Log action details for debugging." \ No newline at end of file + wizard_api_features: "Enable API features (experimental)." \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 539d8b92..2b19912f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,6 +32,8 @@ Discourse::Application.routes.append do get 'admin/wizards/apis/:name/redirect' => 'admin_api#redirect' get 'admin/wizards/apis/:name/authorize' => 'admin_api#authorize' + get 'admin/wizards/logs' => 'admin_logs#index' + get 'admin/wizards/transfer' => 'transfer#index' get 'admin/wizards/transfer/export' => 'transfer#export' post 'admin/wizards/transfer/import' => 'transfer#import' diff --git a/config/settings.yml b/config/settings.yml index 6b3458e0..a8764415 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -20,6 +20,4 @@ plugins: default: false wizard_api_features: client: true - default: false - wizard_action_debug: default: false \ No newline at end of file diff --git a/controllers/custom_wizard/admin/logs.rb b/controllers/custom_wizard/admin/logs.rb new file mode 100644 index 00000000..60303af7 --- /dev/null +++ b/controllers/custom_wizard/admin/logs.rb @@ -0,0 +1,8 @@ +class CustomWizard::AdminLogsController < CustomWizard::AdminController + def index + render_serialized( + CustomWizard::Log.list(params[:page].to_i), + CustomWizard::LogSerializer + ) + end +end \ No newline at end of file diff --git a/controllers/custom_wizard/admin/submissions.rb b/controllers/custom_wizard/admin/submissions.rb index 28dbe553..b7d45e44 100644 --- a/controllers/custom_wizard/admin/submissions.rb +++ b/controllers/custom_wizard/admin/submissions.rb @@ -1,5 +1,6 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController - skip_before_action :check_xhr, only: [:download_submissions] + skip_before_action :preload_json, :check_xhr, only: [:download] + before_action :find_wizard def index @@ -23,8 +24,9 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController def download send_data build_submissions(@wizard.id).to_json, - filename: "#{Discourse.current_hostname}-wizard-submissions-#{wizard['name']}.json", - content_type: "application/json" + filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", + content_type: "application/json", + disposition: "attachment" end private diff --git a/lib/custom_wizard/actions.rb b/lib/custom_wizard/action.rb similarity index 84% rename from lib/custom_wizard/actions.rb rename to lib/custom_wizard/action.rb index 3708b906..59172283 100644 --- a/lib/custom_wizard/actions.rb +++ b/lib/custom_wizard/action.rb @@ -6,27 +6,29 @@ class CustomWizard::Action :result def initialize(params) + @wizard = params[:wizard] @action = params[:action] @user = params[:user] @data = params[:data] @updater = params[:updater] + @log = [] end def perform ActiveRecord::Base.transaction do self.send(action['type'].to_sym) - - if SiteSetting.wizard_action_debug - log = "action: #{action['type']}; " - log << "result: #{@result}" - - updater.errors.messages.each do |field, msg| - log << "error: #{field.to_s}; #{msg.to_s}; " - end - - Rails.logger.warn("Wizard Action: #{log.to_s}") + end + + log = "wizard: #{@wizard.id}; action: #{action['type']}; user: #{user.username}" + + if @log.any? + @log.each do |item| + log << "; result: " + log << item.to_s end end + + CustomWizard::Log.create(log) end def mapper @@ -44,17 +46,18 @@ class CustomWizard::Action post = creator.create if creator.errors.present? - @result = "failed to create" - updater.errors.add(:create_topic, creator.errors.full_messages.join(" ")) + messages = creator.errors.full_messages.join(" ") + log_error("failed to create", messages) + updater.errors.add(:create_topic, messages) elsif action['skip_redirect'].blank? data['redirect_on_complete'] = post.topic.url end if creator.errors.blank? - @result = "success (created topic: #{post.topic.id})" + log_success("created topic", post.topic.id) end else - @result = "invalid params" + log_error("invalid topic params") end end @@ -75,17 +78,18 @@ class CustomWizard::Action post = creator.create if creator.errors.present? - @result = "failed to create" - updater.errors.add(:send_message, creator.errors.full_messages.join(" ")) + messages = creator.errors.full_messages.join(" ") + log_error("failed to create message", messages) + updater.errors.add(:send_message, messages) elsif action['skip_redirect'].blank? data['redirect_on_complete'] = post.topic.url end if creator.errors.blank? - @result = "success (created pm: #{post.topic.id})" + log_error("created message", post.topic.id) end else - @result = "invalid params" + log_error("invalid message params") end end @@ -111,12 +115,12 @@ class CustomWizard::Action end if result - @result = "success (updated fields #{params.keys.map{ |p| p.to_s }.join(',')})" + log_success("updated profile fields", params.keys.map{ |p| p.to_s }.join(',')) else - @result = "failed to update" + log_error("failed to update profile fields") end else - @result = "invalid params" + log_error("invalid profile fields params") end end @@ -201,9 +205,9 @@ class CustomWizard::Action end if result - @result = "success (added to groups: #{groups.map { |g| g.id.to_s }.join(',')})" + log_success("added to groups", groups.map { |g| g.id.to_s }.join(',')) else - @result = "failed to add" + log_error("failed to add to groups") end end @@ -333,4 +337,12 @@ class CustomWizard::Action user.save! user.user_avatar.save! end + + def log_success(message, detail = nil) + @log.push("success - #{message} - #{detail}") + end + + def log_error(message, detail = nil) + @log.push("error - #{message} - #{detail}") + end end \ No newline at end of file diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index 985ef175..fb29ff03 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -157,6 +157,7 @@ class CustomWizard::Builder (final_step && (!action['run_after'] || (action['run_after'] === 'wizard_completion'))) CustomWizard::Action.new( + wizard: @wizard, action: action, user: user, data: data, diff --git a/lib/custom_wizard/log.rb b/lib/custom_wizard/log.rb new file mode 100644 index 00000000..1aa4751a --- /dev/null +++ b/lib/custom_wizard/log.rb @@ -0,0 +1,38 @@ +class CustomWizard::Log + include ActiveModel::Serialization + + attr_accessor :message, :date + + PAGE_LIMIT = 100 + + def initialize(attrs) + @message = attrs['message'] + @date = attrs['date'] + end + + def self.create(message) + log_id = SecureRandom.hex(12) + + PluginStore.set('custom_wizard', + "log_#{log_id}", + { + date: Time.now, + message: message + } + ) + end + + def self.list_query + PluginStoreRow.where(" + plugin_name = 'custom_wizard' AND + key LIKE 'log_%' AND + (value::json->'date') IS NOT NULL + ").order("value::json->>'date' DESC") + end + + def self.list(page = 0) + self.list_query.limit(PAGE_LIMIT) + .offset(page * PAGE_LIMIT) + .map { |r| self.new(JSON.parse(r.value)) } + end +end \ No newline at end of file diff --git a/plugin.rb b/plugin.rb index cb38529d..7c891033 100644 --- a/plugin.rb +++ b/plugin.rb @@ -48,6 +48,7 @@ after_initialize do ../controllers/custom_wizard/admin/wizard.rb ../controllers/custom_wizard/admin/submissions.rb ../controllers/custom_wizard/admin/api.rb + ../controllers/custom_wizard/admin/logs.rb ../controllers/custom_wizard/wizard.rb ../controllers/custom_wizard/steps.rb ../controllers/custom_wizard/transfer.rb @@ -57,10 +58,11 @@ after_initialize do ../jobs/clear_after_time_wizard.rb ../jobs/refresh_api_access_token.rb ../jobs/set_after_time_wizard.rb - ../lib/custom_wizard/actions.rb + ../lib/custom_wizard/action.rb ../lib/custom_wizard/builder.rb ../lib/custom_wizard/field.rb ../lib/custom_wizard/mapper.rb + ../lib/custom_wizard/log.rb ../lib/custom_wizard/step_updater.rb ../lib/custom_wizard/validator.rb ../lib/custom_wizard/wizard.rb @@ -80,6 +82,7 @@ after_initialize do ../serializers/custom_wizard/wizard_field_serializer.rb ../serializers/custom_wizard/wizard_step_serializer.rb ../serializers/custom_wizard/wizard_serializer.rb + ../serializers/custom_wizard/log_serializer.rb ../serializers/site_serializer.rb ].each do |path| load File.expand_path(path, __FILE__) diff --git a/serializers/custom_wizard/log_serializer.rb b/serializers/custom_wizard/log_serializer.rb new file mode 100644 index 00000000..5b88d3f0 --- /dev/null +++ b/serializers/custom_wizard/log_serializer.rb @@ -0,0 +1,3 @@ +class CustomWizard::LogSerializer < ApplicationSerializer + attributes :message, :date +end \ No newline at end of file