From 5d8388c2db41fd0e8ba198c9e9bea59b8f6799b1 Mon Sep 17 00:00:00 2001 From: Hein Date: Thu, 23 Oct 2025 16:31:45 +0200 Subject: [PATCH] docs(changeset): Added selectFirstRowOnMount and fixed selection of first row --- .changeset/sad-ideas-raise.md | 5 +++ src/Gridler/components/Computer.tsx | 39 +++++++++++++++++++ src/Gridler/components/GridlerStore.tsx | 18 ++++++--- .../adaptors/GlidlerAPIAdaptorForGoLangv2.tsx | 33 +++++++++++++--- src/Gridler/stories/Examples.goapi.tsx | 1 + 5 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 .changeset/sad-ideas-raise.md diff --git a/.changeset/sad-ideas-raise.md b/.changeset/sad-ideas-raise.md new file mode 100644 index 0000000..366d94a --- /dev/null +++ b/.changeset/sad-ideas-raise.md @@ -0,0 +1,5 @@ +--- +'@warkypublic/oranguru': patch +--- + +Added selectFirstRowOnMount and fixed selection of first row diff --git a/src/Gridler/components/Computer.tsx b/src/Gridler/components/Computer.tsx index 7a0484e..d7b5095 100644 --- a/src/Gridler/components/Computer.tsx +++ b/src/Gridler/components/Computer.tsx @@ -245,6 +245,45 @@ export const Computer = React.memo(() => { loadPage(0); }, [ready, loadPage]); + useEffect(() => { + const _events = getState('_events'); + const loadPage = () => { + const selectFirstRowOnMount = getState('selectFirstRowOnMount'); + if (selectFirstRowOnMount) { + const selectedRow = getState('selectedRow'); + if (selectedRow && selectedRow >= 0) { + return; + } + const keyField = getState('keyField') ?? 'id'; + const page_data = getState('_page_data'); + const firstBuffer = page_data?.[0]?.[0]; + const firstRow = firstBuffer?.[keyField]; + + if (firstRow && firstRow > 0) { + const values = [ + firstBuffer, + ...((getState('values') ?? []) as Array>), + ]; + + const onChange = getState('onChange'); + console.log('Selecting first row:', firstRow, firstBuffer, values); + if (onChange) { + onChange(values); + } else { + setState('values', values); + } + + setState('selectedRow', firstRow); + } + } + }; + + _events?.addEventListener('loadPage', loadPage); + + return () => { + _events?.removeEventListener('loadPage', loadPage); + }; + }, []); // console.log('Gridler:Debug:Computer', { // colFilters, // colOrder, diff --git a/src/Gridler/components/GridlerStore.tsx b/src/Gridler/components/GridlerStore.tsx index 483ab93..2af190f 100644 --- a/src/Gridler/components/GridlerStore.tsx +++ b/src/Gridler/components/GridlerStore.tsx @@ -56,7 +56,6 @@ export type FilterOptionOperator = | 'startswith'; export interface GridlerProps extends PropsWithChildren { - askAPIRowNumber?: (key: string) => Promise; columns?: GridlerColumns; defaultSort?: Array; @@ -99,13 +98,14 @@ export interface GridlerProps extends PropsWithChildren { top?: React.ReactNode; }; selectedRow?: number; + selectFirstRowOnMount?: boolean; selectMode?: 'cell' | 'row'; showMenu?: (id: string, options?: Partial) => void; title?: string; tooltipBarProps?: React.HTMLAttributes; total_rows?: number; uniqueid: string; - useAPIQuery?: (index: number) => Promise>>; + values?: Array>; width?: number | string; } @@ -124,13 +124,14 @@ export interface GridlerState { _visiblePages: Rectangle; addError: (err: string, ...args: Array) => void; + askAPIRowNumber?: (key: string) => Promise; colFilters?: Array; colOrder?: Record; colSize?: Record; colSort?: Array; data?: Array; - errors: Array; + focused?: boolean; get: () => GridlerState; getCellContent: (cell: Item) => GridCell; @@ -140,8 +141,8 @@ export interface GridlerState { ) => CellArray | GetCellsThunk; getRowBuffer: (row: number) => Record; getState: (key: K) => GridlerStoreState[K]; - hasLocalData: boolean; + loadingData?: boolean; loadPage: (page: number, clearMode?: 'all' | 'page') => Promise; mounted: boolean; @@ -159,7 +160,6 @@ export interface GridlerState { onHeaderClicked: (colIndex: number, event: HeaderClickedEventArgs) => void; onHeaderMenuClick: (col: number, screenPosition: Rectangle) => void; onItemHovered: (args: GridMouseEventArgs) => void; - onVisibleRegionChanged: ( r: Rectangle, tx: number, @@ -172,6 +172,7 @@ export interface GridlerState { ) => void; pageSize: number; + ready: boolean; reload?: () => Promise; renderColumns?: GridlerColumns; @@ -184,6 +185,7 @@ export interface GridlerState { value: (current: GridlerStoreState[K]) => Partial ) => Promise; toCell: >(row: TRowType, col: number) => GridCell; + useAPIQuery?: (index: number) => Promise>>; } export type GridlerStoreState = GridlerProps & GridlerState; @@ -842,6 +844,11 @@ const { Provider, useStore: useGridlerStore } = createSyncStore 0) { ref.scrollTo(0, rowIndex); + getState('_events').dispatchEvent( + new CustomEvent('selectedRowFound', { + detail: { rowNumber: rowIndex, selectedRow: selectedRow }, + }) + ); } else if (typeof askAPIRowNumber === 'function') { askAPIRowNumber(String(selectedRow)) .then((r) => { @@ -868,6 +875,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore extends APIOptions { + filter?: string; initialData?: Array; options?: Array; } function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForGoLangv2Props) { - const [setStateFN, setState, getState, addError, mounted] = useGridlerStore((s) => [ + const [setStateFN, setState, getState, addError, mounted, loadPage] = useGridlerStore((s) => [ s.setStateFN, s.setState, s.getState, s.addError, s.mounted, + s.loadPage, ]); const useAPIQuery: (index: number) => Promise = useCallback( @@ -54,7 +56,9 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG } }); } - + if (props.filter && props.filter !== '') { + head.set('x-custom-sql-w-buildin-filter', props.filter); + } if (props.options && props.options.length > 0) { const optionHeaders = GoAPIHeaders(props.options); for (const oh in optionHeaders) { @@ -116,7 +120,16 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG setState('loadingData', false); return []; }, - [getState, props.authtoken, props.url, props.options, setState, setStateFN, addError] + [ + getState, + props.authtoken, + props.url, + props.filter, + props.options, + setState, + setStateFN, + addError, + ] ); const askAPIRowNumber: (key: string) => Promise = useCallback( @@ -141,6 +154,10 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG }); } + if (props.filter && props.filter !== '') { + head.set('x-custom-sql-w-buildin-filter', props.filter); + } + if (props.options && props.options.length > 0) { const optionHeaders = GoAPIHeaders(props.options); for (const oh in optionHeaders) { @@ -165,13 +182,19 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG } return []; }, - [props.url, props.authtoken, props.options, getState, addError] + [props.url, props.authtoken, props.filter, props.options, getState, addError] ); + //Reset the loaded pages to new rules + useEffect(() => { + loadPage(0, 'all'); + }, [JSON.stringify(props.options), props.filter, props.url, props.authtoken]); + + //Reset the function in the store. useEffect(() => { setState('useAPIQuery', useAPIQuery); setState('askAPIRowNumber', askAPIRowNumber); - }, [props.url, props.authtoken, props.options, mounted, setState]); + }, [props.url, props.authtoken, props.filter, props.options, mounted, setState]); return <>; } diff --git a/src/Gridler/stories/Examples.goapi.tsx b/src/Gridler/stories/Examples.goapi.tsx index 8f04e5e..8d7dab1 100644 --- a/src/Gridler/stories/Examples.goapi.tsx +++ b/src/Gridler/stories/Examples.goapi.tsx @@ -108,6 +108,7 @@ export const GridlerGoAPIExampleEventlog = () => { }} sections={{ ...sections, rightElementDisabled: false }} selectedRow={selectRow ? parseInt(selectRow, 10) : undefined} + selectFirstRowOnMount={true} selectMode="row" title="Go API Example" uniqueid="gridtest"