mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 00:32:52 +08:00
DEV: Refactor the Automation Plugin UI to match admin UI guidelines (#31060)
This change updates the Automation plugin to make use of the `use_new_show_route` plugin flag, as well as generally updating the UI to match current admin UI guidelines. Notable changes include: - Moving template/router/controller files to make use of the `admin.adminPlugins.show` route. - Changing the URIs from `/admin/plugins/discourse-automation` to `/admin/plugins/automation`, to match the `PLUGIN_NAME`. - Adding UI wrappers around the New/Edit forms, and polishing the list of defined automations.
This commit is contained in:
@ -2,7 +2,7 @@ import RestAdapter from "discourse/adapters/rest";
|
||||
|
||||
export default class Adapter extends RestAdapter {
|
||||
basePath() {
|
||||
return "/admin/plugins/discourse-automation/";
|
||||
return "/admin/plugins/automation/";
|
||||
}
|
||||
|
||||
pathFor() {
|
||||
|
@ -1,19 +0,0 @@
|
||||
import Controller from "@ember/controller";
|
||||
import { action, computed } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
|
||||
export default class Automation extends Controller {
|
||||
@service router;
|
||||
|
||||
@computed("router.currentRouteName")
|
||||
get showNewAutomation() {
|
||||
return (
|
||||
this.router.currentRouteName === "adminPlugins.discourse-automation.index"
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
newAutomation() {
|
||||
this.router.transitionTo("adminPlugins.discourse-automation.new");
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class Automation extends DiscourseRoute {
|
||||
controllerName = "admin-plugins-discourse-automation";
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
<section class="discourse-automation-form edit">
|
||||
<form class="form-horizontal">
|
||||
<FormError @error={{this.error}} />
|
||||
|
||||
<section class="form-section edit">
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.automation.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<TextField
|
||||
@value={{this.automationForm.name}}
|
||||
@type="text"
|
||||
@autofocus={{true}}
|
||||
@name="automation-name"
|
||||
class="input-large"
|
||||
@input={{with-event-value (fn (mut this.automationForm.name))}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.script.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<ComboBox
|
||||
@value={{this.automationForm.script}}
|
||||
@content={{this.model.scriptables}}
|
||||
@onChange={{this.onChangeScript}}
|
||||
@options={{hash filterable=true}}
|
||||
class="scriptables"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="trigger-section form-section edit">
|
||||
<h2 class="title">
|
||||
{{i18n "discourse_automation.edit_automation.trigger_section.title"}}
|
||||
</h2>
|
||||
|
||||
<div class="control-group">
|
||||
{{#if this.model.automation.script.forced_triggerable}}
|
||||
<div class="alert alert-warning">
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.trigger_section.forced"
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.trigger.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<ComboBox
|
||||
@value={{this.automationForm.trigger}}
|
||||
@content={{this.model.triggerables}}
|
||||
@onChange={{this.onChangeTrigger}}
|
||||
@options={{hash
|
||||
filterable=true
|
||||
none="discourse_automation.select_trigger"
|
||||
disabled=this.model.automation.script.forced_triggerable
|
||||
}}
|
||||
class="triggerables"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
{{#if this.model.automation.trigger.doc}}
|
||||
<div class="alert alert-info">
|
||||
<p>{{this.model.automation.trigger.doc}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if
|
||||
(and
|
||||
this.model.automation.enabled
|
||||
this.model.automation.trigger.settings.manual_trigger
|
||||
)
|
||||
}}
|
||||
<div class="alert alert-info next-trigger">
|
||||
|
||||
{{#if this.nextPendingAutomationAtFormatted}}
|
||||
<p>
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.trigger_section.next_pending_automation"
|
||||
date=this.nextPendingAutomationAtFormatted
|
||||
}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@label="discourse_automation.edit_automation.trigger_section.trigger_now"
|
||||
@isLoading={{this.isTriggeringAutomation}}
|
||||
@action={{fn
|
||||
this.onManualAutomationTrigger
|
||||
this.model.automation.id
|
||||
}}
|
||||
class="btn-primary trigger-now-btn"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#each this.triggerFields as |field|}}
|
||||
<AutomationField
|
||||
@automation={{this.automation}}
|
||||
@field={{field}}
|
||||
@saveAutomation={{fn this.saveAutomation this.automation}}
|
||||
/>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
{{#if this.scriptFields}}
|
||||
<section class="fields-section form-section edit">
|
||||
<h2 class="title">
|
||||
{{i18n "discourse_automation.edit_automation.fields_section.title"}}
|
||||
</h2>
|
||||
|
||||
{{#if this.model.automation.script.with_trigger_doc}}
|
||||
<div class="alert alert-info">
|
||||
<p>{{this.model.automation.script.with_trigger_doc}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
{{#each this.scriptFields as |field|}}
|
||||
<AutomationField
|
||||
@automation={{this.automation}}
|
||||
@field={{field}}
|
||||
@saveAutomation={{fn this.saveAutomation this.automation}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
<div
|
||||
class="control-group automation-enabled alert
|
||||
{{if this.automationForm.enabled 'alert-info' 'alert-warning'}}"
|
||||
>
|
||||
<span>{{i18n
|
||||
"discourse_automation.models.automation.enabled.label"
|
||||
}}</span>
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{this.automationForm.enabled}}
|
||||
{{on
|
||||
"click"
|
||||
(action (mut this.automationForm.enabled) value="target.checked")
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
<DButton
|
||||
@isLoading={{this.isUpdatingAutomation}}
|
||||
@label="discourse_automation.update"
|
||||
@type="submit"
|
||||
@action={{fn this.saveAutomation this.automation true}}
|
||||
class="btn-primary update-automation"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
</form>
|
||||
</section>
|
@ -1,117 +0,0 @@
|
||||
{{#if this.model.length}}
|
||||
<table class="d-admin-table automations">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{{i18n "discourse_automation.models.automation.name.label"}}</th>
|
||||
<th>{{i18n "discourse_automation.models.automation.trigger.label"}}</th>
|
||||
<th>{{i18n "discourse_automation.models.automation.script.label"}}</th>
|
||||
<th>{{i18n
|
||||
"discourse_automation.models.automation.last_updated_by.label"
|
||||
}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this.model as |automation|}}
|
||||
<tr class="d-admin-row__content">
|
||||
{{#if automation.script.not_found}}
|
||||
<td colspan="5" class="d-admin-row__detail alert alert-danger">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{i18n
|
||||
"discourse_automation.scriptables.not_found"
|
||||
script=automation.script.id
|
||||
automation=automation.name
|
||||
}}
|
||||
</td>
|
||||
{{else if automation.trigger.not_found}}
|
||||
<td colspan="5" class="d-admin-row__detail alert alert-danger">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{i18n
|
||||
"discourse_automation.triggerables.not_found"
|
||||
trigger=automation.trigger.id
|
||||
automation=automation.name
|
||||
}}
|
||||
</td>
|
||||
{{else}}
|
||||
<td
|
||||
class="d-admin-row__detail automations__status"
|
||||
role="button"
|
||||
{{on "click" (fn this.editAutomation automation)}}
|
||||
>
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{format-enabled-automation
|
||||
automation.enabled
|
||||
automation.trigger
|
||||
}}
|
||||
</td>
|
||||
<td
|
||||
class="d-admin-row__overview automations__name"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
{{on "keypress" (fn this.editAutomation automation)}}
|
||||
{{on "click" (fn this.editAutomation automation)}}
|
||||
>
|
||||
{{if
|
||||
automation.name
|
||||
automation.name
|
||||
(i18n "discourse_automation.unnamed_automation")
|
||||
}}
|
||||
</td>
|
||||
<td
|
||||
class="d-admin-row__detail automations__script"
|
||||
role="button"
|
||||
{{on "click" (fn this.editAutomation automation)}}
|
||||
>
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.trigger.label"}}
|
||||
</div>
|
||||
{{if automation.trigger.id automation.trigger.name "-"}}
|
||||
</td>
|
||||
<td
|
||||
class="d-admin-row__detail automations__version"
|
||||
role="button"
|
||||
{{on "click" (fn this.editAutomation automation)}}
|
||||
>
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.script.label"}}
|
||||
</div>
|
||||
{{automation.script.name}}
|
||||
(v{{automation.script.version}})
|
||||
</td>
|
||||
<td class="d-admin-row__detail automations__updated-by">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n
|
||||
"discourse_automation.models.automation.last_updated_by.label"
|
||||
}}
|
||||
</div>
|
||||
<div class="automations__user-timestamp">
|
||||
<a
|
||||
href={{automation.last_updated_by.userPath}}
|
||||
data-user-card={{automation.last_updated_by.username}}
|
||||
>
|
||||
{{avatar automation.last_updated_by imageSize="small"}}
|
||||
</a>
|
||||
{{format-date automation.updated_at leaveAgo="true"}}
|
||||
</div>
|
||||
</td>
|
||||
{{/if}}
|
||||
|
||||
<td class="d-admin-row__controls automations__delete">
|
||||
<DButton
|
||||
@icon="trash-can"
|
||||
@action={{action "destroyAutomation" automation}}
|
||||
class="btn-danger"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
@ -1,33 +0,0 @@
|
||||
<section class="discourse-automation-form new">
|
||||
|
||||
<div
|
||||
class="admin-section-landing__header"
|
||||
{{did-insert this.resetFilterText}}
|
||||
>
|
||||
<h2>{{i18n "discourse_automation.select_script"}}</h2>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder={{i18n "discourse_automation.filter_placeholder"}}
|
||||
{{on "input" this.updateFilterText}}
|
||||
class="admin-section-landing__header-filter"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{{#unless this.model.scripts.length}}
|
||||
<div class="alert alert-info">
|
||||
<p>{{i18n "discourse_automation.no_automation_yet"}}</p>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="admin-section-landing__wrapper">
|
||||
{{#each this.scriptableContent as |script|}}
|
||||
<AdminSectionLandingItem
|
||||
{{on "click" (fn this.selectScriptToEdit script)}}
|
||||
@titleLabelTranslated={{script.name}}
|
||||
@descriptionLabelTranslated={{script.description}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
</section>
|
@ -1,21 +0,0 @@
|
||||
<LinkTo
|
||||
@route="adminPlugins.discourse-automation"
|
||||
class="discourse-automation-title"
|
||||
>
|
||||
<h1 class="title">
|
||||
{{i18n "discourse_automation.title"}}
|
||||
</h1>
|
||||
|
||||
{{#if this.showNewAutomation}}
|
||||
<DButton
|
||||
@label="discourse_automation.create"
|
||||
@icon="plus"
|
||||
@action={{action "newAutomation"}}
|
||||
class="new-automation"
|
||||
/>
|
||||
{{/if}}
|
||||
</LinkTo>
|
||||
|
||||
<hr />
|
||||
|
||||
{{outlet}}
|
@ -31,7 +31,7 @@ export default class AutomationEdit extends Controller {
|
||||
this.setProperties({ error: null, isUpdatingAutomation: true });
|
||||
|
||||
return ajax(
|
||||
`/admin/plugins/discourse-automation/automations/${this.model.automation.id}.json`,
|
||||
`/admin/plugins/automation/automations/${this.model.automation.id}.json`,
|
||||
{
|
||||
type: "PUT",
|
||||
data: JSON.stringify({ automation: this.automationForm }),
|
||||
@ -42,7 +42,7 @@ export default class AutomationEdit extends Controller {
|
||||
.then(() => {
|
||||
this.send("refreshRoute");
|
||||
if (routeToIndex) {
|
||||
this.router.transitionTo("adminPlugins.discourse-automation.index");
|
||||
this.router.transitionTo("adminPlugins.show.automation.index");
|
||||
}
|
||||
})
|
||||
.catch((e) => this._showError(e))
|
@ -12,14 +12,14 @@ export default class AutomationIndex extends Controller {
|
||||
@action
|
||||
editAutomation(automation) {
|
||||
this.router.transitionTo(
|
||||
"adminPlugins.discourse-automation.edit",
|
||||
"adminPlugins.show.automation.edit",
|
||||
automation.id
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
newAutomation() {
|
||||
this.router.transitionTo("adminPlugins.discourse-automation.new");
|
||||
this.router.transitionTo("adminPlugins.show.automation.new");
|
||||
}
|
||||
|
||||
@action
|
@ -38,7 +38,7 @@ export default class AutomationNew extends Controller {
|
||||
selectScriptToEdit(newScript) {
|
||||
this.model.automation.save({ script: newScript.id }).then(() => {
|
||||
this.router.transitionTo(
|
||||
"adminPlugins.discourse-automation.edit",
|
||||
"adminPlugins.show.automation.edit",
|
||||
this.model.automation.id
|
||||
);
|
||||
});
|
@ -2,18 +2,16 @@ import { action } from "@ember/object";
|
||||
import { hash } from "rsvp";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import Field from "../models/discourse-automation-field";
|
||||
import Field from "discourse/plugins/automation/admin/models/discourse-automation-field";
|
||||
|
||||
export default class AutomationEdit extends DiscourseRoute {
|
||||
controllerName = "admin-plugins-discourse-automation-edit";
|
||||
|
||||
model(params) {
|
||||
return hash({
|
||||
scriptables: this.store
|
||||
.findAll("discourse-automation-scriptable")
|
||||
.then((result) => result.content),
|
||||
triggerables: ajax(
|
||||
`/admin/plugins/discourse-automation/triggerables.json?automation_id=${params.id}`
|
||||
`/admin/plugins/automation/triggerables.json?automation_id=${params.id}`
|
||||
).then((result) => (result ? result.triggerables : [])),
|
||||
automation: this.store.find("discourse-automation-automation", params.id),
|
||||
});
|
@ -5,18 +5,10 @@ import DiscourseRoute from "discourse/routes/discourse";
|
||||
export default class AutomationIndex extends DiscourseRoute {
|
||||
@service router;
|
||||
|
||||
controllerName = "admin-plugins-discourse-automation-index";
|
||||
|
||||
model() {
|
||||
return this.store.findAll("discourse-automation-automation");
|
||||
}
|
||||
|
||||
afterModel(model) {
|
||||
if (!model.length) {
|
||||
this.router.transitionTo("adminPlugins.discourse-automation.new");
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
triggerRefresh() {
|
||||
this.refresh();
|
@ -2,8 +2,6 @@ import { hash } from "rsvp";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class AutomationNew extends DiscourseRoute {
|
||||
controllerName = "admin-plugins-discourse-automation-new";
|
||||
|
||||
model() {
|
||||
return hash({
|
||||
scripts: this.store.findAll("discourse-automation-automation"),
|
@ -0,0 +1,189 @@
|
||||
<div class="admin-detail discourse-automation-edit discourse-automation-form">
|
||||
<BackButton
|
||||
@label="discourse_automation.back"
|
||||
@route="adminPlugins.show.automation.index"
|
||||
class="discourse-automation-back"
|
||||
/>
|
||||
<AdminConfigAreaCard @heading="discourse_automation.select_script">
|
||||
<:content>
|
||||
<form class="form-horizontal">
|
||||
<FormError @error={{this.error}} />
|
||||
|
||||
<section class="form-section edit">
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.automation.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<TextField
|
||||
@value={{this.automationForm.name}}
|
||||
@type="text"
|
||||
@autofocus={{true}}
|
||||
@name="automation-name"
|
||||
class="input-large"
|
||||
@input={{with-event-value (fn (mut this.automationForm.name))}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.script.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<ComboBox
|
||||
@value={{this.automationForm.script}}
|
||||
@content={{this.model.scriptables}}
|
||||
@onChange={{this.onChangeScript}}
|
||||
@options={{hash filterable=true}}
|
||||
class="scriptables"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="trigger-section form-section edit">
|
||||
<h2 class="title">
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.trigger_section.title"
|
||||
}}
|
||||
</h2>
|
||||
|
||||
<div class="control-group">
|
||||
{{#if this.model.automation.script.forced_triggerable}}
|
||||
<div class="alert alert-warning">
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.trigger_section.forced"
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<label class="control-label">
|
||||
{{i18n "discourse_automation.models.trigger.name.label"}}
|
||||
</label>
|
||||
|
||||
<div class="controls">
|
||||
<ComboBox
|
||||
@value={{this.automationForm.trigger}}
|
||||
@content={{this.model.triggerables}}
|
||||
@onChange={{this.onChangeTrigger}}
|
||||
@options={{hash
|
||||
filterable=true
|
||||
none="discourse_automation.select_trigger"
|
||||
disabled=this.model.automation.script.forced_triggerable
|
||||
}}
|
||||
class="triggerables"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
{{#if this.model.automation.trigger.doc}}
|
||||
<div class="alert alert-info">
|
||||
<p>{{this.model.automation.trigger.doc}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if
|
||||
(and
|
||||
this.model.automation.enabled
|
||||
this.model.automation.trigger.settings.manual_trigger
|
||||
)
|
||||
}}
|
||||
<div class="alert alert-info next-trigger">
|
||||
|
||||
{{#if this.nextPendingAutomationAtFormatted}}
|
||||
<p>
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.trigger_section.next_pending_automation"
|
||||
date=this.nextPendingAutomationAtFormatted
|
||||
}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@label="discourse_automation.edit_automation.trigger_section.trigger_now"
|
||||
@isLoading={{this.isTriggeringAutomation}}
|
||||
@action={{fn
|
||||
this.onManualAutomationTrigger
|
||||
this.model.automation.id
|
||||
}}
|
||||
class="btn-primary trigger-now-btn"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#each this.triggerFields as |field|}}
|
||||
<AutomationField
|
||||
@automation={{this.automation}}
|
||||
@field={{field}}
|
||||
@saveAutomation={{fn this.saveAutomation this.automation}}
|
||||
/>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
{{#if this.scriptFields}}
|
||||
<section class="fields-section form-section edit">
|
||||
<h2 class="title">
|
||||
{{i18n
|
||||
"discourse_automation.edit_automation.fields_section.title"
|
||||
}}
|
||||
</h2>
|
||||
|
||||
{{#if this.model.automation.script.with_trigger_doc}}
|
||||
<div class="alert alert-info">
|
||||
<p>{{this.model.automation.script.with_trigger_doc}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
{{#each this.scriptFields as |field|}}
|
||||
<AutomationField
|
||||
@automation={{this.automation}}
|
||||
@field={{field}}
|
||||
@saveAutomation={{fn this.saveAutomation this.automation}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.automationForm.trigger}}
|
||||
<div
|
||||
class="control-group automation-enabled alert
|
||||
{{if this.automationForm.enabled 'alert-info' 'alert-warning'}}"
|
||||
>
|
||||
<span>{{i18n
|
||||
"discourse_automation.models.automation.enabled.label"
|
||||
}}</span>
|
||||
<Input
|
||||
@type="checkbox"
|
||||
@checked={{this.automationForm.enabled}}
|
||||
{{on
|
||||
"click"
|
||||
(action
|
||||
(mut this.automationForm.enabled) value="target.checked"
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
<DButton
|
||||
@isLoading={{this.isUpdatingAutomation}}
|
||||
@label="discourse_automation.update"
|
||||
@type="submit"
|
||||
@action={{fn this.saveAutomation this.automation true}}
|
||||
class="btn-primary update-automation"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
</form>
|
||||
</:content>
|
||||
</AdminConfigAreaCard>
|
||||
</div>
|
@ -0,0 +1,131 @@
|
||||
<section class="discourse-automations-table">
|
||||
<DPageSubheader @titleLabel={{i18n "discourse_automation.table_title"}}>
|
||||
<:actions as |actions|>
|
||||
<actions.Primary
|
||||
@label="discourse_automation.create"
|
||||
@route="adminPlugins.show.automation.new"
|
||||
@icon="plus"
|
||||
class="discourse-automation__create-btn"
|
||||
/>
|
||||
</:actions>
|
||||
</DPageSubheader>
|
||||
|
||||
{{#if this.model.length}}
|
||||
<table class="d-admin-table automations">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{{i18n "discourse_automation.models.automation.name.label"}}</th>
|
||||
<th>{{i18n
|
||||
"discourse_automation.models.automation.trigger.label"
|
||||
}}</th>
|
||||
<th>{{i18n
|
||||
"discourse_automation.models.automation.script.label"
|
||||
}}</th>
|
||||
<th>{{i18n
|
||||
"discourse_automation.models.automation.last_updated_by.label"
|
||||
}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this.model as |automation|}}
|
||||
<tr class="d-admin-row__content">
|
||||
{{#if automation.script.not_found}}
|
||||
<td colspan="5" class="d-admin-row__detail alert alert-danger">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{i18n
|
||||
"discourse_automation.scriptables.not_found"
|
||||
script=automation.script.id
|
||||
automation=automation.name
|
||||
}}
|
||||
</td>
|
||||
{{else if automation.trigger.not_found}}
|
||||
<td colspan="5" class="d-admin-row__detail alert alert-danger">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{i18n
|
||||
"discourse_automation.triggerables.not_found"
|
||||
trigger=automation.trigger.id
|
||||
automation=automation.name
|
||||
}}
|
||||
</td>
|
||||
{{else}}
|
||||
<td class="d-admin-row__detail automations__status">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.status.label"}}
|
||||
</div>
|
||||
{{format-enabled-automation
|
||||
automation.enabled
|
||||
automation.trigger
|
||||
}}
|
||||
</td>
|
||||
<td class="d-admin-row__overview automations__name">
|
||||
{{if
|
||||
automation.name
|
||||
automation.name
|
||||
(i18n "discourse_automation.unnamed_automation")
|
||||
}}
|
||||
</td>
|
||||
<td class="d-admin-row__detail automations__script">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n
|
||||
"discourse_automation.models.automation.trigger.label"
|
||||
}}
|
||||
</div>
|
||||
{{if automation.trigger.id automation.trigger.name "-"}}
|
||||
</td>
|
||||
<td class="d-admin-row__detail automations__version">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n "discourse_automation.models.automation.script.label"}}
|
||||
</div>
|
||||
{{automation.script.name}}
|
||||
(v{{automation.script.version}})
|
||||
</td>
|
||||
<td class="d-admin-row__detail automations__updated-by">
|
||||
<div class="d-admin-row__mobile-label">
|
||||
{{i18n
|
||||
"discourse_automation.models.automation.last_updated_by.label"
|
||||
}}
|
||||
</div>
|
||||
<div class="automations__user-timestamp">
|
||||
<a
|
||||
href={{automation.last_updated_by.userPath}}
|
||||
data-user-card={{automation.last_updated_by.username}}
|
||||
>
|
||||
{{avatar automation.last_updated_by imageSize="small"}}
|
||||
</a>
|
||||
{{format-date automation.updated_at leaveAgo="true"}}
|
||||
</div>
|
||||
</td>
|
||||
{{/if}}
|
||||
|
||||
<td class="d-admin-row__controls automations__controls">
|
||||
<DButton
|
||||
@label="discourse_automation.edit"
|
||||
class="btn-small"
|
||||
@action={{action "editAutomation" automation}}
|
||||
/>
|
||||
|
||||
<DButton
|
||||
@icon="trash-can"
|
||||
@action={{action "destroyAutomation" automation}}
|
||||
class="btn-small btn-danger"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
<AdminConfigAreaEmptyList
|
||||
@ctaLabel="discourse_automation.create"
|
||||
@ctaRoute="adminPlugins.show.automation.new"
|
||||
@ctaClass="discourse-automation__create-btn"
|
||||
@emptyLabel="discourse_automation.no_automation_yet"
|
||||
/>
|
||||
{{/if}}
|
||||
</section>
|
@ -0,0 +1,27 @@
|
||||
<div class="admin-detail discourse-automation-new discourse-automation-form">
|
||||
<BackButton
|
||||
@label="discourse_automation.back"
|
||||
@route="adminPlugins.show.automation.index"
|
||||
class="discourse-automation-back"
|
||||
/>
|
||||
<AdminConfigAreaCard @heading="discourse_automation.select_script">
|
||||
<:content>
|
||||
<input
|
||||
type="text"
|
||||
placeholder={{i18n "discourse_automation.filter_placeholder"}}
|
||||
{{on "input" this.updateFilterText}}
|
||||
class="admin-section-landing__header-filter"
|
||||
/>
|
||||
|
||||
<div class="admin-section-landing__wrapper">
|
||||
{{#each this.scriptableContent as |script|}}
|
||||
<AdminSectionLandingItem
|
||||
{{on "click" (fn this.selectScriptToEdit script)}}
|
||||
@titleLabelTranslated={{script.name}}
|
||||
@descriptionLabelTranslated={{script.description}}
|
||||
/>
|
||||
{{/each}}
|
||||
</div>
|
||||
</:content>
|
||||
</AdminConfigAreaCard>
|
||||
</div>
|
@ -1,11 +1,11 @@
|
||||
export default {
|
||||
resource: "admin.adminPlugins",
|
||||
resource: "admin.adminPlugins.show",
|
||||
|
||||
path: "/plugins",
|
||||
|
||||
map() {
|
||||
this.route(
|
||||
"discourse-automation",
|
||||
"automation",
|
||||
|
||||
function () {
|
||||
this.route("new");
|
@ -0,0 +1,21 @@
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
|
||||
export default {
|
||||
name: "automation-admin-plugin-configuration-nav",
|
||||
|
||||
initialize(container) {
|
||||
const currentUser = container.lookup("service:current-user");
|
||||
if (!currentUser?.admin) {
|
||||
return;
|
||||
}
|
||||
|
||||
withPluginApi("1.1.0", (api) => {
|
||||
api.addAdminPluginConfigurationNav("automation", [
|
||||
{
|
||||
label: "discourse_automation.title",
|
||||
route: "adminPlugins.show.automation",
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
.discourse-automation {
|
||||
.admin-plugins.automation {
|
||||
.automations {
|
||||
.relative-date {
|
||||
font-size: $font-down-1;
|
||||
@ -13,6 +13,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.discourse-automations-table {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.d-admin-table.automations {
|
||||
.d-admin-row__content {
|
||||
@include breakpoint("tablet") {
|
||||
@ -51,6 +55,18 @@
|
||||
order: 5;
|
||||
}
|
||||
}
|
||||
|
||||
.d-admin-row__controls.automations__controls {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5em;
|
||||
justify-content: flex-end;
|
||||
|
||||
@include breakpoint("tablet") {
|
||||
order: 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-section-landing__header {
|
||||
|
@ -7,13 +7,16 @@ en:
|
||||
delete_automation: delete automation
|
||||
discourse_automation:
|
||||
title: Automation
|
||||
create: Create
|
||||
update: Update
|
||||
table_title: Automations
|
||||
create: Add automation
|
||||
update: Update automation
|
||||
back: Back
|
||||
edit: Edit
|
||||
select_script: Select a script
|
||||
select_trigger: Select a trigger
|
||||
confirm_automation_reset: This action will reset script and trigger options, new state will be saved, do you want to proceed?
|
||||
confirm_automation_trigger: This action will trigger the automation, do you want to proceed?
|
||||
no_automation_yet: You haven’t created any automations yet. Choose an option below to get started.
|
||||
no_automation_yet: There are currently no automations configured.
|
||||
filter_placeholder: Filter by name or description...
|
||||
edit_automation:
|
||||
trigger_section:
|
||||
|
@ -10,13 +10,13 @@ DiscourseAutomation::Engine.routes.draw do
|
||||
put "/append-last-checked-by/:post_id" => "append_last_checked_by#post_checked"
|
||||
end
|
||||
|
||||
scope "/admin/plugins/discourse-automation",
|
||||
scope "/admin/plugins/automation",
|
||||
as: "admin_discourse_automation",
|
||||
constraints: AdminConstraint.new do
|
||||
scope format: false do
|
||||
get "/" => "admin#index"
|
||||
get "/new" => "admin#new"
|
||||
get "/:id" => "admin#edit"
|
||||
get "/automation" => "admin#index"
|
||||
get "/automation/new" => "admin#new"
|
||||
get "/automation/:id" => "admin#edit"
|
||||
end
|
||||
|
||||
scope format: :json do
|
||||
|
@ -87,7 +87,7 @@ after_initialize do
|
||||
Plugin::Instance.prepend DiscourseAutomation::PluginInstanceExtension
|
||||
end
|
||||
|
||||
add_admin_route "discourse_automation.title", "discourse-automation"
|
||||
add_admin_route "discourse_automation.title", "automation", use_new_show_route: true
|
||||
|
||||
add_api_key_scope(
|
||||
:automations_trigger,
|
||||
|
@ -32,7 +32,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:admin)) }
|
||||
|
||||
it "shows the automation" do
|
||||
get "/admin/plugins/discourse-automation/automations/#{automation.id}.json"
|
||||
get "/admin/plugins/automation/automations/#{automation.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["automation"]["id"]).to eq(automation.id)
|
||||
end
|
||||
@ -42,7 +42,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
|
||||
it "raises a 404" do
|
||||
get "/admin/plugins/discourse-automation/automations/#{automation.id}.json"
|
||||
get "/admin/plugins/automation/automations/#{automation.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
@ -63,7 +63,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:admin)) }
|
||||
|
||||
it "creates the 'forced triggerable' automation" do
|
||||
post "/admin/plugins/discourse-automation/automations.json",
|
||||
post "/admin/plugins/automation/automations.json",
|
||||
params: {
|
||||
automation: {
|
||||
name: "foobar",
|
||||
@ -78,7 +78,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
|
||||
it "raises a 404" do
|
||||
post "/admin/plugins/discourse-automation/automations.json",
|
||||
post "/admin/plugins/automation/automations.json",
|
||||
params: {
|
||||
automation: {
|
||||
name: "foobar",
|
||||
@ -95,7 +95,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:admin)) }
|
||||
|
||||
it "updates the automation" do
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
trigger: "another-trigger",
|
||||
@ -106,7 +106,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
|
||||
describe "invalid field’s component" do
|
||||
it "errors" do
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
script: automation.script,
|
||||
@ -129,7 +129,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
end
|
||||
|
||||
it "errors" do
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
script: automation.script,
|
||||
@ -147,7 +147,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
it "forces the automation to be disabled" do
|
||||
expect(automation.enabled).to eq(true)
|
||||
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
script: "bar",
|
||||
@ -164,7 +164,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
it "forces the automation to be disabled" do
|
||||
expect(automation.enabled).to eq(true)
|
||||
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
script: automation.script,
|
||||
@ -181,7 +181,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
it "disables the automation" do
|
||||
expect(automation.enabled).to eq(true)
|
||||
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
trigger: automation.trigger,
|
||||
@ -196,7 +196,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
|
||||
context "with invalid field’s metadata" do
|
||||
it "errors" do
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
script: automation.script,
|
||||
@ -214,7 +214,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
|
||||
it "raises a 404" do
|
||||
put "/admin/plugins/discourse-automation/automations/#{automation.id}.json",
|
||||
put "/admin/plugins/automation/automations/#{automation.id}.json",
|
||||
params: {
|
||||
automation: {
|
||||
trigger: "another-trigger",
|
||||
@ -232,13 +232,13 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:admin)) }
|
||||
|
||||
it "destroys the automation" do
|
||||
delete "/admin/plugins/discourse-automation/automations/#{automation.id}.json"
|
||||
delete "/admin/plugins/automation/automations/#{automation.id}.json"
|
||||
expect(DiscourseAutomation::Automation.find_by(id: automation.id)).to eq(nil)
|
||||
end
|
||||
|
||||
context "when the automation is not found" do
|
||||
it "raises a 404" do
|
||||
delete "/admin/plugins/discourse-automation/automations/999.json"
|
||||
delete "/admin/plugins/automation/automations/999.json"
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
@ -248,7 +248,7 @@ describe DiscourseAutomation::AdminAutomationsController do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
|
||||
it "raises a 404" do
|
||||
delete "/admin/plugins/discourse-automation/automations/#{automation.id}.json"
|
||||
delete "/admin/plugins/automation/automations/#{automation.id}.json"
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
@ -4,7 +4,7 @@ module PageObjects
|
||||
module Pages
|
||||
class Automation < PageObjects::Pages::Base
|
||||
def visit(automation)
|
||||
super("/admin/plugins/discourse-automation/#{automation.id}")
|
||||
super("/admin/plugins/automation/automation/#{automation.id}")
|
||||
self
|
||||
end
|
||||
|
||||
@ -34,7 +34,7 @@ module PageObjects
|
||||
end
|
||||
|
||||
def form
|
||||
@form ||= find(".discourse-automation-form.edit")
|
||||
@form ||= find(".discourse-automation-edit")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -4,7 +4,7 @@ module PageObjects
|
||||
module Pages
|
||||
class NewAutomation < PageObjects::Pages::Base
|
||||
def visit
|
||||
super("/admin/plugins/discourse-automation/new")
|
||||
super("/admin/plugins/automation/automation/new")
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -21,7 +21,10 @@ describe "DiscourseAutomation | smoke test", type: :system do
|
||||
after { DiscourseAutomation::Scriptable.remove("test") }
|
||||
|
||||
it "populate correctly" do
|
||||
visit("/admin/plugins/discourse-automation")
|
||||
visit("/admin/plugins/automation")
|
||||
|
||||
find(".admin-config-area-empty-list__cta-button").click
|
||||
|
||||
find(".admin-section-landing__header-filter").set("test")
|
||||
find(".admin-section-landing-item__content", match: :first).click
|
||||
fill_in("automation-name", with: "aaaaa")
|
||||
@ -34,7 +37,9 @@ describe "DiscourseAutomation | smoke test", type: :system do
|
||||
end
|
||||
|
||||
it "works" do
|
||||
visit("/admin/plugins/discourse-automation")
|
||||
visit("/admin/plugins/automation")
|
||||
|
||||
find(".admin-config-area-empty-list__cta-button").click
|
||||
|
||||
find(".admin-section-landing__header-filter").set("user group membership through badge")
|
||||
find(".admin-section-landing-item__content", match: :first).click
|
||||
@ -51,6 +56,6 @@ describe "DiscourseAutomation | smoke test", type: :system do
|
||||
find(".automation-enabled input").click
|
||||
find(".update-automation").click
|
||||
|
||||
expect(page).to have_css('[role="button"]', text: "aaaaa")
|
||||
expect(page).to have_css(".automations__name", text: "aaaaa")
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user