docs(changeset): Search String and Better GoAPI functionality

This commit is contained in:
Hein 2025-10-29 16:26:38 +02:00
parent b977308e54
commit 57c72e656f
6 changed files with 83 additions and 19 deletions

View File

@ -0,0 +1,5 @@
---
'@warkypublic/oranguru': patch
---
Search String and Better GoAPI functionality

View File

@ -23,6 +23,7 @@ export interface GridlerColumn extends Partial<BaseGridColumn> {
disableFilter?: boolean; disableFilter?: boolean;
disableMove?: boolean; disableMove?: boolean;
disableResize?: boolean; disableResize?: boolean;
disableSearch?: boolean;
disableSort?: boolean; disableSort?: boolean;
getMenuItems?: ( getMenuItems?: (
id: string, id: string,

View File

@ -90,6 +90,7 @@ export interface GridlerProps extends PropsWithChildren {
rowHeight?: number; rowHeight?: number;
scrollToRowKey?: number; scrollToRowKey?: number;
searchStr?: string;
sections?: { sections?: {
bottom?: React.ReactNode; bottom?: React.ReactNode;
left?: React.ReactNode; left?: React.ReactNode;
@ -106,8 +107,8 @@ export interface GridlerProps extends PropsWithChildren {
title?: string; title?: string;
tooltipBarProps?: React.HTMLAttributes<HTMLDivElement>; tooltipBarProps?: React.HTMLAttributes<HTMLDivElement>;
total_rows?: number; total_rows?: number;
uniqueid: string;
uniqueid: string;
values?: Array<Record<string, any>>; values?: Array<Record<string, any>>;
width?: number | string; width?: number | string;
} }

View File

@ -4,7 +4,11 @@ import React, { useCallback, useEffect } from 'react';
import type { APIOptions } from '../../utils/types'; import type { APIOptions } from '../../utils/types';
import type { GridlerColumn } from '../Column'; 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'; import { useGridlerStore } from '../GridlerStore';
export interface GlidlerAPIAdaptorForGoLangv2Props<T = unknown> extends APIOptions { export interface GlidlerAPIAdaptorForGoLangv2Props<T = unknown> extends APIOptions {
@ -30,38 +34,63 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
const colSort = getState('colSort'); const colSort = getState('colSort');
const pageSize = getState('pageSize'); const pageSize = getState('pageSize');
const colFilters = getState('colFilters'); const colFilters = getState('colFilters');
const searchStr = getState('searchStr');
const _active_requests = getState('_active_requests'); const _active_requests = getState('_active_requests');
setState('loadingData', true); setState('loadingData', true);
try { try {
//console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props }); //console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props });
if (props && props.url) { if (props && props.url) {
const head = new Headers(); 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}`); 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) { if (colSort?.length && colSort.length > 0) {
head.set( ops.push({
'x-sort', type: 'sort',
colSort value: colSort
?.map((sort: any) => `${sort.id} ${sort.direction}`) ?.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
colFilters ?.filter((f) => f.value?.length > 0)
?.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) => { ?.forEach((filter: any) => {
if (filter.value && filter.value !== '') { ops.push({
head.set(`x-searchop-${filter.operator}-${filter.id}`, `${filter.value}`); name: `${filter.id}`,
} op: filter.operator,
type: 'searchor',
value: searchStr,
});
}); });
} }
if (props.filter && props.filter !== '') { 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) { if (props.options && props.options.length > 0) {
const optionHeaders = GoAPIHeaders(props.options); const optionHeaders = GoAPIHeaders(props.options);
for (const oh in optionHeaders) { for (const oh in optionHeaders) {
@ -80,8 +109,18 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
col_ids?.push(props.hotfields.join(',')); 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) { 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; const currentRequestIndex = _active_requests?.findIndex((f) => f.page === index) ?? -1;
@ -90,6 +129,7 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
r.controller?.abort?.(); r.controller?.abort?.();
} }
}); });
if ( if (
_active_requests && _active_requests &&
currentRequestIndex >= 0 && currentRequestIndex >= 0 &&

View File

@ -16,23 +16,30 @@ export interface GlidlerLocalDataAdaptorProps<T = unknown> {
cols: GridlerColumns | undefined, cols: GridlerColumns | undefined,
data: Array<T> data: Array<T>
) => Array<T>; ) => Array<T>;
onSearch?: (
searchField: string | undefined,
cols: GridlerColumns | undefined,
data: Array<T>
) => Array<T>;
} }
//The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders. //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
function _GlidlerLocalDataAdaptor<T = unknown>(props: GlidlerLocalDataAdaptorProps<T>) { function _GlidlerLocalDataAdaptor<T = unknown>(props: GlidlerLocalDataAdaptorProps<T>) {
const [setState, getState, mounted] = useGridlerStore((s) => [s.setState, s.getState, s.mounted]); 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, colFilters: s.colFilters,
colOrder: s.colOrder, colOrder: s.colOrder,
colSize: s.colSize, colSize: s.colSize,
colSort: s.colSort, colSort: s.colSort,
columns: s.columns, columns: s.columns,
searchStr: s.searchStr,
})); }));
const refChanged = React.useRef({ const refChanged = React.useRef({
colFilters: colFilters, colFilters: colFilters,
colSort: colSort, colSort: colSort,
searchStr: searchStr,
}); });
const useAPIQuery: (index: number) => Promise<any> = async (index: number) => { const useAPIQuery: (index: number) => Promise<any> = async (index: number) => {
@ -70,6 +77,16 @@ function _GlidlerLocalDataAdaptor<T = unknown>(props: GlidlerLocalDataAdaptorPro
} }
}, [colFilters, props.onColumnFilter]); }, [colFilters, props.onColumnFilter]);
useEffect(() => {
if (props.onSearch && searchStr !== refChanged?.current?.searchStr) {
const filteredData = props.onSearch(searchStr, columns, props.data as Array<T>);
setState('total_rows', filteredData.length);
setState('data', filteredData);
refChanged.current.colFilters = colFilters;
getState('refreshCells')?.();
}
}, [searchStr, props.onSearch]);
return <></>; return <></>;
} }
export const GlidlerLocalDataAdaptor = React.memo(_GlidlerLocalDataAdaptor); export const GlidlerLocalDataAdaptor = React.memo(_GlidlerLocalDataAdaptor);

View File

@ -2,7 +2,7 @@ export {GlidlerAPIAdaptorForGoLangv2 } from './components/adaptors/GlidlerAPIAda
export {GlidlerFormAdaptor } from './components/adaptors/GlidlerFormAdaptor' export {GlidlerFormAdaptor } from './components/adaptors/GlidlerFormAdaptor'
export {GlidlerLocalDataAdaptor } from './components/adaptors/GlidlerLocalDataAdaptor' export {GlidlerLocalDataAdaptor } from './components/adaptors/GlidlerLocalDataAdaptor'
export * from './components/Column' 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 { GridlerRightMenuIcon } from './components/RightMenuIcon'
export {Gridler} from './Gridler' export {Gridler} from './Gridler'
export * from './utils' export * from './utils'