Merge "Add support for disabled check actions"
diff --git a/polygerrit-ui/app/api/checks.ts b/polygerrit-ui/app/api/checks.ts
index 5d20f3f..e74eee1 100644
--- a/polygerrit-ui/app/api/checks.ts
+++ b/polygerrit-ui/app/api/checks.ts
@@ -231,7 +231,16 @@
* primary actions might be rendered as buttons versus just menu entries in
* an overflow menu.
*/
- primary: boolean;
+ primary?: boolean;
+ /**
+ * Renders the action button in a disabled state. That can be useful for
+ * actions that are present most of the time, but sometimes don't apply. Then
+ * a grayed out button with a tooltip makes it easier for the user to
+ * understand why an expected action is not available. The tooltip should then
+ * contain a message about why the disabled state was set, not just about what
+ * the action would normally do.
+ */
+ disabled?: boolean;
callback: ActionCallback;
}
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-action.ts b/polygerrit-ui/app/elements/checks/gr-checks-action.ts
new file mode 100644
index 0000000..6a7b24d
--- /dev/null
+++ b/polygerrit-ui/app/elements/checks/gr-checks-action.ts
@@ -0,0 +1,78 @@
+/**
+ * @license
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {html} from 'lit-html';
+import {css, customElement, property} from 'lit-element';
+import {GrLitElement} from '../lit/gr-lit-element';
+import {Action} from '../../api/checks';
+import {checkRequiredProperty} from '../../utils/common-util';
+import {fireActionTriggered} from '../../services/checks/checks-util';
+
+@customElement('gr-checks-action')
+export class GrChecksAction extends GrLitElement {
+ @property()
+ action!: Action;
+
+ @property()
+ eventTarget?: EventTarget;
+
+ connectedCallback() {
+ super.connectedCallback();
+ checkRequiredProperty(this.action, 'action');
+ }
+
+ static get styles() {
+ return [
+ css`
+ :host {
+ display: inline-block;
+ }
+ gr-button {
+ --padding: var(--spacing-s) var(--spacing-m);
+ }
+ gr-button paper-tooltip {
+ text-transform: none;
+ }
+ `,
+ ];
+ }
+
+ render() {
+ return html`
+ <gr-button
+ link
+ ?disabled="${this.action.disabled}"
+ class="action"
+ @click="${this.handleClick}"
+ >
+ ${this.action.name}
+ <paper-tooltip ?hidden="${!this.action.tooltip}" offset="5"
+ >${this.action.tooltip}</paper-tooltip
+ >
+ </gr-button>
+ `;
+ }
+
+ handleClick() {
+ fireActionTriggered(this.eventTarget ?? this, this.action);
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'gr-checks-action': GrChecksAction;
+ }
+}
diff --git a/polygerrit-ui/app/elements/checks/gr-checks-results.ts b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
index 1bbef18..42ce718 100644
--- a/polygerrit-ui/app/elements/checks/gr-checks-results.ts
+++ b/polygerrit-ui/app/elements/checks/gr-checks-results.ts
@@ -27,6 +27,7 @@
TemplateResult,
} from 'lit-element';
import {GrLitElement} from '../lit/gr-lit-element';
+import './gr-checks-action';
import './gr-checks-attempt';
import '@polymer/paper-tooltip/paper-tooltip';
import {
@@ -53,11 +54,7 @@
iconForLink,
tooltipForLink,
} from '../../services/checks/checks-util';
-import {
- assertIsDefined,
- check,
- checkRequiredProperty,
-} from '../../utils/common-util';
+import {assertIsDefined, check} from '../../utils/common-util';
import {toggleClass, whenVisible} from '../../utils/dom-util';
import {durationString} from '../../utils/date-util';
import {charsOnly} from '../../utils/string-util';
@@ -363,6 +360,9 @@
const overflowItems = actions.slice(2).map(action => {
return {...action, id: action.name};
});
+ const disabledItems = overflowItems
+ .filter(action => action.disabled)
+ .map(action => action.id);
return html`<div class="actions">
${this.renderAction(actions[0])} ${this.renderAction(actions[1])}
<gr-dropdown
@@ -375,6 +375,7 @@
toggleClass(this, 'dropdown-open', e.detail.value)}"
?hidden="${overflowItems.length === 0}"
.items="${overflowItems}"
+ .disabledIds="${disabledItems}"
>
<iron-icon icon="gr-icons:more-vert" aria-labelledby="moreMessage">
</iron-icon>
@@ -790,6 +791,9 @@
const overflowItems = this.actions.slice(2).map(action => {
return {...action, id: action.name};
});
+ const disabledItems = overflowItems
+ .filter(action => action.disabled)
+ .map(action => action.id);
return html`
${this.renderAction(this.actions[0])}
${this.renderAction(this.actions[1])}
@@ -801,6 +805,7 @@
@tap-item="${this.handleAction}"
?hidden="${overflowItems.length === 0}"
.items="${overflowItems}"
+ .disabledIds="${disabledItems}"
>
<iron-icon icon="gr-icons:more-vert" aria-labelledby="moreMessage">
</iron-icon>
@@ -1076,53 +1081,10 @@
}
}
-@customElement('gr-checks-action')
-export class GrChecksAction extends GrLitElement {
- @property()
- action!: Action;
-
- connectedCallback() {
- super.connectedCallback();
- checkRequiredProperty(this.action, 'action');
- }
-
- static get styles() {
- return [
- css`
- :host {
- display: inline-block;
- }
- gr-button {
- --padding: var(--spacing-s) var(--spacing-m);
- }
- gr-button paper-tooltip {
- text-transform: none;
- }
- `,
- ];
- }
-
- render() {
- return html`
- <gr-button link class="action" @click="${this.handleClick}">
- ${this.action.name}
- <paper-tooltip ?hidden="${!this.action.tooltip}" offset="5"
- >${this.action.tooltip}</paper-tooltip
- >
- </gr-button>
- `;
- }
-
- handleClick() {
- fireActionTriggered(this, this.action);
- }
-}
-
declare global {
interface HTMLElementTagNameMap {
'gr-result-row': GrResultRow;
'gr-result-expanded': GrResultExpanded;
'gr-checks-results': GrChecksResults;
- 'gr-checks-action': GrChecksAction;
}
}
diff --git a/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts b/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
index ae6408d..10f036e 100644
--- a/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
+++ b/polygerrit-ui/app/elements/checks/gr-hovercard-run.ts
@@ -19,6 +19,7 @@
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-hovercard-run_html';
import {customElement, property} from '@polymer/decorators';
+import './gr-checks-action';
import {CheckRun} from '../../services/checks/checks-model';
import {
iconForCategory,
diff --git a/polygerrit-ui/app/elements/checks/gr-hovercard-run_html.ts b/polygerrit-ui/app/elements/checks/gr-hovercard-run_html.ts
index 08ceefe..c4402f5 100644
--- a/polygerrit-ui/app/elements/checks/gr-hovercard-run_html.ts
+++ b/polygerrit-ui/app/elements/checks/gr-hovercard-run_html.ts
@@ -202,7 +202,12 @@
</div>
</div>
<template is="dom-repeat" items="[[computeActions(run)]]">
- <div class="action"><gr-button link>[[item.name]]</gr-button></div>
+ <div class="action">
+ <gr-checks-action
+ event-target="[[_target]]"
+ action="[[item]]"
+ ></gr-checks-action>
+ </div>
</template>
</div>
`;
diff --git a/polygerrit-ui/app/services/checks/checks-model.ts b/polygerrit-ui/app/services/checks/checks-model.ts
index ecd56cb..6275d69 100644
--- a/polygerrit-ui/app/services/checks/checks-model.ts
+++ b/polygerrit-ui/app/services/checks/checks-model.ts
@@ -257,19 +257,20 @@
name: 'Ignore',
tooltip: 'Ignore this result',
primary: true,
- callback: () => undefined,
+ callback: () => Promise.resolve({message: 'fake "ignore" triggered'}),
},
{
name: 'Flag',
tooltip: 'Flag this result as not useful',
primary: true,
- callback: () => undefined,
+ disabled: true,
+ callback: () => Promise.resolve({message: 'flag "flag" triggered'}),
},
{
name: 'Upload',
tooltip: 'Upload the result to the super cloud.',
primary: false,
- callback: () => undefined,
+ callback: () => Promise.resolve({message: 'fake "upload" triggered'}),
},
],
tags: [{name: 'INTERRUPTED'}, {name: 'WINDOWS'}],
@@ -334,17 +335,18 @@
name: 'Re-Run',
tooltip: 'More powerful run than before',
primary: true,
- callback: () => undefined,
+ callback: () => Promise.resolve({message: 'fake "re-run" triggered'}),
},
{
name: 'Monetize',
primary: true,
- callback: () => undefined,
+ disabled: true,
+ callback: () => Promise.resolve({message: 'fake "monetize" triggered'}),
},
{
name: 'Delete',
primary: true,
- callback: () => undefined,
+ callback: () => Promise.resolve({message: 'fake "delete" triggered'}),
},
],
results: [
@@ -446,29 +448,22 @@
{
name: 'Fake Action 1',
primary: false,
+ disabled: true,
tooltip: 'Tooltip for Fake Action 1',
- callback: () => {
- console.warn('fake action 1 triggered');
- return undefined;
- },
+ callback: () => Promise.resolve({message: 'fake action 1 triggered'}),
},
{
name: 'Fake Action 2',
primary: false,
+ disabled: true,
tooltip: 'Tooltip for Fake Action 2',
- callback: () => {
- console.warn('fake action 2 triggered');
- return undefined;
- },
+ callback: () => Promise.resolve({message: 'fake action 2 triggered'}),
},
{
name: 'Fake Action 3',
primary: false,
tooltip: 'Tooltip for Fake Action 3',
- callback: () => {
- console.warn('fake action 3 triggered');
- return undefined;
- },
+ callback: () => Promise.resolve({message: 'fake action 3 triggered'}),
},
];
diff --git a/polygerrit-ui/app/services/checks/checks-util.ts b/polygerrit-ui/app/services/checks/checks-util.ts
index 0a0881b..7eb2a5d 100644
--- a/polygerrit-ui/app/services/checks/checks-util.ts
+++ b/polygerrit-ui/app/services/checks/checks-util.ts
@@ -130,7 +130,7 @@
export function primaryRunAction(run: CheckRun): Action | undefined {
return runActions(run).filter(
- action => action.name === primaryActionName(run.status)
+ action => !action.disabled && action.name === primaryActionName(run.status)
)[0];
}