fix(Gridler): 🐛 improve state management and cleanup
* Update `askAPIRowNumber` to return `null` or `number` for better type safety. * Refactor conditionals to ensure proper handling of row indices. * Clean up console logs for improved readability and performance. * Ensure consistent formatting across the codebase.
This commit is contained in:
@@ -188,6 +188,7 @@ export const GridlerDataGrid = () => {
|
|||||||
if (!refContextActivated.current) {
|
if (!refContextActivated.current) {
|
||||||
refContextActivated.current = true;
|
refContextActivated.current = true;
|
||||||
onContextClick('cell', event, cell[0], cell[1]);
|
onContextClick('cell', event, cell[0], cell[1]);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
refContextActivated.current = false;
|
refContextActivated.current = false;
|
||||||
}, 100);
|
}, 100);
|
||||||
@@ -231,7 +232,7 @@ export const GridlerDataGrid = () => {
|
|||||||
rows = rows.hasIndex(r) ? rows : rows.add(r);
|
rows = rows.hasIndex(r) ? rows : rows.add(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('Debug:onGridSelectionChange', currentSelection, selection);
|
//console.log('Debug:onGridSelectionChange', currentSelection, selection);
|
||||||
if (
|
if (
|
||||||
JSON.stringify(currentSelection?.columns) !== JSON.stringify(selection.columns) ||
|
JSON.stringify(currentSelection?.columns) !== JSON.stringify(selection.columns) ||
|
||||||
JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows) ||
|
JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows) ||
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const Computer = React.memo(() => {
|
|||||||
selectFirstRowOnMount,
|
selectFirstRowOnMount,
|
||||||
setState,
|
setState,
|
||||||
setStateFN,
|
setStateFN,
|
||||||
values
|
values,
|
||||||
} = useGridlerStore((s) => ({
|
} = useGridlerStore((s) => ({
|
||||||
_glideref: s._glideref,
|
_glideref: s._glideref,
|
||||||
_gridSelectionRows: s._gridSelectionRows,
|
_gridSelectionRows: s._gridSelectionRows,
|
||||||
@@ -100,9 +100,12 @@ export const Computer = React.memo(() => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(rowIndex >= 0)) {
|
|
||||||
|
if (rowIndex >= 0) {
|
||||||
|
rowIndexes.push(rowIndex);
|
||||||
|
} else {
|
||||||
const idx = await getRowIndexByKey(key);
|
const idx = await getRowIndexByKey(key);
|
||||||
if (idx) {
|
if (idx !== null) {
|
||||||
rowIndexes.push(idx);
|
rowIndexes.push(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +118,9 @@ export const Computer = React.memo(() => {
|
|||||||
searchSelection().then((rowIndexes) => {
|
searchSelection().then((rowIndexes) => {
|
||||||
let rows = CompactSelection.empty();
|
let rows = CompactSelection.empty();
|
||||||
rowIndexes.forEach((r) => {
|
rowIndexes.forEach((r) => {
|
||||||
|
if (r !== undefined) {
|
||||||
rows = rows.add(r);
|
rows = rows.add(r);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setStateFN('_gridSelectionRows', () => {
|
setStateFN('_gridSelectionRows', () => {
|
||||||
@@ -276,10 +281,8 @@ export const Computer = React.memo(() => {
|
|||||||
const ready = getState('ready');
|
const ready = getState('ready');
|
||||||
|
|
||||||
if (ready && selectFirstRowOnMount) {
|
if (ready && selectFirstRowOnMount) {
|
||||||
|
|
||||||
const scrollToRowKey = getState('scrollToRowKey');
|
const scrollToRowKey = getState('scrollToRowKey');
|
||||||
|
|
||||||
|
|
||||||
if (scrollToRowKey && scrollToRowKey >= 0) {
|
if (scrollToRowKey && scrollToRowKey >= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -299,7 +302,6 @@ export const Computer = React.memo(() => {
|
|||||||
) {
|
) {
|
||||||
const values = [firstBuffer, ...(currentValues as Array<Record<string, unknown>>)];
|
const values = [firstBuffer, ...(currentValues as Array<Record<string, unknown>>)];
|
||||||
|
|
||||||
|
|
||||||
const onChange = getState('onChange');
|
const onChange = getState('onChange');
|
||||||
//console.log('Selecting first row:', firstRow, firstBuffer, values);
|
//console.log('Selecting first row:', firstRow, firstBuffer, values);
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
@@ -348,9 +350,10 @@ export const Computer = React.memo(() => {
|
|||||||
const key = selectedRowKey ?? scrollToRowKey;
|
const key = selectedRowKey ?? scrollToRowKey;
|
||||||
|
|
||||||
if (key && ref && ready) {
|
if (key && ref && ready) {
|
||||||
|
//console.log('Computer:Scrolling to key:', key);
|
||||||
getRowIndexByKey?.(key).then((r) => {
|
getRowIndexByKey?.(key).then((r) => {
|
||||||
if (r !== undefined) {
|
if (r !== undefined) {
|
||||||
//console.log('Scrolling to selected row:', r, selectedRowKey, scrollToRowKey);
|
console.log('Scrolling to selected row:', r, selectedRowKey, scrollToRowKey);
|
||||||
|
|
||||||
if (selectedRowKey) {
|
if (selectedRowKey) {
|
||||||
const onChange = getState('onChange');
|
const onChange = getState('onChange');
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export interface GridlerState {
|
|||||||
_visibleArea: Rectangle;
|
_visibleArea: Rectangle;
|
||||||
_visiblePages: Rectangle;
|
_visiblePages: Rectangle;
|
||||||
addError: (err: string, ...args: Array<any>) => void;
|
addError: (err: string, ...args: Array<any>) => void;
|
||||||
askAPIRowNumber?: (key: string) => Promise<number>;
|
askAPIRowNumber?: (key: string) => Promise<null | number>;
|
||||||
colFilters?: Array<FilterOption>;
|
colFilters?: Array<FilterOption>;
|
||||||
colOrder?: Record<string, number>;
|
colOrder?: Record<string, number>;
|
||||||
colSize?: Record<string, number>;
|
colSize?: Record<string, number>;
|
||||||
@@ -162,7 +162,7 @@ export interface GridlerState {
|
|||||||
hasLocalData: boolean;
|
hasLocalData: boolean;
|
||||||
isEmpty: boolean;
|
isEmpty: boolean;
|
||||||
|
|
||||||
isValuesInPages: () => boolean
|
isValuesInPages: () => boolean;
|
||||||
loadingData?: boolean;
|
loadingData?: boolean;
|
||||||
loadPage: (page: number, clearMode?: 'all' | 'page') => Promise<void>;
|
loadPage: (page: number, clearMode?: 'all' | 'page') => Promise<void>;
|
||||||
mounted: boolean;
|
mounted: boolean;
|
||||||
@@ -191,7 +191,6 @@ export interface GridlerState {
|
|||||||
freezeRegions?: readonly Rectangle[];
|
freezeRegions?: readonly Rectangle[];
|
||||||
selected?: Item;
|
selected?: Item;
|
||||||
}
|
}
|
||||||
|
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
@@ -200,10 +199,7 @@ export interface GridlerState {
|
|||||||
|
|
||||||
reload?: () => Promise<void>;
|
reload?: () => Promise<void>;
|
||||||
renderColumns?: GridlerColumns;
|
renderColumns?: GridlerColumns;
|
||||||
setState: <K extends keyof GridlerStoreState>(
|
setState: <K extends keyof GridlerStoreState>(key: K, value: GridlerStoreState[K]) => void;
|
||||||
key: K,
|
|
||||||
value: GridlerStoreState[K]
|
|
||||||
) => void;
|
|
||||||
setStateFN: <K extends keyof GridlerStoreState>(
|
setStateFN: <K extends keyof GridlerStoreState>(
|
||||||
key: K,
|
key: K,
|
||||||
value: (current: GridlerStoreState[K]) => Partial<GridlerStoreState[K]>
|
value: (current: GridlerStoreState[K]) => Partial<GridlerStoreState[K]>
|
||||||
@@ -357,7 +353,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rowIndex > 0) {
|
if (rowIndex > 0) {
|
||||||
console.log('Local row index', rowIndex, key);
|
//console.log('Local row index', rowIndex, key);
|
||||||
return rowIndex;
|
return rowIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,8 +362,8 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
return rowIndex;
|
return rowIndex;
|
||||||
} else if (typeof state.askAPIRowNumber === 'function') {
|
} else if (typeof state.askAPIRowNumber === 'function') {
|
||||||
const rn = await state.askAPIRowNumber(String(key));
|
const rn = await state.askAPIRowNumber(String(key));
|
||||||
|
|
||||||
if (rn && rn >= 0) {
|
if (rn && rn >= 0) {
|
||||||
console.log('Remote row index', rowIndex, key);
|
|
||||||
return rn;
|
return rn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,7 +399,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false;
|
||||||
},
|
},
|
||||||
keyField: 'id',
|
keyField: 'id',
|
||||||
loadPage: async (pPage: number, clearMode?: 'all' | 'page') => {
|
loadPage: async (pPage: number, clearMode?: 'all' | 'page') => {
|
||||||
@@ -488,13 +484,16 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
onCellClicked: (cell: Item, event: CellClickedEventArgs) => {
|
onCellClicked: (cell: Item, event: CellClickedEventArgs) => {
|
||||||
const state = get();
|
const state = get();
|
||||||
const [col, row] = cell;
|
const [col, row] = cell;
|
||||||
|
const rowBuffer = state.getRowBuffer(row);
|
||||||
if (state.glideProps?.onCellClicked) {
|
if (state.glideProps?.onCellClicked) {
|
||||||
state.glideProps?.onCellClicked?.(cell, event);
|
state.glideProps?.onCellClicked?.(cell, event);
|
||||||
}
|
}
|
||||||
if (state.values?.length) {
|
if (state.values?.length && state.values?.length > 0) {
|
||||||
if (state.onChange) {
|
if (state.onChange) {
|
||||||
state.onChange(state.values);
|
state.onChange(state.values);
|
||||||
}
|
}
|
||||||
|
} else if (rowBuffer && state.onChange) {
|
||||||
|
state.onChange([rowBuffer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
state._events.dispatchEvent(
|
state._events.dispatchEvent(
|
||||||
@@ -949,7 +948,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
total_rows: 1000,
|
total_rows: 1000,
|
||||||
uniqueid: getUUID()
|
uniqueid: getUUID(),
|
||||||
}),
|
}),
|
||||||
(props) => {
|
(props) => {
|
||||||
const [setState, getState] = props.useStore((s) => [s.setState, s.getState]);
|
const [setState, getState] = props.useStore((s) => [s.setState, s.getState]);
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
|||||||
)
|
)
|
||||||
?.forEach((filter: any) => {
|
?.forEach((filter: any) => {
|
||||||
ops.push({
|
ops.push({
|
||||||
name: `${filter.id ?? ""}`,
|
name: `${filter.id ?? ''}`,
|
||||||
op: 'contains',
|
op: 'contains',
|
||||||
type: 'searchor',
|
type: 'searchor',
|
||||||
value: searchStr,
|
value: searchStr,
|
||||||
@@ -202,11 +202,13 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const askAPIRowNumber: (key: string) => Promise<number> = useCallback(
|
const askAPIRowNumber: (key: string) => Promise<null | number> = useCallback(
|
||||||
async (key: string) => {
|
async (key: string) => {
|
||||||
const colFilters = getState('colFilters');
|
const colFilters = getState('colFilters');
|
||||||
|
if (!key) {
|
||||||
//console.log('APIAdaptorGoLangv2', { _active_requests, index, pageSize, props });
|
return null;
|
||||||
|
}
|
||||||
|
//console.log('APIAdaptorGoLangv2', { key, props });
|
||||||
if (props && props.url) {
|
if (props && props.url) {
|
||||||
const head = new Headers();
|
const head = new Headers();
|
||||||
const ops: FetchAPIOperation[] = [
|
const ops: FetchAPIOperation[] = [
|
||||||
@@ -250,7 +252,7 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
|||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
|
||||||
const res = await fetch(`${props.url}?x-fetch-rownumber=${key}}`, {
|
const res = await fetch(`${props.url}?x-fetch-rownumber=${key}`, {
|
||||||
headers: head,
|
headers: head,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
signal: controller?.signal,
|
signal: controller?.signal,
|
||||||
@@ -293,8 +295,6 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
|||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//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.
|
||||||
export const GlidlerAPIAdaptorForGoLangv2 = React.memo(_GlidlerAPIAdaptorForGoLangv2);
|
export const GlidlerAPIAdaptorForGoLangv2 = React.memo(_GlidlerAPIAdaptorForGoLangv2);
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export function GlidlerFormAdaptor(props: {
|
|||||||
col?: GridlerColumn,
|
col?: GridlerColumn,
|
||||||
defaultItems?: MantineBetterMenuInstanceItem[]
|
defaultItems?: MantineBetterMenuInstanceItem[]
|
||||||
): MantineBetterMenuInstanceItem[] => {
|
): MantineBetterMenuInstanceItem[] => {
|
||||||
//console.log('GlidlerFormInterface getMenuItems', id);
|
//console.log('GlidlerFormInterface getMenuItems', id, row, defaultItems);
|
||||||
|
|
||||||
if (id === 'header-menu') {
|
if (id === 'header-menu') {
|
||||||
return defaultItems || [];
|
return defaultItems || [];
|
||||||
@@ -88,7 +88,7 @@ export function GlidlerFormAdaptor(props: {
|
|||||||
? props.descriptionField(row)
|
? props.descriptionField(row)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
if (id === 'other') {
|
if (id === 'other' || (id === 'cell' && !row)) {
|
||||||
items.push({
|
items.push({
|
||||||
c: 'blue',
|
c: 'blue',
|
||||||
label: 'Add',
|
label: 'Add',
|
||||||
|
|||||||
Reference in New Issue
Block a user