From 760de4bc8ebc25740a4fea9046f47157a91a1186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Sun, 12 Oct 2025 12:51:54 +0200 Subject: [PATCH 1/5] fix: improvements and fixes for infinite tree https://github.com/gisce/webclient/issues/2622 --- src/context/ActionViewContext.tsx | 2 +- src/hooks/useSearchTreeState.ts | 2 +- src/widgets/views/SearchTreeInfinite.tsx | 92 ++++++++++++++++++++---- 3 files changed, 79 insertions(+), 17 deletions(-) diff --git a/src/context/ActionViewContext.tsx b/src/context/ActionViewContext.tsx index c83112173..79472c14e 100644 --- a/src/context/ActionViewContext.tsx +++ b/src/context/ActionViewContext.tsx @@ -27,7 +27,7 @@ type ActionViewProviderProps = { sorter: any; setSorter: (sorter: any) => void; totalItems?: number; - setTotalItems: (totalItems: number) => void; + setTotalItems: (totalItems: number | ((prev: number) => number)) => void; selectedRowItems?: any[]; setSelectedRowItems: (value: any[] | ((prevValue: any[]) => any[])) => void; setSearchTreeNameSearch: (searchString?: string) => void; diff --git a/src/hooks/useSearchTreeState.ts b/src/hooks/useSearchTreeState.ts index c8ef4bddb..742b67c5b 100644 --- a/src/hooks/useSearchTreeState.ts +++ b/src/hooks/useSearchTreeState.ts @@ -33,7 +33,7 @@ export type SearchTreeState = { searchQuery?: SearchQueryParams; setSearchQuery: (value: SearchQueryParams) => void; totalItems: number; - setTotalItems: (value: number) => void; + setTotalItems: (value: number | ((prev: number) => number)) => void; isActive?: boolean; order?: ColumnState[]; setOrder: (value: ColumnState[] | undefined) => void; diff --git a/src/widgets/views/SearchTreeInfinite.tsx b/src/widgets/views/SearchTreeInfinite.tsx index 0cb251cca..b5a41e561 100644 --- a/src/widgets/views/SearchTreeInfinite.tsx +++ b/src/widgets/views/SearchTreeInfinite.tsx @@ -113,6 +113,7 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { const [totalRows, setTotalRows] = useState(); const [nameSearchFetchCompleted, setNameSearchFetchCompleted] = useState(false); + const prevTotalRows = useRef(); const containerRef = useRef(null); const calculatedHeight = useAvailableHeight({ @@ -180,24 +181,77 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { const currentSearchParamsString = useRef(); const prevSortOrder = useRef(); const isUpdatingTotalRows = useRef(false); + const prevNameSearchForTotalRows = useRef(nameSearch); + const manualRefreshJustCalled = useRef(false); + // Reset scroll when totalRows changes (indicates new query/different results) useEffect(() => { if ( - (nameSearch !== undefined && prevNameSearch.current === undefined) || - (typeof nameSearch === "string" && - typeof prevNameSearch.current === "string" && + prevTotalRows.current !== undefined && + prevTotalRows.current !== totalRows + ) { + setTreeFirstVisibleRow?.(0); + + // Skip cache purge if: + // 1. We're staying in name search mode (both prev and current are name search) + // 2. A manual refresh was just called (from searchParams or nameSearch useEffect) + const wasInNameSearch = prevNameSearchForTotalRows.current !== undefined; + const isInNameSearch = nameSearch !== undefined; + const stayingInNameSearch = wasInNameSearch && isInNameSearch; + + if (!stayingInNameSearch && !manualRefreshJustCalled.current) { + tableRef.current?.refresh(); + } + + // Reset the flag after checking + manualRefreshJustCalled.current = false; + + setTimeout(() => { + tableRef.current?.scrollToTop(); + }, 0); + } + prevTotalRows.current = totalRows; + prevNameSearchForTotalRows.current = nameSearch; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [totalRows]); + + useEffect(() => { + const isNameSearchActive = nameSearch && nameSearch.trim().length > 0; + const wasNameSearchActive = + prevNameSearch.current && + typeof prevNameSearch.current === "string" && + prevNameSearch.current.trim().length > 0; + + if ( + (isNameSearchActive && !wasNameSearchActive) || + (isNameSearchActive && + wasNameSearchActive && nameSearch !== prevNameSearch.current) ) { - isNameSearchMode.current = Boolean(nameSearch); + // Entering name search or changing search term + isNameSearchMode.current = true; setSearchParams?.([]); setSearchValues?.({}); + changeSelectedRowItems([]); tableRef.current?.unselectAll(); - } else if ( - nameSearch === undefined && - prevNameSearch.current !== undefined - ) { + // Reset scroll position to top when entering/changing name search + // This ensures the first data request starts from row 0 + setTreeFirstVisibleRow?.(0); + tableRef.current?.scrollToTop(); + } else if (!isNameSearchActive && wasNameSearchActive) { + // Exiting name search (either undefined or empty string) isNameSearchMode.current = false; + changeSelectedRowItems([]); tableRef.current?.unselectAll(); + // Reset scroll position to top BEFORE calling refresh + // This ensures AG Grid will request from row 0, which triggers updateTotalRows + setTreeFirstVisibleRow?.(0); + tableRef.current?.scrollToTop(); + // Call refresh to reload data and update totalRows when exiting name search + setTimeout(() => { + manualRefreshJustCalled.current = true; + refresh(); + }, 0); } prevNameSearch.current = nameSearch; // eslint-disable-next-line react-hooks/exhaustive-deps @@ -306,8 +360,7 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { } isUpdatingTotalRows.current = true; - setTotalRows(undefined); - setTotalItemsActionView(0); + // Don't reset totalRows to undefined - keep previous value during update try { const totalItems = await searchCount({ params: nameSearch ? domain : mergedParams, @@ -319,6 +372,9 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { setTotalItemsActionView(totalItems); } catch (err) { showErrorNotification(err); + // On error, preserve previous values if they exist + setTotalRows((prev) => prev ?? 0); + setTotalItemsActionView((prev) => prev ?? 0); } finally { isUpdatingTotalRows.current = false; } @@ -431,8 +487,12 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { if (results.length === 0) { lastAssignedResults.current = []; - setTotalRows(0); - setTotalItemsActionView(0); + // Only set totalRows to 0 if this is the first request (startRow === 0) + // Otherwise, 0 results just means we're beyond the end of the data + if (startRow === 0) { + setTotalRows(0); + setTotalItemsActionView(0); + } return []; } @@ -553,8 +613,9 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { return results; } catch (error) { console.error(error); - setTotalRows(null); - setTotalItemsActionView(0); + // On error, preserve previous values if they exist + setTotalRows((prev) => prev ?? 0); + setTotalItemsActionView((prev) => prev ?? 0); setTreeIsLoading?.(false); showErrorNotification(error); throw error; @@ -624,7 +685,7 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { onSelectionCheckboxClicked={ hideSelectionColumn ? undefined : onSelectionCheckboxClicked } - totalRows={totalRows || 99999} + totalRows={totalRows ?? undefined} footer={footerComponent} hasStatusColumn={treeOoui.status !== null} statusComponent={statusComponent} @@ -677,6 +738,7 @@ function SearchTreeInfiniteComp(props: SearchTreeInfiniteProps, ref: any) { searchParamsChanged && (searchVisibleChangedToFalse || filterType === "top") ) { + manualRefreshJustCalled.current = true; refresh(); } From 8c781959d3a855a4c913dd5436ed21bd522431e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Sun, 12 Oct 2025 13:08:17 +0200 Subject: [PATCH 2/5] fix: ts issues --- src/context/ActionViewContext.tsx | 7 ++++++- src/hooks/useSearchTreeState.ts | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/context/ActionViewContext.tsx b/src/context/ActionViewContext.tsx index 79472c14e..770ca6e4c 100644 --- a/src/context/ActionViewContext.tsx +++ b/src/context/ActionViewContext.tsx @@ -27,7 +27,12 @@ type ActionViewProviderProps = { sorter: any; setSorter: (sorter: any) => void; totalItems?: number; - setTotalItems: (totalItems: number | ((prev: number) => number)) => void; + setTotalItems: ( + totalItems: + | number + | undefined + | ((prev: number | undefined) => number | undefined), + ) => void; selectedRowItems?: any[]; setSelectedRowItems: (value: any[] | ((prevValue: any[]) => any[])) => void; setSearchTreeNameSearch: (searchString?: string) => void; diff --git a/src/hooks/useSearchTreeState.ts b/src/hooks/useSearchTreeState.ts index 742b67c5b..326276998 100644 --- a/src/hooks/useSearchTreeState.ts +++ b/src/hooks/useSearchTreeState.ts @@ -33,7 +33,12 @@ export type SearchTreeState = { searchQuery?: SearchQueryParams; setSearchQuery: (value: SearchQueryParams) => void; totalItems: number; - setTotalItems: (value: number | ((prev: number) => number)) => void; + setTotalItems: ( + value: + | number + | undefined + | ((prev: number | undefined) => number | undefined), + ) => void; isActive?: boolean; order?: ColumnState[]; setOrder: (value: ColumnState[] | undefined) => void; @@ -135,7 +140,18 @@ export function useSearchTreeState({ searchQuery: localSearchQuery, setSearchQuery: setLocalSearchQuery, totalItems: localTotalItems, - setTotalItems: setLocalTotalItems, + setTotalItems: (value) => { + if (value === undefined) { + setLocalTotalItems(0); + } else if (typeof value === "function") { + setLocalTotalItems((prev) => { + const result = value(prev); + return result ?? 0; + }); + } else { + setLocalTotalItems(value); + } + }, isActive: undefined, order: localOrder, setOrder: setLocalOrder, From 567eb44faa091caaf3330f68c97e90f36db58f57 Mon Sep 17 00:00:00 2001 From: mguellsegarra <5711443+mguellsegarra@users.noreply.github.com> Date: Tue, 14 Oct 2025 17:05:59 +0000 Subject: [PATCH 3/5] fix: update gisce/react-formiga-table to v1.16.1 https://github.com/gisce/react-formiga-table/releases/tag/v1.16.1 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 050d7bde3..0f47b492a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@gisce/fiber-diagram": "2.1.1", "@gisce/ooui": "2.36.0", "@gisce/react-formiga-components": "1.18.0", - "@gisce/react-formiga-table": "1.16.0", + "@gisce/react-formiga-table": "1.16.1", "@monaco-editor/react": "^4.4.5", "@types/deep-equal": "^1.0.4", "antd": "5.25.1", @@ -2310,9 +2310,9 @@ } }, "node_modules/@gisce/react-formiga-table": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@gisce/react-formiga-table/-/react-formiga-table-1.16.0.tgz", - "integrity": "sha512-XebiVdMFPNG0RMHU0ouvU7g7qSIe5QD6eIX6QdIKVEsLdH0G+j9pa1fU3H0Tv3Y2yGh3OCiq6XHsqfJxrk06fw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@gisce/react-formiga-table/-/react-formiga-table-1.16.1.tgz", + "integrity": "sha512-MlSXkX3kifnn//5uGOAA5/Vuz8VFvZBvbWIHDXrDS4WvbiEGzPmAJ76D/SkjzkdBVgFsuy3cMbiZ5jQyHn/VFw==", "dependencies": { "ag-grid-community": "^31.2.1", "ag-grid-react": "^31.2.1", diff --git a/package.json b/package.json index 74cb10c24..ba426e3c0 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@gisce/fiber-diagram": "2.1.1", "@gisce/ooui": "2.36.0", "@gisce/react-formiga-components": "1.18.0", - "@gisce/react-formiga-table": "1.16.0", + "@gisce/react-formiga-table": "1.16.1", "@monaco-editor/react": "^4.4.5", "@types/deep-equal": "^1.0.4", "antd": "5.25.1", From f1ed77eb66a0e123bebb6647210d40a856c3dd4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Thu, 16 Oct 2025 10:52:40 +0200 Subject: [PATCH 4/5] fix: update tests --- e2e-test-app/e2e/infinite-one2many.spec.ts | 10 +++- e2e-test-app/e2e/infinite-tree-view.spec.ts | 61 ++++++++++++++++++--- e2e-test-app/package-lock.json | 12 ++-- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/e2e-test-app/e2e/infinite-one2many.spec.ts b/e2e-test-app/e2e/infinite-one2many.spec.ts index 33216c762..0d399546c 100644 --- a/e2e-test-app/e2e/infinite-one2many.spec.ts +++ b/e2e-test-app/e2e/infinite-one2many.spec.ts @@ -152,6 +152,9 @@ test.describe("Infinite One2Many Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const firstRowCheckbox = page .locator(".ag-row") @@ -159,7 +162,7 @@ test.describe("Infinite One2Many Component", () => { .locator('input[type="checkbox"]'); await firstRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); await expect(firstRowCheckbox).toBeChecked(); @@ -178,6 +181,9 @@ test.describe("Infinite One2Many Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const rows = page.locator(".ag-row"); const firstRowCheckbox = rows.nth(0).locator('input[type="checkbox"]'); @@ -187,7 +193,7 @@ test.describe("Infinite One2Many Component", () => { await firstRowCheckbox.click(); await secondRowCheckbox.click(); await thirdRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); await expect(firstRowCheckbox).toBeChecked(); await expect(secondRowCheckbox).toBeChecked(); diff --git a/e2e-test-app/e2e/infinite-tree-view.spec.ts b/e2e-test-app/e2e/infinite-tree-view.spec.ts index cae8c9475..47610f909 100644 --- a/e2e-test-app/e2e/infinite-tree-view.spec.ts +++ b/e2e-test-app/e2e/infinite-tree-view.spec.ts @@ -155,6 +155,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const firstRowCheckbox = page .locator(".ag-row") @@ -162,7 +165,7 @@ test.describe("Infinite TreeActionView Component", () => { .locator('input[type="checkbox"]'); await firstRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); await expect(firstRowCheckbox).toBeChecked(); @@ -189,6 +192,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const rows = page.locator(".ag-row"); const firstRowCheckbox = rows.nth(0).locator('input[type="checkbox"]'); @@ -198,7 +204,7 @@ test.describe("Infinite TreeActionView Component", () => { await firstRowCheckbox.click(); await secondRowCheckbox.click(); await thirdRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); await expect(firstRowCheckbox).toBeChecked(); await expect(secondRowCheckbox).toBeChecked(); @@ -229,6 +235,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const headerCheckbox = page .locator('.ag-header input[type="checkbox"]') @@ -305,6 +314,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const headerCheckbox = page .locator('.ag-header input[type="checkbox"]') @@ -364,6 +376,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); // Test 1: Copy single row ID const firstRowCheckbox = page @@ -371,7 +386,7 @@ test.describe("Infinite TreeActionView Component", () => { .first() .locator('input[type="checkbox"]'); await firstRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); const copyButton = page.getByRole("button", { name: "Copy", exact: true }); await expect(copyButton).toBeVisible(); @@ -462,6 +477,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const statusBadges = page.locator(".ag-row .ag-cell .ant-badge"); const badgeCount = await statusBadges.count(); @@ -499,6 +517,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const statusDots = page.locator( ".ag-row .ag-cell .ant-badge .ant-badge-status-dot", @@ -840,6 +861,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-header", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const rows = page.locator(".ag-row"); const rowCount = await rows.count(); @@ -936,6 +960,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); const totalSalaryElement = page.getByText(/Total.*[Ss]alary/); @@ -949,7 +976,8 @@ test.describe("Infinite TreeActionView Component", () => { .first() .locator('input[type="checkbox"]'); await firstRowCheckbox.click(); - await page.waitForTimeout(500); + // Wait longer for aggregate to update (increased from 1000ms to account for debounce + calculation) + await page.waitForTimeout(1500); // Verify Total Salary equals first row salary const afterFirstSelection = await totalSalaryElement.textContent(); @@ -962,7 +990,7 @@ test.describe("Infinite TreeActionView Component", () => { .nth(1) .locator('input[type="checkbox"]'); await secondRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1500); // Verify Total Salary increased const afterSecondSelection = await totalSalaryElement.textContent(); @@ -977,7 +1005,7 @@ test.describe("Infinite TreeActionView Component", () => { .nth(2) .locator('input[type="checkbox"]'); await thirdRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1500); // Verify Total Salary increased again const afterThirdSelection = await totalSalaryElement.textContent(); @@ -988,7 +1016,7 @@ test.describe("Infinite TreeActionView Component", () => { await firstRowCheckbox.click(); await secondRowCheckbox.click(); await thirdRowCheckbox.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1500); // Verify it returns to "-" const afterDeselection = await totalSalaryElement.textContent(); @@ -1002,6 +1030,9 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(800); // Find the three dots menu button using the correct aria-label const threeDotsMenu = page.getByRole("button", { name: "More options" }); @@ -1013,7 +1044,7 @@ test.describe("Infinite TreeActionView Component", () => { // Click the three dots menu await threeDotsMenu.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(1000); // Verify menu options appeared const pageText = await page.textContent("body"); @@ -1288,6 +1319,8 @@ test.describe("Infinite TreeActionView Component", () => { test("should reset table view to original state when clicking Reset table view", async ({ page, }) => { + test.setTimeout(60000); // Increase timeout to 60s for this complex test + await page.goto( getStoryUrl(E2E_TEST_APP_CONFIG.STORIES.TREE_ACTION_VIEW.INFINITE), ); @@ -1295,6 +1328,18 @@ test.describe("Infinite TreeActionView Component", () => { await page.waitForSelector(".ag-root", { state: "visible" }); await page.waitForSelector(".ag-header", { state: "visible" }); await page.waitForSelector(".ag-row", { state: "visible" }); + // Wait for data to be fully loaded (debounce is 500ms in v1.16.1) + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(1000); + + // Wait for all columns to be rendered + await page.waitForFunction( + () => { + const headers = document.querySelectorAll(".ag-header-cell-text"); + return headers.length >= 9; // Expect at least 9 columns + }, + { timeout: 5000 } + ); const getColumnOrder = async () => { return await page.locator(".ag-header-cell-text").allTextContents(); diff --git a/e2e-test-app/package-lock.json b/e2e-test-app/package-lock.json index 0f9c0bbfd..17741f3b0 100644 --- a/e2e-test-app/package-lock.json +++ b/e2e-test-app/package-lock.json @@ -27,14 +27,18 @@ }, "..": { "name": "@gisce/react-ooui", - "version": "2.92.3", + "version": "2.105.3", "dependencies": { "@ant-design/colors": "^7.2.0", "@ant-design/plots": "^1.0.9", + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", "@gisce/fiber-diagram": "2.1.1", - "@gisce/ooui": "2.32.1", - "@gisce/react-formiga-components": "1.17.0", - "@gisce/react-formiga-table": "1.15.0", + "@gisce/ooui": "2.36.0", + "@gisce/react-formiga-components": "1.18.0", + "@gisce/react-formiga-table": "1.16.1", "@monaco-editor/react": "^4.4.5", "@types/deep-equal": "^1.0.4", "antd": "5.25.1", From a6cfdba22bd01b8ccfa3a88effc8b617e2199df9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 16 Oct 2025 09:30:10 +0000 Subject: [PATCH 5/5] chore(release): 2.105.4 [skip ci] ## [2.105.4](https://github.com/gisce/react-ooui/compare/v2.105.3...v2.105.4) (2025-10-16) ### Bug Fixes * improvements and fixes for infinite tree ([760de4b](https://github.com/gisce/react-ooui/commit/760de4bc8ebc25740a4fea9046f47157a91a1186)) * ts issues ([8c78195](https://github.com/gisce/react-ooui/commit/8c781959d3a855a4c913dd5436ed21bd522431e1)) * update gisce/react-formiga-table to v1.16.1 ([567eb44](https://github.com/gisce/react-ooui/commit/567eb44faa091caaf3330f68c97e90f36db58f57)) * update tests ([f1ed77e](https://github.com/gisce/react-ooui/commit/f1ed77eb66a0e123bebb6647210d40a856c3dd4d)) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f47b492a..d478ea7ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@gisce/react-ooui", - "version": "2.105.3", + "version": "2.105.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@gisce/react-ooui", - "version": "2.105.3", + "version": "2.105.4", "dependencies": { "@ant-design/colors": "^7.2.0", "@ant-design/plots": "^1.0.9", diff --git a/package.json b/package.json index ba426e3c0..fe35eaf07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gisce/react-ooui", - "version": "2.105.3", + "version": "2.105.4", "engines": { "node": "20.5.0" },