diff --git a/src/frontend/CHANGELOG.md b/src/frontend/CHANGELOG.md
index 4e62d3cfc3..158082281c 100644
--- a/src/frontend/CHANGELOG.md
+++ b/src/frontend/CHANGELOG.md
@@ -2,7 +2,19 @@
This file contains historical changelog information for the InvenTree UI components library.
-### 0.11.4 - Unreleased
+### 1.4.0 - May 2026
+
+#### Version Numbering
+
+This update brings the version numbering in-line with the core InvenTree server version, which is currently at `1.4.0`. This versioning scheme will be maintained going forward, with the UI components library version matching the core server version.
+
+Thus, version `1.4.x` of the UI components library will be compatible with version `1.4.x` of the InvenTree server, and so on.
+
+#### Mantine Library Update
+
+The underlying Mantine library has been updated from version `8.x` to version `9.x`. This update may introduce breaking changes for plugins that rely on the InvenTree UI components library, as the Mantine library is a core dependency. Plugin developers should test their plugins against this new version to ensure compatibility.
+
+#### New Components
Adds additional functions in the plugin context related to form rendering and API invocation:
- `useInstance`
@@ -15,7 +27,6 @@ Exposes sub-components related to DetailDrawer rendering:
- `DetailDrawerComponent`
- `useLocalLibState`
-
### 0.11.3 - April 2026
Exposes additional type definitions related to rendering drawers from tables:
diff --git a/src/frontend/lib/components/RowActions.tsx b/src/frontend/lib/components/RowActions.tsx
index 464744277c..ff2ad44c40 100644
--- a/src/frontend/lib/components/RowActions.tsx
+++ b/src/frontend/lib/components/RowActions.tsx
@@ -139,8 +139,8 @@ export function RowActions({
aria-label={`row-action-menu-${index ?? ''}`}
onClick={openMenu}
disabled={disabled}
- variant='subtle'
- color='gray'
+ variant='transparent'
+ size='sm'
>
diff --git a/src/frontend/lib/hooks/UseFilterSet.tsx b/src/frontend/lib/hooks/UseFilterSet.tsx
index 80a7791f1e..52749f0c54 100644
--- a/src/frontend/lib/hooks/UseFilterSet.tsx
+++ b/src/frontend/lib/hooks/UseFilterSet.tsx
@@ -1,5 +1,5 @@
import { useLocalStorage } from '@mantine/hooks';
-import { useCallback, useMemo } from 'react';
+import { useCallback, useEffect, useMemo } from 'react';
import type { FilterSetState, TableFilter } from '../types/Filters';
export default function useFilterSet(
@@ -16,15 +16,15 @@ export default function useFilterSet(
getInitialValueInEffect: false
});
- const activeFilters: TableFilter[] = useMemo(() => {
+ useEffect(() => {
if (storedFilters == null) {
- // If there are no stored filters, set initial values
- const filters = initialFilters || [];
- setStoredFilters(filters);
- return filters;
+ setStoredFilters(initialFilters || []);
}
- return storedFilters || [];
- }, [storedFilters]);
+ }, [storedFilters, initialFilters, setStoredFilters]);
+
+ const activeFilters: TableFilter[] = useMemo(() => {
+ return storedFilters ?? initialFilters ?? [];
+ }, [storedFilters, initialFilters]);
// Callback to clear all active filters from the table
const clearActiveFilters = useCallback(() => {
diff --git a/src/frontend/lib/types/Tables.tsx b/src/frontend/lib/types/Tables.tsx
index aa8272f727..4b3d064f79 100644
--- a/src/frontend/lib/types/Tables.tsx
+++ b/src/frontend/lib/types/Tables.tsx
@@ -100,7 +100,7 @@ export type TableState = {
*/
export type TableColumnProps = {
accessor?: string;
- title?: string;
+ title?: string | ReactNode;
ordering?: string;
sortable?: boolean;
switchable?: boolean;
diff --git a/src/frontend/package.json b/src/frontend/package.json
index 132cd11437..dd80683ac5 100644
--- a/src/frontend/package.json
+++ b/src/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "@inventreedb/ui",
"description": "UI components for the InvenTree project",
- "version": "0.11.3",
+ "version": "1.4.0",
"private": false,
"type": "module",
"license": "MIT",
@@ -60,17 +60,17 @@
"@github/webauthn-json": "^2.1.1",
"@lingui/core": "^5.9.2",
"@lingui/react": "^5.9.2",
- "@mantine/carousel": "^8.2.7",
- "@mantine/charts": "^8.2.7",
- "@mantine/core": "^8.2.7",
- "@mantine/dates": "^8.2.7",
- "@mantine/dropzone": "^8.2.7",
- "@mantine/form": "^8.2.7",
- "@mantine/hooks": "^8.2.7",
- "@mantine/modals": "^8.2.7",
- "@mantine/notifications": "^8.2.7",
- "@mantine/spotlight": "^8.2.7",
- "@mantine/vanilla-extract": "^8.2.7",
+ "@mantine/carousel": "^9.2.1",
+ "@mantine/charts": "^9.2.1",
+ "@mantine/core": "^9.2.1",
+ "@mantine/dates": "^9.2.1",
+ "@mantine/dropzone": "^9.2.1",
+ "@mantine/form": "^9.2.1",
+ "@mantine/hooks": "^9.2.1",
+ "@mantine/modals": "^9.2.1",
+ "@mantine/notifications": "^9.2.1",
+ "@mantine/spotlight": "^9.2.1",
+ "@mantine/vanilla-extract": "^9.2.1",
"@messageformat/date-skeleton": "^1.1.0",
"@sentry/react": "^10.43.0",
"@tabler/icons-react": "^3.17.0",
@@ -89,8 +89,8 @@
"embla-carousel-react": "^8.5.2",
"fuse.js": "^7.0.0",
"html5-qrcode": "^2.3.8",
- "mantine-contextmenu": "^8.2.0",
- "mantine-datatable": "^8.2.0",
+ "mantine-contextmenu": "^9.2.1",
+ "mantine-datatable": "^9.2.0",
"qrcode": "^1.5.4",
"react": "^19.2.4",
"react-dom": "^19.2.4",
diff --git a/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx b/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
index fa531ce69e..c1b28f20d0 100644
--- a/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
+++ b/src/frontend/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx
@@ -1,7 +1,7 @@
-import { ActionIcon, Anchor, Group, Loader } from '@mantine/core';
+import { ActionIcon, Anchor, Group, RollingNumber } from '@mantine/core';
import { IconExclamationCircle } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
-import { type ReactNode, useCallback, useMemo } from 'react';
+import { type ReactNode, useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { StylishText } from '@lib/components/StylishText';
@@ -37,11 +37,15 @@ function QueryCountWidget({
const modelProperties = ModelInformationDict[modelType];
+ const [count, setCount] = useState(0);
+
const query = useQuery({
queryKey: ['dashboard-query-count', modelType, params, visibility],
enabled: user.hasViewPermission(modelType) && visibility === 'visible',
+ refetchOnWindowFocus: false,
refetchOnMount: true,
refetchInterval: 10 * 60 * 1000, // 10 minute refetch interval
+ staleTime: 5 * 60 * 1000, // 5 minute stale time
queryFn: () => {
if (visibility !== 'visible') {
return null;
@@ -54,7 +58,10 @@ function QueryCountWidget({
limit: 1
}
})
- .then((res) => res.data);
+ .then((res) => {
+ setCount(res.data?.count ?? 0);
+ return res.data;
+ });
}
});
@@ -81,18 +88,16 @@ function QueryCountWidget({
);
const result: ReactNode = useMemo(() => {
- if (query.isFetching) {
- return ;
- } else if (query.isError) {
+ if (query.isError) {
return (
);
} else {
- return {query.data?.count ?? '-'};
+ return ;
}
- }, [query.isFetching, query.isError, query.data]);
+ }, [query.isFetching, query.isError, count]);
return (
diff --git a/src/frontend/src/components/forms/fields/ApiFormField.tsx b/src/frontend/src/components/forms/fields/ApiFormField.tsx
index 32a506acdc..cd53a45f1d 100644
--- a/src/frontend/src/components/forms/fields/ApiFormField.tsx
+++ b/src/frontend/src/components/forms/fields/ApiFormField.tsx
@@ -81,10 +81,14 @@ export function ApiFormField({
...fieldDefinition,
autoFill: undefined,
placeholderAutofill: undefined,
+ placeholderWarning: undefined,
+ placeholderWarningCompare: undefined,
+ singleFetchFunction: undefined,
autoFillFilters: undefined,
onValueChange: undefined,
adjustFilters: undefined,
adjustValue: undefined,
+ allow_blank: undefined,
allow_null: undefined,
read_only: undefined,
children: undefined,
diff --git a/src/frontend/src/components/forms/fields/RelatedModelField.tsx b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
index 259fab72f2..70e427549e 100644
--- a/src/frontend/src/components/forms/fields/RelatedModelField.tsx
+++ b/src/frontend/src/components/forms/fields/RelatedModelField.tsx
@@ -419,7 +419,13 @@ export function RelatedModelField({
modelRenderer: undefined,
onValueChange: undefined,
adjustFilters: undefined,
+ adjustValue: undefined,
+ placeholderAutofill: undefined,
+ placeholderWarning: undefined,
+ placeholderWarningCompare: undefined,
+ singleFetchFunction: undefined,
exclude: undefined,
+ allow_blank: undefined,
allow_null: undefined,
read_only: undefined
};
diff --git a/src/frontend/src/components/nav/Header.tsx b/src/frontend/src/components/nav/Header.tsx
index 299feafb6f..8324da3e9a 100644
--- a/src/frontend/src/components/nav/Header.tsx
+++ b/src/frontend/src/components/nav/Header.tsx
@@ -114,7 +114,9 @@ export function Header() {
},
// Refetch every minute, *if* the tab is visible
refetchInterval: 60 * 1000,
- refetchOnMount: true
+ refetchOnMount: true,
+ refetchOnWindowFocus: false,
+ staleTime: 30 * 1000
});
// Sync Navigation Drawer state with zustand
diff --git a/src/frontend/src/components/nav/PageDetail.tsx b/src/frontend/src/components/nav/PageDetail.tsx
index e91afa384a..d8cbb6b167 100644
--- a/src/frontend/src/components/nav/PageDetail.tsx
+++ b/src/frontend/src/components/nav/PageDetail.tsx
@@ -48,7 +48,10 @@ export function PageDetail({
useHotkeys([
[
'mod+E',
- () => {
+ (event) => {
+ if (event.repeat) {
+ return;
+ }
if (editEnabled ?? true) {
editAction?.();
}
diff --git a/src/frontend/src/components/nav/SearchDrawer.tsx b/src/frontend/src/components/nav/SearchDrawer.tsx
index 1d5874eb6f..cb2066a903 100644
--- a/src/frontend/src/components/nav/SearchDrawer.tsx
+++ b/src/frontend/src/components/nav/SearchDrawer.tsx
@@ -30,7 +30,7 @@ import {
IconX
} from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
-import { useCallback, useEffect, useMemo, useState } from 'react';
+import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { type NavigateFunction, useNavigate } from 'react-router-dom';
import { Boundary } from '@lib/components/Boundary';
@@ -165,7 +165,7 @@ function QueryResultGroup({
{query.results.results.map((result: any, index: number) => (
- <>
+
)}
- >
+
))}
diff --git a/src/frontend/src/components/panels/PanelGroup.tsx b/src/frontend/src/components/panels/PanelGroup.tsx
index a5dcf701e5..c07249f303 100644
--- a/src/frontend/src/components/panels/PanelGroup.tsx
+++ b/src/frontend/src/components/panels/PanelGroup.tsx
@@ -370,6 +370,7 @@ function BasePanelGroup({
(panel) =>
!panel.hidden && (
diff --git a/src/frontend/src/hooks/UseForm.tsx b/src/frontend/src/hooks/UseForm.tsx
index c92f321f6d..b832be4dae 100644
--- a/src/frontend/src/hooks/UseForm.tsx
+++ b/src/frontend/src/hooks/UseForm.tsx
@@ -62,14 +62,18 @@ export function useApiFormModal(props: ApiFormModalProps) {
id: modalId,
title: formProps.title,
onOpen: () => {
- setIsOpen(true);
- modalState.setModalOpen(modalId, true);
- formProps.onOpen?.();
+ queueMicrotask(() => {
+ setIsOpen(true);
+ modalState.setModalOpen(modalId, true);
+ formProps.onOpen?.();
+ });
},
onClose: () => {
- setIsOpen(false);
- modalState.setModalOpen(modalId, false);
- formProps.onClose?.();
+ queueMicrotask(() => {
+ setIsOpen(false);
+ modalState.setModalOpen(modalId, false);
+ formProps.onClose?.();
+ });
},
closeOnClickOutside: formProps.closeOnClickOutside,
size: props.size ?? 'xl',
diff --git a/src/frontend/src/pages/Index/Settings/AccountSettings/UserPanel.tsx b/src/frontend/src/pages/Index/Settings/AccountSettings/UserPanel.tsx
index 918418452c..8e1e2ce9eb 100644
--- a/src/frontend/src/pages/Index/Settings/AccountSettings/UserPanel.tsx
+++ b/src/frontend/src/pages/Index/Settings/AccountSettings/UserPanel.tsx
@@ -8,17 +8,15 @@ export function AccountContent() {
const SECONDARY_COL_HEIGHT = PRIMARY_COL_HEIGHT / 2 - 8;
return (
-
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/frontend/src/tables/ColumnRenderers.tsx b/src/frontend/src/tables/ColumnRenderers.tsx
index a60642bb05..1c0bed0ede 100644
--- a/src/frontend/src/tables/ColumnRenderers.tsx
+++ b/src/frontend/src/tables/ColumnRenderers.tsx
@@ -330,7 +330,7 @@ export function PathColumn(props: TableColumnProps): TableColumn {
{instance.name}}
icon='sitemap'
- title={props.title}
+ title={props.title?.toLocaleString() ?? t`Path`}
extra={[{instance.pathstring}]}
/>
);
diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx
index c8b78770ba..714edf23ab 100644
--- a/src/frontend/src/tables/InvenTreeTable.tsx
+++ b/src/frontend/src/tables/InvenTreeTable.tsx
@@ -7,7 +7,6 @@ import { cancelEvent } from '@lib/functions/Events';
import { mapFields } from '@lib/functions/Forms';
import { getDetailUrl } from '@lib/functions/Navigation';
import { navigateToLink } from '@lib/functions/Navigation';
-import { hashString } from '@lib/functions/String';
import { useStoredTableState } from '@lib/states/StoredTableState';
import type { TableFilter } from '@lib/types/Filters';
import type { ApiFormFieldSet } from '@lib/types/Forms';
@@ -18,8 +17,8 @@ import type {
} from '@lib/types/Tables';
import type { TableColumn } from '@lib/types/Tables';
import { t } from '@lingui/core/macro';
-import { Box, Stack } from '@mantine/core';
-import { IconArrowRight } from '@tabler/icons-react';
+import { ActionIcon, Box, Stack } from '@mantine/core';
+import { IconArrowRight, IconClick } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import {
type ContextMenuItemOptions,
@@ -254,12 +253,6 @@ export function InvenTreeTableInternal>({
[tableState.setSelectedRecords]
);
- // A hash of the current column configuration
- // This is a workaround to fix an issue with mantine-datatable where
- // the columns do not update correctly when they are changed dynamically
- // Ref: https://github.com/icflorescu/mantine-datatable/issues/759
- const [columnHash, setColumnHash] = useState('');
-
// Update column visibility when hiddenColumns change
const dataColumns: any = useMemo(() => {
let cols: TableColumn[] = columns.filter((col) => col?.hidden != true);
@@ -326,7 +319,11 @@ export function InvenTreeTableInternal>({
if (tableProps.rowActions) {
cols.push({
accessor: ACTIONS_COLUMN_ACCESSOR,
- title: ' ',
+ title: (
+
+
+
+ ),
hidden: false,
resizable: false,
switchable: false,
@@ -350,13 +347,6 @@ export function InvenTreeTableInternal>({
tableState.selectedRecords
]);
- useEffect(() => {
- const columnNames: string = dataColumns
- .map((col: any) => col.accessor)
- .join(',');
- setColumnHash(hashString(columnNames));
- }, [dataColumns]);
-
// Callback when column visibility is toggled
const toggleColumn = useCallback(
(columnName: string) => {
@@ -378,19 +368,25 @@ export function InvenTreeTableInternal>({
[cacheKey, dataColumns]
);
+ // Generate an ordered list of column names,
+ // which we use to ensure the table is reloaded correctly when columns are added/removed/renamed
+ const tableColumnNames = useMemo(
+ () => dataColumns.map((col: any) => col.accessor).join(','),
+ [dataColumns]
+ );
+
// Final state of the table columns
const tableColumns = useDataTableColumns({
- key: `${cacheKey}-${columnHash}`,
+ key: cacheKey,
columns: dataColumns,
getInitialValueInEffect: false
});
// Reset column ordering and custom widths when the component is mounted
- // Ref: https://github.com/icflorescu/mantine-datatable/issues/759#issuecomment-4148942070
+ // Ref: https://github.com/icflorescu/mantine-datatable/issues/759
useEffect(() => {
- tableColumns.resetColumnsOrder();
- tableColumns.resetColumnsWidth();
- }, []);
+ tableColumns.setColumnsOrder(dataColumns.map((col: any) => col.accessor));
+ }, [tableColumnNames]);
// Reset the pagination state when the search term changes
useEffect(() => {
diff --git a/src/frontend/src/tables/build/BuildOutputTable.tsx b/src/frontend/src/tables/build/BuildOutputTable.tsx
index 9b3f182a5e..2ecdcb2f76 100644
--- a/src/frontend/src/tables/build/BuildOutputTable.tsx
+++ b/src/frontend/src/tables/build/BuildOutputTable.tsx
@@ -122,6 +122,9 @@ function OutputAllocationDrawer({
opened={opened}
onClose={close}
withCloseButton
+ closeButtonProps={{
+ 'aria-label': 'close-allocation-drawer'
+ }}
closeOnEscape
closeOnClickOutside
styles={{
diff --git a/src/frontend/tests/login.ts b/src/frontend/tests/login.ts
index ab19bddbba..4bb52d44f9 100644
--- a/src/frontend/tests/login.ts
+++ b/src/frontend/tests/login.ts
@@ -36,8 +36,8 @@ export const doLogin = async (page: Page, options?: LoginOptions) => {
await page.waitForURL('**/web/login');
- await page.getByLabel('username').fill(username);
- await page.getByLabel('password').fill(password);
+ await page.getByRole('textbox', { name: 'login-username' }).fill(username);
+ await page.getByRole('textbox', { name: 'login-password' }).fill(password);
await page.waitForTimeout(100);
diff --git a/src/frontend/tests/pages/pui_build.spec.ts b/src/frontend/tests/pages/pui_build.spec.ts
index 0e01e57c99..bdc9cb34a9 100644
--- a/src/frontend/tests/pages/pui_build.spec.ts
+++ b/src/frontend/tests/pages/pui_build.spec.ts
@@ -225,6 +225,7 @@ test('Build Order - Build Outputs', async ({ browser }) => {
await page.getByRole('cell', { name: 'BO0011' }).click();
await loadTab(page, 'Incomplete Outputs');
+ await page.getByRole('cell', { name: 'BX-123' }).waitFor();
// Check the "printing" actions for the selected outputs
await page.getByRole('checkbox', { name: 'Select all records' }).check();
@@ -523,6 +524,8 @@ test('Build Order - Consume Stock', async ({ browser }) => {
// Consume the rest of the stock via line items
await loadTab(page, 'Required Parts');
+ await page.getByText('10K resistor in 0805 SMD').first().waitFor();
+
await page.getByRole('checkbox', { name: 'Select all records' }).check();
await page
.getByRole('button', { name: 'action-button-consume-stock' })
@@ -603,7 +606,7 @@ test('Build Order - Tracked Outputs', async ({ browser }) => {
await allocationRow.getByText('1 / 1').waitFor();
// Close the allocation wizard
- await page.getByRole('banner').getByRole('button').click();
+ await page.getByRole('button', { name: 'close-allocation-drawer' }).click();
// Check that the output is now allocated as expected
await row.getByText('1 / 6').waitFor();
diff --git a/src/frontend/tests/pages/pui_dashboard.spec.ts b/src/frontend/tests/pages/pui_dashboard.spec.ts
index dd9ef7ea05..07af2a5a0b 100644
--- a/src/frontend/tests/pages/pui_dashboard.spec.ts
+++ b/src/frontend/tests/pages/pui_dashboard.spec.ts
@@ -1,6 +1,8 @@
import type { Page } from '@playwright/test';
import { expect } from '@playwright/test';
+import { createApi } from '../api.js';
import { test } from '../baseFixtures.js';
+import { allaccessuser } from '../defaults.js';
import { doCachedLogin } from '../login.js';
import { setPluginState } from '../settings.js';
@@ -96,9 +98,7 @@ test('Dashboard - Plugins', async ({ browser }) => {
await page.getByText('Hello world! This is a sample').waitFor();
});
-test('Dashboard - Preserve widget sizes when adding new widget', async ({
- browser
-}) => {
+test('Dashboard - Preserve widget sizes', async ({ browser }) => {
// Regression: addWidget previously snapped every existing widget back to
// its minW/minH. Fix is in DashboardLayout.tsx::addWidget (overrideSize=false).
const TARGET_W = 10;
@@ -110,7 +110,11 @@ test('Dashboard - Preserve widget sizes when adding new widget', async ({
return raw ? (JSON.parse(raw)?.state?.layouts ?? {}) : {};
});
- const page = await doCachedLogin(browser);
+ const user = allaccessuser;
+
+ const page = await doCachedLogin(browser, {
+ user: user
+ });
await resetDashboard(page);
// Add widget A; this also persists to the backend user profile.
@@ -120,7 +124,7 @@ test('Dashboard - Preserve widget sizes when adding new widget', async ({
await page.getByLabel('add-widget-ovr-so').click();
await page.getByRole('banner').getByRole('button').click();
await page.getByText('Overdue Sales Orders').waitFor();
- await page.waitForTimeout(500);
+ await page.waitForTimeout(100);
// Inflate widget A on the backend profile and reload. The auth flow on
// page load rehydrates layouts from the profile, not localStorage, so a
@@ -132,26 +136,31 @@ test('Dashboard - Preserve widget sizes when adding new widget', async ({
it?.i === 'ovr-so' ? { ...it, w: TARGET_W, h: TARGET_H } : it
);
}
- await page.evaluate(async (layouts) => {
- const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] ?? '';
- await fetch('/api/user/profile/', {
- method: 'PATCH',
- credentials: 'same-origin',
- headers: {
- 'Content-Type': 'application/json',
- 'X-CSRFToken': csrf
- },
- body: JSON.stringify({ widgets: { widgets: ['ovr-so'], layouts } })
- });
- }, inflated);
+
+ const api = createApi({
+ username: user.username,
+ password: user.testcred
+ });
+
+ (await api).patch('user/profile/', {
+ data: {
+ widgets: {
+ widgets: ['ovr-so'],
+ layouts: inflated
+ }
+ }
+ });
await page.reload();
await page.getByText('Overdue Sales Orders').waitFor();
- await page.waitForTimeout(500);
+ await page.waitForTimeout(100);
// Sanity: profile rehydration produced the inflated values.
for (const [bp, items] of Object.entries(await readLayouts(page))) {
const entry = (items as any[]).find((i) => i?.i === 'ovr-so');
+
+ console.log('entry:', bp, entry);
+
expect(entry?.w, `${bp}: ovr-so missing or wrong w`).toBe(TARGET_W);
expect(entry?.h, `${bp}: ovr-so missing or wrong h`).toBe(TARGET_H);
}
@@ -163,7 +172,7 @@ test('Dashboard - Preserve widget sizes when adding new widget', async ({
await page.getByLabel('add-widget-ovr-po').click();
await page.getByRole('banner').getByRole('button').click();
await page.getByText('Overdue Purchase Orders').waitFor();
- await page.waitForTimeout(800);
+ await page.waitForTimeout(100);
for (const [bp, items] of Object.entries(await readLayouts(page))) {
const entry = (items as any[]).find((i) => i?.i === 'ovr-so');
diff --git a/src/frontend/tests/pages/pui_part.spec.ts b/src/frontend/tests/pages/pui_part.spec.ts
index ab3dd9952e..72726aa541 100644
--- a/src/frontend/tests/pages/pui_part.spec.ts
+++ b/src/frontend/tests/pages/pui_part.spec.ts
@@ -344,7 +344,9 @@ test('Parts - BOM Comparison', async ({ browser }) => {
await page.getByText('Removed from BOM').first().waitFor();
// Change display mode
- await page.getByRole('textbox', { name: 'bom-compare-display-mode' }).click();
+ await page
+ .getByRole('combobox', { name: 'bom-compare-display-mode' })
+ .click();
await page.getByRole('option', { name: 'Show different Parts' }).click();
// Use URL params to compare directly
diff --git a/src/frontend/tests/pages/pui_purchasing.spec.ts b/src/frontend/tests/pages/pui_purchasing.spec.ts
index 8c06c4cc13..6025e15ab2 100644
--- a/src/frontend/tests/pages/pui_purchasing.spec.ts
+++ b/src/frontend/tests/pages/pui_purchasing.spec.ts
@@ -162,7 +162,7 @@ test('Purchasing - Manufacturer Parts', async ({ browser }) => {
await page.getByRole('button', { name: 'table-export-data' }).click();
await page.getByText('Select export plugin').waitFor();
await page
- .getByRole('textbox', { name: 'choice-field-export_plugin' })
+ .getByRole('combobox', { name: 'choice-field-export_plugin' })
.fill('CSV');
await page.getByRole('button', { name: 'Export', exact: true }).click();
await page.getByText('Process completed successfully').waitFor();
@@ -509,8 +509,9 @@ test('Purchase Orders - Receive Items', async ({ browser }) => {
// Select all line items to receive
await loadTab(page, 'Line Items');
+ await page.getByRole('cell', { name: '002.02-PCB' }).waitFor();
await page.getByLabel('Select all records').click();
- await page.waitForTimeout(200);
+ await page.waitForTimeout(100);
await page.getByLabel('action-button-receive-items').click();
// Check for display of individual locations
@@ -606,6 +607,8 @@ test('Purchase Orders - Receive Virtual Items', async ({ browser }) => {
// Receive the line item
await loadTab(page, 'Line Items');
+ await page.getByRole('cell', { name: 'Thumbnail CRM license' }).waitFor();
+
await page.getByRole('checkbox', { name: 'Select all records' }).click();
await page
.getByRole('button', { name: 'action-button-receive-items' })
diff --git a/src/frontend/tests/pages/pui_return.spec.ts b/src/frontend/tests/pages/pui_return.spec.ts
index b3656a1c30..96962d0574 100644
--- a/src/frontend/tests/pages/pui_return.spec.ts
+++ b/src/frontend/tests/pages/pui_return.spec.ts
@@ -12,6 +12,8 @@ test('Return Orders - Receive Items', async ({ browser }) => {
await loadTab(page, 'Attachments');
await loadTab(page, 'Line Items');
+ await page.getByRole('cell', { name: 'WID-REV-A' }).first().waitFor();
+
await page.getByRole('checkbox', { name: 'Select all records' }).click();
await page.getByRole('button', { name: 'action-button-receive-' }).click();
await page.getByRole('banner').getByText('Receive Items').waitFor();
diff --git a/src/frontend/tests/pages/pui_stock.spec.ts b/src/frontend/tests/pages/pui_stock.spec.ts
index 0592576892..eef8ee935c 100644
--- a/src/frontend/tests/pages/pui_stock.spec.ts
+++ b/src/frontend/tests/pages/pui_stock.spec.ts
@@ -111,14 +111,14 @@ test('Stock - Location Delete', async ({ browser }) => {
.click();
await page
- .getByRole('textbox', { name: 'choice-field-delete_stock_items' })
+ .getByRole('combobox', { name: 'choice-field-delete_stock_items' })
.click();
await page
.getByRole('option', { name: 'Move items to parent location' })
.click();
await page
- .getByRole('textbox', { name: 'choice-field-delete_sub_locations' })
+ .getByRole('combobox', { name: 'choice-field-delete_sub_locations' })
.click();
await page.getByRole('option', { name: 'Delete items' }).click();
diff --git a/src/frontend/tests/pui_exporting.spec.ts b/src/frontend/tests/pui_exporting.spec.ts
index 8f2dcbd253..acf9a38345 100644
--- a/src/frontend/tests/pui_exporting.spec.ts
+++ b/src/frontend/tests/pui_exporting.spec.ts
@@ -6,7 +6,8 @@ import { doCachedLogin } from './login';
// Helper function to open the export data dialog
const openExportDialog = async (page) => {
await page.waitForLoadState('networkidle');
- await page.getByLabel('table-export-data').click();
+
+ await page.getByRole('button', { name: 'table-export-data' }).click();
await page.getByText('Export Format *', { exact: true }).waitFor();
await page.getByText('Export Plugin *', { exact: true }).waitFor();
};
diff --git a/src/frontend/tests/pui_importing.spec.ts b/src/frontend/tests/pui_importing.spec.ts
index 0d1233eadc..abd34cb201 100644
--- a/src/frontend/tests/pui_importing.spec.ts
+++ b/src/frontend/tests/pui_importing.spec.ts
@@ -26,7 +26,7 @@ test('Importing - Admin Center', async ({ browser }) => {
await page.getByText('Errors exist for one or more').waitFor();
await page
- .getByRole('textbox', { name: 'choice-field-model_type' })
+ .getByRole('combobox', { name: 'choice-field-model_type' })
.fill('bom');
await page.getByRole('option', { name: 'BOM Item', exact: true }).click();
await page.getByRole('button', { name: 'Submit' }).click();
@@ -36,7 +36,7 @@ test('Importing - Admin Center', async ({ browser }) => {
await page.getByText('Existing database identifier for the record').waitFor();
await page
- .getByRole('textbox', { name: 'import-column-map-reference' })
+ .getByRole('combobox', { name: 'import-column-map-reference' })
.click();
await page.getByRole('option', { name: 'Ignore this field' }).click();
@@ -195,7 +195,7 @@ test('Importing - Natural Keys', async ({ browser }) => {
// Select different columns for data import
// We will use the "SKU" field to map to the supplier part
- await page.getByRole('textbox', { name: 'import-column-map-part' }).click();
+ await page.getByRole('combobox', { name: 'import-column-map-part' }).click();
await page.getByRole('option', { name: 'SKU' }).click();
// Other import fields will be left as default
diff --git a/src/frontend/tests/pui_machines.spec.ts b/src/frontend/tests/pui_machines.spec.ts
index a764c8d105..0d5987b2ab 100644
--- a/src/frontend/tests/pui_machines.spec.ts
+++ b/src/frontend/tests/pui_machines.spec.ts
@@ -47,14 +47,17 @@ test('Machines - Activation', async ({ browser }) => {
.getByRole('textbox', { name: 'text-field-name' })
.fill('my-dummy-machine');
await page
- .getByRole('textbox', { name: 'choice-field-machine_type' })
+ .getByRole('combobox', { name: 'choice-field-machine_type' })
.fill('label');
await page.getByRole('option', { name: 'Label Printer' }).click();
- await page.getByRole('textbox', { name: 'choice-field-driver' }).click();
+ await page.getByRole('combobox', { name: 'choice-field-driver' }).click();
+ await page.waitForTimeout(200);
await page
.getByRole('option', { name: 'Sample Label Printer Driver' })
.click();
+ await page.waitForTimeout(200);
+
await page.getByRole('button', { name: 'Submit' }).click();
} else {
// Machine already exists - just click on it to open the "machine drawer"
@@ -64,10 +67,13 @@ test('Machines - Activation', async ({ browser }) => {
// Creating the new machine opens the "machine drawer"
// Check for "machine type" settings
- await page.getByText('Scope the printer to a specific location').waitFor();
+ await page
+ .getByText('Scope the printer to a specific location')
+ .first()
+ .waitFor();
// Check for "machine driver" settings
- await page.getByText('Custom string for connecting').waitFor();
+ await page.getByText('Custom string for connecting').first().waitFor();
// Edit the available setting
await page.getByRole('button', { name: 'edit-setting-CONNECTION' }).click();
@@ -94,6 +100,7 @@ test('Machines - Activation', async ({ browser }) => {
// Let's print something with the machine
await navigate(page, 'stock/location/1/stock-items');
+ await page.getByText('Blue plastic enclosure').first().waitFor();
await page.getByRole('checkbox', { name: 'Select all records' }).check();
await page
@@ -110,7 +117,7 @@ test('Machines - Activation', async ({ browser }) => {
await page.getByText('InvenTreeLabelMachine').click();
await page
- .getByRole('textbox', { name: 'choice-field-machine' })
+ .getByRole('combobox', { name: 'choice-field-machine' })
.fill('dummy');
await page.getByRole('option', { name: 'my-dummy-machine' }).click();
diff --git a/src/frontend/tests/pui_settings.spec.ts b/src/frontend/tests/pui_settings.spec.ts
index 35f2936dbd..c594f003f6 100644
--- a/src/frontend/tests/pui_settings.spec.ts
+++ b/src/frontend/tests/pui_settings.spec.ts
@@ -45,9 +45,9 @@ test('Settings - User theme', async ({ browser }) => {
await page.getByRole('menuitem', { name: 'User settings' }).click();
// loader
- await page.getByRole('textbox', { name: 'Loader Type Selector' }).click();
+ await page.getByRole('combobox', { name: 'Loader Type Selector' }).click();
await page.getByRole('option', { name: 'Oval' }).click();
- await page.getByRole('textbox', { name: 'Loader Type Selector' }).click();
+ await page.getByRole('combobox', { name: 'Loader Type Selector' }).click();
await page.getByRole('option', { name: 'Bars' }).click();
// dark / light mode
@@ -92,7 +92,7 @@ test('Settings - User', async ({ browser }) => {
await page.getByText('Profile Details').waitFor();
// Language selection
- await page.getByRole('textbox', { name: 'Select language' }).click();
+ await page.getByRole('combobox', { name: 'Select language' }).click();
await page.getByRole('option', { name: 'العربية' }).waitFor();
await page.getByRole('option', { name: 'Deutsch' }).waitFor();
await page.getByRole('option', { name: 'English' }).waitFor();
@@ -321,8 +321,8 @@ test('Settings - Admin - Background Tasks', async ({ browser }) => {
// Background worker should be running, and idle
await page.getByText('Background worker running').waitFor();
- await page.getByText('Failed Tasks0').waitFor();
- await page.getByText('Pending Tasks0').waitFor();
+ await page.getByText(/Failed Tasks\d+/).waitFor();
+ await page.getByText(/Pending Tasks\d+/).waitFor();
// Expand the "scheduled tasks" view
await page.getByRole('button', { name: 'Scheduled Tasks' }).click();
diff --git a/src/frontend/yarn.lock b/src/frontend/yarn.lock
index 4596ca15f4..ba2887a475 100644
--- a/src/frontend/yarn.lock
+++ b/src/frontend/yarn.lock
@@ -874,7 +874,7 @@
dependencies:
"@floating-ui/dom" "^1.7.6"
-"@floating-ui/react@^0.27.16":
+"@floating-ui/react@^0.27.19":
version "0.27.19"
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.27.19.tgz#d8d5d895b7cb97dac370bfbf55f3e630878fdf1f"
integrity sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==
@@ -1169,84 +1169,84 @@
"@babel/runtime" "^7.20.13"
"@lingui/core" "5.9.3"
-"@mantine/carousel@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/carousel/-/carousel-8.3.18.tgz#55489c09de7a7ccb3b758d3386eef56db91cec4b"
- integrity sha512-jrXqpoiL+/GTTgW4/UWLqvo5pWnUEvuwaUlvD/Yl8XC+iyBiZHgzyq0erEMIRGertVvpet4vsiZjye7ycPHlfA==
+"@mantine/carousel@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/carousel/-/carousel-9.2.1.tgz#bc470ae1c2801d66b40de9d1e76eee869995fb1c"
+ integrity sha512-b0ZBDnKhzztEFWNWbbFpPMqaV/4k/lclX8KB0PfU+qhu3Fa6wjS1VIn4XLZu9N3vgkzPkNXwDzpcwFShA9Uvqw==
-"@mantine/charts@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/charts/-/charts-8.3.18.tgz#329db5b50c12cbda2be3609d359a068ad8ac2f47"
- integrity sha512-oudif3EUH7Nb9DPm0abAPxpFYDWWjR3k2S5ll0/CcB+pJzlhwaBG19QwpOJaRA6VAvAXDDKOXCO4mi9XCEN78g==
+"@mantine/charts@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/charts/-/charts-9.2.1.tgz#64811e07c1094b2b9bc67f04230e5dcebfe76be1"
+ integrity sha512-AVP0VEfcsbWwLBeU8rbEsN2gz3GebQECTreRq5AJ0Z5V1eWmTO7XFkRP9C5C6oHnkY4Vppa1x8cRYgyTsc/YbQ==
-"@mantine/core@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/core/-/core-8.3.18.tgz#25d206caef1110a50671139520b1434b581a62ca"
- integrity sha512-9tph1lTVogKPjTx02eUxDUOdXacPzK62UuSqb4TdGliI54/Xgxftq0Dfqu6XuhCxn9J5MDJaNiLDvL/1KRkYqA==
+"@mantine/core@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/core/-/core-9.2.1.tgz#6bed4beac0b8c5f385f8923e4f158eb7472b633d"
+ integrity sha512-CicPg9i2dM2pGp1jj+dMiR/63OFDsPjgJke4v5+0nbfJ+C7gn4C+7ltrp4RIETDMZHcj0fFuDRG0qtbiyBxvWA==
dependencies:
- "@floating-ui/react" "^0.27.16"
+ "@floating-ui/react" "^0.27.19"
clsx "^2.1.1"
- react-number-format "^5.4.4"
- react-remove-scroll "^2.7.1"
- react-textarea-autosize "8.5.9"
- type-fest "^4.41.0"
+ react-number-format "^5.4.5"
+ react-remove-scroll "^2.7.2"
+ type-fest "^5.6.0"
-"@mantine/dates@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/dates/-/dates-8.3.18.tgz#e73b1847c4903eba20b80907162dbf93c99e4956"
- integrity sha512-FHx5teJOhupI0gO2o5evtVYQEdqOjayOkLRhEQfB5Nc5DvcysfPfmNILGkc1Nrp9ZQeQWKLT9qr+CkcCXwHOaw==
+"@mantine/dates@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/dates/-/dates-9.2.1.tgz#47c9eb8a854a7f1e6fa3993e9966babb793e9e4a"
+ integrity sha512-cyRC8bnZ6W+SzQf/RM+/eDeWhZTZF148z+OcgqiERdkAujh0q88Ddybv/Hshv1EOf0rCe6oiHSZWxIxmUf7KAg==
dependencies:
clsx "^2.1.1"
-"@mantine/dropzone@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/dropzone/-/dropzone-8.3.18.tgz#abc9e4b35fc4c18041ba6f6f3b574935a1d6e03f"
- integrity sha512-GaYUUl/382R7hl1g6heTCZ5a6T5x6qYPg0oID6ik/J0j7e5+XMZyTH5ITpaqpsBQ09GKKsF5y3iNehpSby8Kew==
+"@mantine/dropzone@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/dropzone/-/dropzone-9.2.1.tgz#3003d745da2f08246fc055137d250beb4f743283"
+ integrity sha512-rgebEz2bUubqA5jQpsh0SZ9/4DJFnUSF+a4p8uzAVlgNfo6aU/r+I4lEsD8gzLKuxrfN0TgkwR1qmAjLWIy0yQ==
dependencies:
react-dropzone "15.0.0"
-"@mantine/form@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/form/-/form-8.3.18.tgz#c0e6ed7f564a69cbb157ed5d9925a5244057029c"
- integrity sha512-r5OGLJWTkmIruFjRZRZy9oA7maNYlyt50jB4Pmd2X5360WOmJLd4KH8MFhHZQC7vN+z8/rmBl3t3XGAR2I8xig==
+"@mantine/form@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/form/-/form-9.2.1.tgz#f75d82a16d82a1aa3105ff86328a032b6ff712bb"
+ integrity sha512-PV0dcbmsKhZkn3Ryztqp8Kb1N16v2nWXO71p4utTmN7E/lHWHO1ccj7Y72sIteWJo1YeNHzzkssaYRSnxgOvYA==
dependencies:
+ "@standard-schema/spec" "^1.1.0"
fast-deep-equal "^3.1.3"
klona "^2.0.6"
-"@mantine/hooks@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-8.3.18.tgz#7e5601c0683ed2411e3aee8fcb81a151e5341ad2"
- integrity sha512-QoWr9+S8gg5050TQ06aTSxtlpGjYOpIllRbjYYXlRvZeTsUqiTbVfvQROLexu4rEaK+yy9Wwriwl9PMRgbLqPw==
+"@mantine/hooks@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-9.2.1.tgz#8f81303b5eab68b10f4b3d7c99795b70932bc2db"
+ integrity sha512-IX/ztVG9eWmQTRsN7G8odyW4JckNvN8qv5A2ULzXyazjtAKLuaUpuMz0c6XhRp10J0g4bVfV3rhrTgWeImqxqg==
-"@mantine/modals@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/modals/-/modals-8.3.18.tgz#e17a49253944bbb5de4142fd0d15cc944ca63fc2"
- integrity sha512-JfPDS4549L314SxFPC1x6CbKwzh82OdnIzwgMxPCVNsWLKV2vEHHUH/fzUYj4Wli6IBrsW4cufjMj9BTj3hm3Q==
+"@mantine/modals@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/modals/-/modals-9.2.1.tgz#257c09088372b38848fb08beeb1124ed3fbe63b3"
+ integrity sha512-YvZ85ZtMg6arFserkmmP18gJRD9ztLLT3vz8UrkwCdVwTGGr14X93hhS0UtR5X96ANXUzC8fU/S2ncQmNqw+NQ==
-"@mantine/notifications@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/notifications/-/notifications-8.3.18.tgz#50b9463afab3af0ea3de375dd92cf2fa60aed964"
- integrity sha512-IpQ0lmwbigTBbZCR6iSYWqIOKEx1tlcd7PcEJ5M5X1qeVSY/N3mmDQt1eJmObvcyDeL5cTJMbSA9UPqhRqo9jw==
+"@mantine/notifications@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/notifications/-/notifications-9.2.1.tgz#de99ed4fc64e05024cb5a66e2d619a248ac2e042"
+ integrity sha512-H6lSsKUPdWPYcXFeOcqqcegUl72Iua9yD369s/gchfDvI+PrL4IM5UuWNHTeABJ1eb9FbTOw8B5RDSMZjTZNSA==
dependencies:
- "@mantine/store" "8.3.18"
+ "@mantine/store" "9.2.1"
react-transition-group "4.4.5"
-"@mantine/spotlight@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/spotlight/-/spotlight-8.3.18.tgz#1747a6afdd2b0aab3cf03c364fbc7b3ea3c4ae4b"
- integrity sha512-yFoEYG0wKduxbnv6+1CUOXc91lmQ5DN4QvEShYO2ftDm0kXhxeOvJFtGOBYK80tpmSCsaT253p9E3J3DcaOt2w==
+"@mantine/spotlight@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/spotlight/-/spotlight-9.2.1.tgz#4157cef5a9a1b9ac5f6025b57435a8dc484b58b9"
+ integrity sha512-D6/BJ8/ftUBwiSFGTtYUM/LqlBk40XZqZFlmEFRM8chDPzEId1O+5FU7mj8KapPR9zRgoAcdT4LMI6JaLp0c0A==
dependencies:
- "@mantine/store" "8.3.18"
+ "@mantine/store" "9.2.1"
-"@mantine/store@8.3.18":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/store/-/store-8.3.18.tgz#fda5e84bb58d4fa4a86cf4e158e166904867caf6"
- integrity sha512-i+QRTLmZzLldea0egtUVnGALd6UMIu8jd44nrNWBSNIXJU/8B6rMlC6gyX+l4szopZSuOaaNJIXkqRdC1gQsVg==
+"@mantine/store@9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/store/-/store-9.2.1.tgz#27a3548c4cc1567baa2613490d7dcb9300b391ba"
+ integrity sha512-sBTHt9ilfSZAeXQlqFkm8nRm22RunhevxuOUtdSwS9HhuMuS8T27dRRgbdKH2oEFUbaccdQSy5bHbmGbEgVO8w==
-"@mantine/vanilla-extract@^8.2.7":
- version "8.3.18"
- resolved "https://registry.yarnpkg.com/@mantine/vanilla-extract/-/vanilla-extract-8.3.18.tgz#ba7aaa0fd2ebf547821ef7138a8f12f4149b089d"
- integrity sha512-W7YwNJMeYJKsW+m1ntq+D0bt/b2GmGDWdHUxD+REjVlrXPhsKcb7nFX59ot/sgl35ak4yT2SFM1aPkUvgOQMCg==
+"@mantine/vanilla-extract@^9.2.1":
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/@mantine/vanilla-extract/-/vanilla-extract-9.2.1.tgz#ba86032eaaf278153d3dd110c8e4327457cc0606"
+ integrity sha512-5cNesX5kdmClWCMFqxDIVZF2JRCne2OrIj5UE3tuyGJAY3IGkchBnAf/bEx3c5QDSXxq4+6y97hs5gQBgODePA==
"@marijn/find-cluster-break@^1.0.0":
version "1.0.2"
@@ -1799,7 +1799,7 @@
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.10.tgz#beefe675f1853f73676aecc915b2bd2ac98c4fc6"
integrity sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==
-"@standard-schema/spec@^1.0.0":
+"@standard-schema/spec@^1.0.0", "@standard-schema/spec@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8"
integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==
@@ -3811,15 +3811,15 @@ make-dir@^4.0.0:
dependencies:
semver "^7.5.3"
-mantine-contextmenu@^8.2.0:
- version "8.3.13"
- resolved "https://registry.yarnpkg.com/mantine-contextmenu/-/mantine-contextmenu-8.3.13.tgz#f9194d806f29dae76dc5d6c63ab50c1e6b50d038"
- integrity sha512-Idbgaou23M18NxCnPfC1A5l6ShS43UbYwJ4u5z6N30HRXXzUPe479/v50H/UfTZQUbBsrl+qnaYjogIvU3boog==
+mantine-contextmenu@^9.2.1:
+ version "9.2.1"
+ resolved "https://registry.yarnpkg.com/mantine-contextmenu/-/mantine-contextmenu-9.2.1.tgz#d1d4dab0ca1eeaba7f1bba6cf2cad8cf31636709"
+ integrity sha512-oqFPT9qOQBPgf2eSuiujGQp38QgV0WsIIMxQkPfkjVc8FWAKcnXv7OGxGN1ctRrcMqUbsS34rjI0SvNdmFwG8A==
-mantine-datatable@^8.2.0:
- version "8.3.13"
- resolved "https://registry.yarnpkg.com/mantine-datatable/-/mantine-datatable-8.3.13.tgz#7bbb2878a5ead7cb6e61996f0f03335718107d69"
- integrity sha512-MQ7FNSyKCPeijiWHSeVmFU38m7MgHkomOm/VXm1XFpCAjVxdK8ZCVHGA2e5GK/dIkPX9Sdiwt812YDOhchPiHQ==
+mantine-datatable@^9.2.0:
+ version "9.2.0"
+ resolved "https://registry.yarnpkg.com/mantine-datatable/-/mantine-datatable-9.2.0.tgz#936f2307462d5420dc1ba7b520ae825dc6b2d97c"
+ integrity sha512-TK6SZ6dH/PQUedfhkJuSLMcd4P4m5L6kMJWfAF9cS4wBeoAtBWGpLs+n/E8yI6w1rYAtLsGQvFA6S9Xnfw0JFw==
marked@^4.1.0:
version "4.3.0"
@@ -4367,7 +4367,7 @@ react-is@^19.2.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.4.tgz#a080758243c572ccd4a63386537654298c99d135"
integrity sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==
-react-number-format@^5.4.4:
+react-number-format@^5.4.5:
version "5.4.5"
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.5.tgz#5855f2ae4e4153e6231d3a36b635c38be6824c8a"
integrity sha512-y8O2yHHj3w0aE9XO8d2BCcUOOdQTRSVq+WIuMlLVucAm5XNjJAy+BoOJiuQMldVYVOKTMyvVNfnbl2Oqp+YxGw==
@@ -4393,7 +4393,7 @@ react-remove-scroll-bar@^2.3.7:
react-style-singleton "^2.2.2"
tslib "^2.0.0"
-react-remove-scroll@^2.7.1:
+react-remove-scroll@^2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz#6442da56791117661978ae99cd29be9026fecca0"
integrity sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==
@@ -4457,15 +4457,6 @@ react-style-singleton@^2.2.2, react-style-singleton@^2.2.3:
get-nonce "^1.0.0"
tslib "^2.0.0"
-react-textarea-autosize@8.5.9:
- version "8.5.9"
- resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz#ab8627b09aa04d8a2f45d5b5cd94c84d1d4a8893"
- integrity sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==
- dependencies:
- "@babel/runtime" "^7.20.13"
- use-composed-ref "^1.3.0"
- use-latest "^1.2.1"
-
react-transition-group@4.4.5, react-transition-group@^4.3.0:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
@@ -4928,6 +4919,11 @@ tabbable@^6.0.0:
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.4.0.tgz#36eb7a06d80b3924a22095daf45740dea3bf5581"
integrity sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==
+tagged-tag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/tagged-tag/-/tagged-tag-1.0.0.tgz#a0b5917c2864cba54841495abfa3f6b13edcf4d6"
+ integrity sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==
+
test-exclude@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-8.0.0.tgz#85891add3fa46bb822b1b1579c7f8c9a3d04ebd8"
@@ -4991,10 +4987,12 @@ type-fest@^0.8.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
-type-fest@^4.41.0:
- version "4.41.0"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58"
- integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==
+type-fest@^5.6.0:
+ version "5.6.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-5.6.0.tgz#502f7a003b7309e96a7e17052cc2ab2c7e5c7a31"
+ integrity sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==
+ dependencies:
+ tagged-tag "^1.0.0"
typedarray-to-buffer@^3.1.5:
version "3.1.5"
@@ -5066,23 +5064,11 @@ use-callback-ref@^1.3.3:
dependencies:
tslib "^2.0.0"
-use-composed-ref@^1.3.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.4.0.tgz#09e023bf798d005286ad85cd20674bdf5770653b"
- integrity sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==
-
-use-isomorphic-layout-effect@^1.1.1, use-isomorphic-layout-effect@^1.2.0:
+use-isomorphic-layout-effect@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz#2f11a525628f56424521c748feabc2ffcc962fce"
integrity sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==
-use-latest@^1.2.1:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.3.0.tgz#549b9b0d4c1761862072f0899c6f096eb379137a"
- integrity sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==
- dependencies:
- use-isomorphic-layout-effect "^1.1.1"
-
use-sidecar@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb"