mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-17 23:08:28 +00:00
[UI] Mantine 9 (#11947)
* Update mantine deps * Get it to compile * Update QueryCount widgets - use new RollingNumber component * Table updates - Remove "hack" for column ordering * "Fix" the column pinning bug (maybe?) * Fix ColumnRenderers.tsx * Fix login code for playwright * Remove hashing requirement * Fix build tests * More fixes * More test fixes * Fix playwright test for dashboard item * Update frontend version * Update changelog * Reduce query repeats * More playwright fixes * Further playwright fixes * Fix for useFilterSet hook * Fix unique key error * Fix rendering issues when opening edit forms * reduce console errors * Fix unique key issues in search drawer * Update frontend CHANGELOG.md * More form tweaks --------- Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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'
|
||||
>
|
||||
<IconDots />
|
||||
</ActionIcon>
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -100,7 +100,7 @@ export type TableState = {
|
||||
*/
|
||||
export type TableColumnProps<T = any> = {
|
||||
accessor?: string;
|
||||
title?: string;
|
||||
title?: string | ReactNode;
|
||||
ordering?: string;
|
||||
sortable?: boolean;
|
||||
switchable?: boolean;
|
||||
|
||||
+14
-14
@@ -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",
|
||||
|
||||
@@ -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<number>(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 <Loader size='xs' />;
|
||||
} else if (query.isError) {
|
||||
if (query.isError) {
|
||||
return (
|
||||
<ActionIcon color='red' variant='transparent' size='lg'>
|
||||
<IconExclamationCircle />
|
||||
</ActionIcon>
|
||||
);
|
||||
} else {
|
||||
return <StylishText size='xl'>{query.data?.count ?? '-'}</StylishText>;
|
||||
return <RollingNumber value={count} fz='20px' />;
|
||||
}
|
||||
}, [query.isFetching, query.isError, query.data]);
|
||||
}, [query.isFetching, query.isError, count]);
|
||||
|
||||
return (
|
||||
<Anchor href='#' onClick={onFollowLink} underline='never'>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,7 +48,10 @@ export function PageDetail({
|
||||
useHotkeys([
|
||||
[
|
||||
'mod+E',
|
||||
() => {
|
||||
(event) => {
|
||||
if (event.repeat) {
|
||||
return;
|
||||
}
|
||||
if (editEnabled ?? true) {
|
||||
editAction?.();
|
||||
}
|
||||
|
||||
@@ -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({
|
||||
<Accordion.Panel>
|
||||
<Stack gap={'xs'} aria-label={`search-group-results-${query.model}`}>
|
||||
{query.results.results.map((result: any, index: number) => (
|
||||
<>
|
||||
<Fragment key={`result-group-${query.model}-${result.pk}`}>
|
||||
<Anchor
|
||||
underline='never'
|
||||
href={getDetailUrl(query.model, result.pk, true)}
|
||||
@@ -184,7 +184,7 @@ function QueryResultGroup({
|
||||
key={`divider-${query.model}-${result.pk}`}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
</Stack>
|
||||
</Accordion.Panel>
|
||||
|
||||
@@ -370,6 +370,7 @@ function BasePanelGroup({
|
||||
(panel) =>
|
||||
!panel.hidden && (
|
||||
<PanelTabComponent
|
||||
key={`panel-tab-${group.id}-${panel.name}`}
|
||||
expanded={expanded}
|
||||
panel={panel}
|
||||
onClick={(event: any) =>
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -8,17 +8,15 @@ export function AccountContent() {
|
||||
const SECONDARY_COL_HEIGHT = PRIMARY_COL_HEIGHT / 2 - 8;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }} spacing='md'>
|
||||
<Container w='100%'>
|
||||
<AccountDetailPanel />
|
||||
</Container>
|
||||
<Grid gutter='md'>
|
||||
<Grid.Col>
|
||||
<UserTheme height={SECONDARY_COL_HEIGHT} />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</SimpleGrid>
|
||||
</div>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }} spacing='md'>
|
||||
<Container w='100%'>
|
||||
<AccountDetailPanel />
|
||||
</Container>
|
||||
<Grid gap='md'>
|
||||
<Grid.Col>
|
||||
<UserTheme height={SECONDARY_COL_HEIGHT} />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</SimpleGrid>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ export function PathColumn(props: TableColumnProps): TableColumn {
|
||||
<TableHoverCard
|
||||
value={<Text size='sm'>{instance.name}</Text>}
|
||||
icon='sitemap'
|
||||
title={props.title}
|
||||
title={props.title?.toLocaleString() ?? t`Path`}
|
||||
extra={[<Text size='sm'>{instance.pathstring}</Text>]}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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<T extends Record<string, any>>({
|
||||
[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<string>('');
|
||||
|
||||
// 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<T extends Record<string, any>>({
|
||||
if (tableProps.rowActions) {
|
||||
cols.push({
|
||||
accessor: ACTIONS_COLUMN_ACCESSOR,
|
||||
title: ' ',
|
||||
title: (
|
||||
<ActionIcon variant='transparent' size='sm'>
|
||||
<IconClick />
|
||||
</ActionIcon>
|
||||
),
|
||||
hidden: false,
|
||||
resizable: false,
|
||||
switchable: false,
|
||||
@@ -350,13 +347,6 @@ export function InvenTreeTableInternal<T extends Record<string, any>>({
|
||||
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<T extends Record<string, any>>({
|
||||
[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(() => {
|
||||
|
||||
@@ -122,6 +122,9 @@ function OutputAllocationDrawer({
|
||||
opened={opened}
|
||||
onClose={close}
|
||||
withCloseButton
|
||||
closeButtonProps={{
|
||||
'aria-label': 'close-allocation-drawer'
|
||||
}}
|
||||
closeOnEscape
|
||||
closeOnClickOutside
|
||||
styles={{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' })
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
+79
-93
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user