Interesting delemma
This commit is contained in:
parent
04c516f702
commit
24227f2110
@ -1,5 +1,10 @@
|
||||
import '@glideapps/glide-data-grid/dist/index.css';
|
||||
import { DataEditor, type DataEditorRef, type GridColumn } from '@glideapps/glide-data-grid';
|
||||
import {
|
||||
CompactSelection,
|
||||
DataEditor,
|
||||
type DataEditorRef,
|
||||
type GridColumn,
|
||||
} from '@glideapps/glide-data-grid';
|
||||
import { ActionIcon } from '@mantine/core';
|
||||
import { useElementSize, useMergedRef } from '@mantine/hooks';
|
||||
import { IconMenu2 } from '@tabler/icons-react';
|
||||
@ -20,9 +25,12 @@ export const GridlerDataGrid = () => {
|
||||
const { ref: refWrapper, width } = useElementSize();
|
||||
|
||||
const {
|
||||
_gridSelection,
|
||||
focused,
|
||||
getCellContent,
|
||||
getCellsForSelection,
|
||||
getState,
|
||||
glideProps,
|
||||
hasLocalData,
|
||||
headerHeight,
|
||||
mounted,
|
||||
@ -36,13 +44,16 @@ export const GridlerDataGrid = () => {
|
||||
onVisibleRegionChanged,
|
||||
renderColumns,
|
||||
rowHeight,
|
||||
setState,
|
||||
setStateFN,
|
||||
total_rows,
|
||||
glideProps,
|
||||
} = useGridlerStore((s) => ({
|
||||
_gridSelection: s._gridSelection,
|
||||
focused: s.focused,
|
||||
getCellContent: s.getCellContent,
|
||||
getCellsForSelection: s.getCellsForSelection,
|
||||
getState: s.getState,
|
||||
glideProps: s.glideProps,
|
||||
hasLocalData: s.hasLocalData,
|
||||
headerHeight: s.headerHeight,
|
||||
mounted: s.mounted,
|
||||
@ -56,13 +67,12 @@ export const GridlerDataGrid = () => {
|
||||
onVisibleRegionChanged: s.onVisibleRegionChanged,
|
||||
renderColumns: s.renderColumns,
|
||||
rowHeight: s.rowHeight,
|
||||
setState: s.setState,
|
||||
setStateFN: s.setStateFN,
|
||||
total_rows: s.total_rows,
|
||||
glideProps: s.glideProps,
|
||||
}));
|
||||
|
||||
const refMerged = useMergedRef(ref, (r) => {
|
||||
|
||||
setStateFN('_glideref', () => {
|
||||
return r ?? undefined;
|
||||
});
|
||||
@ -80,7 +90,12 @@ export const GridlerDataGrid = () => {
|
||||
const theme = useGridTheme();
|
||||
|
||||
if (!mounted) {
|
||||
return <>Loadings...<Computer /></>;
|
||||
return (
|
||||
<>
|
||||
Loadings...
|
||||
<Computer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
@ -105,10 +120,10 @@ export const GridlerDataGrid = () => {
|
||||
columns={(renderColumns as Array<GridColumn>) ?? []}
|
||||
columnSelect="none"
|
||||
drawFocusRing
|
||||
|
||||
getCellContent={getCellContent}
|
||||
getCellsForSelection={getCellsForSelection}
|
||||
getRowThemeOverride={theme.getRowThemeOverride}
|
||||
gridSelection={_gridSelection}
|
||||
headerHeight={headerHeight ?? 32}
|
||||
headerIcons={{ sort: SortSprite, sortdown: SortDownSprite, sortup: SortUpSprite }}
|
||||
height={width}
|
||||
@ -126,6 +141,30 @@ export const GridlerDataGrid = () => {
|
||||
onColumnMoved={onColumnMoved}
|
||||
onColumnProposeMove={onColumnProposeMove}
|
||||
onColumnResize={onColumnResize}
|
||||
onGridSelectionChange={(selection) => {
|
||||
let rows = CompactSelection.empty();
|
||||
const currentSelection = getState('_gridSelection');
|
||||
// const currentRowSelection = getState('_gridSelectionRows') ?? CompactSelection.empty();
|
||||
// for (const r of currentRowSelection) {
|
||||
// rows = rows.hasIndex(r) ? rows : rows.add(r);
|
||||
// }
|
||||
for (const r of selection.rows) {
|
||||
rows = rows.hasIndex(r) ? rows : rows.add(r);
|
||||
}
|
||||
|
||||
if (
|
||||
JSON.stringify(currentSelection?.columns) !== JSON.stringify(selection.columns) ||
|
||||
JSON.stringify(currentSelection?.rows) !== JSON.stringify(selection.rows) ||
|
||||
JSON.stringify(currentSelection?.current) !== JSON.stringify(selection.current)
|
||||
) {
|
||||
setState('_gridSelection', { ...selection, rows });
|
||||
if (JSON.stringify(currentSelection?.rows) !== JSON.stringify(selection.rows)) {
|
||||
setState('_gridSelectionRows', rows);
|
||||
}
|
||||
}
|
||||
|
||||
//console.log('Selection', selection);
|
||||
}}
|
||||
onHeaderClicked={onHeaderClicked}
|
||||
onHeaderContextMenu={(col, event) => {
|
||||
event.preventDefault();
|
||||
@ -139,7 +178,7 @@ export const GridlerDataGrid = () => {
|
||||
}}
|
||||
onHeaderMenuClick={onHeaderMenuClick}
|
||||
onVisibleRegionChanged={onVisibleRegionChanged}
|
||||
rangeSelect="none"
|
||||
rangeSelect="multi-rect"
|
||||
ref={refMerged as any}
|
||||
rightElement={
|
||||
<ActionIcon mr="xs" mt="2px" onClick={(e) => onContextClick('menu', e)} variant="subtle">
|
||||
@ -151,11 +190,9 @@ export const GridlerDataGrid = () => {
|
||||
//rowMarkersKind='both'
|
||||
rowMarkers={{
|
||||
checkboxStyle: 'square',
|
||||
kind: 'both'
|
||||
kind: 'both',
|
||||
}}
|
||||
|
||||
rows={total_rows}
|
||||
|
||||
rowSelect="multi"
|
||||
// onGridSelectionChange={(sel) => {
|
||||
// console.log("Selection",sel);
|
||||
@ -169,7 +206,7 @@ export const GridlerDataGrid = () => {
|
||||
// width: 30
|
||||
// }}
|
||||
|
||||
rowSelectionMode='auto'
|
||||
rowSelectionMode="auto"
|
||||
spanRangeBehavior="default"
|
||||
theme={theme.gridTheme}
|
||||
width="100%"
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import type { APIOptions } from '../utils/types';
|
||||
@ -11,7 +12,7 @@ export const APIAdaptorGoLangv2 = React.memo((props: APIOptions) => {
|
||||
s.setState,
|
||||
s.getState,
|
||||
s.addError,
|
||||
s.mounted
|
||||
s.mounted,
|
||||
]);
|
||||
|
||||
const useAPIQuery: (index: number) => Promise<any> = async (index: number) => {
|
||||
@ -19,7 +20,7 @@ export const APIAdaptorGoLangv2 = React.memo((props: APIOptions) => {
|
||||
const pageSize = getState('pageSize');
|
||||
const colFilters = getState('colFilters');
|
||||
const _active_requests = getState('_active_requests');
|
||||
|
||||
//console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props });
|
||||
if (props && props.url) {
|
||||
const head = new Headers();
|
||||
head.set('x-limit', String(pageSize ?? 50));
|
||||
@ -37,11 +38,13 @@ export const APIAdaptorGoLangv2 = React.memo((props: APIOptions) => {
|
||||
}
|
||||
|
||||
if (colFilters?.length && colFilters.length > 0) {
|
||||
colFilters?.filter((f)=>f.value?.length > 0)?.forEach((filter: any) => {
|
||||
if (filter.value && filter.value !== '') {
|
||||
head.set(`x-searchop-${filter.operator}-${filter.id}`, `${filter.value}`);
|
||||
}
|
||||
});
|
||||
colFilters
|
||||
?.filter((f) => f.value?.length > 0)
|
||||
?.forEach((filter: any) => {
|
||||
if (filter.value && filter.value !== '') {
|
||||
head.set(`x-searchop-${filter.operator}-${filter.id}`, `${filter.value}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const currentRequestIndex = _active_requests?.findIndex((f) => f.page === index) ?? -1;
|
||||
@ -56,17 +59,14 @@ export const APIAdaptorGoLangv2 = React.memo((props: APIOptions) => {
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
await setStateFN('_active_requests', (cv) => [
|
||||
...(cv ?? []),
|
||||
{ controller, page: index }
|
||||
]);
|
||||
await setStateFN('_active_requests', (cv) => [...(cv ?? []), { controller, page: index }]);
|
||||
|
||||
const res = await fetch(
|
||||
`${props.url}?x-limit=${String(pageSize ?? 50)}&x-offset=${String((pageSize ?? 50) * index)}`,
|
||||
{
|
||||
headers: head,
|
||||
method: 'GET',
|
||||
signal: controller?.signal
|
||||
signal: controller?.signal,
|
||||
}
|
||||
);
|
||||
|
||||
@ -79,17 +79,56 @@ export const APIAdaptorGoLangv2 = React.memo((props: APIOptions) => {
|
||||
const data = await res.json();
|
||||
|
||||
return data ?? [];
|
||||
}
|
||||
addError(`${res.status} ${res.statusText}`, 'api', props.url);
|
||||
|
||||
}
|
||||
addError(`${res.status} ${res.statusText}`, 'api', props.url);
|
||||
|
||||
await setStateFN('_active_requests', (cv) => [...(cv ?? []).filter((f) => f.page !== index)]);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const askAPIRowNumber: (key: string) => Promise<number> = async (key: string) => {
|
||||
const colFilters = getState('colFilters');
|
||||
|
||||
//console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props });
|
||||
if (props && props.url) {
|
||||
const head = new Headers();
|
||||
head.set('x-limit', '10');
|
||||
head.set('x-fetch-rownumber', String(key));
|
||||
|
||||
head.set('Authorization', `Token ${props.authtoken}`);
|
||||
|
||||
if (colFilters?.length && colFilters.length > 0) {
|
||||
colFilters
|
||||
?.filter((f) => f.value?.length > 0)
|
||||
?.forEach((filter: any) => {
|
||||
if (filter.value && filter.value !== '') {
|
||||
head.set(`x-searchop-${filter.operator}-${filter.id}`, `${filter.value}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
|
||||
const res = await fetch(`${props.url}?x-fetch-rownumber=${key}}`, {
|
||||
headers: head,
|
||||
method: 'GET',
|
||||
signal: controller?.signal,
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
|
||||
return data?.[0]?._rownumber ?? data?._rownumber ?? 0;
|
||||
}
|
||||
addError(`${res.status} ${res.statusText}`, 'api', props.url);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setState('useAPIQuery', useAPIQuery);
|
||||
setState('askAPIRowNumber', askAPIRowNumber);
|
||||
}, [props.url, props.authtoken, mounted, setState]);
|
||||
|
||||
return <></>;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { CompactSelection } from '@glideapps/glide-data-grid';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { useGridlerStore } from './Store';
|
||||
@ -8,28 +10,157 @@ export const Computer = React.memo(() => {
|
||||
const refLastFilters = useRef<any>(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<any>) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
//console.log('Setting SSS', { key, rowIndex });
|
||||
}
|
||||
//console.log('Setting selection', { rowIndexes, values });
|
||||
return rowIndexes;
|
||||
};
|
||||
|
||||
if (values) {
|
||||
searchSelection().then((rowIndexes) => {
|
||||
// const newObj : GridSelection = {
|
||||
// ...cur,
|
||||
|
||||
// rows: {
|
||||
// items: rowIndexes.map((r) => [r - 1, r]) ?? [],
|
||||
// },
|
||||
// };
|
||||
// console.log('Setting selection', {
|
||||
// rowIndexes,
|
||||
// values,
|
||||
// newObj,
|
||||
// });
|
||||
setStateFN('_gridSelectionRows', () => {
|
||||
let rows = CompactSelection.empty();
|
||||
rowIndexes.forEach((r) => {
|
||||
rows = rows.add(r);
|
||||
});
|
||||
// for (const r of cur ?? CompactSelection.empty()) {
|
||||
// rows = rows.add(r);
|
||||
// }
|
||||
setStateFN('_gridSelection', (c) => ({
|
||||
columns: c?.columns ?? CompactSelection.empty(),
|
||||
...c,
|
||||
rows,
|
||||
}));
|
||||
|
||||
return rows;
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [values]);
|
||||
|
||||
useEffect(() => {
|
||||
//console.log('Gridler:Computer: Selection changed', _gridSelectionRows?.toArray());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log('Calling onChange with buffers', buffers, _gridSelectionRows?.toArray());
|
||||
const _values = getState('values');
|
||||
|
||||
if (JSON.stringify(_values) !== JSON.stringify(buffers)) {
|
||||
onChange(buffers);
|
||||
}
|
||||
}
|
||||
}, [JSON.stringify(_gridSelectionRows), getState]);
|
||||
|
||||
useEffect(() => {
|
||||
setState(
|
||||
'renderColumns',
|
||||
@ -45,6 +176,14 @@ export const Computer = React.memo(() => {
|
||||
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,
|
||||
@ -64,7 +203,7 @@ export const Computer = React.memo(() => {
|
||||
if (!colFilters) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (JSON.stringify(refLastFilters.current) !== JSON.stringify(colFilters)) {
|
||||
loadPage(0, 'all');
|
||||
refLastFilters.current = colFilters;
|
||||
@ -87,6 +226,7 @@ export const Computer = React.memo(() => {
|
||||
if (!colOrder) {
|
||||
return;
|
||||
}
|
||||
|
||||
setStateFN('renderColumns', (cols) => {
|
||||
const result = cols?.sort((a, b) => {
|
||||
if (colOrder[a.id] > colOrder[b.id]) {
|
||||
|
||||
@ -10,9 +10,10 @@ import {
|
||||
type GridCell,
|
||||
GridCellKind,
|
||||
type GridColumn,
|
||||
type GridSelection,
|
||||
type HeaderClickedEventArgs,
|
||||
type Item,
|
||||
type Rectangle
|
||||
type Rectangle,
|
||||
} from '@glideapps/glide-data-grid';
|
||||
import { getUUID } from '@warkypublic/artemis-kit';
|
||||
import { getNestedValue } from '@warkypublic/artemis-kit/object';
|
||||
@ -47,6 +48,7 @@ export type FilterOptionOperator =
|
||||
| 'startswith';
|
||||
|
||||
export interface GridlerProps extends PropsWithChildren {
|
||||
askAPIRowNumber?: (key: string) => Promise<number>;
|
||||
columns?: GridlerColumns;
|
||||
data?: Array<any>;
|
||||
defaultSort?: Array<SortOption>;
|
||||
@ -58,11 +60,13 @@ export interface GridlerProps extends PropsWithChildren {
|
||||
col?: GridlerColumn,
|
||||
defaultItems?: Array<any>
|
||||
) => Array<any>;
|
||||
glideProps?: Partial<DataEditorProps>
|
||||
|
||||
glideProps?: Partial<DataEditorProps>;
|
||||
headerHeight?: number;
|
||||
hideMenu?: (id: string) => void;
|
||||
keyField?: string;
|
||||
maxConcurrency?: number;
|
||||
onChange?: (values: Array<Record<string, any>>) => void;
|
||||
pageSize?: number;
|
||||
progressiveScroll?: boolean;
|
||||
RenderCell?: <TRowType extends Record<string, string>>(
|
||||
@ -77,11 +81,15 @@ export interface GridlerProps extends PropsWithChildren {
|
||||
selectedRow?: number;
|
||||
showMenu?: (id: string, options?: Partial<MantineBetterMenuInstance>) => void;
|
||||
uniqueid: string;
|
||||
useAPIQuery?: (index: number) => Promise<Array<Record<string, any>>>;
|
||||
values?: Array<Record<string, any>>;
|
||||
}
|
||||
|
||||
export interface GridlerState {
|
||||
_active_requests?: Array<{ controller: AbortController; page: number }>;
|
||||
_glideref?: DataEditorRef;
|
||||
_gridSelection?: GridSelection;
|
||||
_gridSelectionRows?: GridSelection['rows'];
|
||||
_loadingList: CompactSelection;
|
||||
_page_data: Record<number, Array<any>>;
|
||||
_scrollTimeout?: any | number;
|
||||
@ -93,7 +101,6 @@ export interface GridlerState {
|
||||
colSize?: Record<string, number>;
|
||||
colSort?: Array<SortOption>;
|
||||
data?: Array<any>;
|
||||
|
||||
|
||||
errors: Array<string>;
|
||||
focused?: boolean;
|
||||
@ -145,7 +152,6 @@ export interface GridlerState {
|
||||
) => Promise<void>;
|
||||
toCell: <TRowType extends Record<string, string>>(row: any, col: number) => GridCell;
|
||||
total_rows: number;
|
||||
useAPIQuery?: (index: number) => Promise<Array<Record<string, any>>>;
|
||||
}
|
||||
|
||||
export type GridlerStoreState = GridlerProps & GridlerState;
|
||||
@ -206,7 +212,6 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
const state = get();
|
||||
//const firstPage = Math.max(0, Math.floor(selection.y / state.pageSize));
|
||||
//const lastPage = Math.floor((selection.y + selection.height) / state.pageSize);
|
||||
//console.log('Gridler:Debug:getCellsForSelection', selection, firstPage, lastPage);
|
||||
|
||||
await state.setStateFN('_visibleArea', (cv) => {
|
||||
//if (r.x === cv.x && r.y === cv.y && r.width === cv.width && r.height === cv.height)
|
||||
@ -214,17 +219,6 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
return selection;
|
||||
});
|
||||
|
||||
// for (const pageChunk of chunk(
|
||||
// range(firstPage, lastPage + 1).filter((i) => !state._loadingList.hasIndex(i)),
|
||||
// state.maxConcurrency
|
||||
// )) {
|
||||
// await Promise.all(pageChunk.map(state.loadPage));
|
||||
// }
|
||||
|
||||
// for (const page of range(firstPage - 1, lastPage + 1, 1)) {
|
||||
// state.loadPage(page);
|
||||
// }
|
||||
|
||||
const result: GridCell[][] = [];
|
||||
|
||||
for (let y = selection.y; y < selection.y + selection.height; y++) {
|
||||
@ -235,6 +229,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
result.push(row);
|
||||
}
|
||||
|
||||
//console.log('Gridler:Debug:getCellsForSelection', selection, result);
|
||||
return result as CellArray;
|
||||
};
|
||||
},
|
||||
@ -242,6 +237,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
return get()[key];
|
||||
},
|
||||
hasLocalData: false,
|
||||
keyField: 'id',
|
||||
loadPage: async (pPage: number, clearMode?: 'all' | 'page') => {
|
||||
const state = get();
|
||||
const page = pPage < 0 ? 0 : pPage;
|
||||
@ -477,7 +473,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
},
|
||||
];
|
||||
const items = [
|
||||
...(coldef.disableSort ? []: sortItems),
|
||||
...(coldef.disableSort ? [] : sortItems),
|
||||
{
|
||||
label: `Filter ${coldef?.title ?? coldef?.id}`,
|
||||
},
|
||||
@ -649,11 +645,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
uniqueid: getUUID(),
|
||||
}),
|
||||
(props) => {
|
||||
const [setState, glideref, getState] = props.useStore((s) => [
|
||||
s.setState,
|
||||
s._glideref,
|
||||
s.getState,
|
||||
]);
|
||||
const [setState, getState] = props.useStore((s) => [s.setState, s.getState]);
|
||||
|
||||
const menus = useMantineBetterMenus();
|
||||
|
||||
@ -661,6 +653,47 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
setState('mounted', true);
|
||||
}, [setState]);
|
||||
|
||||
/// logic to apply the selected row.
|
||||
useEffect(() => {
|
||||
const ref = getState('_glideref');
|
||||
const keyField = getState('keyField') ?? 'id';
|
||||
const selectedRow = getState('selectedRow') ?? props.selectedRow;
|
||||
const askAPIRowNumber = getState('askAPIRowNumber');
|
||||
let rowIndex = -1;
|
||||
if (selectedRow && ref) {
|
||||
const page_data = getState('_page_data');
|
||||
const pageSize = getState('pageSize');
|
||||
for (const p in page_data) {
|
||||
for (const r in page_data[p]) {
|
||||
const idx = Number(p) * pageSize + Number(r);
|
||||
//console.log('Found row', idx, page_data[p][r]?.[keyField], selectedRow);
|
||||
if (String(page_data[p][r]?.[keyField]) === String(selectedRow)) {
|
||||
rowIndex =
|
||||
page_data[p][r]?._rownumber > 0 ? page_data[p][r]?._rownumber : idx > 0 ? idx : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rowIndex > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rowIndex > 0) {
|
||||
ref.scrollTo(0, rowIndex);
|
||||
} else if (typeof askAPIRowNumber === 'function') {
|
||||
askAPIRowNumber(String(selectedRow))
|
||||
.then((r) => {
|
||||
if (r >= 0) {
|
||||
ref.scrollTo(0, r);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.warn('Error in askAPIRowNumber', e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [props.selectedRow]);
|
||||
|
||||
return {
|
||||
...props,
|
||||
hasLocalData: props.data && props.data.length > 0,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Divider, Stack, TextInput } from '@mantine/core';
|
||||
import { Divider, Group, Stack, TagsInput, TextInput } from '@mantine/core';
|
||||
import { useLocalStorage } from '@mantine/hooks';
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { GridlerColumns } from '../components/Column';
|
||||
|
||||
@ -12,7 +13,8 @@ export const GridlerGoAPIExampleEventlog = () => {
|
||||
key: 'apiurl',
|
||||
});
|
||||
const [apiKey, setApiKey] = useLocalStorage({ defaultValue: '', key: 'apikey' });
|
||||
|
||||
const [selectRow, setSelectRow] = useState<string | undefined>('');
|
||||
const [values, setValues] = useState<Array<Record<string, any>>>([]);
|
||||
const columns: GridlerColumns = [
|
||||
{
|
||||
id: 'id_process',
|
||||
@ -58,10 +60,33 @@ export const GridlerGoAPIExampleEventlog = () => {
|
||||
// },
|
||||
];
|
||||
}}
|
||||
keyField="id_process"
|
||||
onChange={(v) => {
|
||||
console.log('GridlerGoAPIExampleEventlog onChange', v);
|
||||
setValues(v);
|
||||
}}
|
||||
selectedRow={selectRow ? parseInt(selectRow, 10) : undefined}
|
||||
uniqueid="gridtest"
|
||||
values={values}
|
||||
>
|
||||
<APIAdaptorGoLangv2 authtoken={apiKey} url={`${apiUrl}/public/process`} />
|
||||
</Gridler>
|
||||
<Divider />
|
||||
<Group>
|
||||
<TextInput
|
||||
onChange={(e) => setSelectRow(e.target.value)}
|
||||
placeholder="row"
|
||||
value={selectRow}
|
||||
w="90px"
|
||||
/>
|
||||
<TagsInput
|
||||
data={[]}
|
||||
onChange={(str) => setValues(str.map((v) => ({ id_process: String(v) })))}
|
||||
placeholder="Values"
|
||||
value={values.map((v) => String(v?.id_process))}
|
||||
/>
|
||||
;
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user