import { Iterable } from 'ix'; import { IterableLike, ObservableLike } from '../../../WebRx'; import { flattenItems } from '../ListItems/TreeListItemsViewModel'; import { SearchRequest, SearchViewModel } from '../Search/SearchViewModel'; import { ItemListPanelViewModel } from './ItemListPanelViewModel'; export function filterTreeItems( items: IterableLike | undefined, itemsSource: (item: T) => IterableLike | undefined, itemsAssign: (item: T, items: Iterable) => T, filter: (item: T) => boolean, ): Iterable { if (items == null) { return Iterable.empty(); } return Iterable.from(items) .map(x => { const result = filterTreeItems( itemsSource(x), itemsSource, itemsAssign, filter, ); if (result.some(() => true) || filter(x)) { return itemsAssign(x, result); } return undefined; }) .filterNull(); } export class TreeItemListPanelViewModel< T, TRequestContext = any > extends ItemListPanelViewModel { public static displayName = 'TreeItemListPanelViewModel'; /** * @param source data source. * @param itemsSource delegate to produce sub-items from a source item. * @param itemsAssign delegate to produce a source item with the sub-items assigned. * @param filterer filter predicate. executed for each item when the search context is available. * @param search search handler. if omitted a default search handler will be created. use null for no search handling. * @param context request context included in projection requests. if included requests are bound to context events. */ constructor( source: ObservableLike>, protected readonly itemsSource: (item: T) => IterableLike | undefined, protected readonly itemsAssign: (item: T, items: Iterable) => T, filterer?: (item: T, search: SearchRequest) => boolean, search?: SearchViewModel | null, context?: ObservableLike, rateLimit?: number, ) { super(source, filterer, search, null, context, undefined, rateLimit); } getItems() { return Iterable.from(this.getItemsSource()).flatMap(x => this.flattenItems(x), ); } getItemsForIndicies(indicies: IterableLike) { return undefined; } getIndiciesForItems(items: IterableLike) { return undefined; } getFilteredItems(items: Iterable, searchRequest: SearchRequest) { return filterTreeItems(items, this.itemsSource, this.itemsAssign, x => this.filterer!(x, searchRequest), ); } protected flattenItems(item: T): Iterable { return flattenItems(item, this.itemsSource); } }