2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-01 21:16:46 +00:00

Add scan to action menu (#8781)

* small style fixes

* refactor: split scanning and dialog logic

* feat: Add modal and quick action to scan a barcode from anywhere
This commit is contained in:
Matthias Mair 2024-12-28 15:12:42 +01:00 committed by GitHub
parent 3e73162368
commit c582ca0afd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 63 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import { t } from '@lingui/macro';
import { Box, Divider, Modal } from '@mantine/core';
import { useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { type NavigateFunction, useNavigate } from 'react-router-dom';
import { api } from '../../App';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import type { ModelType } from '../../enums/ModelType';
@ -17,17 +17,34 @@ export default function BarcodeScanDialog({
title,
opened,
onClose
}: {
}: Readonly<{
title?: string;
opened: boolean;
onClose: () => void;
}) {
}>) {
const navigate = useNavigate();
const user = useUserState();
return (
<Modal
size='lg'
opened={opened}
onClose={onClose}
title={<StylishText size='xl'>{title ?? t`Scan Barcode`}</StylishText>}
>
<Divider />
<Box>
<ScanInputHandler navigate={navigate} onClose={onClose} />
</Box>
</Modal>
);
}
export function ScanInputHandler({
onClose,
navigate
}: Readonly<{ onClose: () => void; navigate: NavigateFunction }>) {
const [error, setError] = useState<string>('');
const [processing, setProcessing] = useState<boolean>(false);
const user = useUserState();
const onScan = useCallback((barcode: string) => {
if (!barcode || barcode.length === 0) {
@ -80,19 +97,5 @@ export default function BarcodeScanDialog({
});
}, []);
return (
<>
<Modal
size='lg'
opened={opened}
onClose={onClose}
title={<StylishText size='xl'>{title ?? t`Scan Barcode`}</StylishText>}
>
<Divider />
<Box>
<BarcodeInput onScan={onScan} error={error} processing={processing} />
</Box>
</Modal>
</>
);
return <BarcodeInput onScan={onScan} error={error} processing={processing} />;
}

View File

@ -0,0 +1,21 @@
import {} from '@mantine/core';
import type { ContextModalProps } from '@mantine/modals';
import type { NavigateFunction } from 'react-router-dom';
import { ScanInputHandler } from '../barcodes/BarcodeScanDialog';
export function QrModal({
context,
id,
innerProps
}: Readonly<
ContextModalProps<{ modalBody: string; navigate: NavigateFunction }>
>) {
function close() {
context.closeModal(id);
}
function navigate() {
context.closeModal(id);
}
return <ScanInputHandler navigate={innerProps.navigate} onClose={close} />;
}

View File

@ -6,6 +6,7 @@ import { ContextMenuProvider } from 'mantine-contextmenu';
import { AboutInvenTreeModal } from '../components/modals/AboutInvenTreeModal';
import { LicenseModal } from '../components/modals/LicenseModal';
import { QrModal } from '../components/modals/QrModal';
import { ServerInfoModal } from '../components/modals/ServerInfoModal';
import { useLocalState } from '../states/LocalState';
import { LanguageContext } from './LanguageContext';
@ -47,7 +48,8 @@ export function ThemeContext({
modals={{
info: ServerInfoModal,
about: AboutInvenTreeModal,
license: LicenseModal
license: LicenseModal,
qr: QrModal
}}
>
<Notifications />

View File

@ -1,12 +1,20 @@
import { t } from '@lingui/macro';
import type { SpotlightActionData } from '@mantine/spotlight';
import { IconLink, IconPointer } from '@tabler/icons-react';
import { IconBarcode, IconLink, IconPointer } from '@tabler/icons-react';
import type { NavigateFunction } from 'react-router-dom';
import { openContextModal } from '@mantine/modals';
import { useLocalState } from '../states/LocalState';
import { useUserState } from '../states/UserState';
import { aboutInvenTree, docLinks, licenseInfo, serverInfo } from './links';
export function openQrModal(navigate: NavigateFunction) {
return openContextModal({
modal: 'qr',
innerProps: { navigate: navigate }
});
}
export function getActions(navigate: NavigateFunction) {
const setNavigationOpen = useLocalState((state) => state.setNavigationOpen);
const { user } = useUserState();
@ -55,6 +63,13 @@ export function getActions(navigate: NavigateFunction) {
description: t`Open the main navigation menu`,
onClick: () => setNavigationOpen(true),
leftSection: <IconPointer size='1.2rem' />
},
{
id: 'scan',
label: t`Scan`,
description: t`Scan a barcode or QR code`,
onClick: () => openQrModal(navigate),
leftSection: <IconBarcode size='1.2rem' />
}
];