[UI] Panel indicator badges (#11956)

* Refactor panel indicator dots

- Allow indicator status to be fetched async

* Add indicator dot for attachments

* Support parameters panel

* Refactor

- Expose more types to @lib
- Define new PanelIndicatorType type
- Support old interface
This commit is contained in:
Oliver 2026-05-17 10:58:23 +10:00 committed by GitHub
parent d732f35e5c
commit c09848422c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 179 additions and 77 deletions

View File

@ -21,6 +21,12 @@ export type {
StockAdjustmentFormsContext
} from './types/Plugins';
export type {
PanelIndicatorType,
PanelType,
PanelGroupType
} from './types/Panel';
export type {
RowAction,
RowViewProps,

View File

@ -1,5 +1,8 @@
import type { ReactNode } from 'react';
// The type of indicator dot to be shown against a panel
export type PanelIndicatorType = 'info' | 'warning' | 'danger' | null;
/**
* Type used to specify a single panel in a panel group
*/
@ -8,7 +11,7 @@ export type PanelType = {
label: string;
controls?: ReactNode;
icon?: ReactNode;
notification_dot?: 'info' | 'warning' | 'danger' | null;
notification_dot?: PanelIndicatorType | (() => Promise<PanelIndicatorType>);
content?: ReactNode;
hidden?: boolean;
disabled?: boolean;
@ -16,6 +19,9 @@ export type PanelType = {
supportsDirty?: boolean;
};
/**
* Type used to specify a group of panels
*/
export type PanelGroupType = {
id: string;
label: string;

View File

@ -3,8 +3,10 @@ import { Skeleton } from '@mantine/core';
import { IconPaperclip } from '@tabler/icons-react';
import type { ModelType } from '@lib/enums/ModelType';
import { ApiEndpoints, apiUrl } from '@lib/index';
import type { PanelType } from '@lib/types/Panel';
import { api } from '../../App';
import { AttachmentTable } from '../../tables/general/AttachmentTable';
import type { PanelType } from './Panel';
export default function AttachmentPanel({
model_type,
@ -17,6 +19,21 @@ export default function AttachmentPanel({
name: 'attachments',
label: t`Attachments`,
icon: <IconPaperclip />,
notification_dot: async () => {
if (!model_type || !model_id) {
return null;
}
return api
.get(apiUrl(ApiEndpoints.attachment_list), {
params: {
model_type: model_type,
model_id: model_id,
limit: 1
}
})
.then((response) => ((response.data?.count ?? 0) > 0 ? 'info' : null));
},
content:
model_type && model_id ? (
<AttachmentTable model_type={model_type} model_id={model_id} />

View File

@ -3,9 +3,9 @@ import { Skeleton } from '@mantine/core';
import { IconNotes } from '@tabler/icons-react';
import type { ModelType } from '@lib/enums/ModelType';
import type { PanelType } from '@lib/types/Panel';
import { lazy } from 'react';
import { useUserState } from '../../states/UserState';
import type { PanelType } from './Panel';
const NotesEditor = lazy(() => import('../editors/NotesEditor'));

View File

@ -5,6 +5,7 @@ import {
Group,
Indicator,
Loader,
type MantineColor,
Paper,
Stack,
Tabs,
@ -39,14 +40,19 @@ import { identifierString } from '@lib/functions/Conversion';
import { cancelEvent } from '@lib/functions/Events';
import { eventModified, getBaseUrl } from '@lib/functions/Navigation';
import { navigateToLink } from '@lib/functions/Navigation';
import type {
PanelGroupType,
PanelIndicatorType,
PanelType
} from '@lib/types/Panel';
import { t } from '@lingui/core/macro';
import { useWindowEvent } from '@mantine/hooks';
import { useDocumentVisibility, useWindowEvent } from '@mantine/hooks';
import { useQuery } from '@tanstack/react-query';
import { useShallow } from 'zustand/react/shallow';
import { generateUrl } from '../../functions/urls';
import { usePluginPanels } from '../../hooks/UsePluginPanels';
import { useLocalState } from '../../states/LocalState';
import { vars } from '../../theme';
import type { PanelGroupType, PanelType } from '../panels/Panel';
import * as classes from './PanelGroup.css';
/**
@ -79,6 +85,99 @@ export type PanelProps = {
pluginPanelKey?: PluginPanelKey;
};
/**
* Render a single panel tab within the side menu
*/
function PanelTabComponent({
expanded,
panel,
onClick
}: {
expanded: boolean;
panel: PanelType;
onClick: (event: any) => void;
}) {
const visibility = useDocumentVisibility();
// Check if we should display an indicator dot for this panel
const notificationDot = useQuery({
enabled: panel.notification_dot !== undefined && visibility === 'visible',
queryKey: ['panel-notification', panel.name],
queryFn: async () => {
if (panel.notification_dot === undefined) {
return null;
} else if (typeof panel.notification_dot === 'function') {
return await panel.notification_dot();
} else {
return panel.notification_dot as PanelIndicatorType;
}
},
staleTime: 5 * 60 * 1000, // cache for 5 minutes
refetchOnMount: false,
refetchOnWindowFocus: false
});
const indicatorColor: MantineColor | undefined = useMemo(() => {
switch (notificationDot.data) {
case 'info':
return 'blue';
case 'warning':
return 'yellow';
case 'danger':
return 'red';
default:
return undefined;
}
}, [notificationDot.data]);
return (
<Tooltip
label={panel.label ?? panel.name}
key={panel.name}
disabled={expanded}
position='right'
>
<Tabs.Tab
p='xs'
key={`panel-label-${panel.name}`}
w={'100%'}
value={panel.name}
leftSection={
<Indicator
position='top-end'
disabled={!indicatorColor}
color={indicatorColor}
withBorder
size={14}
>
{panel.icon}
</Indicator>
}
hidden={panel.hidden}
disabled={panel.disabled}
style={{
cursor: panel.disabled ? 'unset' : 'pointer'
}}
onClick={(event: any) => onClick(event)}
>
<Group justify='left' gap='xs' wrap='nowrap'>
<UnstyledButton
component={'a'}
style={{
textAlign: 'left'
}}
href={generateUrl(
`/${getBaseUrl()}${location.pathname}/${panel.name}`
)}
>
{expanded && panel.label}
</UnstyledButton>
</Group>
</Tabs.Tab>
</Tooltip>
);
}
function BasePanelGroup({
pageKey,
panels,
@ -269,54 +368,13 @@ function BasePanelGroup({
{group.panels?.map(
(panel) =>
!panel.hidden && (
<Tooltip
label={panel.label ?? panel.name}
key={panel.name}
disabled={expanded}
position='right'
>
<Tabs.Tab
p='xs'
key={`panel-label-${panel.name}`}
w={'100%'}
value={panel.name}
leftSection={panel.icon}
hidden={panel.hidden}
disabled={panel.disabled}
style={{
cursor: panel.disabled ? 'unset' : 'pointer'
}}
onClick={(event: any) =>
handlePanelChange(panel.name, event)
}
>
<Indicator
color={
panel.notification_dot == 'info'
? 'blue'
: panel.notification_dot == 'warning'
? 'yellow'
: 'red'
}
position='middle-end'
disabled={!panel.notification_dot}
>
<Group justify='left' gap='xs' wrap='nowrap'>
<UnstyledButton
component={'a'}
style={{
textAlign: 'left'
}}
href={generateUrl(
`/${getBaseUrl()}${location.pathname}/${panel.name}`
)}
>
{expanded && panel.label}
</UnstyledButton>
</Group>
</Indicator>
</Tabs.Tab>
</Tooltip>
<PanelTabComponent
expanded={expanded}
panel={panel}
onClick={(event: any) =>
handlePanelChange(panel.name, event)
}
/>
)
)}
</Box>

View File

@ -1,9 +1,12 @@
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import type { ModelType } from '@lib/enums/ModelType';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import { t } from '@lingui/core/macro';
import { Skeleton } from '@mantine/core';
import { IconListDetails } from '@tabler/icons-react';
import { api } from '../../App';
import { ParameterTable } from '../../tables/general/ParameterTable';
import type { PanelType } from './Panel';
export default function ParametersPanel({
model_type,
@ -21,6 +24,21 @@ export default function ParametersPanel({
label: t`Parameters`,
icon: <IconListDetails />,
hidden: hidden ?? false,
notification_dot: async () => {
if (!model_type || !model_id) {
return null;
}
return api
.get(apiUrl(ApiEndpoints.parameter_list), {
params: {
model_type: model_type,
model_id: model_id,
limit: 1
}
})
.then((response) => ((response.data?.count ?? 0) > 0 ? 'info' : null));
},
content:
model_type && model_id ? (
<ParameterTable

View File

@ -1,5 +1,5 @@
import type { PanelType } from '@lib/types/Panel';
import SegmentedIconControl from '../buttons/SegmentedIconControl';
import type { PanelType } from './Panel';
export type SegmentedControlPanelSelection = {
value: string;

View File

@ -4,10 +4,10 @@ import { useMemo } from 'react';
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import type { ModelType, PluginPanelKey } from '@lib/enums/ModelType';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import type { InvenTreePluginContext } from '@lib/types/Plugins';
import { api } from '../App';
import { ApiIcon } from '../components/items/ApiIcon';
import type { PanelType } from '../components/panels/Panel';
import { useInvenTreeContext } from '../components/plugins/PluginContext';
import PluginPanelContent from '../components/plugins/PluginPanel';
import {

View File

@ -24,13 +24,10 @@ import { lazy, useMemo } from 'react';
import { PluginPanelKey } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import type { PanelGroupType, PanelType } from '@lib/types/Panel';
import PermissionDenied from '../../../../components/errors/PermissionDenied';
import PageTitle from '../../../../components/nav/PageTitle';
import { SettingsHeader } from '../../../../components/nav/SettingsHeader';
import type {
PanelGroupType,
PanelType
} from '../../../../components/panels/Panel';
import { PanelGroup } from '../../../../components/panels/PanelGroup';
import { GlobalSettingList } from '../../../../components/settings/SettingList';
import { Loadable } from '../../../../functions/loading';

View File

@ -18,11 +18,11 @@ import {
import { lazy, useMemo } from 'react';
import { PluginPanelKey } from '@lib/enums/ModelType';
import type { PanelType } from '@lib/types/Panel';
import { useShallow } from 'zustand/react/shallow';
import PermissionDenied from '../../../components/errors/PermissionDenied';
import PageTitle from '../../../components/nav/PageTitle';
import { SettingsHeader } from '../../../components/nav/SettingsHeader';
import type { PanelType } from '../../../components/panels/Panel';
import { PanelGroup } from '../../../components/panels/PanelGroup';
import { GlobalSettingList } from '../../../components/settings/SettingList';
import { Loadable } from '../../../functions/loading';

View File

@ -12,10 +12,10 @@ import {
import { lazy, useMemo } from 'react';
import { PluginPanelKey } from '@lib/enums/ModelType';
import type { PanelType } from '@lib/types/Panel';
import { useShallow } from 'zustand/react/shallow';
import PageTitle from '../../../components/nav/PageTitle';
import { SettingsHeader } from '../../../components/nav/SettingsHeader';
import type { PanelType } from '../../../components/panels/Panel';
import { PanelGroup } from '../../../components/panels/PanelGroup';
import { UserSettingList } from '../../../components/settings/SettingList';
import { Loadable } from '../../../functions/loading';

View File

@ -22,6 +22,7 @@ import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { ApiFormFieldSet } from '@lib/types/Forms';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@ -44,7 +45,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { StatusRenderer } from '../../components/render/StatusRenderer';

View File

@ -11,11 +11,11 @@ import { useMemo } from 'react';
import { ModelType, PluginPanelKey } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import type { TableFilter } from '@lib/types/Filters';
import type { PanelType } from '@lib/types/Panel';
import { useLocalStorage } from '@mantine/hooks';
import OrderCalendar from '../../components/calendar/OrderCalendar';
import PermissionDenied from '../../components/errors/PermissionDenied';
import { PageDetail } from '../../components/nav/PageDetail';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import SegmentedControlPanel from '../../components/panels/SegmentedControlPanel';
import { useGlobalSettingsState } from '../../states/SettingsStates';

View File

@ -18,6 +18,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
import {
@ -37,7 +38,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { companyFields } from '../../forms/CompanyForms';

View File

@ -13,6 +13,7 @@ import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import {
type DetailsField,
@ -30,7 +31,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { useManufacturerPartFields } from '../../forms/CompanyForms';

View File

@ -15,6 +15,7 @@ import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { formatDecimal } from '@lib/functions/Formatting';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import {
type DetailsField,
@ -34,7 +35,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { useSupplierPartFields } from '../../forms/CompanyForms';

View File

@ -1,6 +1,7 @@
import { StylishText } from '@lib/components/StylishText';
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import type { PanelType } from '@lib/types/Panel';
import { t } from '@lingui/core/macro';
import { Paper, Skeleton, Stack } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
@ -15,7 +16,6 @@ import {} from '../../components/items/ActionDropdown';
import { RoleTable, type RuleSet } from '../../components/items/RoleTable';
import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import {} from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance';

View File

@ -1,5 +1,6 @@
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import type { PanelType } from '@lib/types/Panel';
import { t } from '@lingui/core/macro';
import { Badge, Group, Skeleton, Stack } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
@ -13,7 +14,6 @@ import { ItemDetailsGrid } from '../../components/details/ItemDetails';
import {} from '../../components/items/ActionDropdown';
import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import {} from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance';

View File

@ -16,6 +16,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { PanelType } from '@lib/types/Panel';
import { useLocalStorage } from '@mantine/hooks';
import AdminButton from '../../components/buttons/AdminButton';
import StarredToggleButton from '../../components/buttons/StarredToggleButton';
@ -33,7 +34,6 @@ import { ApiIcon } from '../../components/items/ApiIcon';
import InstanceDetail from '../../components/nav/InstanceDetail';
import NavigationTree from '../../components/nav/NavigationTree';
import { PageDetail } from '../../components/nav/PageDetail';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import SegmentedControlPanel from '../../components/panels/SegmentedControlPanel';
import { partCategoryFields } from '../../forms/PartForms';

View File

@ -44,6 +44,7 @@ import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { StockOperationProps } from '@lib/types/Forms';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
import StarredToggleButton from '../../components/buttons/StarredToggleButton';
@ -68,7 +69,6 @@ import NavigationTree from '../../components/nav/NavigationTree';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import { RenderPart } from '../../components/render/Part';
import OrderPartsWizard from '../../components/wizards/OrderPartsWizard';

View File

@ -9,6 +9,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@ -30,7 +31,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { StatusRenderer } from '../../components/render/StatusRenderer';

View File

@ -9,6 +9,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@ -30,7 +31,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { RenderAddress } from '../../components/render/Company';

View File

@ -15,6 +15,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@ -36,7 +37,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { RenderAddress } from '../../components/render/Company';

View File

@ -13,6 +13,7 @@ import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { PanelType } from '@lib/types/Panel';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@ -33,7 +34,6 @@ import InstanceDetail from '../../components/nav/InstanceDetail';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { RenderAddress } from '../../components/render/Company';

View File

@ -4,6 +4,7 @@ import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { StockOperationProps } from '@lib/types/Forms';
import type { PanelType } from '@lib/types/Panel';
import { t } from '@lingui/core/macro';
import { Group, Skeleton, Stack } from '@mantine/core';
import {
@ -34,7 +35,6 @@ import { ApiIcon } from '../../components/items/ApiIcon';
import InstanceDetail from '../../components/nav/InstanceDetail';
import NavigationTree from '../../components/nav/NavigationTree';
import { PageDetail } from '../../components/nav/PageDetail';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import SegmentedControlPanel from '../../components/panels/SegmentedControlPanel';

View File

@ -36,6 +36,7 @@ import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl, getOverviewUrl } from '@lib/functions/Navigation';
import type { ApiFormFieldSet, StockOperationProps } from '@lib/types/Forms';
import type { PanelType } from '@lib/types/Panel';
import { notifications } from '@mantine/notifications';
import { useBarcodeScanDialog } from '../../components/barcodes/BarcodeScanDialog';
import AdminButton from '../../components/buttons/AdminButton';
@ -60,7 +61,6 @@ import NavigationTree from '../../components/nav/NavigationTree';
import { PageDetail } from '../../components/nav/PageDetail';
import AttachmentPanel from '../../components/panels/AttachmentPanel';
import NotesPanel from '../../components/panels/NotesPanel';
import type { PanelType } from '../../components/panels/Panel';
import { PanelGroup } from '../../components/panels/PanelGroup';
import LocateItemButton from '../../components/plugins/LocateItemButton';
import { StatusRenderer } from '../../components/render/StatusRenderer';