docs(changeset): Eslint, fixes on container rendering
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
type GridColumn,
|
||||
} from '@glideapps/glide-data-grid';
|
||||
import { Group, Stack } from '@mantine/core';
|
||||
import { useMergedRef } from '@mantine/hooks';
|
||||
import { useElementSize, useMergedRef } from '@mantine/hooks';
|
||||
import React from 'react';
|
||||
|
||||
import { BottomBar } from './components/BottomBar';
|
||||
@@ -24,6 +24,8 @@ export const GridlerDataGrid = () => {
|
||||
const ref = React.useRef<DataEditorRef | null>(null);
|
||||
const refContextActivated = React.useRef<boolean>(false);
|
||||
|
||||
const { height, ref: refWrapper, width } = useElementSize();
|
||||
|
||||
const {
|
||||
_gridSelection,
|
||||
focused,
|
||||
@@ -86,18 +88,16 @@ export const GridlerDataGrid = () => {
|
||||
setStateFN('_glideref', () => {
|
||||
return r ?? undefined;
|
||||
});
|
||||
|
||||
const ready = getState('ready');
|
||||
const newReady = !!(r && mounted);
|
||||
if (ready !== newReady) {
|
||||
setState('ready', newReady);
|
||||
}
|
||||
});
|
||||
|
||||
const theme = useGridTheme();
|
||||
|
||||
if (!mounted) {
|
||||
return (
|
||||
<>
|
||||
Loading...
|
||||
<Computer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Stack
|
||||
align="stretch"
|
||||
@@ -115,7 +115,7 @@ export const GridlerDataGrid = () => {
|
||||
//Yes this is a litle hacky, but it works to prevent double context menu
|
||||
if (!refContextActivated.current) {
|
||||
refContextActivated.current = true;
|
||||
onContextClick('other', e);
|
||||
onContextClick('other', e as any);
|
||||
setTimeout(() => {
|
||||
refContextActivated.current = false;
|
||||
}, 100);
|
||||
@@ -123,100 +123,112 @@ export const GridlerDataGrid = () => {
|
||||
}}
|
||||
>
|
||||
{sections?.left}
|
||||
<DataEditor
|
||||
cellActivationBehavior="double-click"
|
||||
//getCelrefMergedlContent={getCellContent}
|
||||
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 }}
|
||||
onCellContextMenu={(cell, event) => {
|
||||
event.preventDefault();
|
||||
if (!refContextActivated.current) {
|
||||
refContextActivated.current = true;
|
||||
onContextClick('cell', event, cell[0], cell[1]);
|
||||
setTimeout(() => {
|
||||
refContextActivated.current = false;
|
||||
}, 100);
|
||||
}
|
||||
<div
|
||||
ref={refWrapper}
|
||||
style={{
|
||||
flexGrow: 2,
|
||||
height: '100%',
|
||||
minHeight: '80px',
|
||||
width: '100%',
|
||||
}}
|
||||
onCellEdited={onCellEdited}
|
||||
onColumnMoved={onColumnMoved}
|
||||
onColumnProposeMove={onColumnProposeMove}
|
||||
onColumnResize={onColumnResize}
|
||||
onGridSelectionChange={(selection) => {
|
||||
let rows = CompactSelection.empty();
|
||||
const currentSelection = getState('_gridSelection');
|
||||
for (const r of selection.rows) {
|
||||
rows = rows.hasIndex(r) ? rows : rows.add(r);
|
||||
}
|
||||
if (selectMode === 'row' && selection.current?.range) {
|
||||
for (
|
||||
let y = selection.current.range.y;
|
||||
y < selection.current.range.y + selection.current.range.height;
|
||||
y++
|
||||
) {
|
||||
rows = rows.hasIndex(y) ? rows : rows.add(y);
|
||||
>
|
||||
{width && width > 0 && height && height > 0 && (
|
||||
<DataEditor
|
||||
cellActivationBehavior="double-click"
|
||||
//getCelrefMergedlContent={getCellContent}
|
||||
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={(height ?? 400) - 4}
|
||||
onCellContextMenu={(cell, event) => {
|
||||
event.preventDefault();
|
||||
if (!refContextActivated.current) {
|
||||
refContextActivated.current = true;
|
||||
onContextClick('cell', event, cell[0], cell[1]);
|
||||
setTimeout(() => {
|
||||
refContextActivated.current = false;
|
||||
}, 100);
|
||||
}
|
||||
}}
|
||||
onCellEdited={onCellEdited}
|
||||
onColumnMoved={onColumnMoved}
|
||||
onColumnProposeMove={onColumnProposeMove}
|
||||
onColumnResize={onColumnResize}
|
||||
onGridSelectionChange={(selection) => {
|
||||
let rows = CompactSelection.empty();
|
||||
const currentSelection = getState('_gridSelection');
|
||||
for (const r of selection.rows) {
|
||||
rows = rows.hasIndex(r) ? rows : rows.add(r);
|
||||
}
|
||||
if (selectMode === 'row' && selection.current?.range) {
|
||||
for (
|
||||
let y = selection.current.range.y;
|
||||
y < selection.current.range.y + selection.current.range.height;
|
||||
y++
|
||||
) {
|
||||
rows = rows.hasIndex(y) ? rows : rows.add(y);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
JSON.stringify(currentSelection?.columns) !== JSON.stringify(selection.columns) ||
|
||||
JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows) ||
|
||||
JSON.stringify(currentSelection?.current) !== JSON.stringify(selection.current)
|
||||
) {
|
||||
setState('_gridSelection', { ...selection, rows });
|
||||
if (JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows)) {
|
||||
setState('_gridSelectionRows', rows);
|
||||
}
|
||||
}
|
||||
|
||||
//console.log('Selection', selection);
|
||||
}}
|
||||
onHeaderClicked={onHeaderClicked}
|
||||
onHeaderContextMenu={(col, event) => {
|
||||
event.preventDefault();
|
||||
if (!refContextActivated.current) {
|
||||
refContextActivated.current = true;
|
||||
onContextClick('header', event as any, col);
|
||||
setTimeout(() => {
|
||||
refContextActivated.current = false;
|
||||
}, 100);
|
||||
}
|
||||
}}
|
||||
onHeaderMenuClick={onHeaderMenuClick}
|
||||
onItemHovered={onItemHovered}
|
||||
onVisibleRegionChanged={onVisibleRegionChanged}
|
||||
rangeSelect="multi-rect"
|
||||
ref={refMerged as React.Ref<DataEditorRef>}
|
||||
rightElement={
|
||||
<Group>
|
||||
{sections?.rightElementStart}
|
||||
<RightMenuIcon />
|
||||
{sections?.rightElementEnd}
|
||||
</Group>
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
JSON.stringify(currentSelection?.columns) !== JSON.stringify(selection.columns) ||
|
||||
JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows) ||
|
||||
JSON.stringify(currentSelection?.current) !== JSON.stringify(selection.current)
|
||||
) {
|
||||
setState('_gridSelection', { ...selection, rows });
|
||||
if (JSON.stringify(currentSelection?.rows) !== JSON.stringify(rows)) {
|
||||
setState('_gridSelectionRows', rows);
|
||||
}
|
||||
}
|
||||
|
||||
//console.log('Selection', selection);
|
||||
}}
|
||||
onHeaderClicked={onHeaderClicked}
|
||||
onHeaderContextMenu={(col, event) => {
|
||||
event.preventDefault();
|
||||
if (!refContextActivated.current) {
|
||||
refContextActivated.current = true;
|
||||
onContextClick('header', event, col);
|
||||
setTimeout(() => {
|
||||
refContextActivated.current = false;
|
||||
}, 100);
|
||||
}
|
||||
}}
|
||||
onHeaderMenuClick={onHeaderMenuClick}
|
||||
onItemHovered={onItemHovered}
|
||||
onVisibleRegionChanged={onVisibleRegionChanged}
|
||||
rangeSelect="multi-rect"
|
||||
ref={refMerged as any}
|
||||
rightElement={
|
||||
<Group>
|
||||
{sections?.rightElementStart}
|
||||
<RightMenuIcon />
|
||||
{sections?.rightElementEnd}
|
||||
</Group>
|
||||
}
|
||||
rowHeight={rowHeight ?? 22}
|
||||
//rowMarkersCheckboxStyle='square'
|
||||
//rowMarkersKind='both'
|
||||
rowMarkers={{
|
||||
checkboxStyle: 'square',
|
||||
kind: 'both',
|
||||
}}
|
||||
rows={total_rows ?? 0}
|
||||
rowSelect="multi"
|
||||
rowSelectionMode="auto"
|
||||
spanRangeBehavior="default"
|
||||
theme={theme.gridTheme}
|
||||
width="100%"
|
||||
{...glideProps}
|
||||
/>
|
||||
|
||||
rowHeight={rowHeight ?? 22}
|
||||
//rowMarkersCheckboxStyle='square'
|
||||
//rowMarkersKind='both'
|
||||
rowMarkers={{
|
||||
checkboxStyle: 'square',
|
||||
kind: 'both',
|
||||
}}
|
||||
rows={total_rows ?? 0}
|
||||
rowSelect="multi"
|
||||
rowSelectionMode="auto"
|
||||
spanRangeBehavior="default"
|
||||
theme={theme.gridTheme}
|
||||
width={width ?? 200}
|
||||
{...glideProps}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{/* </Portal> */}
|
||||
<Computer />
|
||||
{!hasLocalData && <Pager />}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/react-in-jsx-scope */
|
||||
import { useGridlerStore } from './GridlerStore';
|
||||
|
||||
export function BottomBar() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { CompactSelection } from '@glideapps/glide-data-grid';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
@@ -7,7 +6,7 @@ import { useGridlerStore } from './GridlerStore';
|
||||
//The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
|
||||
export const Computer = React.memo(() => {
|
||||
const refFirstRun = useRef(0);
|
||||
const refLastFilters = useRef<any>(null);
|
||||
const refLastFilters = useRef<unknown>(null);
|
||||
const {
|
||||
_glideref,
|
||||
_gridSelectionRows,
|
||||
@@ -19,6 +18,7 @@ export const Computer = React.memo(() => {
|
||||
columns,
|
||||
getState,
|
||||
loadPage,
|
||||
ready,
|
||||
|
||||
setState,
|
||||
setStateFN,
|
||||
@@ -34,6 +34,7 @@ export const Computer = React.memo(() => {
|
||||
columns: s.columns,
|
||||
getState: s.getState,
|
||||
loadPage: s.loadPage,
|
||||
ready: s.ready,
|
||||
|
||||
setState: s.setState,
|
||||
setStateFN: s.setStateFN,
|
||||
@@ -47,7 +48,7 @@ export const Computer = React.memo(() => {
|
||||
const pageSize = getState('pageSize');
|
||||
const keyField = getState('keyField') ?? 'id';
|
||||
const rowIndexes = [];
|
||||
for (const vi in values as Array<any>) {
|
||||
for (const vi in values as Array<Record<string, unknown>>) {
|
||||
let rowIndex = -1;
|
||||
const key = String(
|
||||
typeof values?.[vi] === 'object'
|
||||
@@ -232,7 +233,7 @@ export const Computer = React.memo(() => {
|
||||
}
|
||||
refFirstRun.current = 1;
|
||||
loadPage(0);
|
||||
}, [_glideref]);
|
||||
}, [ready, loadPage]);
|
||||
|
||||
// console.log('Gridler:Debug:Computer', {
|
||||
// colFilters,
|
||||
@@ -245,3 +246,5 @@ export const Computer = React.memo(() => {
|
||||
|
||||
return <></>;
|
||||
});
|
||||
|
||||
Computer.displayName = 'Gridler-Computer';
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable react/react-in-jsx-scope */
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import {
|
||||
type CellArray,
|
||||
type CellClickedEventArgs,
|
||||
CompactSelection,
|
||||
type DataEditorProps,
|
||||
type DataEditorRef,
|
||||
@@ -133,7 +136,7 @@ export interface GridlerState {
|
||||
selection: Rectangle,
|
||||
abortSignal: AbortSignal
|
||||
) => CellArray | GetCellsThunk;
|
||||
getRowBuffer: (row: number) => any;
|
||||
getRowBuffer: (row: number) => Record<string, any>;
|
||||
getState: <K extends keyof GridlerStoreState>(key: K) => GridlerStoreState[K];
|
||||
|
||||
hasLocalData: boolean;
|
||||
@@ -149,7 +152,7 @@ export interface GridlerState {
|
||||
colIndex: number,
|
||||
newSizeWithGrow: number
|
||||
) => void;
|
||||
onContextClick: (area: string, event: any, col?: number, row?: number) => void;
|
||||
onContextClick: (area: string, event: CellClickedEventArgs, col?: number, row?: number) => void;
|
||||
onHeaderClicked: (colIndex: number, event: HeaderClickedEventArgs) => void;
|
||||
onHeaderMenuClick: (col: number, screenPosition: Rectangle) => void;
|
||||
onItemHovered: (args: GridMouseEventArgs) => void;
|
||||
@@ -166,6 +169,7 @@ export interface GridlerState {
|
||||
) => void;
|
||||
|
||||
pageSize: number;
|
||||
ready: boolean;
|
||||
reload?: () => Promise<void>;
|
||||
renderColumns?: GridlerColumns;
|
||||
setState: <K extends keyof GridlerStoreState>(
|
||||
@@ -190,7 +194,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
_page_data: {},
|
||||
_visibleArea: { height: 10000, width: 1000, x: 0, y: 0 },
|
||||
_visiblePages: { height: 0, width: 0, x: 0, y: 0 },
|
||||
addError: (err: string, ...args: Array<any>) => {
|
||||
addError: (err: string, ...args: Array<unknown>) => {
|
||||
const s = get();
|
||||
console.log('Gridler Error', s.uniqueid, err, args);
|
||||
set(
|
||||
@@ -205,7 +209,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
const state = get();
|
||||
const [col, row] = cell;
|
||||
|
||||
const buffer = state.getRowBuffer(row);
|
||||
const buffer = state.getRowBuffer(row) as Record<string, string> | undefined;
|
||||
|
||||
if (buffer !== undefined) {
|
||||
return state.toCell(buffer, col);
|
||||
@@ -404,7 +408,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
}
|
||||
},
|
||||
|
||||
onContextClick: (area: string, event: any, col?: number, row?: number) => {
|
||||
onContextClick: (area: string, event: CellClickedEventArgs, col?: number, row?: number) => {
|
||||
const s = get();
|
||||
const coldef = s.renderColumns?.[col ?? -1];
|
||||
|
||||
@@ -490,7 +494,9 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
) ??
|
||||
s.getMenuItems?.(area, s, col && row ? s.getRowBuffer(row) : undefined, coldef, items) ??
|
||||
items,
|
||||
//@ts-expect-error Check bounds
|
||||
x: event.clientX ?? event.bounds?.x,
|
||||
//@ts-expect-error Check bounds
|
||||
y: event.clientY ?? event.bounds?.y,
|
||||
});
|
||||
},
|
||||
@@ -681,8 +687,8 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
}, 100)
|
||||
);
|
||||
},
|
||||
|
||||
pageSize: 50,
|
||||
ready: false,
|
||||
setState: (key, value) => {
|
||||
set(
|
||||
produce((state) => {
|
||||
@@ -695,7 +701,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
set(
|
||||
produce((state) => {
|
||||
if (typeof value === 'function') {
|
||||
state[key] = (value as (value: any) => any)(state[key]);
|
||||
state[key] = (value as (value: unknown) => unknown)(state[key]);
|
||||
} else {
|
||||
reject(new Error(`Not a function ${value}`));
|
||||
throw Error(`Not a function ${value}`);
|
||||
@@ -799,12 +805,13 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
|
||||
/// logic to apply the selected row.
|
||||
useEffect(() => {
|
||||
const ready = getState('ready');
|
||||
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) {
|
||||
if (selectedRow && ref && ready) {
|
||||
const page_data = getState('_page_data');
|
||||
const pageSize = getState('pageSize');
|
||||
for (const p in page_data) {
|
||||
|
||||
@@ -63,3 +63,5 @@ export const Pager = React.memo(() => {
|
||||
|
||||
return <></>;
|
||||
});
|
||||
|
||||
Pager.displayName = 'Gridler-Pager';
|
||||
|
||||
@@ -14,7 +14,7 @@ export function RightMenuIcon() {
|
||||
loading={loadingData}
|
||||
mr="xs"
|
||||
mt="2px"
|
||||
onClick={(e) => onContextClick('menu', e)}
|
||||
onClick={(e) => onContextClick('menu', e as any)}
|
||||
variant="subtle"
|
||||
>
|
||||
<IconMenu2 />
|
||||
|
||||
@@ -143,3 +143,5 @@ export const GlidlerAPIAdaptorForGoLangv2 = React.memo((props: APIOptions) => {
|
||||
|
||||
return <></>;
|
||||
});
|
||||
|
||||
GlidlerAPIAdaptorForGoLangv2.displayName = 'Gridler-GlidlerAPIAdaptorForGoLangv2';
|
||||
|
||||
@@ -27,3 +27,5 @@ export const GlidlerLocalDataAdaptor = React.memo((props: GlidlerLocalDataAdapto
|
||||
|
||||
return <></>;
|
||||
});
|
||||
|
||||
GlidlerLocalDataAdaptor.displayName = 'Gridler-GlidlerLocalDataAdaptor';
|
||||
|
||||
@@ -45,7 +45,7 @@ export const GridlerGoAPIExampleEventlog = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack h="60vh">
|
||||
<Stack h="80vh">
|
||||
<h2>Demo Using Go API Adaptor</h2>
|
||||
<TextInput label="API Url" onChange={(e) => setApiUrl(e.target.value)} value={apiUrl} />
|
||||
<TextInput label="API Key" onChange={(e) => setApiKey(e.target.value)} value={apiKey} />
|
||||
|
||||
@@ -6,7 +6,12 @@ import { fn } from 'storybook/test';
|
||||
import { GridlerLocaldataExampleEventlog } from './Examples.localdata';
|
||||
|
||||
const Renderable = (props: any) => {
|
||||
return <Box h="100%" mih="400px" miw="400px" w='100%' > <GridlerLocaldataExampleEventlog {...props} /></Box>;
|
||||
return (
|
||||
<Box h="100%" mih="400px" miw="400px" w="100%">
|
||||
{' '}
|
||||
<GridlerLocaldataExampleEventlog {...props} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const meta = {
|
||||
|
||||
Reference in New Issue
Block a user