import { IStoreState, ID, IRow } from '../../index.data'; import { _getCell } from './base'; import { SimpleNodeContext } from 'valor-app-utils/dist/tree/context'; import * as R from 'rambda'; import { RootNodeId } from 'valor-app-utils/dist/tree/interface'; import { IRowWithCell } from '../../SpreadSheetProvider/index.data'; /** * 根据row.id 找到 row */ export function getRow(state: IStoreState, id: ID): IRow { // return state.rows.find(row => row.id + '' === id + '')!; return state.rows[getRowIndex(state, id)]; } export function getRowIndex(state: IStoreState, id: ID): number { return state.rows.findIndex(row => row.id + '' === id + '')!; } export function getRowWithCells(state: IStoreState, id: ID): IRowWithCell { const row = getRow(state, id); const cells = (row.cellIds || ([] as ID[])).map(cellId => (cellId ? state.cells[cellId] : null)); return Object.assign({}, row, { cells }); } /** * 获取当前选择的行 ( 返回单行 ) */ export function getSelectedRow(state: IStoreState): IRow | null { if (state.selectionType === 'row' && state.selectedRowRange.length > 0) { return getRow(state, state.selectedRowRange[0]); } else if (state.selectionType === 'cell' && state.selectedCellRange.length > 0) { return getRowByCell(state, state.selectedCellRange[0]); } return null; } /** * 获取row的index export function getRowIndex(state: IStoreState, rowId: ID): number { return state.rows.findIndex(row => row.id + '' === rowId + ''); } */ /** * 根据cellId找到row */ export function getRowByCell(state: IStoreState, cellId: ID): IRow { const cell = _getCell(state, cellId)!; return getRow(state, cell.rowId!); } // rowId行的变动, 将引起其它哪些行的变动? // 换句话说: 有哪些行, 依赖于rowId行 export function getHostRows(state: IStoreState, i: number): ID[] { const row = state.rows[i]; const hostCellIds = getHostCells(state, (row.cellIds || ([] as any)).filter(Boolean)); return hostCellIds .map(cellId => state.cells[cellId]!.rowId) .reduce((acc, rowId) => (acc.indexOf(rowId!) > 0 ? acc : acc.concat([rowId!])), [] as ID[]); } // 批量获取cellIds的hostCells ( 递归 ) // excludeDelay: 排除象比例这样的delay单元格, 以免发生全局重算 function getHostCells(state: IStoreState, cellIds: ID[], excludeDelay = true): ID[] { if (cellIds.length === 0) return []; const hosts = cellIds .map(cellId => (state.cellDeps || ({} as any))[cellId!]) .filter(Boolean) .reduce((acc, _hostCellIds) => acc.concat(_hostCellIds), []) // 去掉delay的, 因为通过这种方式, 肯定会delay .filter(hostCellId => { if (excludeDelay) { return !state.cells[hostCellId]!.delay; } return true; }); return hosts.concat(getHostCells(state, hosts, excludeDelay)); } export function getRowi(state: IStoreState, rowId: ID): number { return state.rows.findIndex(row => row.id === rowId || row.id + '' === rowId + ''); } // 排除row为header或area='flatten'的行 export function getPureTreeContext( state: IStoreState, treeContext: Record, ) { const isTreeRowMap: Record = state.rows.reduce( (acc, row) => Object.assign(acc, { [row.id]: isTreeRow(row) }), {}, ); const newTreeContext = R.filter((context, rowId) => { // 返回rootNode if (rowId + '' === RootNodeId) return true; // row.type默认为body return isTreeRowMap[rowId]; }, treeContext); return R.map( (context, rowId) => context.childrenIds && context.childrenIds.length > 0 ? Object.assign({}, context, { childrenIds: context.childrenIds.filter(id => isTreeRowMap[id]), }) : context, newTreeContext, ); } export function isTreeRow(row: IRow) { return row && (row.type || 'body') === 'body' && (row.area || 'tree') === 'tree'; }