private filterHelper()

in components/RunStore.ts [109:175]


	private filterHelper(treeItems: ITreeItem<ResultOrRuleOrMore>[]) {
		const filter = this.filter.getState()
		const filterKeywords = (filter.Keywords?.value ?? '').toLowerCase().split(/\s+/).filter(part => part)
		const {sortColumnIndex, sortOrder} = this

		treeItems.forEach(treeItem => {
			// if (!treeItem.hasOwnProperty('isShowAll')) extendObservable(treeItem, { isShowAll: false })
			treeItem.isShowAll = false

			// Filtering logic: Show if 1) dropdowns match AND 2) any field matches text.
			const isDriverMatch = isMatch(this.driverName.toLowerCase(), filterKeywords)

			const resultContainer = treeItem.data as { results: Result[] }
			treeItem.childItemsAll = resultContainer.results
				.filter(result => {
					const {_rule} = result
					const ruleId = _rule.id.toLowerCase()
					const ruleName = _rule.name?.toLowerCase() ?? ''
					const isRuleMatch = isMatch(ruleId, filterKeywords) || isMatch(ruleName, filterKeywords)

					for (const columnName in filter) {
						if (columnName === 'Discussion') continue // Discussion filter does not apply to Results.
						const selectedValues = filter[columnName].value
						if (!Array.isArray(selectedValues)) continue
						if (!selectedValues.length) continue
						const map = {
							Baseline: (result: Result) => result.baselineState as string || 'new', // TODO: Merge with column def.
							Level: (result: Result) => result.level || 'warning',
							Suppression: (result: Result) => result.suppressions?.some(s => s.status === undefined || s.status === 'accepted') ? 'suppressed' : 'unsuppressed',
							Age: (result: Result) => result.sla.toLowerCase(),
						}
						const translatedCellValue = map[columnName] ? map[columnName](result) : result
						if (!selectedValues.includes(translatedCellValue)) return false
					}

					const isKeywordMatch = this.columns.some(column => {
						const field = column.filterString(result).toLowerCase()
						return isMatch(field, filterKeywords)
					})

					return isDriverMatch || isRuleMatch || isKeywordMatch
				})
				.map(result => ({ data: result })) // Can cache the result here.

			treeItem.childItemsAll.sort((treeItemLeft, treeItemRight) => {
				const resultToValue = this.columns[sortColumnIndex].sortString
				const valueLeft = resultToValue(treeItemLeft.data as Result)
				const valueRight = resultToValue(treeItemRight.data as Result)

				const inverter = sortOrder === SortOrder.ascending ? 1 : -1
				return inverter * valueLeft.localeCompare(valueRight)
			})

			return treeItem as ITreeItem<ResultOrRuleOrMore>
		})

		const treeItemsVisible = treeItems.filter(rule => rule.childItemsAll.length)

		treeItemsVisible.sort(this.sortRuleBy === SortRuleBy.Count
			? (a, b) => b.childItemsAll.length - a.childItemsAll.length
			: (a, b) => (a.data as Rule).id.localeCompare((b.data as Rule).id)
		)
		
		treeItemsVisible.forEach((rule, i) => rule.expanded = i === 0)

		return treeItemsVisible
	}