import { injectable } from '@servicetitan/react-ioc'; import { computed, observe, Lambda, makeObservable } from 'mobx'; import { InMemoryDataSource, TableState } from '../..'; import { Product } from './product'; import { products } from './products'; import { ProductDetail } from './product-detail'; import { productDetails } from './product-details'; @injectable() export class MasterTableStore { tableState: TableState = new TableState({ dataSource: new InMemoryDataSource(products, row => row.ProductID), getDetailTableState: row => this.getDetailTableState(row), }); details = new Map>(); @computed get selectedIds() { return Array.from(this.tableState.selectedIds); } private disposeSelectedIdsObserve: Lambda; constructor() { makeObservable(this); this.disposeSelectedIdsObserve = observe(this, 'selectedIds', change => { const { oldValue = [], newValue } = change as { oldValue: number[]; newValue: number[]; }; const before = new Set(oldValue); const after = new Set(newValue); for (const id of oldValue) { if (!after.has(id)) { this.setDetailSelection(id, false); } } for (const id of newValue) { if (!before.has(id)) { this.setDetailSelection(id, true); } } }); } dispose() { this.disposeSelectedIdsObserve(); } private getDetailTableState(row: Product) { const id = this.tableState.dataSource!.idSelector!(row); if (this.details.has(id)) { return this.details.get(id)!; } const detailTableState = new TableState({ dataSource: new InMemoryDataSource( productDetails.filter(x => x.ProductID === id), row => row.Field ), isRowUnselectable: row => !!row.IsLocked, parent: { row, tableState: this.tableState, }, }); if (this.tableState.selectedIds.has(id)) { detailTableState.selectAll(); } this.details.set(id, detailTableState); return detailTableState; } private setDetailSelection(id: number, value: boolean) { const detail = this.tableState.getDetailTableState!({ ProductID: id } as Product); if (!detail?.totalCount) { return; } if (value) { detail.selectAll({ ignoreUnselectable: false }); } else if (!detail.isSomePageRowsSelected) { detail.deselectAll({ ignoreUnselectable: false }); } } }