Merge "Disable Cherry pick button if no change is selected"
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts
index 05e3c7f..eb12e1d 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.ts
@@ -144,7 +144,8 @@
@state()
latestCommitter?: GitPersonInfo;
- private selectedChangeIds = new Set<ChangeInfoId>();
+ @state()
+ selectedChangeIds = new Set<ChangeInfoId>();
private readonly restApiService = getAppContext().restApiService;
@@ -261,12 +262,8 @@
<gr-dialog
confirm-label="Cherry Pick"
.cancelLabel=${this.computeCancelLabel()}
- ?disabled=${this.computeDisableCherryPick(
- this.cherryPickType,
- this.duplicateProjectChanges,
- this.statuses,
- this.branch
- )}
+ ?disabled=${this.computeDisableCherryPick()}
+ title=${this.computeTitleForCherryPick()}
@confirm=${this.handleConfirmTap}
@cancel=${this.handleCancelTap}
>
@@ -438,6 +435,23 @@
`;
}
+ // private but compute in tests
+ computeTitleForCherryPick() {
+ if (!this.computeDisableCherryPick()) {
+ return 'Cherry pick changes';
+ }
+ if (this.noChangesSelected())
+ return 'Disabled because no changes are selected';
+
+ if (
+ this.cherryPickType === CherryPickType.TOPIC &&
+ this.duplicateProjectChanges
+ ) {
+ return 'Duplicate projects selected';
+ }
+ return 'Cherry pick button disabled';
+ }
+
containsDuplicateProject(changes: (ChangeInfo | ParsedChangeInfo)[]) {
const projects: {[projectName: string]: boolean} = {};
for (let i = 0; i < changes.length; i++) {
@@ -481,6 +495,8 @@
this.selectedChangeIds.has(change.id)
);
this.duplicateProjectChanges = this.containsDuplicateProject(changes);
+ // Explicitly trigger a re-render
+ this.selectedChangeIds = new Set(this.selectedChangeIds);
}
private computeTopicErrorMessage() {
@@ -533,18 +549,24 @@
return isRunningChange ? 'Close' : 'Cancel';
}
- private computeDisableCherryPick(
- cherryPickType: CherryPickType,
- duplicateProjectChanges: boolean,
- statuses: Statuses,
- branch: BranchName
- ) {
- if (!branch) return true;
+ private noChangesSelected() {
+ const changes = this.changes.filter(change =>
+ this.selectedChangeIds.has(change.id)
+ );
+ if (this.cherryPickType === CherryPickType.TOPIC && changes.length === 0)
+ return true;
+ return false;
+ }
+
+ private computeDisableCherryPick() {
+ if (!this.branch) return true;
+ if (this.noChangesSelected()) return true;
const duplicateProject =
- cherryPickType === CherryPickType.TOPIC && duplicateProjectChanges;
+ this.cherryPickType === CherryPickType.TOPIC &&
+ this.duplicateProjectChanges;
if (duplicateProject) return true;
- if (!statuses) return false;
- const isRunningChange = Object.values(statuses).some(
+ if (!this.statuses) return false;
+ const isRunningChange = Object.values(this.statuses).some(
v => v.status === ProgressStatus.RUNNING
);
return isRunningChange;
@@ -600,8 +622,6 @@
this.selectedChangeIds.has(change.id)
);
if (!changes.length) {
- const errorSpan = this.shadowRoot?.querySelector('.error-message');
- errorSpan!.innerHTML = 'No change selected';
return;
}
const topic = this.generateRandomCherryPickTopic(changes[0]);
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts
index 8f81710..b0cc4d9 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.ts
@@ -105,7 +105,12 @@
assert.shadowDom.equal(
element,
/* HTML */ `
- <gr-dialog confirm-label="Cherry Pick" disabled="" role="dialog">
+ <gr-dialog
+ confirm-label="Cherry Pick"
+ disabled=""
+ role="dialog"
+ title="Cherry pick button disabled"
+ >
<div class="header title" slot="header">
Cherry Pick Change to Another Branch
</div>
@@ -238,31 +243,31 @@
assert.equal(checkboxes.length, 2);
assert.isTrue(checkboxes[0].checked);
checkboxes[0].click();
+ assert.isTrue(checkboxes[1].checked);
queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click();
await element.updateComplete;
assert.equal(executeChangeActionStub.callCount, 1);
assert.isTrue(duplicateChangesStub.called);
});
- test('deselecting all change shows error message', async () => {
+ test('deselecting all change disables the confirm button', async () => {
element.branch = 'master' as BranchName;
await element.updateComplete;
- const executeChangeActionStub = stubRestApi(
- 'executeChangeAction'
- ).resolves(new Response());
const checkboxes = queryAll<HTMLInputElement>(
element,
'input[type="checkbox"]'
);
assert.equal(checkboxes.length, 2);
+ assert.equal(element.cherryPickType, CHERRY_PICK_TYPES.TOPIC);
checkboxes[0].click();
checkboxes[1].click();
- queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton!.click();
await element.updateComplete;
- assert.equal(executeChangeActionStub.callCount, 0);
+ assert.isTrue(
+ queryAndAssert<GrDialog>(element, 'gr-dialog').confirmButton?.disabled
+ );
assert.equal(
- queryAndAssert<HTMLElement>(element, '.error-message').innerText,
- 'No change selected'
+ queryAndAssert<GrDialog>(element, 'gr-dialog').title,
+ 'Disabled because no changes are selected'
);
});