diff --git a/assets/javascripts/discourse/components/submission-field.js.es6 b/assets/javascripts/discourse/components/wizard-table-field.js.es6
similarity index 69%
rename from assets/javascripts/discourse/components/submission-field.js.es6
rename to assets/javascripts/discourse/components/wizard-table-field.js.es6
index 5ebc0ccd..ce6b1584 100644
--- a/assets/javascripts/discourse/components/submission-field.js.es6
+++ b/assets/javascripts/discourse/components/wizard-table-field.js.es6
@@ -1,10 +1,11 @@
import Component from "@ember/component";
import { action } from "@ember/object";
-import { equal } from "@ember/object/computed";
+import { equal, notEmpty } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "I18n";
export default Component.extend({
+ classNameBindings: ["value.type"],
isText: equal("value.type", "text"),
isComposer: equal("value.type", "composer"),
isDate: equal("value.type", "date"),
@@ -18,13 +19,29 @@ export default Component.extend({
isTag: equal("value.type", "tag"),
isCategory: equal("value.type", "category"),
isGroup: equal("value.type", "group"),
- isUser: equal("fieldName", "username"),
isUserSelector: equal("value.type", "user_selector"),
- isSubmittedAt: equal("fieldName", "submitted_at"),
- isTextArea: equal("value.type", "textarea"),
+ isSubmittedAt: equal("field", "submitted_at"),
isComposerPreview: equal("value.type", "composer_preview"),
textState: "text-collapsed",
- toggleText: I18n.t("admin.wizard.submissions.expand_text"),
+ toggleText: I18n.t("admin.wizard.expand_text"),
+
+ @discourseComputed("value", "isUser")
+ hasValue(value, isUser) {
+ if (isUser) {
+ return value;
+ }
+ return value && value.value;
+ },
+
+ @discourseComputed("field", "value.type")
+ isUser(field, type) {
+ return field === "username" || field === "user" || type === "user";
+ },
+
+ @discourseComputed("value.type")
+ isLongtext(type) {
+ return type === "textarea" || type === "long_text";
+ },
@discourseComputed("value")
checkboxValue(value) {
@@ -44,10 +61,10 @@ export default Component.extend({
if (state === "text-collapsed") {
this.set("textState", "text-expanded");
- this.set("toggleText", I18n.t("admin.wizard.submissions.collapse_text"));
+ this.set("toggleText", I18n.t("admin.wizard.collapse_text"));
} else if (state === "text-expanded") {
this.set("textState", "text-collapsed");
- this.set("toggleText", I18n.t("admin.wizard.submissions.expand_text"));
+ this.set("toggleText", I18n.t("admin.wizard.expand_text"));
}
},
@@ -83,19 +100,24 @@ export default Component.extend({
return users;
},
- @discourseComputed("value")
- userProfileUrl(value) {
- const isUser = this.get("isUser");
+ @discourseComputed("isUser", "field", "value")
+ username(isUser, field, value) {
+ if (isUser) {return value.username;}
+ if (field === "username") {return value.value;}
+ return null;
+ },
- if (isUser) {
- return `/u/${value.username}`;
- }
+ showUsername: notEmpty("username"),
+
+ @discourseComputed("username")
+ userProfileUrl(username) {
+ if (username) {return `/u/${username}`;}
+ return "/";
},
@discourseComputed("value")
categoryUrl(value) {
const isCategory = this.get("isCategory");
-
if (isCategory) {
return `/c/${value.value}`;
}
@@ -104,7 +126,6 @@ export default Component.extend({
@discourseComputed("value")
groupUrl(value) {
const isGroup = this.get("isGroup");
-
if (isGroup) {
return `/g/${value.value}`;
}
diff --git a/assets/javascripts/discourse/controllers/admin-wizards-submissions-columns.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6
similarity index 73%
rename from assets/javascripts/discourse/controllers/admin-wizards-submissions-columns.js.es6
rename to assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6
index 4af487ee..4754c577 100644
--- a/assets/javascripts/discourse/controllers/admin-wizards-submissions-columns.js.es6
+++ b/assets/javascripts/discourse/controllers/admin-wizards-columns.js.es6
@@ -6,10 +6,9 @@ export default Controller.extend(ModalFunctionality, {
save() {
this.send("closeModal");
},
+
resetToDefault() {
- this.get("model.fields").forEach((field) => {
- field.set("enabled", true);
- });
+ this.get("model.reset")();
},
},
});
diff --git a/assets/javascripts/discourse/controllers/admin-wizards-logs-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-logs-show.js.es6
new file mode 100644
index 00000000..7e3fdff1
--- /dev/null
+++ b/assets/javascripts/discourse/controllers/admin-wizards-logs-show.js.es6
@@ -0,0 +1,52 @@
+import discourseComputed from "discourse-common/utils/decorators";
+import { notEmpty } from "@ember/object/computed";
+import CustomWizardLogs from "../models/custom-wizard-logs";
+import Controller from "@ember/controller";
+
+export default Controller.extend({
+ refreshing: false,
+ hasLogs: notEmpty("logs"),
+ page: 0,
+ canLoadMore: true,
+ logs: [],
+ messageKey: "viewing",
+
+ loadLogs() {
+ if (!this.canLoadMore) {
+ return;
+ }
+ const page = this.get("page");
+ const wizardId = this.get("wizard.id");
+
+ this.set("refreshing", true);
+
+ CustomWizardLogs.list(wizardId, page)
+ .then((result) => {
+ this.set("logs", this.logs.concat(result.logs));
+ })
+ .finally(() => this.set("refreshing", false));
+ },
+
+ @discourseComputed("hasLogs", "refreshing")
+ noResults(hasLogs, refreshing) {
+ return !hasLogs && !refreshing;
+ },
+
+ actions: {
+ loadMore() {
+ if (!this.loadingMore && this.logs.length < this.total) {
+ this.set("page", (this.page += 1));
+ this.loadLogs();
+ }
+ },
+
+ refresh() {
+ this.setProperties({
+ canLoadMore: true,
+ page: 0,
+ logs: [],
+ });
+ this.loadLogs();
+ },
+ },
+});
diff --git a/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6
index f45013d7..7388a8d6 100644
--- a/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6
+++ b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6
@@ -1,52 +1,34 @@
-import discourseComputed from "discourse-common/utils/decorators";
-import { notEmpty } from "@ember/object/computed";
-import CustomWizardLogs from "../models/custom-wizard-logs";
import Controller from "@ember/controller";
+import { default as discourseComputed } from "discourse-common/utils/decorators";
export default Controller.extend({
- refreshing: false,
- hasLogs: notEmpty("logs"),
- page: 0,
- canLoadMore: true,
- logs: [],
documentationUrl: "https://thepavilion.io/t/2818",
- messageKey: "viewing",
- loadLogs() {
- if (!this.canLoadMore) {
- return;
+ @discourseComputed("wizardId")
+ wizardName(wizardId) {
+ let currentWizard = this.wizardList.find(
+ (wizard) => wizard.id === wizardId
+ );
+ if (currentWizard) {
+ return currentWizard.name;
+ }
+ },
+
+ @discourseComputed("wizardName")
+ messageOpts(wizardName) {
+ return {
+ wizardName,
+ };
+ },
+
+ @discourseComputed("wizardId")
+ messageKey(wizardId) {
+ let key = "select";
+
+ if (wizardId) {
+ key = "viewing";
}
- this.set("refreshing", true);
-
- CustomWizardLogs.list()
- .then((result) => {
- if (!result || result.length === 0) {
- this.set("canLoadMore", false);
- }
- this.set("logs", this.logs.concat(result));
- })
- .finally(() => this.set("refreshing", false));
- },
-
- @discourseComputed("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();
- },
+ return key;
},
});
diff --git a/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6
index 7ba0050f..10621cd3 100644
--- a/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6
+++ b/assets/javascripts/discourse/controllers/admin-wizards-submissions-show.js.es6
@@ -54,10 +54,14 @@ export default Controller.extend({
},
showEditColumnsModal() {
- return showModal("admin-wizards-submissions-columns", {
+ return showModal("admin-wizards-columns", {
model: {
- fields: this.get("fields"),
- submissions: this.get("submissions"),
+ columns: this.get("fields"),
+ reset: () => {
+ this.get("fields").forEach((field) => {
+ field.set("enabled", true);
+ });
+ },
},
});
},
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 5468e863..1ca6d41b 100644
--- a/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6
+++ b/assets/javascripts/discourse/custom-wizard-admin-route-map.js.es6
@@ -43,10 +43,16 @@ export default {
}
);
- this.route("adminWizardsLogs", {
- path: "/logs",
- resetNamespace: true,
- });
+ this.route(
+ "adminWizardsLogs",
+ { path: "/logs", resetNamespace: true },
+ function () {
+ this.route("adminWizardsLogsShow", {
+ path: "/:wizardId/",
+ resetNamespace: true,
+ });
+ }
+ );
this.route("adminWizardsManager", {
path: "/manager",
diff --git a/assets/javascripts/discourse/models/custom-wizard-logs.js.es6 b/assets/javascripts/discourse/models/custom-wizard-logs.js.es6
index e2de8a07..1bd19dfe 100644
--- a/assets/javascripts/discourse/models/custom-wizard-logs.js.es6
+++ b/assets/javascripts/discourse/models/custom-wizard-logs.js.es6
@@ -3,14 +3,48 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import EmberObject from "@ember/object";
const CustomWizardLogs = EmberObject.extend();
+const logItemTypes = {
+ date: "date_time",
+ action: "text",
+ message: "long_text",
+ user: "user",
+ username: "text",
+};
+
+function logItem(item, attr) {
+ return {
+ value: item[attr],
+ type: logItemTypes[attr],
+ };
+}
CustomWizardLogs.reopenClass({
- list(page = 0) {
- return ajax("/admin/wizards/logs", {
- data: {
- page,
- },
- }).catch(popupAjaxError);
+ list(wizardId, page = 0) {
+ let data = {
+ page,
+ };
+
+ return ajax(`/admin/wizards/logs/${wizardId}`, { data })
+ .catch(popupAjaxError)
+ .then((result) => {
+ if (result.logs) {
+ result.logs = result.logs.map((item) => {
+ let map = {};
+
+ if (item.date) {map.date = logItem(item, "date");}
+ if (item.action) {map.action = logItem(item, "action");}
+ if (item.user) {
+ map.user = item.user;
+ } else {
+ map.user = logItem(item, "username");
+ }
+ if (item.message) {map.message = logItem(item, "message");}
+
+ return map;
+ });
+ }
+ return result;
+ });
},
});
diff --git a/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6
new file mode 100644
index 00000000..474360ec
--- /dev/null
+++ b/assets/javascripts/discourse/routes/admin-wizards-logs-show.js.es6
@@ -0,0 +1,17 @@
+import CustomWizardLogs from "../models/custom-wizard-logs";
+import DiscourseRoute from "discourse/routes/discourse";
+import { A } from "@ember/array";
+
+export default DiscourseRoute.extend({
+ model(params) {
+ return CustomWizardLogs.list(params.wizardId);
+ },
+
+ setupController(controller, model) {
+ controller.setProperties({
+ wizard: model.wizard,
+ logs: A(model.logs),
+ total: model.total,
+ });
+ },
+});
diff --git a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6
index 56b91350..a1575050 100644
--- a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6
+++ b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6
@@ -1,12 +1,24 @@
-import CustomWizardLogs from "../models/custom-wizard-logs";
import DiscourseRoute from "discourse/routes/discourse";
+import { ajax } from "discourse/lib/ajax";
export default DiscourseRoute.extend({
model() {
- return CustomWizardLogs.list();
+ return ajax(`/admin/wizards/wizard`);
},
setupController(controller, model) {
- controller.set("logs", model);
+ const showParams = this.paramsFor("adminWizardsLogsShow");
+
+ controller.setProperties({
+ wizardId: showParams.wizardId,
+ wizardList: model.wizard_list,
+ });
+ },
+
+ actions: {
+ changeWizard(wizardId) {
+ this.controllerFor("adminWizardsLogs").set("wizardId", wizardId);
+ this.transitionTo("adminWizardsLogsShow", wizardId);
+ },
},
});
diff --git a/assets/javascripts/discourse/templates/admin-wizards-logs-show.hbs b/assets/javascripts/discourse/templates/admin-wizards-logs-show.hbs
new file mode 100644
index 00000000..898198d1
--- /dev/null
+++ b/assets/javascripts/discourse/templates/admin-wizards-logs-show.hbs
@@ -0,0 +1,45 @@
+{{#if logs}}
+
+
+
+ {{#load-more selector=".wizard-table tr" action=(action "loadMore")}}
+ {{#if noResults}}
+
{{i18n "search.no_results"}}
+ {{else}}
+
+
+
+ {{i18n "admin.wizard.log.date"}} |
+ {{i18n "admin.wizard.log.action"}} |
+ {{i18n "admin.wizard.log.user"}} |
+ {{i18n "admin.wizard.log.message"}} |
+
+
+
+ {{#each logs as |log|}}
+
+ {{#each-in log as |field value|}}
+ {{wizard-table-field field=field value=value}} |
+ {{/each-in}}
+
+ {{/each}}
+
+
+ {{/if}}
+
+ {{conditional-loading-spinner condition=refreshing}}
+ {{/load-more}}
+
+{{/if}}
diff --git a/assets/javascripts/discourse/templates/admin-wizards-logs.hbs b/assets/javascripts/discourse/templates/admin-wizards-logs.hbs
index ea0afb7c..45738a9f 100644
--- a/assets/javascripts/discourse/templates/admin-wizards-logs.hbs
+++ b/assets/javascripts/discourse/templates/admin-wizards-logs.hbs
@@ -1,11 +1,11 @@
-
-
{{i18n "admin.wizard.log.nav_label"}}
-
- {{d-button
- label="refresh"
- icon="sync"
- action="refresh"
- class="refresh"}}
+
+ {{combo-box
+ value=wizardId
+ content=wizardList
+ onChange=(route-action "changeWizard")
+ options=(hash
+ none="admin.wizard.select"
+ )}}
{{wizard-message
@@ -14,27 +14,6 @@
url=documentationUrl
component="logs"}}
-{{#load-more selector=".log-list tr" action=(action "loadMore") class="wizard-logs"}}
- {{#if noResults}}
-
{{i18n "search.no_results"}}
- {{else}}
-
-
-
- Message |
- Date |
-
-
-
- {{#each logs as |log|}}
-
- {{log.message}} |
- {{bound-date log.date}} |
-
- {{/each}}
-
-
- {{/if}}
-
- {{conditional-loading-spinner condition=refreshing}}
-{{/load-more}}
+
+ {{outlet}}
+
diff --git a/assets/javascripts/discourse/templates/admin-wizards-submissions-show.hbs b/assets/javascripts/discourse/templates/admin-wizards-submissions-show.hbs
index df97513b..72ec7c38 100644
--- a/assets/javascripts/discourse/templates/admin-wizards-submissions-show.hbs
+++ b/assets/javascripts/discourse/templates/admin-wizards-submissions-show.hbs
@@ -7,7 +7,7 @@
{{d-button
icon="sliders-h"
- label="admin.wizard.submissions.edit_columns"
+ label="admin.wizard.edit_columns"
action=(action "showEditColumnsModal")
class="btn-default open-edit-columns-btn download-link"
}}
@@ -26,12 +26,10 @@
-
- {{#load-more selector=".wizard-submissions tr" action=(action "loadMore")}}
+
+ {{#load-more selector=".wizard-table tr" action=(action "loadMore")}}
{{#if noResults}}
-
- {{i18n "search.no_results"}}
-
+
{{i18n "search.no_results"}}
{{else}}
@@ -49,9 +47,7 @@
{{#each displaySubmissions as |submission|}}
{{#each-in submission as |field value|}}
-
- {{submission-field fieldName=field value=value}}
- |
+ {{wizard-table-field field=field value=value}} |
{{/each-in}}
{{/each}}
diff --git a/assets/javascripts/discourse/templates/components/submission-field.hbs b/assets/javascripts/discourse/templates/components/submission-field.hbs
deleted file mode 100644
index c635ff47..00000000
--- a/assets/javascripts/discourse/templates/components/submission-field.hbs
+++ /dev/null
@@ -1,163 +0,0 @@
-{{#if isText}}
- {{value.value}}
-{{/if}}
-
-{{#if isTextArea}}
-
-
- {{value.value}}
-
-
- {{toggleText}}
-
-
-{{/if}}
-
-{{#if isComposer}}
-
-
- {{value.value}}
-
-
- {{toggleText}}
-
-
-{{/if}}
-
-{{#if isComposerPreview}}
- {{d-icon "comment-alt"}}
-
- {{i18n "admin.wizard.submissions.composer_preview"}}: {{value.value}}
-
-{{/if}}
-
-{{#if isTextOnly}}
- {{value.value}}
-{{/if}}
-
-{{#if isDate}}
-
- {{d-icon "calendar"}}{{value.value}}
-
-{{/if}}
-
-{{#if isTime}}
-
- {{d-icon "clock"}}{{value.value}}
-
-{{/if}}
-
-{{#if isDateTime}}
-
- {{d-icon "calendar"}}{{format-date value.value format="medium"}}
-
-{{/if}}
-
-{{#if isNumber}}
- {{value.value}}
-{{/if}}
-
-{{#if isCheckbox}}
- {{#if checkboxValue}}
-
- {{d-icon "check"}}{{value.value}}
-
- {{else}}
-
- {{d-icon "times"}}{{value.value}}
-
- {{/if}}
-{{/if}}
-
-{{#if isUrl}}
-
- {{d-icon "link"}}
-
- {{value.value}}
-
-
-{{/if}}
-
-{{#if isUpload}}
-
- {{file.original_filename}}
-
-{{/if}}
-
-{{#if isDropdown}}
-
- {{d-icon "check-square"}}
- {{value.value}}
-
-{{/if}}
-
-{{#if isTag}}
- {{#each value.value as |tag|}}
- {{discourse-tag tag}}
- {{/each}}
-{{/if}}
-
-{{#if isCategory}}
-
- {{i18n "admin.wizard.submissions.category_id"}}:
-
-
- {{value.value}}
-
-{{/if}}
-
-{{#if isGroup}}
-
- {{i18n "admin.wizard.submissions.group_id"}}:
-
- {{value.value}}
-{{/if}}
-
-{{#if isUserSelector}}
- {{#each submittedUsers as |user|}}
- {{d-icon "user"}}
-
- {{user.username}}
-
- {{/each}}
-{{/if}}
-
-{{#if isUser}}
- {{#link-to "user" value}}
- {{avatar value imageSize="tiny"}}
- {{/link-to}}
-
- {{value.username}}
-
-{{/if}}
-
-{{#if isSubmittedAt}}
-
- {{d-icon "clock"}}{{format-date value format="tiny"}}
-
-{{/if}}
diff --git a/assets/javascripts/discourse/templates/components/wizard-table-field.hbs b/assets/javascripts/discourse/templates/components/wizard-table-field.hbs
new file mode 100644
index 00000000..bd7da5c4
--- /dev/null
+++ b/assets/javascripts/discourse/templates/components/wizard-table-field.hbs
@@ -0,0 +1,161 @@
+{{#if hasValue}}
+ {{#if isText}}
+ {{value.value}}
+ {{/if}}
+
+ {{#if isLongtext}}
+
+
+ {{value.value}}
+
+
+ {{toggleText}}
+
+
+ {{/if}}
+
+ {{#if isComposer}}
+
+
+ {{value.value}}
+
+
+ {{toggleText}}
+
+
+ {{/if}}
+
+ {{#if isComposerPreview}}
+ {{d-icon "comment-alt"}}
+
+ {{i18n "admin.wizard.submissions.composer_preview"}}: {{value.value}}
+
+ {{/if}}
+
+ {{#if isTextOnly}}
+ {{value.value}}
+ {{/if}}
+
+ {{#if isDate}}
+
+ {{d-icon "calendar"}}{{value.value}}
+
+ {{/if}}
+
+ {{#if isTime}}
+
+ {{d-icon "clock"}}{{value.value}}
+
+ {{/if}}
+
+ {{#if isDateTime}}
+
+ {{d-icon "calendar"}}{{format-date value.value format="medium"}}
+
+ {{/if}}
+
+ {{#if isNumber}}
+ {{value.value}}
+ {{/if}}
+
+ {{#if isCheckbox}}
+ {{#if checkboxValue}}
+
+ {{d-icon "check"}}{{value.value}}
+
+ {{else}}
+
+ {{d-icon "times"}}{{value.value}}
+
+ {{/if}}
+ {{/if}}
+
+ {{#if isUrl}}
+
+ {{d-icon "link"}}
+
+ {{value.value}}
+
+
+ {{/if}}
+
+ {{#if isUpload}}
+
+ {{file.original_filename}}
+
+ {{/if}}
+
+ {{#if isDropdown}}
+
+ {{d-icon "check-square"}}
+ {{value.value}}
+
+ {{/if}}
+
+ {{#if isTag}}
+ {{#each value.value as |tag|}}
+ {{discourse-tag tag}}
+ {{/each}}
+ {{/if}}
+
+ {{#if isCategory}}
+
+ {{i18n "admin.wizard.submissions.category_id"}}:
+
+
+ {{value.value}}
+
+ {{/if}}
+
+ {{#if isGroup}}
+
+ {{i18n "admin.wizard.submissions.group_id"}}:
+
+ {{value.value}}
+ {{/if}}
+
+ {{#if isUserSelector}}
+ {{#each submittedUsers as |user|}}
+ {{d-icon "user"}}
+
+ {{user.username}}
+
+ {{/each}}
+ {{/if}}
+
+ {{#if isUser}}
+ {{#link-to "user" value}}
+ {{avatar value imageSize="tiny"}}
+ {{/link-to}}
+ {{/if}}
+
+ {{#if showUsername}}
+
+ {{username}}
+
+ {{/if}}
+
+ {{#if isSubmittedAt}}
+
+ {{d-icon "clock"}}{{format-date value format="tiny"}}
+
+ {{/if}}
+{{else}}
+ —
+{{/if}}
diff --git a/assets/javascripts/discourse/templates/modal/admin-wizards-submissions-columns.hbs b/assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs
similarity index 72%
rename from assets/javascripts/discourse/templates/modal/admin-wizards-submissions-columns.hbs
rename to assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs
index a167a954..eb5218b1 100644
--- a/assets/javascripts/discourse/templates/modal/admin-wizards-submissions-columns.hbs
+++ b/assets/javascripts/discourse/templates/modal/admin-wizards-columns.hbs
@@ -1,14 +1,14 @@
-{{#d-modal-body title="directory.edit_columns.title"}}
+{{#d-modal-body title="admin.wizard.edit_columns"}}
{{#if loading}}
{{loading-spinner size="large"}}
{{else}}
- {{#each model.fields as |field|}}
+ {{#each model.columns as |column|}}
diff --git a/assets/stylesheets/common/wizard-admin.scss b/assets/stylesheets/common/wizard-admin.scss
index 7027950a..7c6cd95d 100644
--- a/assets/stylesheets/common/wizard-admin.scss
+++ b/assets/stylesheets/common/wizard-admin.scss
@@ -66,10 +66,10 @@
}
}
-.wizard-submissions {
+.wizard-table {
overflow: scroll;
- table td {
+ table td:not(.small) {
min-width: 150px;
}
@@ -77,25 +77,26 @@
text-transform: capitalize;
}
- .submission-icon-item {
+ .wizard-table-icon-item {
display: flex;
align-items: center;
+
svg {
margin-right: 5px;
}
}
- .submission-checkbox-true {
+ .wizard-table-checkbox-true {
text-transform: capitalize;
color: var(--success);
}
- .submission-checkbox-false {
+ .wizard-table-checkbox-false {
text-transform: capitalize;
color: var(--danger);
}
- .submission-long-text {
+ .wizard-table-long-text {
&-content {
white-space: nowrap;
word-wrap: break-word;
@@ -114,25 +115,11 @@
}
}
- .submission-composer-text {
+ .wizard-table-composer-text {
font-family: monospace;
}
}
-.admin-wizards-logs {
- .admin-wizard-controls {
- h3 {
- margin: 0 7px;
- }
- }
-
- .wizard-logs {
- .date {
- width: 100px;
- }
- }
-}
-
.wizard-settings-parent {
padding: 20px;
border: 1px solid var(--primary-low);
@@ -215,6 +202,10 @@
margin-bottom: 0;
}
+ button {
+ font-size: 1rem;
+ }
+
.download-link {
font-size: 1rem;
line-height: 20px;
@@ -230,10 +221,6 @@
font-size: 1rem;
background-color: var(--primary-low);
}
-
- button {
- font-size: 1rem;
- }
}
}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index ae2594d2..cb30cf76 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -58,6 +58,9 @@ en:
select_type: "Select a type"
condition: "Condition"
index: "Index"
+ edit_columns: "Edit Columns"
+ expand_text: "Read More"
+ collapse_text: "Show Less"
pro_support_button:
title: "Request Pro Support"
@@ -108,6 +111,7 @@ en:
viewing: "You're viewing the submissions of the %{wizardName}"
documentation: "Check out the submissions documentation"
logs:
+ select: "Select a wizard to see its logs"
viewing: "View recent logs for wizards on the forum"
documentation: "Check out the logs documentation"
@@ -378,9 +382,6 @@ en:
nav_label: "Submissions"
title: "{{name}} Submissions"
download: "Download"
- edit_columns: "Edit Columns"
- expand_text: "Read More"
- collapse_text: "Show Less"
group_id: "Group ID"
category_id: "Category ID"
composer_preview: "Composer Preview"
@@ -437,9 +438,14 @@ en:
log:
label: "Logs"
-
+
log:
nav_label: "Logs"
+ title: "{{name}} Logs"
+ date: Date
+ action: Action
+ user: User
+ message: Message
manager:
nav_label: Manager
diff --git a/config/routes.rb b/config/routes.rb
index abe36479..3a37a137 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -38,6 +38,7 @@ Discourse::Application.routes.append do
get 'admin/wizards/api/:name/authorize' => 'admin_api#authorize'
get 'admin/wizards/logs' => 'admin_logs#index'
+ get 'admin/wizards/logs/:wizard_id' => 'admin_logs#show'
get 'admin/wizards/manager' => 'admin_manager#index'
get 'admin/wizards/manager/export' => 'admin_manager#export'
diff --git a/controllers/custom_wizard/admin/logs.rb b/controllers/custom_wizard/admin/logs.rb
index 976814f8..7ca37bb2 100644
--- a/controllers/custom_wizard/admin/logs.rb
+++ b/controllers/custom_wizard/admin/logs.rb
@@ -1,9 +1,44 @@
# frozen_string_literal: true
class CustomWizard::AdminLogsController < CustomWizard::AdminController
+ before_action :find_wizard, except: [:index]
+
def index
- render_serialized(
- CustomWizard::Log.list(params[:page].to_i, params[:limit].to_i),
- CustomWizard::LogSerializer
+ 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
+ )
+ end
+
+ protected
+
+ def log_list
+ @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
+
+ list.logs.each do |log_item|
+ log_item.user = user_map[log_item.username]
+ end
+ end
+
+ list
+ end
+ end
end
diff --git a/coverage/.last_run.json b/coverage/.last_run.json
index cff5740b..23e2ecb9 100644
--- a/coverage/.last_run.json
+++ b/coverage/.last_run.json
@@ -1,5 +1,5 @@
{
"result": {
- "line": 91.96
+ "line": 92.14
}
}
diff --git a/db/migrate/20210806135416_split_custom_wizard_log_fields.rb b/db/migrate/20210806135416_split_custom_wizard_log_fields.rb
index 984a7a23..8107bc07 100644
--- a/db/migrate/20210806135416_split_custom_wizard_log_fields.rb
+++ b/db/migrate/20210806135416_split_custom_wizard_log_fields.rb
@@ -1,51 +1,56 @@
# frozen_string_literal: true
class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
+ KEY_MAP = {
+ wizard: "wizard_id",
+ action: "action",
+ user: "username",
+ date: "date",
+ message: "message"
+ }
+
def change
reversible do |dir|
dir.up do
# separate wizard/action/user into their own keys
- wizard_logs = PluginStoreRow.where("
- plugin_name = 'custom_wizard_log'
- ")
+ wizard_logs = PluginStoreRow.where("plugin_name = 'custom_wizard_log'")
- if wizard_logs.exists?
- wizard_logs.each do |row|
- begin
- log_json = JSON.parse(row.value)
- rescue TypeError, JSON::ParserError
- next
- end
+ if wizard_logs.exists?
+ wizard_logs.each do |row|
+ begin
+ log_json = JSON.parse(row.value)
+ rescue TypeError, JSON::ParserError
+ next
+ end
- if log_json.key?('message') && log_json['message'].is_a?(String)
+ if log_json.key?('message') && log_json['message'].is_a?(String)
- attr_strs = []
+ attr_strs = []
- # assumes no whitespace in the values
- attr_strs << log_json['message'].slice!(/(wizard: \S*; )/, 1)
- attr_strs << log_json['message'].slice!(/(action: \S*; )/, 1)
- attr_strs << log_json['message'].slice!(/(user: \S*; )/, 1)
+ # assumes no whitespace in the values
+ attr_strs << log_json['message'].slice!(/(wizard: \S*; )/, 1)
+ attr_strs << log_json['message'].slice!(/(action: \S*; )/, 1)
+ attr_strs << log_json['message'].slice!(/(user: \S*; )/, 1)
- attr_strs.each do |attr_str|
- if attr_str.is_a? String
- attr_str.gsub!(/[;]/ , "")
- key, value = attr_str.split(': ')
- value.strip! if value
- log_json[key] = value ? value : ''
- end
+ attr_strs.each do |attr_str|
+ if attr_str.is_a? String
+ attr_str.gsub!(/[;]/ , "")
+ key, value = attr_str.split(': ')
+ value.strip! if value
+ key = KEY_MAP[key.to_sym] ? KEY_MAP[key.to_sym] : key
+ log_json[key] = value ? value : ''
end
-
- row.value = log_json.to_json
- row.save
-
end
+
+ row.value = log_json.to_json
+ row.save
end
end
+ end
end
+
dir.down do
- wizard_logs = PluginStoreRow.where("
- plugin_name = 'custom_wizard_log'
- ")
+ wizard_logs = PluginStoreRow.where("plugin_name = 'custom_wizard_log'")
if wizard_logs.exists?
wizard_logs.each do |row|
@@ -56,19 +61,26 @@ class SplitCustomWizardLogFields < ActiveRecord::Migration[6.1]
end
# concatenate wizard/action/user to start of message
- prefixes = log_json.extract!('wizard', 'action', 'user')
+ prefixes = log_json.extract!('wizard_id', 'action', 'username')
+ message_prefix = ""
- message_prefix = prefixes.map { |k, v| "#{k}: #{v}" }.join('; ')
+ if prefixes.present?
+ message_prefix = prefixes.map do |k, v|
+ key = KEY_MAP.key(k) ? KEY_MAP.key(k) : k
+ "#{key.to_s}: #{v};"
+ end.join(' ')
+ end
if log_json.key?('message')
- log_json['message'] = "#{message_prefix}; #{log_json['message']}"
+ message = log_json['message']
+ message = "#{message_prefix} #{message}" if message_prefix.present?
+ log_json['message'] = message
else
log_json['message'] = message_prefix
end
row.value = log_json.to_json
row.save
-
end
end
end
diff --git a/lib/custom_wizard/log.rb b/lib/custom_wizard/log.rb
index c50a5712..cb5b78c7 100644
--- a/lib/custom_wizard/log.rb
+++ b/lib/custom_wizard/log.rb
@@ -2,46 +2,51 @@
class CustomWizard::Log
include ActiveModel::Serialization
- attr_accessor :date, :wizard, :action, :user, :message
+ attr_reader :date, :wizard_id, :action, :username, :message
+ attr_accessor :user
PAGE_LIMIT = 100
def initialize(attrs)
@date = attrs['date']
- @wizard = attrs['wizard']
@action = attrs['action']
- @user = attrs['user']
@message = attrs['message']
+ @wizard_id = attrs['wizard_id']
+ @username = attrs['username']
end
- def self.create(wizard, action, user, message)
+ def self.create(wizard_id, action, username, message)
log_id = SecureRandom.hex(12)
PluginStore.set('custom_wizard_log',
log_id.to_s,
{
date: Time.now,
- wizard: wizard,
+ wizard_id: wizard_id,
action: action,
- user: user,
+ username: username,
message: message
}
)
end
- def self.list_query
- PluginStoreRow.where("
- plugin_name = 'custom_wizard_log' AND
- (value::json->'date') IS NOT NULL
- ").order("value::json->>'date' DESC")
+ def self.list_query(wizard_id = nil)
+ query = PluginStoreRow.where("plugin_name = 'custom_wizard_log' AND (value::json->'date') IS NOT NULL")
+ query = query.where("(value::json->>'wizard_id') = ?", wizard_id) if wizard_id
+ query.order("value::json->>'date' DESC")
end
- def self.list(page = 0, limit = nil)
+ def self.list(page = 0, limit = nil, wizard_id = nil)
limit = limit.to_i > 0 ? limit.to_i : PAGE_LIMIT
page = page.to_i
+ logs = self.list_query(wizard_id)
- self.list_query.limit(limit)
+ result = OpenStruct.new(logs: [], total: nil)
+ result.total = logs.size
+ result.logs = logs.limit(limit)
.offset(page * limit)
.map { |r| self.new(JSON.parse(r.value)) }
+
+ result
end
end
diff --git a/serializers/custom_wizard/log_serializer.rb b/serializers/custom_wizard/log_serializer.rb
index c4683ba8..56c5fd8f 100644
--- a/serializers/custom_wizard/log_serializer.rb
+++ b/serializers/custom_wizard/log_serializer.rb
@@ -1,4 +1,10 @@
# frozen_string_literal: true
+
class CustomWizard::LogSerializer < ApplicationSerializer
- attributes :date, :wizard, :action, :user, :message
+ attributes :date,
+ :action,
+ :username,
+ :message
+
+ has_one :user, serializer: ::BasicUserSerializer, embed: :objects
end
diff --git a/spec/components/custom_wizard/log_spec.rb b/spec/components/custom_wizard/log_spec.rb
index 62f2e6df..0b4832c0 100644
--- a/spec/components/custom_wizard/log_spec.rb
+++ b/spec/components/custom_wizard/log_spec.rb
@@ -10,19 +10,25 @@ describe CustomWizard::Log do
it "creates logs" do
expect(
- CustomWizard::Log.list.length
+ CustomWizard::Log.list.logs.length
).to eq(3)
end
it "lists logs by time created" do
expect(
- CustomWizard::Log.list.first.message
+ CustomWizard::Log.list.logs.first.message
).to eq("Third log message")
end
it "paginates logs" do
expect(
- CustomWizard::Log.list(0, 2).length
+ CustomWizard::Log.list(0, 2).logs.length
).to eq(2)
end
+
+ it "lists logs by wizard" do
+ expect(
+ CustomWizard::Log.list(0, 2, 'third-test-wizard').logs.length
+ ).to eq(1)
+ end
end
diff --git a/spec/requests/custom_wizard/admin/logs_controller_spec.rb b/spec/requests/custom_wizard/admin/logs_controller_spec.rb
index 5aaf9578..1559fa6f 100644
--- a/spec/requests/custom_wizard/admin/logs_controller_spec.rb
+++ b/spec/requests/custom_wizard/admin/logs_controller_spec.rb
@@ -3,21 +3,40 @@ require_relative '../../../plugin_helper'
describe CustomWizard::AdminLogsController do
fab!(:admin_user) { Fabricate(:user, admin: true) }
+ let(:template) { get_wizard_fixture("wizard") }
before do
- CustomWizard::Log.create('first-test-wizard', 'perform_first_action', 'first_test_user', 'First log message')
- CustomWizard::Log.create('second-test-wizard', 'perform_second_action', 'second_test_user', 'Second log message')
- CustomWizard::Log.create('third-test-wizard', 'perform_third_action', 'third_test_user', 'Third log message')
+ ["first", "second", "third"].each_with_index do |key, index|
+ temp = template.dup
+ temp["id"] = "#{key}_test_wizard"
+ CustomWizard::Template.save(temp, skip_jobs: true)
+ CustomWizard::Log.create("#{key}_test_wizard", "perform_#{key}_action", "#{key}_test_user", "#{key} log message")
+ end
sign_in(admin_user)
end
- it "returns a list of logs" do
+ it "returns a list of wizards" do
get "/admin/wizards/logs.json"
expect(response.parsed_body.length).to eq(3)
end
+ it "returns a list of logs for a wizard" do
+ get "/admin/wizards/logs/first_test_wizard.json"
+ expect(response.parsed_body['logs'].length).to eq(1)
+ end
+
it "paginates" do
- get "/admin/wizards/logs.json", params: { page: 1, limit: 2 }
- expect(response.parsed_body.length).to eq(1)
+ get "/admin/wizards/logs/first_test_wizard.json", params: { page: 1 }
+ expect(response.parsed_body['logs'].length).to eq(0)
+ end
+
+ it "returns total logs for a wizard" do
+ get "/admin/wizards/logs/first_test_wizard.json"
+ expect(response.parsed_body['total']).to eq(1)
+ end
+
+ it "returns basic wizard" do
+ get "/admin/wizards/logs/first_test_wizard.json"
+ expect(response.parsed_body['wizard']['id']).to eq("first_test_wizard")
end
end
diff --git a/spec/serializers/custom_wizard/log_serializer_spec.rb b/spec/serializers/custom_wizard/log_serializer_spec.rb
index b452b9c5..d520fefa 100644
--- a/spec/serializers/custom_wizard/log_serializer_spec.rb
+++ b/spec/serializers/custom_wizard/log_serializer_spec.rb
@@ -10,13 +10,12 @@ describe CustomWizard::LogSerializer do
CustomWizard::Log.create('second-test-wizard', 'perform_second_action', 'second_test_user', 'Second log message')
json_array = ActiveModel::ArraySerializer.new(
- CustomWizard::Log.list(0),
+ CustomWizard::Log.list(0).logs,
each_serializer: CustomWizard::LogSerializer
).as_json
expect(json_array.length).to eq(2)
- expect(json_array[0][:wizard]).to eq("second-test-wizard")
expect(json_array[0][:action]).to eq("perform_second_action")
- expect(json_array[0][:user]).to eq("second_test_user")
+ expect(json_array[0][:username]).to eq('second_test_user')
expect(json_array[0][:message]).to eq("Second log message")
end
end