diff --git a/src/Gridler/Gridler.module.css b/src/Gridler/Gridler.module.css index 3e83763..4d93350 100644 --- a/src/Gridler/Gridler.module.css +++ b/src/Gridler/Gridler.module.css @@ -3,11 +3,7 @@ 1px 0 0 #00000030, 0 1px 0 #00000030, -1px 0 0 #00000030; - display: flex; - min-height: 40px; - min-width: 40px; - height: 100%; - width: 100%; + &[data-focused='true'] { box-shadow: diff --git a/src/Gridler/GridlerDataGrid.tsx b/src/Gridler/GridlerDataGrid.tsx index f8c6be2..10211a1 100644 --- a/src/Gridler/GridlerDataGrid.tsx +++ b/src/Gridler/GridlerDataGrid.tsx @@ -6,7 +6,7 @@ import { type GridColumn, } from '@glideapps/glide-data-grid'; import { Group, Stack } from '@mantine/core'; -import { useElementSize, useMergedRef } from '@mantine/hooks'; +import { useDebouncedValue, useElementSize, useMergedRef } from '@mantine/hooks'; import React from 'react'; import { BottomBar } from './components/BottomBar'; @@ -24,7 +24,19 @@ export const GridlerDataGrid = () => { const ref = React.useRef(null); const refContextActivated = React.useRef(false); - const { height, ref: refWrapper, width } = useElementSize(); + const { height, ref: refWrapper, width } = useElementSize({ box: 'content-box' }); + /* + const [_dimensions, setDimensions] = useState<{ height: number; width: number } | null>(null); + const { height, width } = _dimensions ?? { height: 0, width: 0 }; + + useLayoutEffect(() => { + // Measure container before rendering grid + if (refWrapper.current) { + const { height, width } = refWrapper.current.getBoundingClientRect(); + setDimensions({ height, width }); + } + }, []); + */ const { _gridSelection, @@ -37,6 +49,7 @@ export const GridlerDataGrid = () => { headerHeight, heightProp, mounted, + onCellClicked, onCellEdited, onColumnMoved, onColumnProposeMove, @@ -65,6 +78,7 @@ export const GridlerDataGrid = () => { headerHeight: s.headerHeight, heightProp: s.height, mounted: s.mounted, + onCellClicked: s.onCellClicked, onCellEdited: s.onCellEdited, onColumnMoved: s.onColumnMoved, onColumnProposeMove: s.onColumnProposeMove, @@ -72,6 +86,7 @@ export const GridlerDataGrid = () => { onContextClick: s.onContextClick, onHeaderClicked: s.onHeaderClicked, onHeaderMenuClick: s.onHeaderMenuClick, + onItemHovered: s.onItemHovered, onVisibleRegionChanged: s.onVisibleRegionChanged, renderColumns: s.renderColumns, @@ -122,6 +137,13 @@ export const GridlerDataGrid = () => { } }} ref={refWrapper} + style={{ + display: 'flex', + height: '100%', + minHeight: '64px', + minWidth: '32px', + width: '100%', + }} > {sections?.left} @@ -132,8 +154,14 @@ export const GridlerDataGrid = () => { columns={(renderColumns as Array) ?? []} columnSelect="none" drawFocusRing - height={(height ?? 400) - 4} + height={height ?? 400} + overscrollX={16} + overscrollY={32} rangeSelect="multi-rect" + rightElementProps={{ + fill: false, + sticky: true, + }} rowMarkers={{ checkboxStyle: 'square', kind: 'both', @@ -148,6 +176,7 @@ export const GridlerDataGrid = () => { gridSelection={_gridSelection} headerHeight={headerHeight ?? 32} headerIcons={{ sort: SortSprite, sortdown: SortDownSprite, sortup: SortUpSprite }} + onCellClicked={onCellClicked} onCellContextMenu={(cell, event) => { event.preventDefault(); glideProps?.onCellContextMenu?.(cell, event); @@ -229,8 +258,10 @@ export const GridlerDataGrid = () => { {!hasLocalData && } {sections?.right} - - {sections?.bottom} +
+ + {sections?.bottom} +
{/* */} ); diff --git a/src/Gridler/components/Column.tsx b/src/Gridler/components/Column.tsx index 59f2bdb..857e470 100644 --- a/src/Gridler/components/Column.tsx +++ b/src/Gridler/components/Column.tsx @@ -18,7 +18,7 @@ export interface GridlerColumn extends Partial { colIndx: string, value: any, storeState: GridlerStoreState - ) => GridCellLoose; + ) => Partial; defaultIcon?: string; disableFilter?: boolean; disableMove?: boolean; diff --git a/src/Gridler/components/Computer.tsx b/src/Gridler/components/Computer.tsx index a70c208..7a0484e 100644 --- a/src/Gridler/components/Computer.tsx +++ b/src/Gridler/components/Computer.tsx @@ -181,6 +181,11 @@ export const Computer = React.memo(() => { })); }).then(() => { loadPage(0, 'all'); + getState('_events')?.dispatchEvent?.( + new CustomEvent('onColumnSorted', { + detail: { cols: colSort }, + }) + ); }); }, [colSort]); @@ -192,6 +197,11 @@ export const Computer = React.memo(() => { if (JSON.stringify(refLastFilters.current) !== JSON.stringify(colFilters)) { loadPage(0, 'all'); refLastFilters.current = colFilters; + getState('_events')?.dispatchEvent?.( + new CustomEvent('onColumnFiltered', { + detail: { filters: colFilters }, + }) + ); } }, [colFilters]); diff --git a/src/Gridler/components/GridlerStore.tsx b/src/Gridler/components/GridlerStore.tsx index cbdf9ad..1820416 100644 --- a/src/Gridler/components/GridlerStore.tsx +++ b/src/Gridler/components/GridlerStore.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable react/react-in-jsx-scope */ + /* eslint-disable react-refresh/only-export-components */ /* eslint-disable @typescript-eslint/no-unused-vars */ import { @@ -143,6 +143,7 @@ export interface GridlerState { loadingData?: boolean; loadPage: (page: number, clearMode?: 'all' | 'page') => Promise; mounted: boolean; + onCellClicked: (cell: Item, event: CellClickedEventArgs) => void; onCellEdited: (cell: Item, newVal: EditableGridCell) => void; onColumnMoved: (from: number, to: number) => void; onColumnProposeMove: (startIndex: number, endIndex: number) => boolean; @@ -340,6 +341,16 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { + const state = get(); + const [col, row] = cell; + state.glideProps?.onCellClicked?.(cell, event); + state._events.dispatchEvent( + new CustomEvent('onCellClicked', { + detail: { cell, col, row, state }, + }) + ); + }, onCellEdited: (cell: Item, newVal: EditableGridCell) => { const state = get(); const [, row] = cell; @@ -351,6 +362,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { const s = get(); @@ -737,7 +749,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { const [sections, setSections] = useState | undefined>(undefined); const columns: GridlerColumns = [ { + Cell: (row, col, colIndx, value, storeState) => { + const process = `${ + row?.cql2?.length > 0 + ? '🔖' + : row?.cql1?.length > 0 + ? '📕' + : row?.status === 1 + ? '💡' + : row?.status === 2 + ? '🔒' + : '⚙️' + } ${String(row?.id_process ?? '0')}`; + + return { + data: process, + displayData: process, + status: row?.status, + }; + }, id: 'id_process', title: 'RID', width: 100, @@ -45,7 +64,7 @@ export const GridlerGoAPIExampleEventlog = () => { ]; return ( - +

Demo Using Go API Adaptor

setApiUrl(e.target.value)} value={apiUrl} /> setApiKey(e.target.value)} value={apiKey} />