[PUI] Add image based QR code assigment (#7960)

* Add Link/Unlink Barcode action
Fixes #7920

* remove unneeded imports

* remove duplication

* simplify

* add testing

* refactor type

* wait for reload to add coverage

* Add warning if custom barcode is used

* Add Image based assign

* fix action button size

* fix selection to prevent wrapping

* use left section for button
This commit is contained in:
Matthias Mair 2024-08-27 09:25:34 +02:00 committed by GitHub
parent 594c15b3e3
commit 313cb4758e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 6 deletions

View File

@ -1,9 +1,12 @@
import { Trans, t } from '@lingui/macro';
import {
ActionIcon,
Alert,
Box,
Button,
Code,
Divider,
Flex,
Group,
Image,
Select,
@ -12,13 +15,17 @@ import {
Text,
TextInput
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { modals } from '@mantine/modals';
import { IconQrcode } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import QR from 'qrcode';
import { useEffect, useMemo, useState } from 'react';
import { set } from 'react-hook-form';
import { api } from '../../App';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { InputImageBarcode, ScanItem } from '../../pages/Index/Scan';
import { apiUrl } from '../../states/ApiState';
import { useGlobalSettingsState } from '../../states/SettingsState';
import { CopyButton } from '../buttons/CopyButton';
@ -142,27 +149,47 @@ export const InvenTreeQRCode = ({
export const QRCodeLink = ({ mdl_prop }: { mdl_prop: QrCodeType }) => {
const [barcode, setBarcode] = useState('');
const [isScanning, toggleIsScanning] = useDisclosure(false);
function linkBarcode() {
function linkBarcode(value?: string) {
api
.post(apiUrl(ApiEndpoints.barcode_link), {
[mdl_prop.model]: mdl_prop.pk,
barcode: barcode
barcode: value || barcode
})
.then((response) => {
modals.closeAll();
location.reload();
});
}
const actionSubmit = (data: ScanItem[]) => {
linkBarcode(data[0].data);
};
return (
<Box>
{isScanning ? (
<>
<InputImageBarcode action={actionSubmit} />
<Divider />
</>
) : null}
<TextInput
label={t`Barcode`}
value={barcode}
onChange={(event) => setBarcode(event.currentTarget.value)}
placeholder={t`Scan barcode data here using barcode scanner`}
leftSection={
<ActionIcon
variant="subtle"
onClick={toggleIsScanning.toggle}
size="input-sm"
>
<IconQrcode />
</ActionIcon>
}
w="100%"
/>
<Button color="green" onClick={linkBarcode} mt="lg" fullWidth>
<Button color="green" onClick={() => linkBarcode()} mt="lg" fullWidth>
<Trans>Link</Trans>
</Button>
</Box>

View File

@ -55,7 +55,7 @@ import { notYetImplemented } from '../../functions/notifications';
import { IS_DEV_OR_DEMO } from '../../main';
import { apiUrl } from '../../states/ApiState';
interface ScanItem {
export interface ScanItem {
id: string;
ref: string;
data: any;
@ -545,7 +545,7 @@ function InputManual({ action }: Readonly<ScanInputInterface>) {
}
/* Input that uses QR code detection from images */
function InputImageBarcode({ action }: Readonly<ScanInputInterface>) {
export function InputImageBarcode({ action }: Readonly<ScanInputInterface>) {
const [qrCodeScanner, setQrCodeScanner] = useState<Html5Qrcode | null>(null);
const [camId, setCamId] = useLocalStorage<CameraDevice | null>({
key: 'camId',
@ -714,17 +714,19 @@ function InputImageBarcode({ action }: Readonly<ScanInputInterface>) {
return (
<Stack gap="xs">
<Group gap="xs">
<Group gap="xs" preventGrowOverflow>
<Select
value={cameraValue}
onChange={setCameraValue}
data={cameras.map((device) => {
return { value: device.id, label: device.label };
})}
maw={200}
size="sm"
/>
{scanningEnabled ? (
<ActionIcon
size="input-sm"
onClick={btnStopScanning}
title={t`Stop scanning`}
variant="default"
@ -733,6 +735,7 @@ function InputImageBarcode({ action }: Readonly<ScanInputInterface>) {
</ActionIcon>
) : (
<ActionIcon
size="input-sm"
onClick={btnStartScanning}
title={t`Start scanning`}
disabled={!camId}