2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-10-31 13:15:43 +00:00

[UI] More actions (#10719)

* Add more spotlight actions:

- Open user settings
- Open system settings

* Add some actions

* Multiple attempts in test code
This commit is contained in:
Oliver
2025-10-30 22:05:55 +11:00
committed by GitHub
parent ec9b6e7f84
commit 62440893c1
3 changed files with 160 additions and 70 deletions

View File

@@ -56,7 +56,7 @@ export default function LayoutComponent() {
setActions(defaultActions); setActions(defaultActions);
setCustomActions(false); setCustomActions(false);
} }
}, [location]); }, [customActions, defaultActions, location]);
return ( return (
<ProtectedRoute> <ProtectedRoute>

View File

@@ -1,11 +1,22 @@
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import type { SpotlightActionData } from '@mantine/spotlight'; import type { SpotlightActionData } from '@mantine/spotlight';
import { IconBarcode, IconLink, IconPointer } from '@tabler/icons-react'; import {
IconBarcode,
IconLink,
IconPointer,
IconSettings,
IconUserBolt,
IconUserCog
} from '@tabler/icons-react';
import type { NavigateFunction } from 'react-router-dom'; import type { NavigateFunction } from 'react-router-dom';
import { ModelInformationDict } from '@lib/enums/ModelInformation';
import { UserRoles } from '@lib/index';
import { openContextModal } from '@mantine/modals'; import { openContextModal } from '@mantine/modals';
import { useMemo } from 'react';
import { useShallow } from 'zustand/react/shallow'; import { useShallow } from 'zustand/react/shallow';
import { useLocalState } from '../states/LocalState'; import { useLocalState } from '../states/LocalState';
import { useGlobalSettingsState } from '../states/SettingsStates';
import { useUserState } from '../states/UserState'; import { useUserState } from '../states/UserState';
import { aboutInvenTree, docLinks, licenseInfo, serverInfo } from './links'; import { aboutInvenTree, docLinks, licenseInfo, serverInfo } from './links';
@@ -20,9 +31,11 @@ export function getActions(navigate: NavigateFunction) {
const setNavigationOpen = useLocalState( const setNavigationOpen = useLocalState(
useShallow((state) => state.setNavigationOpen) useShallow((state) => state.setNavigationOpen)
); );
const { user } = useUserState(); const globalSettings = useGlobalSettingsState();
const user = useUserState();
const actions: SpotlightActionData[] = [ const actions: SpotlightActionData[] = useMemo(() => {
const _actions: SpotlightActionData[] = [
{ {
id: 'dashboard', id: 'dashboard',
label: t`Dashboard`, label: t`Dashboard`,
@@ -73,18 +86,78 @@ export function getActions(navigate: NavigateFunction) {
description: t`Scan a barcode or QR code`, description: t`Scan a barcode or QR code`,
onClick: () => openQrModal(navigate), onClick: () => openQrModal(navigate),
leftSection: <IconBarcode size='1.2rem' /> leftSection: <IconBarcode size='1.2rem' />
},
{
id: 'user-settings',
label: t`User Settings`,
description: t`Go to your user settings`,
onClick: () => navigate('/settings/user'),
leftSection: <IconUserCog size='1.2rem' />
} }
]; ];
// Staff actions // Page Actions
user?.is_staff && user?.hasViewRole(UserRoles.purchase_order) &&
actions.push({ _actions.push({
id: 'purchase-orders',
label: t`Purchase Orders`,
description: t`Go to Purchase Orders`,
onClick: () =>
navigate(ModelInformationDict['purchaseorder'].url_overview!),
leftSection: <IconLink size='1.2rem' />
});
user?.hasViewRole(UserRoles.sales_order) &&
_actions.push({
id: 'sales-orders',
label: t`Sales Orders`,
description: t`Go to Sales Orders`,
onClick: () =>
navigate(ModelInformationDict['salesorder'].url_overview!),
leftSection: <IconLink size='1.2rem' />
});
globalSettings.isSet('RETURNORDER_ENABLED') &&
user?.hasViewRole(UserRoles.return_order) &&
_actions.push({
id: 'return-orders',
label: t`Return Orders`,
description: t`Go to Return Orders`,
onClick: () =>
navigate(ModelInformationDict['returnorder'].url_overview!),
leftSection: <IconLink size='1.2rem' />
});
user?.hasViewRole(UserRoles.build) &&
_actions.push({
id: 'builds',
label: t`Build Orders`,
description: t`Go to Build Orders`,
onClick: () => navigate(ModelInformationDict['build'].url_overview!),
leftSection: <IconLink size='1.2rem' />
});
user?.isStaff() &&
_actions.push({
id: 'system-settings',
label: t`System Settings`,
description: t`Go to System Settings`,
onClick: () => navigate('/settings/system'),
leftSection: <IconSettings size='1.2rem' />
});
user?.isStaff() &&
_actions.push({
id: 'admin-center', id: 'admin-center',
label: t`Admin Center`, label: t`Admin Center`,
description: t`Go to the Admin Center`, description: t`Go to the Admin Center`,
onClick: () => {}, /// navigate(menuItems['settings-admin'].link),} onClick: () => {}, /// navigate(menuItems['settings-admin'].link),}
leftSection: <IconLink size='1.2rem' /> leftSection: <IconUserBolt size='1.2rem' />
}); });
return _actions;
}, [navigate, setNavigationOpen, globalSettings, user]);
return actions; return actions;
} }

View File

@@ -336,12 +336,29 @@ test('Settings - Admin - Barcode History', async ({ browser }) => {
for (let i = 0; i < barcodes.length; i++) { for (let i = 0; i < barcodes.length; i++) {
const barcode = barcodes[i]; const barcode = barcodes[i];
await api.post('barcode/', {
let attempts = 5;
while (attempts > 0) {
let result = false;
await api
.post('barcode/', {
data: { data: {
barcode: barcode barcode: barcode
}, },
timeout: 5000 timeout: 5000
})
.then(() => {
result = true;
}); });
if (result) {
break;
} else {
attempts -= 1;
}
}
} }
await page.getByRole('button', { name: 'admin' }).click(); await page.getByRole('button', { name: 'admin' }).click();