blob: 312f84a5dba46fc16b4baa8404cd78e7aff33e05 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001// Copyright 2020 The Chromium Authors
Copybara854996b2021-09-07 19:36:02 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {html, css} from 'lit-element';
6
7import 'elements/framework/mr-warning/mr-warning.js';
8import {hotlists} from 'reducers/hotlists.js';
9import {prpcClient} from 'prpc-client-instance.js';
10import {MrIssueHotlistsDialog} from './mr-issue-hotlists-dialog';
11
12/**
13 * `<mr-move-issue-hotlists-dialog>`
14 *
15 * Displays a dialog to select the Hotlist to move the provided Issues.
16 */
17export class MrMoveIssueDialog extends MrIssueHotlistsDialog {
18 /** @override */
19 static get styles() {
20 return [
21 super.styles,
22 css`
23 .hotlist {
24 padding: 4px;
25 }
26 .hotlist:hover {
27 background: var(--chops-active-choice-bg);
28 cursor: pointer;
29 }
30 `,
31 ];
32 }
33
34 /** @override */
35 renderHeader() {
36 const warningText =
37 `Moving issues will remove them from ${this._viewedHotlist ?
38 this._viewedHotlist.displayName : 'this hotlist'}.`;
39 return html`
40 <h3 class="medium-heading">Move issues to hotlist</h3>
41 <mr-warning title=${warningText}>${warningText}</mr-warning>
42 `;
43 }
44
45 /** @override */
46 renderFilteredHotlist(hotlist) {
47 if (this._viewedHotlist &&
48 hotlist.name === this._viewedHotlist.displayName) return;
49 return html`
50 <div
51 class="hotlist"
52 data-hotlist-name="${hotlist.name}"
53 @click=${this._targetHotlistPicked}>
54 ${hotlist.name}
55 </div>`;
56 }
57
58 /** @override */
59 static get properties() {
60 return {
61 ...MrIssueHotlistsDialog.properties,
62 // Populated from Redux.
63 _viewedHotlist: {type: Object},
64 };
65 }
66
67 /** @override */
68 stateChanged(state) {
69 super.stateChanged(state);
70 this._viewedHotlist = hotlists.viewedHotlist(state);
71 }
72
73 /** @override */
74 constructor() {
75 super();
76
77 /**
78 * The currently viewed Hotlist.
79 * @type {?Hotlist}
80 **/
81 this._viewedHotlist = null;
82 }
83
84 /**
85 * Handles picking a Hotlist to move to.
86 * @param {Event} e
87 */
88 async _targetHotlistPicked(e) {
89 const targetHotlistName = e.target.dataset.hotlistName;
90 const changes = {
91 added: [],
92 removed: [],
93 };
94
95 for (const hotlist of this.userHotlists) {
96 // We move from the current Hotlist to the target Hotlist.
97 if (changes.added.length === 1 && changes.removed.length === 1) break;
98 const change = {
99 name: hotlist.name,
100 owner: hotlist.ownerRef,
101 };
102 if (hotlist.name === targetHotlistName) {
103 changes.added.push(change);
104 } else if (hotlist.name === this._viewedHotlist.displayName) {
105 changes.removed.push(change);
106 }
107 }
108
109 const issueRefs = this.issueRefs;
110 if (!issueRefs) return;
111
112 // TODO(https://crbug.com/monorail/7778): Use action creators.
113 const promises = [];
114 if (changes.added && changes.added.length) {
115 promises.push(prpcClient.call(
116 'monorail.Features', 'AddIssuesToHotlists', {
117 hotlistRefs: changes.added,
118 issueRefs,
119 },
120 ));
121 }
122 if (changes.removed && changes.removed.length) {
123 promises.push(prpcClient.call(
124 'monorail.Features', 'RemoveIssuesFromHotlists', {
125 hotlistRefs: changes.removed,
126 issueRefs,
127 },
128 ));
129 }
130
131 try {
132 await Promise.all(promises);
133 this.dispatchEvent(new Event('saveSuccess'));
134 this.close();
135 } catch (error) {
136 this.error = error.message || error.description;
137 }
138 }
139}
140
141customElements.define('mr-move-issue-hotlists-dialog', MrMoveIssueDialog);