blob: c4b3fafdee3a96bbb2db37f0d5a0c8c528503bf9 [file] [log] [blame]
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +02001import './actions/ReplyWithCR.js';
2
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +02003import '@material/mwc-circular-progress/mwc-circular-progress.js';
4
5import {html, LitElement, nothing} from 'lit';
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +02006import {map} from 'lit/directives/map.js';
7import {createRef, ref} from 'lit/directives/ref.js';
8
9import * as pb from '../../proto/main_pb.js';
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020010import {kActionHeadings, kActionStyles, kSupportedActions} from '../shared/actions.js';
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020011
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020012const actionCases = Object.entries(pb.workflows.Action.ActionCase);
13
14export default class WFActionEditor extends LitElement {
15 static properties = {
16 action: {type: Object},
17 readOnly: {type: Boolean},
18 disableRemoveButton: {type: Boolean},
19 step: {type: Number},
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020020 status: {type: String},
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020021 };
22
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020023 static styles = kActionStyles;
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020024
25 selectRef = createRef();
26
27 constructor() {
28 super();
29 this.action = new pb.workflows.Action();
30 this.readOnly = false;
31 }
32
33 renderActionTitle() {
34 if (this.readOnly) return html`<h3 class="title">${this._stepTitle()}</h3>`;
35
36 let selectedActionCase = this._actionCase;
37
38 return html`
39 <select ${ref(this.selectRef)}
40 class="select"
41 @change=${this._actionCaseChanged}>
42 ${map(actionCases, ([actionName, num]) => {
Adrià Vilanova Martínez6d912742022-10-16 23:57:26 +020043 if (!kSupportedActions.has(num)) return nothing;
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020044 return html`
45 <option value=${num} ?selected=${selectedActionCase == num}>
46 ${kActionHeadings[num] ?? actionName}
47 </option>
48 `;
49 })}
50 </select>
51 `;
52 }
53
54 renderSpecificActionEditor() {
55 switch (this._actionCase) {
56 case pb.workflows.Action.ActionCase.REPLY_WITH_CR_ACTION:
57 return html`
58 <wf-action-reply-with-cr
59 ?readOnly=${this.readOnly}
60 .action=${this.action.getReplyWithCrAction()}>
61 </wf-action-reply-with-cr>
62 `;
63
64 default:
65 return html`<p>This action has not yet been implemented.</p>`;
66 }
67 }
68
69 render() {
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020070 let actionClass = '';
71 if (this.readOnly && this.status) actionClass = 'action--' + this.status;
72 return html`
73 <div class="action ${actionClass}">
74 <div class="header">
75 <div class="step">
76 ${this.step}
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020077 ${
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020078 this.status == 'running' ?
79 html`<mwc-circular-progress indeterminate density="-1"></mwc-circular-progress>` :
80 ''}
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020081 </div>
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020082 ${this.renderActionTitle()}
83 ${
84 !this.readOnly ? html`
85 <button
86 ?disabled=${this.disableRemoveButton}
87 @click=${this._remove}>
88 Remove
89 </button>
90 ` :
91 nothing}
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020092 </div>
Adrià Vilanova Martínez54964a52022-10-26 23:53:29 +020093 ${this.renderSpecificActionEditor()}
94 </div>
95 `;
Adrià Vilanova Martínezf276ac72022-10-13 22:16:22 +020096 }
97
98 checkValidity() {
99 if (this.readOnly || !kSupportedActions.has(this._actionCase)) return true;
100 return this._specificActionEditor().checkValidity();
101 }
102
103 _actionCaseChanged() {
104 this._actionCaseString = this.selectRef.value.value;
105 }
106
107 _dispatchUpdateEvent() {
108 // Transmit to other components that the action has changed
109 const e = new Event('action-updated', {bubbles: true, composed: true});
110 this.renderRoot.dispatchEvent(e);
111 }
112
113 _remove() {
114 // Transmit to other components that the action has to be removed
115 const e = new Event('action-removed', {bubbles: true, composed: true});
116 this.renderRoot.dispatchEvent(e);
117 }
118
119 _stepTitle() {
120 return kActionHeadings[this._actionCase] ?? this._actionCase;
121 }
122
123 get _actionCase() {
124 return this.action.getActionCase();
125 }
126
127 set _actionCase(newCase) {
128 let value;
129 switch (newCase) {
130 case pb.workflows.Action.ActionCase.REPLY_ACTION:
131 value = new pb.workflows.Action.ReplyAction;
132 this.action.setReplyAction(value);
133 break;
134 case pb.workflows.Action.ActionCase.MOVE_ACTION:
135 value = new pb.workflows.Action.MoveAction;
136 this.action.setMoveAction(value);
137 break;
138 case pb.workflows.Action.ActionCase.MARK_DUPLICATE_ACTION:
139 value = new pb.workflows.Action.MarkDuplicateAction;
140 this.action.setMarkDuplicateAction(value);
141 break;
142 case pb.workflows.Action.ActionCase.UNMARK_DUPLICATE_ACTION:
143 value = new pb.workflows.Action.UnmarkDuplicateAction;
144 this.action.setUnmarkDuplicateAction(value);
145 break;
146 case pb.workflows.Action.ActionCase.ATTRIBUTE_ACTION:
147 value = new pb.workflows.Action.AttributeAction;
148 this.action.setAttributeAction(value);
149 break;
150 case pb.workflows.Action.ActionCase.REPLY_WITH_CR_ACTION:
151 value = new pb.workflows.Action.ReplyWithCRAction;
152 this.action.setReplyWithCrAction(value);
153 break;
154 case pb.workflows.Action.ActionCase.STAR_ACTION:
155 value = new pb.workflows.Action.StarAction;
156 this.action.setStarAction(value);
157 break;
158 case pb.workflows.Action.ActionCase.SUBSCRIBE_ACTION:
159 value = new pb.workflows.Action.SubscribeAction;
160 this.action.setSubscribeAction(value);
161 break;
162 case pb.workflows.Action.ActionCase.VOTE_ACTION:
163 value = new pb.workflows.Action.VoteAction;
164 this.action.setVoteAction(value);
165 break;
166 case pb.workflows.Action.ActionCase.REPORT_ACTION:
167 value = new pb.workflows.Action.ReportAction;
168 this.action.setReportAction(value);
169 break;
170 default:
171 this.action.clearReplyAction();
172 this.action.clearMoveAction();
173 this.action.clearMarkDuplicateAction();
174 this.action.clearUnmarkDuplicateAction();
175 this.action.clearAttributeAction();
176 this.action.clearReplyWithCrAction();
177 this.action.clearStarAction();
178 this.action.clearSubscribeAction();
179 this.action.clearVoteAction();
180 this.action.clearReportAction();
181 }
182
183 this.requestUpdate();
184 this._dispatchUpdateEvent();
185 }
186
187 // The same as _actionCase, but represented as a String instead of a Number
188 get _actionCaseString() {
189 return this._actionCase.toString();
190 }
191
192 set _actionCaseString(newCase) {
193 this._actionCase = parseInt(newCase);
194 }
195
196 _specificActionEditor() {
197 switch (this._actionCase) {
198 case pb.workflows.Action.ActionCase.REPLY_WITH_CR_ACTION:
199 return this.renderRoot.querySelector('wf-action-reply-with-cr');
200
201 default:
202 return null;
203 }
204 }
205}
206window.customElements.define('wf-action-editor', WFActionEditor);