From 57c72e656fd9862cbdbdfd7a1132c6143c7cc6c2 Mon Sep 17 00:00:00 2001 From: Hein Date: Wed, 29 Oct 2025 16:26:38 +0200 Subject: [PATCH] docs(changeset): Search String and Better GoAPI functionality --- .changeset/salty-apes-cheat.md | 5 ++ src/Gridler/components/Column.tsx | 1 + src/Gridler/components/GridlerStore.tsx | 3 +- .../adaptors/GlidlerAPIAdaptorForGoLangv2.tsx | 72 ++++++++++++++----- .../adaptors/GlidlerLocalDataAdaptor.tsx | 19 ++++- src/Gridler/index.ts | 2 +- 6 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 .changeset/salty-apes-cheat.md diff --git a/.changeset/salty-apes-cheat.md b/.changeset/salty-apes-cheat.md new file mode 100644 index 0000000..9789d26 --- /dev/null +++ b/.changeset/salty-apes-cheat.md @@ -0,0 +1,5 @@ +--- +'@warkypublic/oranguru': patch +--- + +Search String and Better GoAPI functionality diff --git a/src/Gridler/components/Column.tsx b/src/Gridler/components/Column.tsx index e89d624..dbb27fc 100644 --- a/src/Gridler/components/Column.tsx +++ b/src/Gridler/components/Column.tsx @@ -23,6 +23,7 @@ export interface GridlerColumn extends Partial { disableFilter?: boolean; disableMove?: boolean; disableResize?: boolean; + disableSearch?: boolean; disableSort?: boolean; getMenuItems?: ( id: string, diff --git a/src/Gridler/components/GridlerStore.tsx b/src/Gridler/components/GridlerStore.tsx index b2af058..d9f1a83 100644 --- a/src/Gridler/components/GridlerStore.tsx +++ b/src/Gridler/components/GridlerStore.tsx @@ -90,6 +90,7 @@ export interface GridlerProps extends PropsWithChildren { rowHeight?: number; scrollToRowKey?: number; + searchStr?: string; sections?: { bottom?: React.ReactNode; left?: React.ReactNode; @@ -106,8 +107,8 @@ export interface GridlerProps extends PropsWithChildren { title?: string; tooltipBarProps?: React.HTMLAttributes; total_rows?: number; - uniqueid: string; + uniqueid: string; values?: Array>; width?: number | string; } diff --git a/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx b/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx index 5509b09..e367085 100644 --- a/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx +++ b/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx @@ -4,7 +4,11 @@ import React, { useCallback, useEffect } from 'react'; import type { APIOptions } from '../../utils/types'; import type { GridlerColumn } from '../Column'; -import { GoAPIHeaders, type GoAPIOperation } from '../../utils/golang-restapi-v2'; +import { + type FetchAPIOperation, + GoAPIHeaders, + type GoAPIOperation, +} from '../../utils/golang-restapi-v2'; import { useGridlerStore } from '../GridlerStore'; export interface GlidlerAPIAdaptorForGoLangv2Props extends APIOptions { @@ -30,38 +34,63 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG const colSort = getState('colSort'); const pageSize = getState('pageSize'); const colFilters = getState('colFilters'); + const searchStr = getState('searchStr'); const _active_requests = getState('_active_requests'); setState('loadingData', true); try { //console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props }); if (props && props.url) { const head = new Headers(); - head.set('x-limit', String(pageSize ?? 50)); - head.set('x-offset', String((pageSize ?? 50) * index)); head.set('Authorization', `Token ${props.authtoken}`); + const ops: FetchAPIOperation[] = [ + { type: 'limit', value: String(pageSize ?? 50) }, + { type: 'offset', value: String((pageSize ?? 50) * index) }, + ]; if (colSort?.length && colSort.length > 0) { - head.set( - 'x-sort', - colSort + ops.push({ + type: 'sort', + value: colSort ?.map((sort: any) => `${sort.id} ${sort.direction}`) - .reduce((acc: any, val: any) => `${acc},${val}`) - ); + .reduce((acc: any, val: any) => `${acc},${val}`), + }); } - if (colFilters?.length && colFilters.length > 0) { - colFilters - ?.filter((f) => f.value?.length > 0) + colFilters + ?.filter((f) => f.value?.length > 0) + ?.forEach((filter: any) => { + if (filter.value && filter.value !== '') { + ops.push({ + name: `${filter.id}`, + op: filter.operator, + type: 'searchop', + value: filter.value, + }); + } + }); + + if (searchStr && searchStr !== '') { + columns + ?.filter((f) => !f.disableFilter && !f.disableSearch) ?.forEach((filter: any) => { - if (filter.value && filter.value !== '') { - head.set(`x-searchop-${filter.operator}-${filter.id}`, `${filter.value}`); - } + ops.push({ + name: `${filter.id}`, + op: filter.operator, + type: 'searchor', + value: searchStr, + }); }); } + if (props.filter && props.filter !== '') { - head.set('x-custom-sql-w-buildin-filter', props.filter); + ops.push({ + name: 'sql_filter', + type: 'custom-sql-w', + value: props.filter, + }); } + if (props.options && props.options.length > 0) { const optionHeaders = GoAPIHeaders(props.options); for (const oh in optionHeaders) { @@ -80,8 +109,18 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG col_ids?.push(props.hotfields.join(',')); } + if (ops && ops.length > 0) { + const optionHeaders = GoAPIHeaders(ops); + for (const oh in GoAPIHeaders(ops)) { + head.set(oh, optionHeaders[oh]); + } + } + if (col_ids && col_ids.length > 0) { - head.set(`x-select-fields`, col_ids.join(',')); + ops.push({ + type: 'select-fields', + value: col_ids.join(','), + }); } const currentRequestIndex = _active_requests?.findIndex((f) => f.page === index) ?? -1; @@ -90,6 +129,7 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG r.controller?.abort?.(); } }); + if ( _active_requests && currentRequestIndex >= 0 && diff --git a/src/Gridler/components/adaptors/GlidlerLocalDataAdaptor.tsx b/src/Gridler/components/adaptors/GlidlerLocalDataAdaptor.tsx index 10eefda..1f6f49b 100644 --- a/src/Gridler/components/adaptors/GlidlerLocalDataAdaptor.tsx +++ b/src/Gridler/components/adaptors/GlidlerLocalDataAdaptor.tsx @@ -16,23 +16,30 @@ export interface GlidlerLocalDataAdaptorProps { cols: GridlerColumns | undefined, data: Array ) => Array; + onSearch?: ( + searchField: string | undefined, + cols: GridlerColumns | undefined, + data: Array + ) => Array; } //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders. function _GlidlerLocalDataAdaptor(props: GlidlerLocalDataAdaptorProps) { const [setState, getState, mounted] = useGridlerStore((s) => [s.setState, s.getState, s.mounted]); - const { colFilters, colSort, columns } = useGridlerStore((s) => ({ + const { colFilters, colSort, columns, searchStr } = useGridlerStore((s) => ({ colFilters: s.colFilters, colOrder: s.colOrder, colSize: s.colSize, colSort: s.colSort, columns: s.columns, + searchStr: s.searchStr, })); const refChanged = React.useRef({ colFilters: colFilters, colSort: colSort, + searchStr: searchStr, }); const useAPIQuery: (index: number) => Promise = async (index: number) => { @@ -70,6 +77,16 @@ function _GlidlerLocalDataAdaptor(props: GlidlerLocalDataAdaptorPro } }, [colFilters, props.onColumnFilter]); + useEffect(() => { + if (props.onSearch && searchStr !== refChanged?.current?.searchStr) { + const filteredData = props.onSearch(searchStr, columns, props.data as Array); + setState('total_rows', filteredData.length); + setState('data', filteredData); + refChanged.current.colFilters = colFilters; + getState('refreshCells')?.(); + } + }, [searchStr, props.onSearch]); + return <>; } export const GlidlerLocalDataAdaptor = React.memo(_GlidlerLocalDataAdaptor); diff --git a/src/Gridler/index.ts b/src/Gridler/index.ts index 333ac64..2e8be75 100644 --- a/src/Gridler/index.ts +++ b/src/Gridler/index.ts @@ -2,7 +2,7 @@ export {GlidlerAPIAdaptorForGoLangv2 } from './components/adaptors/GlidlerAPIAda export {GlidlerFormAdaptor } from './components/adaptors/GlidlerFormAdaptor' export {GlidlerLocalDataAdaptor } from './components/adaptors/GlidlerLocalDataAdaptor' export * from './components/Column' -export {type GridlerProps, useGridlerStore } from './components/GridlerStore' +export {type GridlerProps,type GridlerState, useGridlerStore } from './components/GridlerStore' export { GridlerRightMenuIcon } from './components/RightMenuIcon' export {Gridler} from './Gridler' export * from './utils' \ No newline at end of file