diff --git a/app/src/ui/changes/filter-changes-list.tsx b/app/src/ui/changes/filter-changes-list.tsx index 6409aad505c..54aab320868 100644 --- a/app/src/ui/changes/filter-changes-list.tsx +++ b/app/src/ui/changes/filter-changes-list.tsx @@ -236,6 +236,7 @@ interface IFilterChangesListProps { interface IFilterChangesListState { readonly filterText: string + readonly filteredItems: ReadonlyArray readonly selectedItems: ReadonlyArray readonly focusedRow: string | null readonly groups: ReadonlyArray> @@ -280,6 +281,7 @@ export class FilterChangesList extends React.Component< this.state = { filterText: '', + filteredItems: [], selectedItems: getSelectedItemsFromProps(props), focusedRow: null, groups, @@ -1027,6 +1029,14 @@ export class FilterChangesList extends React.Component< this.setState({ filterText: text }) } + private onFilterListResultsChanged = ( + filteredItems: ReadonlyArray + ) => { + this.setState({ filteredItems }) + // TBD: Remove when used. + console.log(this.state.filteredItems, filteredItems) + } + private onFileSelectionChanged = (items: ReadonlyArray) => { const rows = items.map(i => this.props.workingDirectory.findFileIndexByID(i.change.id) @@ -1086,6 +1096,7 @@ export class FilterChangesList extends React.Component< rowHeight={RowHeight} filterText={this.state.filterText} onFilterTextChanged={this.onFilterTextChanged} + onFilterListResultsChanged={this.onFilterListResultsChanged} selectedItems={this.state.selectedItems} selectionMode="multi" renderItem={this.renderChangedFile} diff --git a/app/src/ui/lib/augmented-filter-list.tsx b/app/src/ui/lib/augmented-filter-list.tsx index 3599639d3d5..ba8ac4e78e6 100644 --- a/app/src/ui/lib/augmented-filter-list.tsx +++ b/app/src/ui/lib/augmented-filter-list.tsx @@ -152,7 +152,9 @@ interface IAugmentedSectionFilterListProps { /** * Callback to fire when the items in the filter list are updated */ - readonly onFilterListResultsChanged?: (resultCount: number) => void + readonly onFilterListResultsChanged?: ( + filteredItems: ReadonlyArray + ) => void /** Placeholder text for text box. Default is "Filter". */ readonly placeholderText?: string @@ -253,20 +255,17 @@ export class AugmentedSectionFilterList< prevState: IAugmentedSectionFilterListState ) { if (this.props.onSelectionChanged) { - const oldSelectedItemIds = prevState.selectedRows.map(row => - getItemIdFromRowIndex(prevState.rows, row) - ) - const newSelectedItemIds = this.state.selectedRows.map(row => - getItemIdFromRowIndex(this.state.rows, row) - ) - - // xor = exclusive Or; returns the symmetric difference of given arrays - // i.e. it will create an array that contains an id that doesn’t exist in - // boths arrays indicating that both arrays do not contain the same ids. - if (xor(oldSelectedItemIds, newSelectedItemIds).length > 0) { + const oldSelectedItemIds = prevState.selectedRows + .map(row => getItemIdFromRowIndex(prevState.rows, row)) + .filter(i => i !== null) + const newSelectedItemIds = this.state.selectedRows + .map(row => getItemIdFromRowIndex(this.state.rows, row)) + .filter(i => i !== null) + + if (!this.hasSameIds(oldSelectedItemIds, newSelectedItemIds)) { const propSelectionIds = this.props.selectedItems.map(si => si.id) - if (xor(newSelectedItemIds, propSelectionIds).length > 0) { + if (!this.hasSameIds(newSelectedItemIds, propSelectionIds)) { const newSelectedItems = this.state.selectedRows .map(row => getItemFromRowIndex(this.state.rows, row)) .filter(r => r !== null) @@ -280,14 +279,38 @@ export class AugmentedSectionFilterList< } if (this.props.onFilterListResultsChanged !== undefined) { - const itemCount = this.state.rows + const oldFilteredIds = prevState.rows .flat() - .filter(row => row.kind === 'item').length + .filter(row => row.kind === 'item') + .map(r => r.item.id) + + const currentFilteredItemIds = this.state.rows + .flat() + .filter(row => row.kind === 'item') + .map(r => r.item) + + const currentFilteredIds = currentFilteredItemIds.map(i => i.id) - this.props.onFilterListResultsChanged(itemCount) + if (!this.hasSameIds(oldFilteredIds, currentFilteredIds)) { + this.props.onFilterListResultsChanged(currentFilteredItemIds) + } } } + private hasSameIds( + oldIds: ReadonlyArray, + newIds: ReadonlyArray + ) { + if (oldIds.length !== newIds.length) { + return false + } + + // xor = exclusive Or; returns the symmetric difference of given arrays + // i.e. it will create an array that contains an id that doesn’t exist in + // both arrays. If no empty array, then both arrays contain the same elements. + return xor(oldIds, newIds).length === 0 + } + public componentDidMount() { if (this.filterTextBox !== null) { this.filterTextBox.selectAll()