mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-01 21:16:46 +00:00
[PUI] fix a few sonarcloud warnings (#8133)
* fix a few code issues * fix common sonarcloud issues * more small fixes
This commit is contained in:
parent
45aab46db3
commit
7c937fa283
@ -4,7 +4,7 @@ import { ErrorBoundary, FallbackRender } from '@sentry/react';
|
|||||||
import { IconExclamationCircle } from '@tabler/icons-react';
|
import { IconExclamationCircle } from '@tabler/icons-react';
|
||||||
import { ReactNode, useCallback } from 'react';
|
import { ReactNode, useCallback } from 'react';
|
||||||
|
|
||||||
function DefaultFallback({ title }: { title: String }): ReactNode {
|
function DefaultFallback({ title }: Readonly<{ title: string }>): ReactNode {
|
||||||
return (
|
return (
|
||||||
<Alert
|
<Alert
|
||||||
color="red"
|
color="red"
|
||||||
@ -20,11 +20,11 @@ export function Boundary({
|
|||||||
children,
|
children,
|
||||||
label,
|
label,
|
||||||
fallback
|
fallback
|
||||||
}: {
|
}: Readonly<{
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
label: string;
|
label: string;
|
||||||
fallback?: React.ReactElement | FallbackRender | undefined;
|
fallback?: React.ReactElement | FallbackRender;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
const onError = useCallback(
|
const onError = useCallback(
|
||||||
(error: unknown, componentStack: string | undefined, eventId: string) => {
|
(error: unknown, componentStack: string | undefined, eventId: string) => {
|
||||||
console.error(`Error rendering component: ${label}`);
|
console.error(`Error rendering component: ${label}`);
|
||||||
|
@ -22,7 +22,7 @@ export type AdminButtonProps = {
|
|||||||
* - The user has "superuser" role
|
* - The user has "superuser" role
|
||||||
* - The user has at least read rights for the selected item
|
* - The user has at least read rights for the selected item
|
||||||
*/
|
*/
|
||||||
export default function AdminButton(props: AdminButtonProps) {
|
export default function AdminButton(props: Readonly<AdminButtonProps>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
const enabled: boolean = useMemo(() => {
|
const enabled: boolean = useMemo(() => {
|
||||||
|
@ -12,14 +12,14 @@ export default function PrimaryActionButton({
|
|||||||
color,
|
color,
|
||||||
hidden,
|
hidden,
|
||||||
onClick
|
onClick
|
||||||
}: {
|
}: Readonly<{
|
||||||
title: string;
|
title: string;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
icon?: InvenTreeIconType;
|
icon?: InvenTreeIconType;
|
||||||
color?: string;
|
color?: string;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
}) {
|
}>) {
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ import { ActionButton } from './ActionButton';
|
|||||||
export default function RemoveRowButton({
|
export default function RemoveRowButton({
|
||||||
onClick,
|
onClick,
|
||||||
tooltip = t`Remove this row`
|
tooltip = t`Remove this row`
|
||||||
}: {
|
}: Readonly<{
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
}) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<ActionButton
|
<ActionButton
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
@ -7,14 +7,14 @@ export function PassFailButton({
|
|||||||
value,
|
value,
|
||||||
passText,
|
passText,
|
||||||
failText
|
failText
|
||||||
}: {
|
}: Readonly<{
|
||||||
value: any;
|
value: any;
|
||||||
passText?: string;
|
passText?: string;
|
||||||
failText?: string;
|
failText?: string;
|
||||||
}) {
|
}>) {
|
||||||
const v = isTrue(value);
|
const v = isTrue(value);
|
||||||
const pass = passText || t`Pass`;
|
const pass = passText ?? t`Pass`;
|
||||||
const fail = failText || t`Fail`;
|
const fail = failText ?? t`Fail`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge
|
<Badge
|
||||||
@ -29,11 +29,11 @@ export function PassFailButton({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function YesNoButton({ value }: { value: any }) {
|
export function YesNoButton({ value }: Readonly<{ value: any }>) {
|
||||||
return <PassFailButton value={value} passText={t`Yes`} failText={t`No`} />;
|
return <PassFailButton value={value} passText={t`Yes`} failText={t`No`} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function YesNoUndefinedButton({ value }: { value?: boolean }) {
|
export function YesNoUndefinedButton({ value }: Readonly<{ value?: boolean }>) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
return <Skeleton height={15} width={32} />;
|
return <Skeleton height={15} width={32} />;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
// import SimpleMDE from "react-simplemde-editor";
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { useMantineColorScheme } from '@mantine/core';
|
|
||||||
import { notifications } from '@mantine/notifications';
|
import { notifications } from '@mantine/notifications';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import EasyMDE, { default as SimpleMde } from 'easymde';
|
import EasyMDE, { default as SimpleMde } from 'easymde';
|
||||||
@ -60,13 +58,11 @@ export default function NotesEditor({
|
|||||||
modelType,
|
modelType,
|
||||||
modelId,
|
modelId,
|
||||||
editable
|
editable
|
||||||
}: {
|
}: Readonly<{
|
||||||
modelType: ModelType;
|
modelType: ModelType;
|
||||||
modelId: number;
|
modelId: number;
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
}) {
|
}>) {
|
||||||
const { colorScheme } = useMantineColorScheme();
|
|
||||||
|
|
||||||
// In addition to the editable prop, we also need to check if the user has "enabled" editing
|
// In addition to the editable prop, we also need to check if the user has "enabled" editing
|
||||||
const [editing, setEditing] = useState<boolean>(false);
|
const [editing, setEditing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import NotAuthenticated from './NotAuthenticated';
|
|||||||
import NotFound from './NotFound';
|
import NotFound from './NotFound';
|
||||||
import PermissionDenied from './PermissionDenied';
|
import PermissionDenied from './PermissionDenied';
|
||||||
|
|
||||||
export default function ClientError({ status }: { status?: number }) {
|
export default function ClientError({ status }: Readonly<{ status?: number }>) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 401:
|
case 401:
|
||||||
return <NotAuthenticated />;
|
return <NotAuthenticated />;
|
||||||
|
@ -19,13 +19,13 @@ export default function ErrorPage({
|
|||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
status
|
status
|
||||||
}: {
|
}: Readonly<{
|
||||||
title: string;
|
title: string;
|
||||||
message: string;
|
message: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
redirectMessage?: string;
|
redirectMessage?: string;
|
||||||
redirectTarget?: string;
|
redirectTarget?: string;
|
||||||
}) {
|
}>) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Select } from '@mantine/core';
|
import { Select } from '@mantine/core';
|
||||||
import { useId } from '@mantine/hooks';
|
import { useId } from '@mantine/hooks';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { FieldValues, UseControllerReturn } from 'react-hook-form';
|
import { FieldValues, UseControllerReturn } from 'react-hook-form';
|
||||||
|
|
||||||
import { ApiFormFieldType } from './ApiFormField';
|
import { ApiFormFieldType } from './ApiFormField';
|
||||||
@ -12,11 +12,11 @@ export function ChoiceField({
|
|||||||
controller,
|
controller,
|
||||||
definition,
|
definition,
|
||||||
fieldName
|
fieldName
|
||||||
}: {
|
}: Readonly<{
|
||||||
controller: UseControllerReturn<FieldValues, any>;
|
controller: UseControllerReturn<FieldValues, any>;
|
||||||
definition: ApiFormFieldType;
|
definition: ApiFormFieldType;
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
}) {
|
}>) {
|
||||||
const fieldId = useId();
|
const fieldId = useId();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -18,13 +18,13 @@ export function DependentField({
|
|||||||
definition,
|
definition,
|
||||||
url,
|
url,
|
||||||
setFields
|
setFields
|
||||||
}: {
|
}: Readonly<{
|
||||||
control: Control<FieldValues, any>;
|
control: Control<FieldValues, any>;
|
||||||
definition: ApiFormFieldType;
|
definition: ApiFormFieldType;
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
setFields?: React.Dispatch<React.SetStateAction<ApiFormFieldSet>>;
|
setFields?: React.Dispatch<React.SetStateAction<ApiFormFieldSet>>;
|
||||||
}) {
|
}>) {
|
||||||
const { watch, resetField } = useFormContext();
|
const { watch, resetField } = useFormContext();
|
||||||
|
|
||||||
const mappedFieldNames = useMemo(
|
const mappedFieldNames = useMemo(
|
||||||
|
@ -20,16 +20,16 @@ export function TableField({
|
|||||||
definition,
|
definition,
|
||||||
fieldName,
|
fieldName,
|
||||||
control
|
control
|
||||||
}: {
|
}: Readonly<{
|
||||||
definition: ApiFormFieldType;
|
definition: ApiFormFieldType;
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
control: UseControllerReturn<FieldValues, any>;
|
control: UseControllerReturn<FieldValues, any>;
|
||||||
}) {
|
}>) {
|
||||||
const {
|
const {
|
||||||
field,
|
field,
|
||||||
fieldState: { error }
|
fieldState: { error }
|
||||||
} = control;
|
} = control;
|
||||||
const { value, ref } = field;
|
const { value } = field;
|
||||||
|
|
||||||
const onRowFieldChange = (idx: number, key: string, value: any) => {
|
const onRowFieldChange = (idx: number, key: string, value: any) => {
|
||||||
const val = field.value;
|
const val = field.value;
|
||||||
|
@ -14,12 +14,12 @@ export default function TextField({
|
|||||||
fieldName,
|
fieldName,
|
||||||
definition,
|
definition,
|
||||||
onChange
|
onChange
|
||||||
}: {
|
}: Readonly<{
|
||||||
controller: UseControllerReturn<FieldValues, any>;
|
controller: UseControllerReturn<FieldValues, any>;
|
||||||
definition: any;
|
definition: any;
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
onChange: (value: any) => void;
|
onChange: (value: any) => void;
|
||||||
}) {
|
}>) {
|
||||||
const fieldId = useId();
|
const fieldId = useId();
|
||||||
const {
|
const {
|
||||||
field,
|
field,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { Anchor, Group, Skeleton, Text } from '@mantine/core';
|
import { Anchor, Group } from '@mantine/core';
|
||||||
import { ReactNode, useMemo } from 'react';
|
import { ReactNode, useMemo } from 'react';
|
||||||
|
|
||||||
import { ApiImage } from './ApiImage';
|
import { ApiImage } from './ApiImage';
|
||||||
@ -14,14 +14,14 @@ export function Thumbnail({
|
|||||||
link,
|
link,
|
||||||
text,
|
text,
|
||||||
align
|
align
|
||||||
}: {
|
}: Readonly<{
|
||||||
src?: string | undefined;
|
src?: string;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
size?: number;
|
size?: number;
|
||||||
text?: ReactNode;
|
text?: ReactNode;
|
||||||
align?: string;
|
align?: string;
|
||||||
link?: string;
|
link?: string;
|
||||||
}) {
|
}>) {
|
||||||
const backup_image = '/static/img/blank_image.png';
|
const backup_image = '/static/img/blank_image.png';
|
||||||
|
|
||||||
const inner = useMemo(() => {
|
const inner = useMemo(() => {
|
||||||
|
@ -38,12 +38,12 @@ function ImporterDataCell({
|
|||||||
column,
|
column,
|
||||||
row,
|
row,
|
||||||
onEdit
|
onEdit
|
||||||
}: {
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
column: any;
|
column: any;
|
||||||
row: any;
|
row: any;
|
||||||
onEdit?: () => void;
|
onEdit?: () => void;
|
||||||
}) {
|
}>) {
|
||||||
const onRowEdit = useCallback(
|
const onRowEdit = useCallback(
|
||||||
(event: any) => {
|
(event: any) => {
|
||||||
cancelEvent(event);
|
cancelEvent(event);
|
||||||
@ -128,9 +128,9 @@ function ImporterDataCell({
|
|||||||
|
|
||||||
export default function ImporterDataSelector({
|
export default function ImporterDataSelector({
|
||||||
session
|
session
|
||||||
}: {
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('dataimporter');
|
const table = useTable('dataimporter');
|
||||||
|
|
||||||
const [selectedFieldNames, setSelectedFieldNames] = useState<string[]>([]);
|
const [selectedFieldNames, setSelectedFieldNames] = useState<string[]>([]);
|
||||||
@ -377,6 +377,7 @@ export default function ImporterDataSelector({
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="import-selected-rows"
|
||||||
disabled={!canImport}
|
disabled={!canImport}
|
||||||
icon={<IconArrowRight />}
|
icon={<IconArrowRight />}
|
||||||
color="green"
|
color="green"
|
||||||
|
@ -20,7 +20,10 @@ import { apiUrl } from '../../states/ApiState';
|
|||||||
import { StandaloneField } from '../forms/StandaloneField';
|
import { StandaloneField } from '../forms/StandaloneField';
|
||||||
import { ApiFormFieldType } from '../forms/fields/ApiFormField';
|
import { ApiFormFieldType } from '../forms/fields/ApiFormField';
|
||||||
|
|
||||||
function ImporterColumn({ column, options }: { column: any; options: any[] }) {
|
function ImporterColumn({
|
||||||
|
column,
|
||||||
|
options
|
||||||
|
}: Readonly<{ column: any; options: any[] }>) {
|
||||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||||
|
|
||||||
const [selectedColumn, setSelectedColumn] = useState<string>(
|
const [selectedColumn, setSelectedColumn] = useState<string>(
|
||||||
@ -122,11 +125,11 @@ function ImporterColumnTableRow({
|
|||||||
session,
|
session,
|
||||||
column,
|
column,
|
||||||
options
|
options
|
||||||
}: {
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
column: any;
|
column: any;
|
||||||
options: any;
|
options: any;
|
||||||
}) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<Table.Tr key={column.label ?? column.field}>
|
<Table.Tr key={column.label ?? column.field}>
|
||||||
<Table.Td>
|
<Table.Td>
|
||||||
@ -156,9 +159,9 @@ function ImporterColumnTableRow({
|
|||||||
|
|
||||||
export default function ImporterColumnSelector({
|
export default function ImporterColumnSelector({
|
||||||
session
|
session
|
||||||
}: {
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}) {
|
}>) {
|
||||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||||
|
|
||||||
const acceptMapping = useCallback(() => {
|
const acceptMapping = useCallback(() => {
|
||||||
@ -221,6 +224,7 @@ export default function ImporterColumnSelector({
|
|||||||
{session.columnMappings.map((column: any) => {
|
{session.columnMappings.map((column: any) => {
|
||||||
return (
|
return (
|
||||||
<ImporterColumnTableRow
|
<ImporterColumnTableRow
|
||||||
|
key={`import-${column.field}}`}
|
||||||
session={session}
|
session={session}
|
||||||
column={column}
|
column={column}
|
||||||
options={columnOptions}
|
options={columnOptions}
|
||||||
|
@ -27,7 +27,9 @@ import ImporterImportProgress from './ImporterImportProgress';
|
|||||||
/*
|
/*
|
||||||
* Stepper component showing the current step of the data import process.
|
* Stepper component showing the current step of the data import process.
|
||||||
*/
|
*/
|
||||||
function ImportDrawerStepper({ currentStep }: { currentStep: number }) {
|
function ImportDrawerStepper({
|
||||||
|
currentStep
|
||||||
|
}: Readonly<{ currentStep: number }>) {
|
||||||
/* TODO: Enhance this with:
|
/* TODO: Enhance this with:
|
||||||
* - Custom icons
|
* - Custom icons
|
||||||
* - Loading indicators for "background" states
|
* - Loading indicators for "background" states
|
||||||
@ -54,11 +56,11 @@ export default function ImporterDrawer({
|
|||||||
sessionId,
|
sessionId,
|
||||||
opened,
|
opened,
|
||||||
onClose
|
onClose
|
||||||
}: {
|
}: Readonly<{
|
||||||
sessionId: number;
|
sessionId: number;
|
||||||
opened: boolean;
|
opened: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}>) {
|
||||||
const session = useImportSession({ sessionId: sessionId });
|
const session = useImportSession({ sessionId: sessionId });
|
||||||
|
|
||||||
const importSessionStatus = useStatusCodes({
|
const importSessionStatus = useStatusCodes({
|
||||||
|
@ -10,9 +10,9 @@ import { StylishText } from '../items/StylishText';
|
|||||||
|
|
||||||
export default function ImporterImportProgress({
|
export default function ImporterImportProgress({
|
||||||
session
|
session
|
||||||
}: {
|
}: Readonly<{
|
||||||
session: ImportSessionState;
|
session: ImportSessionState;
|
||||||
}) {
|
}>) {
|
||||||
const importSessionStatus = useStatusCodes({
|
const importSessionStatus = useStatusCodes({
|
||||||
modelType: ModelType.importsession
|
modelType: ModelType.importsession
|
||||||
});
|
});
|
||||||
|
@ -127,11 +127,11 @@ export function OptionsActionDropdown({
|
|||||||
actions = [],
|
actions = [],
|
||||||
tooltip = t`Options`,
|
tooltip = t`Options`,
|
||||||
hidden = false
|
hidden = false
|
||||||
}: {
|
}: Readonly<{
|
||||||
actions: ActionDropdownItem[];
|
actions: ActionDropdownItem[];
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
}) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<ActionDropdown
|
<ActionDropdown
|
||||||
icon={<IconDotsVertical />}
|
icon={<IconDotsVertical />}
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
Text
|
Text
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
|
||||||
import { modals } from '@mantine/modals';
|
import { modals } from '@mantine/modals';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import QR from 'qrcode';
|
import QR from 'qrcode';
|
||||||
@ -143,7 +142,6 @@ export const InvenTreeQRCode = ({
|
|||||||
|
|
||||||
export const QRCodeLink = ({ mdl_prop }: { mdl_prop: QrCodeType }) => {
|
export const QRCodeLink = ({ mdl_prop }: { mdl_prop: QrCodeType }) => {
|
||||||
const [barcode, setBarcode] = useState('');
|
const [barcode, setBarcode] = useState('');
|
||||||
const [isScanning, toggleIsScanning] = useDisclosure(false);
|
|
||||||
|
|
||||||
function linkBarcode(value?: string) {
|
function linkBarcode(value?: string) {
|
||||||
api
|
api
|
||||||
|
@ -8,11 +8,11 @@ export default function InstanceDetail({
|
|||||||
status,
|
status,
|
||||||
loading,
|
loading,
|
||||||
children
|
children
|
||||||
}: {
|
}: Readonly<{
|
||||||
status: number;
|
status: number;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
if (loading || !user.isLoggedIn()) {
|
if (loading || !user.isLoggedIn()) {
|
||||||
|
@ -40,14 +40,14 @@ export default function NavigationTree({
|
|||||||
selectedId,
|
selectedId,
|
||||||
modelType,
|
modelType,
|
||||||
endpoint
|
endpoint
|
||||||
}: {
|
}: Readonly<{
|
||||||
title: string;
|
title: string;
|
||||||
opened: boolean;
|
opened: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
selectedId?: number | null;
|
selectedId?: number | null;
|
||||||
modelType: ModelType;
|
modelType: ModelType;
|
||||||
endpoint: ApiEndpoints;
|
endpoint: ApiEndpoints;
|
||||||
}) {
|
}>) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const treeState = useTree();
|
const treeState = useTree();
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@ export async function isPluginPanelHidden({
|
|||||||
export default function PluginPanelContent({
|
export default function PluginPanelContent({
|
||||||
pluginProps,
|
pluginProps,
|
||||||
pluginContext
|
pluginContext
|
||||||
}: {
|
}: Readonly<{
|
||||||
pluginProps: PluginPanelProps;
|
pluginProps: PluginPanelProps;
|
||||||
pluginContext: PluginContext;
|
pluginContext: PluginContext;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
const ref = useRef<HTMLDivElement>();
|
const ref = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const [error, setError] = useState<string | undefined>(undefined);
|
const [error, setError] = useState<string | undefined>(undefined);
|
||||||
|
@ -121,10 +121,10 @@ export function RenderInstance(props: RenderInstanceProps): ReactNode {
|
|||||||
export function RenderRemoteInstance({
|
export function RenderRemoteInstance({
|
||||||
model,
|
model,
|
||||||
pk
|
pk
|
||||||
}: {
|
}: Readonly<{
|
||||||
model: ModelType;
|
model: ModelType;
|
||||||
pk: number;
|
pk: number;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
const { data, isLoading, isFetching } = useQuery({
|
const { data, isLoading, isFetching } = useQuery({
|
||||||
queryKey: ['model', model, pk],
|
queryKey: ['model', model, pk],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@ -166,7 +166,7 @@ export function RenderInlineModel({
|
|||||||
navigate,
|
navigate,
|
||||||
showSecondary = true,
|
showSecondary = true,
|
||||||
tooltip
|
tooltip
|
||||||
}: {
|
}: Readonly<{
|
||||||
primary: string;
|
primary: string;
|
||||||
secondary?: string;
|
secondary?: string;
|
||||||
showSecondary?: boolean;
|
showSecondary?: boolean;
|
||||||
@ -177,7 +177,7 @@ export function RenderInlineModel({
|
|||||||
url?: string;
|
url?: string;
|
||||||
navigate?: any;
|
navigate?: any;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
// TODO: Handle labels
|
// TODO: Handle labels
|
||||||
|
|
||||||
const onClick = useCallback(
|
const onClick = useCallback(
|
||||||
@ -215,9 +215,9 @@ export function RenderInlineModel({
|
|||||||
|
|
||||||
export function UnknownRenderer({
|
export function UnknownRenderer({
|
||||||
model
|
model
|
||||||
}: {
|
}: Readonly<{
|
||||||
model: ModelType | undefined;
|
model: ModelType | undefined;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
return (
|
return (
|
||||||
<Alert color="red" title={t`Unknown model: ${model}`}>
|
<Alert color="red" title={t`Unknown model: ${model}`}>
|
||||||
<></>
|
<></>
|
||||||
|
@ -6,9 +6,9 @@ import { RenderInlineModel } from './Instance';
|
|||||||
|
|
||||||
export function RenderPlugin({
|
export function RenderPlugin({
|
||||||
instance
|
instance
|
||||||
}: {
|
}: Readonly<{
|
||||||
instance: Readonly<any>;
|
instance: Readonly<any>;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={instance.name}
|
primary={instance.name}
|
||||||
|
@ -4,9 +4,9 @@ import { RenderInlineModel } from './Instance';
|
|||||||
|
|
||||||
export function RenderReportTemplate({
|
export function RenderReportTemplate({
|
||||||
instance
|
instance
|
||||||
}: {
|
}: Readonly<{
|
||||||
instance: any;
|
instance: any;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={instance.name}
|
primary={instance.name}
|
||||||
@ -17,9 +17,9 @@ export function RenderReportTemplate({
|
|||||||
|
|
||||||
export function RenderLabelTemplate({
|
export function RenderLabelTemplate({
|
||||||
instance
|
instance
|
||||||
}: {
|
}: Readonly<{
|
||||||
instance: any;
|
instance: any;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
return (
|
return (
|
||||||
<RenderInlineModel
|
<RenderInlineModel
|
||||||
primary={instance.name}
|
primary={instance.name}
|
||||||
|
@ -5,14 +5,18 @@ import { FactItem } from './FactItem';
|
|||||||
export function FactCollection({
|
export function FactCollection({
|
||||||
items,
|
items,
|
||||||
minItems = 3
|
minItems = 3
|
||||||
}: {
|
}: Readonly<{
|
||||||
items: { title: string; value: any }[];
|
items: { title: string; value: any }[];
|
||||||
minItems?: number;
|
minItems?: number;
|
||||||
}) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<SimpleGrid cols={minItems} spacing="xs">
|
<SimpleGrid cols={minItems} spacing="xs">
|
||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<FactItem key={index} title={item.title} value={item.value} />
|
<FactItem
|
||||||
|
key={`${index}-${item.value}`}
|
||||||
|
title={item.title}
|
||||||
|
value={item.value}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,10 @@ import { Paper, Stack, Text } from '@mantine/core';
|
|||||||
|
|
||||||
import { StylishText } from '../items/StylishText';
|
import { StylishText } from '../items/StylishText';
|
||||||
|
|
||||||
export function FactItem({ title, value }: { title: string; value: number }) {
|
export function FactItem({
|
||||||
|
title,
|
||||||
|
value
|
||||||
|
}: Readonly<{ title: string; value: number }>) {
|
||||||
return (
|
return (
|
||||||
<Paper p="md" shadow="xs">
|
<Paper p="md" shadow="xs">
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { DataTable } from 'mantine-datatable';
|
import { DataTable } from 'mantine-datatable';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
|
|
||||||
import { api } from '../App';
|
import { api } from '../App';
|
||||||
import { ActionButton } from '../components/buttons/ActionButton';
|
import { ActionButton } from '../components/buttons/ActionButton';
|
||||||
@ -25,7 +24,6 @@ import { TableFieldRowProps } from '../components/forms/fields/TableField';
|
|||||||
import { ProgressBar } from '../components/items/ProgressBar';
|
import { ProgressBar } from '../components/items/ProgressBar';
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../enums/ModelType';
|
import { ModelType } from '../enums/ModelType';
|
||||||
import { resolveItem } from '../functions/conversion';
|
|
||||||
import { InvenTreeIcon } from '../functions/icons';
|
import { InvenTreeIcon } from '../functions/icons';
|
||||||
import { useCreateApiFormModal } from '../hooks/UseForm';
|
import { useCreateApiFormModal } from '../hooks/UseForm';
|
||||||
import { useBatchCodeGenerator } from '../hooks/UseGenerator';
|
import { useBatchCodeGenerator } from '../hooks/UseGenerator';
|
||||||
@ -487,11 +485,11 @@ function BuildAllocateLineRow({
|
|||||||
props,
|
props,
|
||||||
record,
|
record,
|
||||||
sourceLocation
|
sourceLocation
|
||||||
}: {
|
}: Readonly<{
|
||||||
props: TableFieldRowProps;
|
props: TableFieldRowProps;
|
||||||
record: any;
|
record: any;
|
||||||
sourceLocation: number | undefined;
|
sourceLocation: number | undefined;
|
||||||
}) {
|
}>) {
|
||||||
const stockField: ApiFormFieldType = useMemo(() => {
|
const stockField: ApiFormFieldType = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
field_type: 'related field',
|
field_type: 'related field',
|
||||||
@ -542,35 +540,33 @@ function BuildAllocateLineRow({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Table.Tr key={`table-row-${record.pk}`}>
|
||||||
<Table.Tr key={`table-row-${record.pk}`}>
|
<Table.Td>{partDetail}</Table.Td>
|
||||||
<Table.Td>{partDetail}</Table.Td>
|
<Table.Td>
|
||||||
<Table.Td>
|
<ProgressBar
|
||||||
<ProgressBar
|
value={record.allocated}
|
||||||
value={record.allocated}
|
maximum={record.quantity}
|
||||||
maximum={record.quantity}
|
progressLabel
|
||||||
progressLabel
|
/>
|
||||||
/>
|
</Table.Td>
|
||||||
</Table.Td>
|
<Table.Td>
|
||||||
<Table.Td>
|
<StandaloneField
|
||||||
<StandaloneField
|
fieldName="stock_item"
|
||||||
fieldName="stock_item"
|
fieldDefinition={stockField}
|
||||||
fieldDefinition={stockField}
|
error={props.rowErrors?.stock_item?.message}
|
||||||
error={props.rowErrors?.stock_item?.message}
|
/>
|
||||||
/>
|
</Table.Td>
|
||||||
</Table.Td>
|
<Table.Td>
|
||||||
<Table.Td>
|
<StandaloneField
|
||||||
<StandaloneField
|
fieldName="quantity"
|
||||||
fieldName="quantity"
|
fieldDefinition={quantityField}
|
||||||
fieldDefinition={quantityField}
|
error={props.rowErrors?.quantity?.message}
|
||||||
error={props.rowErrors?.quantity?.message}
|
/>
|
||||||
/>
|
</Table.Td>
|
||||||
</Table.Td>
|
<Table.Td>
|
||||||
<Table.Td>
|
<RemoveRowButton onClick={() => props.removeFn(props.idx)} />
|
||||||
<RemoveRowButton onClick={() => props.removeFn(props.idx)} />
|
</Table.Td>
|
||||||
</Table.Td>
|
</Table.Tr>
|
||||||
</Table.Tr>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,11 +197,11 @@ function LineItemFormRow({
|
|||||||
props,
|
props,
|
||||||
record,
|
record,
|
||||||
statuses
|
statuses
|
||||||
}: {
|
}: Readonly<{
|
||||||
props: TableFieldRowProps;
|
props: TableFieldRowProps;
|
||||||
record: any;
|
record: any;
|
||||||
statuses: any;
|
statuses: any;
|
||||||
}) {
|
}>) {
|
||||||
// Barcode Modal state
|
// Barcode Modal state
|
||||||
const [opened, { open, close }] = useDisclosure(false, {
|
const [opened, { open, close }] = useDisclosure(false, {
|
||||||
onClose: () => props.changeFn(props.idx, 'barcode', undefined)
|
onClose: () => props.changeFn(props.idx, 'barcode', undefined)
|
||||||
@ -263,7 +263,7 @@ function LineItemFormRow({
|
|||||||
|
|
||||||
// Barcode value
|
// Barcode value
|
||||||
const [barcodeInput, setBarcodeInput] = useState<any>('');
|
const [barcodeInput, setBarcodeInput] = useState<any>('');
|
||||||
const [barcode, setBarcode] = useState<String | undefined>(undefined);
|
const [barcode, setBarcode] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
// Change form value when state is altered
|
// Change form value when state is altered
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -6,11 +6,10 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { api } from '../App';
|
import { api } from '../App';
|
||||||
import { PanelType } from '../components/nav/Panel';
|
import { PanelType } from '../components/nav/Panel';
|
||||||
import { PluginContext } from '../components/plugins/PluginContext';
|
import { PluginContext } from '../components/plugins/PluginContext';
|
||||||
import {
|
import PluginPanelContent, {
|
||||||
PluginPanelProps,
|
PluginPanelProps,
|
||||||
isPluginPanelHidden
|
isPluginPanelHidden
|
||||||
} from '../components/plugins/PluginPanel';
|
} from '../components/plugins/PluginPanel';
|
||||||
import PluginPanelContent from '../components/plugins/PluginPanel';
|
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../enums/ModelType';
|
import { ModelType } from '../enums/ModelType';
|
||||||
import { identifierString } from '../functions/conversion';
|
import { identifierString } from '../functions/conversion';
|
||||||
|
@ -14,13 +14,12 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
useMantineTheme
|
useMantineTheme
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { IconReload, IconRestore } from '@tabler/icons-react';
|
import { IconRestore } from '@tabler/icons-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { ColorToggle } from '../../../../components/items/ColorToggle';
|
import { ColorToggle } from '../../../../components/items/ColorToggle';
|
||||||
import { LanguageSelect } from '../../../../components/items/LanguageSelect';
|
import { LanguageSelect } from '../../../../components/items/LanguageSelect';
|
||||||
import { SizeMarks } from '../../../../defaults/defaults';
|
import { SizeMarks } from '../../../../defaults/defaults';
|
||||||
import { notYetImplemented } from '../../../../functions/notifications';
|
|
||||||
import { IS_DEV } from '../../../../main';
|
import { IS_DEV } from '../../../../main';
|
||||||
import { useLocalState } from '../../../../states/LocalState';
|
import { useLocalState } from '../../../../states/LocalState';
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ const LOOKUP = Object.assign(
|
|||||||
...Object.keys(DEFAULT_THEME.colors).map((clr) => getLkp(clr))
|
...Object.keys(DEFAULT_THEME.colors).map((clr) => getLkp(clr))
|
||||||
);
|
);
|
||||||
|
|
||||||
export function UserTheme({ height }: { height: number }) {
|
export function UserTheme({ height }: Readonly<{ height: number }>) {
|
||||||
const theme = useMantineTheme();
|
const theme = useMantineTheme();
|
||||||
|
|
||||||
const [themeLoader, setThemeLoader] = useLocalState((state) => [
|
const [themeLoader, setThemeLoader] = useLocalState((state) => [
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Trans, t } from '@lingui/macro';
|
import { Trans, t } from '@lingui/macro';
|
||||||
import { Accordion, Alert, Stack } from '@mantine/core';
|
import { Accordion, Alert, Stack } from '@mantine/core';
|
||||||
import { IconInfoCircle } from '@tabler/icons-react';
|
import { IconInfoCircle } from '@tabler/icons-react';
|
||||||
import { userInfo } from 'os';
|
|
||||||
import { lazy } from 'react';
|
import { lazy } from 'react';
|
||||||
|
|
||||||
import { StylishText } from '../../../../components/items/StylishText';
|
import { StylishText } from '../../../../components/items/StylishText';
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
IconQrcode,
|
IconQrcode,
|
||||||
IconServerCog,
|
IconServerCog,
|
||||||
IconShoppingCart,
|
IconShoppingCart,
|
||||||
IconSitemap,
|
|
||||||
IconTag,
|
IconTag,
|
||||||
IconTools,
|
IconTools,
|
||||||
IconTruckDelivery,
|
IconTruckDelivery,
|
||||||
|
@ -13,9 +13,9 @@ import { NoPricingData } from './PricingPanel';
|
|||||||
|
|
||||||
export default function PurchaseHistoryPanel({
|
export default function PurchaseHistoryPanel({
|
||||||
part
|
part
|
||||||
}: {
|
}: Readonly<{
|
||||||
part: any;
|
part: any;
|
||||||
}): ReactNode {
|
}>): ReactNode {
|
||||||
const table = useTable('pricing-purchase-history');
|
const table = useTable('pricing-purchase-history');
|
||||||
|
|
||||||
const calculateUnitPrice = useCallback((record: any) => {
|
const calculateUnitPrice = useCallback((record: any) => {
|
||||||
@ -86,13 +86,6 @@ export default function PurchaseHistoryPanel({
|
|||||||
];
|
];
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const currency: string = useMemo(() => {
|
|
||||||
if (table.records.length === 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return table.records[0].purchase_price_currency;
|
|
||||||
}, [table.records]);
|
|
||||||
|
|
||||||
const purchaseHistoryData = useMemo(() => {
|
const purchaseHistoryData = useMemo(() => {
|
||||||
return table.records.map((record: any) => {
|
return table.records.map((record: any) => {
|
||||||
return {
|
return {
|
||||||
|
@ -12,7 +12,9 @@ import { DateColumn } from '../../../tables/ColumnRenderers';
|
|||||||
import { InvenTreeTable } from '../../../tables/InvenTreeTable';
|
import { InvenTreeTable } from '../../../tables/InvenTreeTable';
|
||||||
import { NoPricingData } from './PricingPanel';
|
import { NoPricingData } from './PricingPanel';
|
||||||
|
|
||||||
export default function SaleHistoryPanel({ part }: { part: any }): ReactNode {
|
export default function SaleHistoryPanel({
|
||||||
|
part
|
||||||
|
}: Readonly<{ part: any }>): ReactNode {
|
||||||
const table = useTable('pricing-sale-history');
|
const table = useTable('pricing-sale-history');
|
||||||
|
|
||||||
const columns: TableColumn[] = useMemo(() => {
|
const columns: TableColumn[] = useMemo(() => {
|
||||||
@ -51,13 +53,6 @@ export default function SaleHistoryPanel({ part }: { part: any }): ReactNode {
|
|||||||
];
|
];
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const currency: string = useMemo(() => {
|
|
||||||
if (table.records.length === 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return table.records[0].sale_price_currency;
|
|
||||||
}, [table.records]);
|
|
||||||
|
|
||||||
const saleHistoryData = useMemo(() => {
|
const saleHistoryData = useMemo(() => {
|
||||||
return table.records.map((record: any) => {
|
return table.records.map((record: any) => {
|
||||||
return {
|
return {
|
||||||
|
@ -34,7 +34,7 @@ export default function BuildAllocatedStockTable({
|
|||||||
allowEdit,
|
allowEdit,
|
||||||
modelTarget,
|
modelTarget,
|
||||||
modelField
|
modelField
|
||||||
}: {
|
}: Readonly<{
|
||||||
buildId?: number;
|
buildId?: number;
|
||||||
stockId?: number;
|
stockId?: number;
|
||||||
partId?: number;
|
partId?: number;
|
||||||
@ -43,7 +43,7 @@ export default function BuildAllocatedStockTable({
|
|||||||
allowEdit?: boolean;
|
allowEdit?: boolean;
|
||||||
modelTarget?: ModelType;
|
modelTarget?: ModelType;
|
||||||
modelField?: string;
|
modelField?: string;
|
||||||
}) {
|
}>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('buildallocatedstock');
|
const table = useTable('buildallocatedstock');
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
IconCircleMinus,
|
IconCircleMinus,
|
||||||
IconShoppingCart,
|
IconShoppingCart,
|
||||||
IconTool,
|
IconTool,
|
||||||
IconTransferIn,
|
|
||||||
IconWand
|
IconWand
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
@ -37,12 +36,12 @@ export default function BuildLineTable({
|
|||||||
build,
|
build,
|
||||||
outputId,
|
outputId,
|
||||||
params = {}
|
params = {}
|
||||||
}: {
|
}: Readonly<{
|
||||||
buildId: number;
|
buildId: number;
|
||||||
build: any;
|
build: any;
|
||||||
outputId?: number;
|
outputId?: number;
|
||||||
params?: any;
|
params?: any;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('buildline');
|
const table = useTable('buildline');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const buildStatus = useStatusCodes({ modelType: ModelType.build });
|
const buildStatus = useStatusCodes({ modelType: ModelType.build });
|
||||||
@ -441,6 +440,7 @@ export default function BuildLineTable({
|
|||||||
const visible = production && canEdit;
|
const visible = production && canEdit;
|
||||||
return [
|
return [
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="auto-allocate"
|
||||||
icon={<IconWand />}
|
icon={<IconWand />}
|
||||||
tooltip={t`Auto Allocate Stock`}
|
tooltip={t`Auto Allocate Stock`}
|
||||||
hidden={!visible}
|
hidden={!visible}
|
||||||
@ -450,6 +450,7 @@ export default function BuildLineTable({
|
|||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="allocate-stock"
|
||||||
icon={<IconArrowRight />}
|
icon={<IconArrowRight />}
|
||||||
tooltip={t`Allocate Stock`}
|
tooltip={t`Allocate Stock`}
|
||||||
hidden={!visible}
|
hidden={!visible}
|
||||||
@ -468,6 +469,7 @@ export default function BuildLineTable({
|
|||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="deallocate-stock"
|
||||||
icon={<IconCircleMinus />}
|
icon={<IconCircleMinus />}
|
||||||
tooltip={t`Deallocate Stock`}
|
tooltip={t`Deallocate Stock`}
|
||||||
hidden={!visible}
|
hidden={!visible}
|
||||||
|
@ -28,10 +28,10 @@ import { TableHoverCard } from '../TableHoverCard';
|
|||||||
export default function BuildOrderTestTable({
|
export default function BuildOrderTestTable({
|
||||||
buildId,
|
buildId,
|
||||||
partId
|
partId
|
||||||
}: {
|
}: Readonly<{
|
||||||
buildId: number;
|
buildId: number;
|
||||||
partId: number;
|
partId: number;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('build-tests');
|
const table = useTable('build-tests');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ type TestResultOverview = {
|
|||||||
result: boolean;
|
result: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function BuildOutputTable({ build }: { build: any }) {
|
export default function BuildOutputTable({ build }: Readonly<{ build: any }>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('build-outputs');
|
const table = useTable('build-outputs');
|
||||||
|
|
||||||
@ -208,11 +208,13 @@ export default function BuildOutputTable({ build }: { build: any }) {
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-build-output"
|
||||||
tooltip={t`Add Build Output`}
|
tooltip={t`Add Build Output`}
|
||||||
hidden={!user.hasAddRole(UserRoles.build)}
|
hidden={!user.hasAddRole(UserRoles.build)}
|
||||||
onClick={addBuildOutput.open}
|
onClick={addBuildOutput.open}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="complete-selected-outputs"
|
||||||
tooltip={t`Complete selected outputs`}
|
tooltip={t`Complete selected outputs`}
|
||||||
icon={<InvenTreeIcon icon="success" />}
|
icon={<InvenTreeIcon icon="success" />}
|
||||||
color="green"
|
color="green"
|
||||||
@ -223,6 +225,7 @@ export default function BuildOutputTable({ build }: { build: any }) {
|
|||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="scrap-selected-outputs"
|
||||||
tooltip={t`Scrap selected outputs`}
|
tooltip={t`Scrap selected outputs`}
|
||||||
icon={<InvenTreeIcon icon="delete" />}
|
icon={<InvenTreeIcon icon="delete" />}
|
||||||
color="red"
|
color="red"
|
||||||
@ -233,6 +236,7 @@ export default function BuildOutputTable({ build }: { build: any }) {
|
|||||||
}}
|
}}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="cancel-selected-outputs"
|
||||||
tooltip={t`Cancel selected outputs`}
|
tooltip={t`Cancel selected outputs`}
|
||||||
icon={<InvenTreeIcon icon="cancel" />}
|
icon={<InvenTreeIcon icon="cancel" />}
|
||||||
color="red"
|
color="red"
|
||||||
|
@ -29,12 +29,12 @@ export default function ExtraLineItemTable({
|
|||||||
orderId,
|
orderId,
|
||||||
currency,
|
currency,
|
||||||
role
|
role
|
||||||
}: {
|
}: Readonly<{
|
||||||
endpoint: ApiEndpoints;
|
endpoint: ApiEndpoints;
|
||||||
orderId: number;
|
orderId: number;
|
||||||
currency: string;
|
currency: string;
|
||||||
role: UserRoles;
|
role: UserRoles;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('extra-line-item');
|
const table = useTable('extra-line-item');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
@ -139,6 +139,7 @@ export default function ExtraLineItemTable({
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-line-item"
|
||||||
tooltip={t`Add Extra Line Item`}
|
tooltip={t`Add Extra Line Item`}
|
||||||
hidden={!user.hasAddRole(role)}
|
hidden={!user.hasAddRole(role)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -30,10 +30,10 @@ import { TableHoverCard } from '../TableHoverCard';
|
|||||||
export function PartParameterTable({
|
export function PartParameterTable({
|
||||||
partId,
|
partId,
|
||||||
partLocked
|
partLocked
|
||||||
}: {
|
}: Readonly<{
|
||||||
partId: any;
|
partId: any;
|
||||||
partLocked?: boolean;
|
partLocked?: boolean;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('part-parameters');
|
const table = useTable('part-parameters');
|
||||||
|
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
@ -8,7 +8,6 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { DateColumn, ReferenceColumn, StatusColumn } from '../ColumnRenderers';
|
import { DateColumn, ReferenceColumn, StatusColumn } from '../ColumnRenderers';
|
||||||
import { StatusFilterOptions, TableFilter } from '../Filter';
|
import { StatusFilterOptions, TableFilter } from '../Filter';
|
||||||
@ -17,11 +16,10 @@ import { TableHoverCard } from '../TableHoverCard';
|
|||||||
|
|
||||||
export default function PartPurchaseOrdersTable({
|
export default function PartPurchaseOrdersTable({
|
||||||
partId
|
partId
|
||||||
}: {
|
}: Readonly<{
|
||||||
partId: number;
|
partId: number;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('partpurchaseorders');
|
const table = useTable('partpurchaseorders');
|
||||||
const user = useUserState();
|
|
||||||
|
|
||||||
const tableColumns: TableColumn[] = useMemo(() => {
|
const tableColumns: TableColumn[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@ -130,23 +128,21 @@ export default function PartPurchaseOrdersTable({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<InvenTreeTable
|
||||||
<InvenTreeTable
|
url={apiUrl(ApiEndpoints.purchase_order_line_list)}
|
||||||
url={apiUrl(ApiEndpoints.purchase_order_line_list)}
|
tableState={table}
|
||||||
tableState={table}
|
columns={tableColumns}
|
||||||
columns={tableColumns}
|
props={{
|
||||||
props={{
|
params: {
|
||||||
params: {
|
base_part: partId,
|
||||||
base_part: partId,
|
part_detail: true,
|
||||||
part_detail: true,
|
order_detail: true,
|
||||||
order_detail: true,
|
supplier_detail: true
|
||||||
supplier_detail: true
|
},
|
||||||
},
|
modelField: 'order',
|
||||||
modelField: 'order',
|
modelType: ModelType.purchaseorder,
|
||||||
modelType: ModelType.purchaseorder,
|
tableFilters: tableFilters
|
||||||
tableFilters: tableFilters
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,10 @@ import { TableHoverCard } from '../TableHoverCard';
|
|||||||
export default function PartTestTemplateTable({
|
export default function PartTestTemplateTable({
|
||||||
partId,
|
partId,
|
||||||
partLocked
|
partLocked
|
||||||
}: {
|
}: Readonly<{
|
||||||
partId: number;
|
partId: number;
|
||||||
partLocked?: boolean;
|
partLocked?: boolean;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('part-test-template');
|
const table = useTable('part-test-template');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -234,6 +234,7 @@ export default function PartTestTemplateTable({
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-test-template"
|
||||||
tooltip={t`Add Test Template`}
|
tooltip={t`Add Test Template`}
|
||||||
onClick={() => newTestTemplate.open()}
|
onClick={() => newTestTemplate.open()}
|
||||||
hidden={partLocked || !can_add}
|
hidden={partLocked || !can_add}
|
||||||
|
@ -73,7 +73,7 @@ export interface PluginI {
|
|||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PluginDrawer({ pluginKey }: { pluginKey: Readonly<string> }) {
|
export function PluginDrawer({ pluginKey }: Readonly<{ pluginKey: string }>) {
|
||||||
const {
|
const {
|
||||||
instance: plugin,
|
instance: plugin,
|
||||||
instanceQuery: { isFetching, error }
|
instanceQuery: { isFetching, error }
|
||||||
@ -151,7 +151,7 @@ export function PluginDrawer({ pluginKey }: { pluginKey: Readonly<string> }) {
|
|||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
) : (
|
) : (
|
||||||
<Text color="red">{t`Plugin is not active`}</Text>
|
<Text c="red">{t`Plugin is not active`}</Text>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card>
|
</Card>
|
||||||
@ -207,7 +207,7 @@ export function PluginDrawer({ pluginKey }: { pluginKey: Readonly<string> }) {
|
|||||||
/**
|
/**
|
||||||
* Construct an indicator icon for a single plugin
|
* Construct an indicator icon for a single plugin
|
||||||
*/
|
*/
|
||||||
function PluginIcon({ plugin }: { plugin: PluginI }) {
|
function PluginIcon({ plugin }: Readonly<{ plugin: PluginI }>) {
|
||||||
if (plugin?.is_installed) {
|
if (plugin?.is_installed) {
|
||||||
if (plugin?.active) {
|
if (plugin?.active) {
|
||||||
return (
|
return (
|
||||||
@ -514,12 +514,14 @@ export default function PluginListTable() {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="reload"
|
||||||
color="green"
|
color="green"
|
||||||
icon={<IconRefresh />}
|
icon={<IconRefresh />}
|
||||||
tooltip={t`Reload Plugins`}
|
tooltip={t`Reload Plugins`}
|
||||||
onClick={reloadPlugins}
|
onClick={reloadPlugins}
|
||||||
/>,
|
/>,
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
key="install"
|
||||||
color="green"
|
color="green"
|
||||||
icon={<IconPlaylistAdd />}
|
icon={<IconPlaylistAdd />}
|
||||||
tooltip={t`Install Plugin`}
|
tooltip={t`Install Plugin`}
|
||||||
|
@ -34,11 +34,11 @@ export default function ReturnOrderLineItemTable({
|
|||||||
orderId,
|
orderId,
|
||||||
customerId,
|
customerId,
|
||||||
currency
|
currency
|
||||||
}: {
|
}: Readonly<{
|
||||||
orderId: number;
|
orderId: number;
|
||||||
customerId: number;
|
customerId: number;
|
||||||
currency: string;
|
currency: string;
|
||||||
}) {
|
}>) {
|
||||||
const table = useTable('return-order-line-item');
|
const table = useTable('return-order-line-item');
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
|
|
||||||
@ -139,6 +139,7 @@ export default function ReturnOrderLineItemTable({
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-line-item"
|
||||||
tooltip={t`Add line item`}
|
tooltip={t`Add line item`}
|
||||||
hidden={!user.hasAddRole(UserRoles.return_order)}
|
hidden={!user.hasAddRole(UserRoles.return_order)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -26,7 +26,7 @@ export default function SalesOrderAllocationTable({
|
|||||||
allowEdit,
|
allowEdit,
|
||||||
modelTarget,
|
modelTarget,
|
||||||
modelField
|
modelField
|
||||||
}: {
|
}: Readonly<{
|
||||||
partId?: number;
|
partId?: number;
|
||||||
stockId?: number;
|
stockId?: number;
|
||||||
orderId?: number;
|
orderId?: number;
|
||||||
@ -35,7 +35,7 @@ export default function SalesOrderAllocationTable({
|
|||||||
allowEdit?: boolean;
|
allowEdit?: boolean;
|
||||||
modelTarget?: ModelType;
|
modelTarget?: ModelType;
|
||||||
modelField?: string;
|
modelField?: string;
|
||||||
}) {
|
}>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('salesorderallocations');
|
const table = useTable('salesorderallocations');
|
||||||
|
|
||||||
@ -110,27 +110,25 @@ export default function SalesOrderAllocationTable({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<InvenTreeTable
|
||||||
<InvenTreeTable
|
url={apiUrl(ApiEndpoints.sales_order_allocation_list)}
|
||||||
url={apiUrl(ApiEndpoints.sales_order_allocation_list)}
|
tableState={table}
|
||||||
tableState={table}
|
columns={tableColumns}
|
||||||
columns={tableColumns}
|
props={{
|
||||||
props={{
|
params: {
|
||||||
params: {
|
part_detail: showPartInfo ?? false,
|
||||||
part_detail: showPartInfo ?? false,
|
order_detail: showOrderInfo ?? false,
|
||||||
order_detail: showOrderInfo ?? false,
|
item_detail: true,
|
||||||
item_detail: true,
|
location_detail: true,
|
||||||
location_detail: true,
|
part: partId,
|
||||||
part: partId,
|
order: orderId,
|
||||||
order: orderId,
|
stock_item: stockId
|
||||||
stock_item: stockId
|
},
|
||||||
},
|
rowActions: rowActions,
|
||||||
rowActions: rowActions,
|
tableFilters: tableFilters,
|
||||||
tableFilters: tableFilters,
|
modelField: modelField ?? 'order',
|
||||||
modelField: modelField ?? 'order',
|
modelType: modelTarget ?? ModelType.salesorder
|
||||||
modelType: modelTarget ?? ModelType.salesorder
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,12 @@ export default function SalesOrderLineItemTable({
|
|||||||
currency,
|
currency,
|
||||||
customerId,
|
customerId,
|
||||||
editable
|
editable
|
||||||
}: {
|
}: Readonly<{
|
||||||
orderId: number;
|
orderId: number;
|
||||||
currency: string;
|
currency: string;
|
||||||
customerId: number;
|
customerId: number;
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
}) {
|
}>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('sales-order-line-item');
|
const table = useTable('sales-order-line-item');
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ export default function SalesOrderLineItemTable({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TableHoverCard
|
<TableHoverCard
|
||||||
value={<Text color={color}>{text}</Text>}
|
value={<Text c={color}>{text}</Text>}
|
||||||
extra={extra}
|
extra={extra}
|
||||||
title={t`Stock Information`}
|
title={t`Stock Information`}
|
||||||
/>
|
/>
|
||||||
@ -254,6 +254,7 @@ export default function SalesOrderLineItemTable({
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-line-item"
|
||||||
tooltip={t`Add line item`}
|
tooltip={t`Add line item`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setInitialData({
|
setInitialData({
|
||||||
|
@ -23,9 +23,9 @@ import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
|
|||||||
|
|
||||||
export default function SalesOrderShipmentTable({
|
export default function SalesOrderShipmentTable({
|
||||||
orderId
|
orderId
|
||||||
}: {
|
}: Readonly<{
|
||||||
orderId: number;
|
orderId: number;
|
||||||
}) {
|
}>) {
|
||||||
const user = useUserState();
|
const user = useUserState();
|
||||||
const table = useTable('sales-order-shipment');
|
const table = useTable('sales-order-shipment');
|
||||||
|
|
||||||
@ -130,6 +130,7 @@ export default function SalesOrderShipmentTable({
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="add-shipment"
|
||||||
tooltip={t`Add shipment`}
|
tooltip={t`Add shipment`}
|
||||||
hidden={!user.hasAddRole(UserRoles.sales_order)}
|
hidden={!user.hasAddRole(UserRoles.sales_order)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -16,7 +16,6 @@ import {
|
|||||||
} from '../../hooks/UseForm';
|
} from '../../hooks/UseForm';
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { DateColumn, StatusColumn } from '../ColumnRenderers';
|
import { DateColumn, StatusColumn } from '../ColumnRenderers';
|
||||||
import { StatusFilterOptions, TableFilter } from '../Filter';
|
import { StatusFilterOptions, TableFilter } from '../Filter';
|
||||||
@ -128,6 +127,7 @@ export default function ImportSesssionTable() {
|
|||||||
const tableActions = useMemo(() => {
|
const tableActions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
<AddItemButton
|
<AddItemButton
|
||||||
|
key="create-import-session"
|
||||||
tooltip={t`Create Import Session`}
|
tooltip={t`Create Import Session`}
|
||||||
onClick={() => newImportSession.open()}
|
onClick={() => newImportSession.open()}
|
||||||
/>
|
/>
|
||||||
|
@ -20,7 +20,6 @@ import {
|
|||||||
} from '../../components/nav/DetailDrawer';
|
} from '../../components/nav/DetailDrawer';
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserPermissions } from '../../enums/Roles';
|
|
||||||
import {
|
import {
|
||||||
useCreateApiFormModal,
|
useCreateApiFormModal,
|
||||||
useDeleteApiFormModal
|
useDeleteApiFormModal
|
||||||
@ -51,10 +50,10 @@ export interface UserDetailI {
|
|||||||
export function UserDrawer({
|
export function UserDrawer({
|
||||||
id,
|
id,
|
||||||
refreshTable
|
refreshTable
|
||||||
}: {
|
}: Readonly<{
|
||||||
id: string;
|
id: string;
|
||||||
refreshTable: () => void;
|
refreshTable: () => void;
|
||||||
}) {
|
}>) {
|
||||||
const {
|
const {
|
||||||
instance: userDetail,
|
instance: userDetail,
|
||||||
refreshInstance,
|
refreshInstance,
|
||||||
|
@ -31,7 +31,7 @@ type StockTrackingEntry = {
|
|||||||
details: ReactNode;
|
details: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function StockTrackingTable({ itemId }: { itemId: number }) {
|
export function StockTrackingTable({ itemId }: Readonly<{ itemId: number }>) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const table = useTable('stock_tracking');
|
const table = useTable('stock_tracking');
|
||||||
|
|
||||||
|
@ -1,26 +1,14 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
|
||||||
import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|
||||||
import { ModelType } from '../../enums/ModelType';
|
|
||||||
import { UserRoles } from '../../enums/Roles';
|
|
||||||
import { stockLocationFields } from '../../forms/StockForms';
|
|
||||||
import { getDetailUrl } from '../../functions/urls';
|
|
||||||
import {
|
|
||||||
useCreateApiFormModal,
|
|
||||||
useEditApiFormModal
|
|
||||||
} from '../../hooks/UseForm';
|
|
||||||
import { useTable } from '../../hooks/UseTable';
|
import { useTable } from '../../hooks/UseTable';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
|
||||||
import { TableColumn } from '../Column';
|
import { TableColumn } from '../Column';
|
||||||
import { BooleanColumn, DescriptionColumn } from '../ColumnRenderers';
|
|
||||||
import { TableFilter } from '../Filter';
|
|
||||||
import { InvenTreeTable } from '../InvenTreeTable';
|
import { InvenTreeTable } from '../InvenTreeTable';
|
||||||
|
|
||||||
export function TestStatisticsTable({ params = {} }: { params?: any }) {
|
export function TestStatisticsTable({
|
||||||
|
params = {}
|
||||||
|
}: Readonly<{ params?: any }>) {
|
||||||
const initialColumns: TableColumn[] = [];
|
const initialColumns: TableColumn[] = [];
|
||||||
const [templateColumnList, setTemplateColumnList] = useState(initialColumns);
|
const [templateColumnList, setTemplateColumnList] = useState(initialColumns);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import test, { Page, expect, request } from 'playwright/test';
|
import test, { expect } from 'playwright/test';
|
||||||
|
|
||||||
import { baseUrl } from './defaults.js';
|
import { baseUrl } from './defaults.js';
|
||||||
import { doQuickLogin } from './login.js';
|
import { doQuickLogin } from './login.js';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user