blob: 1818ea79ce0088db0cc1df7e9a87b5c5ec5c7f73 [file] [log] [blame]
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +02001import '@material/web/button/outlined-button.js';
Renovate botaa5fb8e2024-02-25 18:10:09 +00002import '@material/web/icon/icon.js';
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +02003import '@material/web/textfield/filled-text-field.js';
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +02004import './ActionEditor.js';
5
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +02006import {css, html, LitElement, nothing} from 'lit';
7import {createRef, ref} from 'lit/directives/ref.js';
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +02008import {repeat} from 'lit/directives/repeat.js';
9
10import * as pb from '../../proto/main_pb.js';
Adrià Vilanova Martínez7f1e8ea2022-10-14 15:50:11 +020011import WorkflowsStorage from '../../workflowsStorage.js';
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020012
13export default class WFWorkflowEditor extends LitElement {
14 static properties = {
15 workflow: {type: Object},
16 readOnly: {type: Boolean},
17 };
18
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +020019 static styles = css`
20 .name {
21 width: 100%;
22 margin-bottom: 20px;
23 }
24 `;
25
26 nameRef = createRef();
27
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020028 constructor() {
29 super();
30 this.workflow = new pb.workflows.Workflow();
31 this.readOnly = false;
32 }
33
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +020034 renderName() {
35 return html`
36 <md-filled-text-field ${ref(this.nameRef)}
37 class="name"
38 placeholder="Untitled workflow"
39 value=${this.workflow.getName()}
40 required
41 @input=${this._nameChanged}>
42 </md-filled-text-field>
43 `;
44 }
45
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020046 renderActions() {
47 return repeat(this._actions(), (action, i) => html`
48 <wf-action-editor
49 .action=${action}
50 ?readOnly=${this.readOnly}
51 ?disableRemoveButton=${this._actions().length <= 1}
52 step=${i + 1}
53 @action-removed=${() => this._removeAction(i)}>
54 </wf-action-editor>
55 `);
56 }
57
58 renderAddActionBtn() {
59 if (this.readOnly) return nothing;
60 return html`
61 <md-outlined-button
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020062 @click=${this._addAction}>
Renovate botaa5fb8e2024-02-25 18:10:09 +000063 <md-icon slot="icon">add</md-icon>
64 Add another action
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020065 </md-outlined-button>
66 `;
67 }
68
69 render() {
70 return [
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +020071 this.renderName(),
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020072 this.renderActions(),
73 this.renderAddActionBtn(),
74 ];
75 }
76
Adrià Vilanova Martínez8803b6c2022-10-17 00:36:38 +020077 checkValidity() {
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020078 let allValid = true;
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +020079
80 // Check the workflow name is set
81 allValid &&= this.nameRef.value.reportValidity();
82
83 // Check all the actions are well-formed
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020084 const actionEditors = this.renderRoot.querySelectorAll('wf-action-editor');
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +020085 for (const editor of actionEditors) allValid &&= editor.checkValidity();
86
Adrià Vilanova Martínez8803b6c2022-10-17 00:36:38 +020087 return allValid;
88 }
89
90 save(uuid) {
91 const allValid = this.checkValidity();
92
Adrià Vilanova Martínez7f1e8ea2022-10-14 15:50:11 +020093 // Save the workflow if the validation checks passed
Adrià Vilanova Martínez8803b6c2022-10-17 00:36:38 +020094 if (allValid) {
95 if (!uuid)
96 WorkflowsStorage.add(this.workflow);
97 else
98 WorkflowsStorage.update(uuid, this.workflow);
99 }
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +0200100
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +0200101 return allValid;
102 }
103
104 _actions() {
105 return this.workflow.getActionsList();
106 }
107
Adrià Vilanova Martínezc5507dd2022-10-13 23:04:01 +0200108 _nameChanged() {
109 this.workflow.setName(this.nameRef.value.value);
110 this._dispatchUpdateEvent();
111 }
112
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +0200113 _addAction() {
114 let action = new pb.workflows.Action();
115 let rAction = new pb.workflows.Action.ReplyWithCRAction();
116 action.setReplyWithCrAction(rAction);
117 this.workflow.addActions(action);
118 this._dispatchUpdateEvent();
119 }
120
121 _removeAction(index) {
122 let actions = this.workflow.getActionsList();
123 actions.splice(index, 1);
124 this.workflow.setActionsList(actions);
125 this._dispatchUpdateEvent();
126 }
127
128 _updateAction(index, action) {
129 let actions = this.workflow.getActionsList();
130 actions[index] = action;
131 this.workflow.setActionsList(actions);
132 this._dispatchUpdateEvent();
133 }
134
135 _dispatchUpdateEvent() {
136 // Request an update for this component
137 this.requestUpdate();
138
139 // Transmit to other components that the workflow has changed
140 const e = new Event('workflow-updated', {bubbles: true, composed: true});
141 this.renderRoot.dispatchEvent(e);
142 }
143}
144window.customElements.define('wf-workflow-editor', WFWorkflowEditor);