/* eslint-disable react-hooks/exhaustive-deps */ import { CompactSelection } from '@glideapps/glide-data-grid'; import React, { useEffect, useRef } from 'react'; import { useGridlerStore } from './Store'; //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders. export const Computer = React.memo(() => { const refFirstRun = useRef(0); const refLastFilters = useRef(null); const { _glideref, _gridSelectionRows, askAPIRowNumber, colFilters, colOrder, colSize, colSort, columns, getState, loadPage, setState, setStateFN, values, } = useGridlerStore((s) => ({ _glideref: s._glideref, _gridSelectionRows: s._gridSelectionRows, askAPIRowNumber: s.askAPIRowNumber, colFilters: s.colFilters, colOrder: s.colOrder, colSize: s.colSize, colSort: s.colSort, columns: s.columns, getState: s.getState, loadPage: s.loadPage, setState: s.setState, setStateFN: s.setStateFN, uniqueid: s.uniqueid, values: s.values, })); useEffect(() => { const searchSelection = async () => { const page_data = getState('_page_data'); const pageSize = getState('pageSize'); const keyField = getState('keyField') ?? 'id'; const rowIndexes = []; for (const vi in values as Array) { let rowIndex = -1; const key = String( typeof values?.[vi] === 'object' ? values?.[vi]?.[keyField] : typeof values?.[vi] === 'string' ? values?.[vi] : undefined ); for (const p in page_data) { for (const r in page_data[p]) { const idx = Number(p) * pageSize + Number(r); if (String(page_data[p][r]?.[keyField]) === key) { //console.log('Found row S', idx, page_data[p][r], page_data[p][r]?.[keyField], key); rowIndex = idx; break; } } if (rowIndex >= 0) { rowIndexes.push(rowIndex); break; } } if (!(rowIndex >= 0) && typeof askAPIRowNumber === 'function') { const idx = await askAPIRowNumber(key); if (idx) { rowIndexes.push(idx); } } } return rowIndexes; }; if (values) { searchSelection().then((rowIndexes) => { let rows = CompactSelection.empty(); rowIndexes.forEach((r) => { rows = rows.add(r); }); setStateFN('_gridSelectionRows', () => { return rows; }); setStateFN('_gridSelection', (c) => ({ columns: c?.columns ?? CompactSelection.empty(), ...c, rows, })); }); } }, [values]); useEffect(() => { const onChange = getState('onChange'); if (onChange && typeof onChange === 'function') { const page_data = getState('_page_data'); const pageSize = getState('pageSize'); const buffers = []; if (_gridSelectionRows) { for (const range of _gridSelectionRows) { let buffer = undefined; for (const p in page_data) { for (const r in page_data[p]) { const idx = Number(p) * pageSize + Number(r); if (isNaN(idx)) { continue; } if (Number(page_data[p][r]?._rownumber) === range + 1) { buffer = page_data[p][r]; //console.log('Found row', range, idx, page_data[p][r]?._rownumber); break; } else if (idx === range + 1) { buffer = page_data[p][r]; //console.log('Found row 2', range, idx, page_data[p][r]?._rownumber); break; } } } if (buffer !== undefined) { buffers.push(buffer); } } } const _values = getState('values'); if (JSON.stringify(_values) !== JSON.stringify(buffers)) { onChange(buffers); } } }, [JSON.stringify(_gridSelectionRows), getState]); useEffect(() => { setState( 'renderColumns', columns?.map((c) => ({ ...c, hasMenu: c?.hasMenu ?? true, icon: 'sort', })) ); }, [columns]); useEffect(() => { if (!colSort) { return; } setState('_gridSelection', { columns: CompactSelection.empty(), current: undefined, rows: CompactSelection.empty(), }); setState('_gridSelectionRows', CompactSelection.empty()); setStateFN('renderColumns', (cols) => { return cols?.map((c) => ({ ...c, icon: c.id && colSort?.find((col) => col.id === c.id)?.direction ? colSort?.find((col) => col.id === c.id)?.direction === 'asc' ? 'sortup' : 'sortdown' : (c.defaultIcon ?? 'sort'), })); }).then(() => { loadPage(0, 'all'); }); }, [colSort]); useEffect(() => { if (!colFilters) { return; } if (JSON.stringify(refLastFilters.current) !== JSON.stringify(colFilters)) { loadPage(0, 'all'); refLastFilters.current = colFilters; } }, [colFilters]); useEffect(() => { if (!colSize) { return; } setStateFN('renderColumns', (cols) => { return cols?.map((c) => ({ ...c, width: c.id && colSize?.[c.id] ? colSize?.[c.id] : c.width, })); }); }, [colSize]); useEffect(() => { if (!colOrder) { return; } setStateFN('renderColumns', (cols) => { const result = cols?.sort((a, b) => { if (colOrder[a.id] > colOrder[b.id]) { return 1; } return -1; }); return result; }); }, [colOrder]); useEffect(() => { if (!_glideref) { return; } if (refFirstRun.current > 0) { return; } refFirstRun.current = 1; loadPage(0); }, [_glideref]); // console.log('Gridler:Debug:Computer', { // colFilters, // colOrder, // colSize, // colSort, // columns, // uniqueid // }); return <>; });