From ecb90c69aa5cc6d818c9dde302e8b68f4ac17d79 Mon Sep 17 00:00:00 2001 From: Hein Date: Fri, 23 Jan 2026 10:57:32 +0200 Subject: [PATCH] =?UTF-8?q?feat(Gridler):=20=E2=9C=A8=20add=20isValuesInPa?= =?UTF-8?q?ges=20method=20and=20update=20state=20handling=20*=20Introduce?= =?UTF-8?q?=20isValuesInPages=20method=20to=20check=20if=20values=20exist?= =?UTF-8?q?=20in=20paginated=20data.=20*=20Update=20state=20management=20i?= =?UTF-8?q?n=20GlidlerAPIAdaptorForGoLangv2=20to=20clear=20values=20when?= =?UTF-8?q?=20no=20pages=20are=20found.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - pnpm-lock.yaml | 59 ------------------- src/Gridler/components/GridlerStore.tsx | 35 +++++++++-- .../adaptors/GlidlerAPIAdaptorForGoLangv2.tsx | 10 +++- 4 files changed, 39 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index 3567673..4648c7f 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "devDependencies": { "@changesets/cli": "^2.29.7", "@eslint/js": "^9.38.0", - "@storybook/react": "^10.2.0", "@storybook/react-vite": "^9.1.15", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92c597d..58e8bcc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,9 +60,6 @@ importers: '@eslint/js': specifier: ^9.38.0 version: 9.38.0 - '@storybook/react': - specifier: ^10.2.0 - version: 10.2.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))(typescript@5.9.3) '@storybook/react-vite': specifier: ^9.1.15 version: 9.1.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(rollup@4.50.2)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))) @@ -929,13 +926,6 @@ packages: '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} - '@storybook/react-dom-shim@10.2.0': - resolution: {integrity: sha512-PEQofiruE6dBGzUQPXZZREbuh1t62uRBWoUPRFNAZi79zddlk7+b9qu08VV9cvf68mwOqqT1+VJ1P+3ClD2ZVw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.2.0 - '@storybook/react-dom-shim@9.1.15': resolution: {integrity: sha512-l6smvNwxh6kp2U/BupzQ4/NSraTWysZcAe2x+GO5CiIIB8Jbi41XLu5XIHI/GQRnNqpXXE3uMImiHGOORmHEXA==} peerDependencies: @@ -952,17 +942,6 @@ packages: storybook: ^9.1.15 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/react@10.2.0': - resolution: {integrity: sha512-ciJlh1UGm0GBXQgqrYFeLmiix+KGFB3v37OnAYjGghPS9OP6S99XyshxY/6p0sMOYtS+eWS2gPsOKNXNnLDGYw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.2.0 - typescript: '>= 4.9.x' - peerDependenciesMeta: - typescript: - optional: true - '@storybook/react@9.1.15': resolution: {integrity: sha512-tdd1Od3roaEQ2rjqk1L15yR/N2y/SLNcpPNp3n9AQT1eDPdbKzIzue7u1eW9KUFdwSF9S8xG35roDUkKwBJogQ==} engines: {node: '>=20.0.0'} @@ -2881,10 +2860,6 @@ packages: resolution: {integrity: sha512-kQKsqPLplY3Hx4jGnM3jpQcG3FQDt7ySz32uTHt3C9HAe45kNXG+3o16Eqn3Fw1GtMfHoN3b4J/z2e6cZJCmqQ==} engines: {node: ^20.9.0 || >=22} - react-docgen@8.0.2: - resolution: {integrity: sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==} - engines: {node: ^20.9.0 || >=22} - react-dom@19.2.0: resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: @@ -4553,12 +4528,6 @@ snapshots: '@storybook/global@5.0.0': {} - '@storybook/react-dom-shim@10.2.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))': - dependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - storybook: 9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))) - '@storybook/react-dom-shim@9.1.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))': dependencies: react: 19.2.0 @@ -4585,19 +4554,6 @@ snapshots: - supports-color - typescript - '@storybook/react@10.2.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))(typescript@5.9.3)': - dependencies: - '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.2.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6)))) - react: 19.2.0 - react-docgen: 8.0.2 - react-dom: 19.2.0(react@19.2.0) - storybook: 9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@storybook/react@9.1.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.15(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 @@ -6768,21 +6724,6 @@ snapshots: transitivePeerDependencies: - supports-color - react-docgen@8.0.2: - dependencies: - '@babel/core': 7.28.4 - '@babel/traverse': 7.28.4 - '@babel/types': 7.28.4 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 - '@types/doctrine': 0.0.9 - '@types/resolve': 1.20.6 - doctrine: 3.0.0 - resolve: 1.22.10 - strip-indent: 4.1.0 - transitivePeerDependencies: - - supports-color - react-dom@19.2.0(react@19.2.0): dependencies: react: 19.2.0 diff --git a/src/Gridler/components/GridlerStore.tsx b/src/Gridler/components/GridlerStore.tsx index 2efdc31..4fbadd4 100644 --- a/src/Gridler/components/GridlerStore.tsx +++ b/src/Gridler/components/GridlerStore.tsx @@ -162,6 +162,7 @@ export interface GridlerState { hasLocalData: boolean; isEmpty: boolean; + isValuesInPages: () => boolean loadingData?: boolean; loadPage: (page: number, clearMode?: 'all' | 'page') => Promise; mounted: boolean; @@ -180,6 +181,7 @@ export interface GridlerState { onHeaderClicked: (colIndex: number, event: HeaderClickedEventArgs) => void; onHeaderMenuClick: (col: number, screenPosition: Rectangle) => void; onItemHovered: (args: GridMouseEventArgs) => void; + onVisibleRegionChanged: ( r: Rectangle, tx: number, @@ -189,14 +191,14 @@ export interface GridlerState { freezeRegions?: readonly Rectangle[]; selected?: Item; } + ) => void; pageSize: number; - ready: boolean; refreshCells: (fromRow?: number, toRow?: number, col?: number) => void; - reload?: () => Promise; + reload?: () => Promise; renderColumns?: GridlerColumns; setState: ( key: K, @@ -378,6 +380,31 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { + const state = get(); + if (state.values && Object.keys(state._page_data).length > 0) { + let found = false; + for (const page in state._page_data) { + const pageData = state._page_data[Number(page)]; + for (const row of pageData) { + const keyField = state.keyField ?? 'id'; + const rowKey = row?.[keyField]; + if (rowKey !== undefined) { + const match = state.values.find((v) => String(v?.[keyField]) === String(rowKey)); + if (match) { + found = true; + break; + } + } + } + if (found) { + return true; + } + } + } + + return false + }, keyField: 'id', loadPage: async (pPage: number, clearMode?: 'all' | 'page') => { const state = get(); @@ -511,6 +538,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { const s = get(); const fromItem = s.renderColumns?.[startIndex]; @@ -520,7 +548,6 @@ const { Provider, useStore: useGridlerStore } = createSyncStore { const [setState, getState] = props.useStore((s) => [s.setState, s.getState]); diff --git a/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx b/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx index 3a75af3..093ef42 100644 --- a/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx +++ b/src/Gridler/components/adaptors/GlidlerAPIAdaptorForGoLangv2.tsx @@ -272,9 +272,13 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG useEffect(() => { setState('useAPIQuery', useAPIQuery); setState('askAPIRowNumber', askAPIRowNumber); - + const isValuesInPages = getState('isValuesInPages'); + const _refresh = getState('_refresh'); - + if (!isValuesInPages) { + setState('values', []); + } + //Reset the loaded pages to new rules _refresh?.().then(() => { const onChange = getState('onChange'); @@ -289,6 +293,8 @@ function _GlidlerAPIAdaptorForGoLangv2(props: GlidlerAPIAdaptorForG return <>; } + + //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);