From 8224fbce15f7bb5415ebca3280bb5a2b19173427 Mon Sep 17 00:00:00 2001 From: arturovt Date: Mon, 9 May 2022 04:57:38 +0300 Subject: [PATCH] fix(module:transfer): uncheck "Select all" checkbox when filters items are moved --- .../transfer/transfer-list.component.ts | 19 +++++++++++++++++++ components/transfer/transfer.spec.ts | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/components/transfer/transfer-list.component.ts b/components/transfer/transfer-list.component.ts index e003935ee8c..0ffe106db12 100644 --- a/components/transfer/transfer-list.component.ts +++ b/components/transfer/transfer-list.component.ts @@ -15,12 +15,15 @@ import { Output, QueryList, TemplateRef, + ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; import { fromEvent, merge, Observable } from 'rxjs'; import { startWith, switchMap } from 'rxjs/operators'; +import { NzCheckboxComponent } from 'ng-zorro-antd/checkbox'; + import { TransferDirection, TransferItem } from './interface'; @Component({ @@ -61,6 +64,7 @@ import { TransferDirection, TransferItem } from './interface'; *ngIf="showSelectAll" class="ant-transfer-list-checkbox" nz-checkbox + #headerCheckbox [nzChecked]="stat.checkAll" (nzCheckedChange)="onItemSelectAll($event)" [nzIndeterminate]="stat.checkHalf" @@ -145,6 +149,8 @@ export class NzTransferListComponent implements AfterViewInit { @Output() readonly handleSelect: EventEmitter = new EventEmitter(); @Output() readonly filterChange: EventEmitter<{ direction: TransferDirection; value: string }> = new EventEmitter(); + @ViewChild('headerCheckbox', { read: NzCheckboxComponent }) headerCheckbox?: NzCheckboxComponent; + @ViewChildren('checkboxes', { read: ElementRef }) checkboxes!: QueryList>; stat = { @@ -184,6 +190,19 @@ export class NzTransferListComponent implements AfterViewInit { this.stat.shownCount = this.validData.length; this.stat.checkAll = validCount > 0 && validCount === this.stat.checkCount; this.stat.checkHalf = this.stat.checkCount > 0 && !this.stat.checkAll; + // Note: this is done explicitly since the internal `nzChecked` value may not be updated in edge cases. + // Consider the following flow: + // 1) the initial value of `stat.checkAll` is `false` + // 2) the user filters items + // 3) the user clicks "Select All" checkbox + // 4) the `NzCheckboxComponent` sets `nzChecked` to `true` internally + // 5) the user clicks "Move to right" + // 6) items are moved and the `updateCheckStatus` is invoked + // 7) the `stat.checkAll` value has never been updated in this flow, it's always been `false` + // 8) the `nzChecked` is still `true` and the checkbox is not unchecked + // This is because Angular checks bindings and it checked that `[nzChecked]="stat.checkAll"` has + // never been updated, so Angular did not set new `nzChecked` value on the checkbox. + this.headerCheckbox && (this.headerCheckbox.nzChecked = this.stat.checkAll); } // #endregion diff --git a/components/transfer/transfer.spec.ts b/components/transfer/transfer.spec.ts index 59820319fde..30dc1058ba5 100644 --- a/components/transfer/transfer.spec.ts +++ b/components/transfer/transfer.spec.ts @@ -307,6 +307,24 @@ describe('transfer', () => { expect(event.stopPropagation).toHaveBeenCalled(); }); }); + + describe('https://github.com/NG-ZORRO/ng-zorro-antd/issues/6667', () => { + it('should uncheck "Select all" checkbox after searched items are moved', () => { + const { leftList } = pageObject; + pageObject.search('left', 'content1'); + expect(leftList.querySelectorAll('.ant-transfer-list-content-item').length).toBe(1); + + const selectAll = leftList.querySelector('.ant-transfer-list-header .ant-checkbox')!; + selectAll.click(); + fixture.detectChanges(); + + pageObject.rightBtn.click(); + fixture.detectChanges(); + + expect(selectAll).not.toHaveClass('ant-checkbox-checked'); + expect(selectAll).not.toHaveClass('ant-checkbox-indeterminate'); + }); + }); }); describe('#canMove', () => {