2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 19:46:46 +00:00

fix various sonarlint warnings (#8479)

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair 2024-11-14 06:58:39 +01:00 committed by GitHub
parent 9d8f874bf3
commit ee01ac592f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 363 additions and 376 deletions

View File

@ -30,14 +30,14 @@ export default function DashboardMenu({
onStartEdit, onStartEdit,
onStartRemove, onStartRemove,
onAcceptLayout onAcceptLayout
}: { }: Readonly<{
editing: boolean; editing: boolean;
removing: boolean; removing: boolean;
onAddWidget: () => void; onAddWidget: () => void;
onStartEdit: () => void; onStartEdit: () => void;
onStartRemove: () => void; onStartRemove: () => void;
onAcceptLayout: () => void; onAcceptLayout: () => void;
}) { }>) {
const user = useUserState(); const user = useUserState();
const instanceName = useInstanceName(); const instanceName = useInstanceName();

View File

@ -29,12 +29,12 @@ export default function DashboardWidget({
editing, editing,
removing, removing,
onRemove onRemove
}: { }: Readonly<{
item: DashboardWidgetProps; item: DashboardWidgetProps;
editing: boolean; editing: boolean;
removing: boolean; removing: boolean;
onRemove: () => void; onRemove: () => void;
}) { }>) {
// TODO: Implement visibility check // TODO: Implement visibility check
// if (!props?.visible?.() == false) { // if (!props?.visible?.() == false) {
// return null; // return null;

View File

@ -26,12 +26,12 @@ export default function DashboardWidgetDrawer({
onClose, onClose,
onAddWidget, onAddWidget,
currentWidgets currentWidgets
}: { }: Readonly<{
opened: boolean; opened: boolean;
onClose: () => void; onClose: () => void;
onAddWidget: (widget: string) => void; onAddWidget: (widget: string) => void;
currentWidgets: string[]; currentWidgets: string[];
}) { }>) {
// Load available widgets // Load available widgets
const availableWidgets = useDashboardItems(); const availableWidgets = useDashboardItems();

View File

@ -24,7 +24,7 @@ import { StylishText } from '../../items/StylishText';
/** /**
* Render a link to an external news item * Render a link to an external news item
*/ */
function NewsLink({ item }: { item: any }) { function NewsLink({ item }: Readonly<{ item: any }>) {
let link: string = item.link; let link: string = item.link;
if (link?.startsWith('/')) { if (link?.startsWith('/')) {
@ -45,10 +45,10 @@ function NewsLink({ item }: { item: any }) {
function NewsItem({ function NewsItem({
item, item,
onMarkRead onMarkRead
}: { }: Readonly<{
item: any; item: any;
onMarkRead: (id: number) => void; onMarkRead: (id: number) => void;
}) { }>) {
const date: string = item.published?.split(' ')[0] ?? ''; const date: string = item.published?.split(' ')[0] ?? '';
return ( return (
<Table.Tr> <Table.Tr>

View File

@ -25,12 +25,12 @@ function QueryCountWidget({
title, title,
icon, icon,
params params
}: { }: Readonly<{
modelType: ModelType; modelType: ModelType;
title: string; title: string;
icon?: InvenTreeIconType; icon?: InvenTreeIconType;
params: any; params: any;
}): ReactNode { }>): ReactNode {
const user = useUserState(); const user = useUserState();
const navigate = useNavigate(); const navigate = useNavigate();

View File

@ -8,10 +8,10 @@ import { LanguageToggle } from '../items/LanguageToggle';
export function AuthFormOptions({ export function AuthFormOptions({
hostname, hostname,
toggleHostEdit toggleHostEdit
}: { }: Readonly<{
hostname: string; hostname: string;
toggleHostEdit: () => void; toggleHostEdit: () => void;
}) { }>) {
const [server] = useServerApiState((state) => [state.server]); const [server] = useServerApiState((state) => [state.server]);
return ( return (

View File

@ -26,7 +26,7 @@ function TableFieldRow({
control, control,
changeFn, changeFn,
removeFn removeFn
}: { }: Readonly<{
item: any; item: any;
idx: number; idx: number;
errors: any; errors: any;
@ -34,7 +34,7 @@ function TableFieldRow({
control: UseControllerReturn<FieldValues, any>; control: UseControllerReturn<FieldValues, any>;
changeFn: (idx: number, key: string, value: any) => void; changeFn: (idx: number, key: string, value: any) => void;
removeFn: (idx: number) => void; removeFn: (idx: number) => void;
}) { }>) {
// Table fields require render function // Table fields require render function
if (!definition.modelRenderer) { if (!definition.modelRenderer) {
return ( return (
@ -62,11 +62,11 @@ export function TableFieldErrorWrapper({
props, props,
errorKey, errorKey,
children children
}: { }: Readonly<{
props: TableFieldRowProps; props: TableFieldRowProps;
errorKey: string; errorKey: string;
children: ReactNode; children: ReactNode;
}) { }>) {
const msg = props?.rowErrors?.[errorKey]; const msg = props?.rowErrors?.[errorKey];
return ( return (

View File

@ -6,7 +6,7 @@ import * as classes from './GettingStartedCarousel.css';
import type { MenuLinkItem } from './MenuLinks'; import type { MenuLinkItem } from './MenuLinks';
import { StylishText } from './StylishText'; import { StylishText } from './StylishText';
function StartedCard({ title, description, link }: MenuLinkItem) { function StartedCard({ title, description, link }: Readonly<MenuLinkItem>) {
return ( return (
<Paper shadow='md' p='xl' radius='md' className={classes.card}> <Paper shadow='md' p='xl' radius='md' className={classes.card}>
<div> <div>

View File

@ -17,7 +17,7 @@ import { api } from '../../App';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
export function LicenceView(entries: any[]) { export function LicenceView(entries: Readonly<any[]>) {
return ( return (
<Stack gap='xs'> <Stack gap='xs'>
<Divider /> <Divider />

View File

@ -46,7 +46,7 @@ export function NavigationDrawer({
); );
} }
function DrawerContent({ closeFunc }: { closeFunc?: () => void }) { function DrawerContent({ closeFunc }: Readonly<{ closeFunc?: () => void }>) {
const user = useUserState(); const user = useUserState();
const globalSettings = useGlobalSettingsState(); const globalSettings = useGlobalSettingsState();
@ -186,13 +186,11 @@ function DrawerContent({ closeFunc }: { closeFunc?: () => void }) {
/> />
<Space h='md' /> <Space h='md' />
{plugins.length > 0 ? ( {plugins.length > 0 ? (
<> <MenuLinks
<MenuLinks title={t`Plugins`}
title={t`Plugins`} links={plugins}
links={plugins} beforeClick={closeFunc}
beforeClick={closeFunc} />
/>
</>
) : ( ) : (
<></> <></>
)} )}

View File

@ -36,10 +36,10 @@ import { ModelInformationDict } from '../render/ModelType';
function NotificationEntry({ function NotificationEntry({
notification, notification,
onRead onRead
}: { }: Readonly<{
notification: any; notification: any;
onRead: () => void; onRead: () => void;
}) { }>) {
const navigate = useNavigate(); const navigate = useNavigate();
let link = notification.target?.link; let link = notification.target?.link;

View File

@ -7,10 +7,10 @@ import { useGlobalSettingsState } from '../../states/SettingsState';
export default function PageTitle({ export default function PageTitle({
title, title,
subtitle subtitle
}: { }: Readonly<{
title?: string; title?: string;
subtitle?: string; subtitle?: string;
}) { }>) {
const globalSettings = useGlobalSettingsState(); const globalSettings = useGlobalSettingsState();
const pageTitle = useMemo(() => { const pageTitle = useMemo(() => {

View File

@ -12,10 +12,10 @@ import type { PluginInterface } from './PluginInterface';
export default function LocateItemButton({ export default function LocateItemButton({
stockId, stockId,
locationId locationId
}: { }: Readonly<{
stockId?: number; stockId?: number;
locationId?: number; locationId?: number;
}) { }>) {
const locatePlugins = usePluginsWithMixin('locate'); const locatePlugins = usePluginsWithMixin('locate');
const [selectedPlugin, setSelectedPlugin] = useState<string | undefined>( const [selectedPlugin, setSelectedPlugin] = useState<string | undefined>(

View File

@ -18,10 +18,10 @@ import PluginSettingsPanel from './PluginSettingsPanel';
export default function PluginDrawer({ export default function PluginDrawer({
pluginKey, pluginKey,
pluginInstance pluginInstance
}: { }: Readonly<{
pluginKey?: string; pluginKey?: string;
pluginInstance: PluginInterface; pluginInstance: PluginInterface;
}) { }>) {
const { id } = useParams(); const { id } = useParams();
const pluginPrimaryKey: string = useMemo(() => { const pluginPrimaryKey: string = useMemo(() => {
@ -53,106 +53,104 @@ export default function PluginDrawer({
} }
return ( return (
<> <Accordion defaultValue={['plugin-details', 'plugin-settings']} multiple>
<Accordion defaultValue={['plugin-details', 'plugin-settings']} multiple> <Accordion.Item value='plugin-details'>
<Accordion.Item value='plugin-details'> <Accordion.Control>
<StylishText size='lg'>{t`Plugin Information`}</StylishText>
</Accordion.Control>
<Accordion.Panel>
<Stack gap='xs'>
<Card withBorder>
<Stack gap='md'>
<Stack pos='relative' gap='xs'>
<InfoItem
type='text'
name={t`Name`}
value={pluginInstance?.name}
/>
<InfoItem
type='text'
name={t`Description`}
value={pluginInstance?.meta.description}
/>
<InfoItem
type='text'
name={t`Author`}
value={pluginInstance?.meta.author}
/>
<InfoItem
type='text'
name={t`Date`}
value={pluginInstance?.meta.pub_date}
/>
<InfoItem
type='text'
name={t`Version`}
value={pluginInstance?.meta.version}
/>
<InfoItem
type='boolean'
name={t`Active`}
value={pluginInstance?.active}
/>
</Stack>
</Stack>
</Card>
<Card withBorder>
<Stack gap='md'>
<Stack pos='relative' gap='xs'>
{pluginInstance?.is_package && (
<InfoItem
type='text'
name={t`Package Name`}
value={pluginInstance?.package_name}
/>
)}
<InfoItem
type='text'
name={t`Installation Path`}
value={pluginInstance?.meta.package_path}
/>
<InfoItem
type='boolean'
name={t`Builtin`}
value={pluginInstance?.is_builtin}
/>
<InfoItem
type='boolean'
name={t`Package`}
value={pluginInstance?.is_package}
/>
</Stack>
</Stack>
</Card>
</Stack>
</Accordion.Panel>
</Accordion.Item>
{hasSettings && (
<Accordion.Item value='plugin-settings'>
<Accordion.Control> <Accordion.Control>
<StylishText size='lg'>{t`Plugin Information`}</StylishText> <StylishText size='lg'>{t`Plugin Settings`}</StylishText>
</Accordion.Control> </Accordion.Control>
<Accordion.Panel> <Accordion.Panel>
<Stack gap='xs'> <Card withBorder>
<Card withBorder> <PluginSettingList pluginKey={pluginPrimaryKey} />
<Stack gap='md'> </Card>
<Stack pos='relative' gap='xs'>
<InfoItem
type='text'
name={t`Name`}
value={pluginInstance?.name}
/>
<InfoItem
type='text'
name={t`Description`}
value={pluginInstance?.meta.description}
/>
<InfoItem
type='text'
name={t`Author`}
value={pluginInstance?.meta.author}
/>
<InfoItem
type='text'
name={t`Date`}
value={pluginInstance?.meta.pub_date}
/>
<InfoItem
type='text'
name={t`Version`}
value={pluginInstance?.meta.version}
/>
<InfoItem
type='boolean'
name={t`Active`}
value={pluginInstance?.active}
/>
</Stack>
</Stack>
</Card>
<Card withBorder>
<Stack gap='md'>
<Stack pos='relative' gap='xs'>
{pluginInstance?.is_package && (
<InfoItem
type='text'
name={t`Package Name`}
value={pluginInstance?.package_name}
/>
)}
<InfoItem
type='text'
name={t`Installation Path`}
value={pluginInstance?.meta.package_path}
/>
<InfoItem
type='boolean'
name={t`Builtin`}
value={pluginInstance?.is_builtin}
/>
<InfoItem
type='boolean'
name={t`Package`}
value={pluginInstance?.is_package}
/>
</Stack>
</Stack>
</Card>
</Stack>
</Accordion.Panel> </Accordion.Panel>
</Accordion.Item> </Accordion.Item>
{hasSettings && ( )}
<Accordion.Item value='plugin-settings'> {pluginAdmin?.source && (
<Accordion.Control> <Accordion.Item value='plugin-custom'>
<StylishText size='lg'>{t`Plugin Settings`}</StylishText> <Accordion.Control>
</Accordion.Control> <StylishText size='lg'>{t`Plugin Configuration`}</StylishText>
<Accordion.Panel> </Accordion.Control>
<Card withBorder> <Accordion.Panel>
<PluginSettingList pluginKey={pluginPrimaryKey} /> <Card withBorder>
</Card> <PluginSettingsPanel pluginAdmin={pluginAdmin} />
</Accordion.Panel> </Card>
</Accordion.Item> </Accordion.Panel>
)} </Accordion.Item>
{pluginAdmin?.source && ( )}
<Accordion.Item value='plugin-custom'> </Accordion>
<Accordion.Control>
<StylishText size='lg'>{t`Plugin Configuration`}</StylishText>
</Accordion.Control>
<Accordion.Panel>
<Card withBorder>
<PluginSettingsPanel pluginAdmin={pluginAdmin} />
</Card>
</Accordion.Panel>
</Accordion.Item>
)}
</Accordion>
</>
); );
} }

View File

@ -18,9 +18,9 @@ export interface PluginAdminInterface {
*/ */
export default function PluginSettingsPanel({ export default function PluginSettingsPanel({
pluginAdmin pluginAdmin
}: { }: Readonly<{
pluginAdmin: PluginAdminInterface; pluginAdmin: PluginAdminInterface;
}) { }>) {
const pluginContext = useInvenTreeContext(); const pluginContext = useInvenTreeContext();
return ( return (

View File

@ -21,11 +21,11 @@ export default function RemoteComponent({
source, source,
defaultFunctionName, defaultFunctionName,
context context
}: { }: Readonly<{
source: string; source: string;
defaultFunctionName: string; defaultFunctionName: string;
context: InvenTreeContext; context: InvenTreeContext;
}) { }>) {
const componentRef = useRef<HTMLDivElement>(); const componentRef = useRef<HTMLDivElement>();
const [renderingError, setRenderingError] = useState<string | undefined>( const [renderingError, setRenderingError] = useState<string | undefined>(
@ -78,28 +78,23 @@ export default function RemoteComponent({
}, [sourceFile, functionName, context]); }, [sourceFile, functionName, context]);
return ( return (
<> <Boundary
<Boundary label={identifierString(`RemoteComponent-${sourceFile}-${functionName}`)}
label={identifierString( >
`RemoteComponent-${sourceFile}-${functionName}` <Stack gap='xs'>
{renderingError && (
<Alert
color='red'
title={t`Error Loading Content`}
icon={<IconExclamationCircle />}
>
<Text>
{t`Error occurred while loading plugin content`}: {renderingError}
</Text>
</Alert>
)} )}
> <div ref={componentRef as any} />
<Stack gap='xs'> </Stack>
{renderingError && ( </Boundary>
<Alert
color='red'
title={t`Error Loading Content`}
icon={<IconExclamationCircle />}
>
<Text>
{t`Error occurred while loading plugin content`}:{' '}
{renderingError}
</Text>
</Alert>
)}
<div ref={componentRef as any} />
</Stack>
</Boundary>
</>
); );
} }

View File

@ -121,11 +121,11 @@ function SalesOrderAllocateLineRow({
props, props,
record, record,
sourceLocation sourceLocation
}: { }: Readonly<{
props: TableFieldRowProps; props: TableFieldRowProps;
record: any; record: any;
sourceLocation?: number | null; sourceLocation?: number | null;
}) { }>) {
// Statically defined field for selecting the stock item // Statically defined field for selecting the stock item
const stockItemField: ApiFormFieldType = useMemo(() => { const stockItemField: ApiFormFieldType = useMemo(() => {
return { return {
@ -360,7 +360,7 @@ export function useSalesOrderAllocationFields({
shipment shipment
}: { }: {
orderId?: number; orderId?: number;
shipment: any | null; shipment: any;
}): ApiFormFieldSet { }): ApiFormFieldSet {
return useMemo(() => { return useMemo(() => {
return { return {

View File

@ -7,36 +7,34 @@ import { useUserState } from '../../states/UserState';
import PartBuildAllocationsTable from '../../tables/part/PartBuildAllocationsTable'; import PartBuildAllocationsTable from '../../tables/part/PartBuildAllocationsTable';
import PartSalesAllocationsTable from '../../tables/part/PartSalesAllocationsTable'; import PartSalesAllocationsTable from '../../tables/part/PartSalesAllocationsTable';
export default function PartAllocationPanel({ part }: { part: any }) { export default function PartAllocationPanel({ part }: Readonly<{ part: any }>) {
const user = useUserState(); const user = useUserState();
return ( return (
<> <Accordion
<Accordion multiple={true}
multiple={true} defaultValue={['buildallocations', 'salesallocations']}
defaultValue={['buildallocations', 'salesallocations']} >
> {part.component && user.hasViewRole(UserRoles.build) && (
{part.component && user.hasViewRole(UserRoles.build) && ( <Accordion.Item value='buildallocations' key='buildallocations'>
<Accordion.Item value='buildallocations' key='buildallocations'> <Accordion.Control>
<Accordion.Control> <StylishText size='lg'>{t`Build Order Allocations`}</StylishText>
<StylishText size='lg'>{t`Build Order Allocations`}</StylishText> </Accordion.Control>
</Accordion.Control> <Accordion.Panel>
<Accordion.Panel> <PartBuildAllocationsTable partId={part.pk} />
<PartBuildAllocationsTable partId={part.pk} /> </Accordion.Panel>
</Accordion.Panel> </Accordion.Item>
</Accordion.Item> )}
)} {part.salable && user.hasViewRole(UserRoles.sales_order) && (
{part.salable && user.hasViewRole(UserRoles.sales_order) && ( <Accordion.Item value='salesallocations' key='salesallocations'>
<Accordion.Item value='salesallocations' key='salesallocations'> <Accordion.Control>
<Accordion.Control> <StylishText size='lg'>{t`Sales Order Allocations`}</StylishText>
<StylishText size='lg'>{t`Sales Order Allocations`}</StylishText> </Accordion.Control>
</Accordion.Control> <Accordion.Panel>
<Accordion.Panel> <PartSalesAllocationsTable partId={part.pk} />
<PartSalesAllocationsTable partId={part.pk} /> </Accordion.Panel>
</Accordion.Panel> </Accordion.Item>
</Accordion.Item> )}
)} </Accordion>
</Accordion>
</>
); );
} }

View File

@ -26,7 +26,7 @@ import { TableHoverCard } from '../../tables/TableHoverCard';
/* /*
* Render a tooltip for the chart, with correct date information * Render a tooltip for the chart, with correct date information
*/ */
function ChartTooltip({ label, payload }: ChartTooltipProps) { function ChartTooltip({ label, payload }: Readonly<ChartTooltipProps>) {
if (!payload) { if (!payload) {
return null; return null;
} }
@ -56,7 +56,9 @@ function ChartTooltip({ label, payload }: ChartTooltipProps) {
); );
} }
export default function PartSchedulingDetail({ part }: { part: any }) { export default function PartSchedulingDetail({
part
}: Readonly<{ part: any }>) {
const table = useTable('part-scheduling'); const table = useTable('part-scheduling');
const navigate = useNavigate(); const navigate = useNavigate();

View File

@ -33,7 +33,7 @@ import { RowDeleteAction, RowEditAction } from '../../tables/RowActions';
/* /*
* Render a tooltip for the chart, with correct date information * Render a tooltip for the chart, with correct date information
*/ */
function ChartTooltip({ label, payload }: ChartTooltipProps) { function ChartTooltip({ label, payload }: Readonly<ChartTooltipProps>) {
const formattedLabel: string = useMemo(() => { const formattedLabel: string = useMemo(() => {
if (label && typeof label === 'number') { if (label && typeof label === 'number') {
return formatDate(new Date(label).toISOString()) ?? label; return formatDate(new Date(label).toISOString()) ?? label;
@ -66,7 +66,9 @@ function ChartTooltip({ label, payload }: ChartTooltipProps) {
); );
} }
export default function PartStocktakeDetail({ partId }: { partId: number }) { export default function PartStocktakeDetail({
partId
}: Readonly<{ partId: number }>) {
const user = useUserState(); const user = useUserState();
const table = useTable('part-stocktake'); const table = useTable('part-stocktake');

View File

@ -5,7 +5,9 @@ import { StylishText } from '../../components/items/StylishText';
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable'; import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable'; import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
export default function PartSupplierDetail({ partId }: { partId: number }) { export default function PartSupplierDetail({
partId
}: Readonly<{ partId: number }>) {
return ( return (
<Accordion multiple defaultValue={['part-suppliers', 'part-manufacturers']}> <Accordion multiple defaultValue={['part-suppliers', 'part-manufacturers']}>
<Accordion.Item value='part-suppliers'> <Accordion.Item value='part-suppliers'>

View File

@ -41,7 +41,7 @@ export default function InvenTreeTableHeader({
columns, columns,
filters, filters,
toggleColumn toggleColumn
}: { }: Readonly<{
tableUrl: string; tableUrl: string;
tableState: TableState; tableState: TableState;
tableProps: InvenTreeTableProps<any>; tableProps: InvenTreeTableProps<any>;
@ -49,7 +49,7 @@ export default function InvenTreeTableHeader({
columns: any; columns: any;
filters: TableFilter[]; filters: TableFilter[];
toggleColumn: (column: string) => void; toggleColumn: (column: string) => void;
}) { }>) {
// Filter list visibility // Filter list visibility
const [filtersVisible, setFiltersVisible] = useState<boolean>(false); const [filtersVisible, setFiltersVisible] = useState<boolean>(false);

View File

@ -4,10 +4,10 @@ import { IconChevronDown, IconChevronRight } from '@tabler/icons-react';
export default function RowExpansionIcon({ export default function RowExpansionIcon({
enabled, enabled,
expanded expanded
}: { }: Readonly<{
enabled: boolean; enabled: boolean;
expanded: boolean; expanded: boolean;
}) { }>) {
return ( return (
<ActionIcon size='sm' variant='transparent' disabled={!enabled}> <ActionIcon size='sm' variant='transparent' disabled={!enabled}>
{expanded ? <IconChevronDown /> : <IconChevronRight />} {expanded ? <IconChevronDown /> : <IconChevronRight />}

View File

@ -56,11 +56,11 @@ export function BuildLineSubTable({
lineItem, lineItem,
onEditAllocation, onEditAllocation,
onDeleteAllocation onDeleteAllocation
}: { }: Readonly<{
lineItem: any; lineItem: any;
onEditAllocation?: (pk: number) => void; onEditAllocation?: (pk: number) => void;
onDeleteAllocation?: (pk: number) => void; onDeleteAllocation?: (pk: number) => void;
}) { }>) {
const user = useUserState(); const user = useUserState();
const navigate = useNavigate(); const navigate = useNavigate();

View File

@ -61,61 +61,59 @@ function OutputAllocationDrawer({
output, output,
opened, opened,
close close
}: { }: Readonly<{
build: any; build: any;
output: any; output: any;
opened: boolean; opened: boolean;
close: () => void; close: () => void;
}) { }>) {
return ( return (
<> <Drawer
<Drawer position='bottom'
position='bottom' size='lg'
size='lg' title={
title={ <Group p='md' wrap='nowrap' justify='space-apart'>
<Group p='md' wrap='nowrap' justify='space-apart'> <StylishText size='lg'>{t`Build Output Stock Allocation`}</StylishText>
<StylishText size='lg'>{t`Build Output Stock Allocation`}</StylishText> <Space h='lg' />
<Space h='lg' /> <PartColumn part={build.part_detail} />
<PartColumn part={build.part_detail} /> {output?.serial && (
{output?.serial && ( <Text size='sm'>
<Text size='sm'> {t`Serial Number`}: {output.serial}
{t`Serial Number`}: {output.serial} </Text>
</Text> )}
)} {output?.batch && (
{output?.batch && ( <Text size='sm'>
<Text size='sm'> {t`Batch Code`}: {output.batch}
{t`Batch Code`}: {output.batch} </Text>
</Text> )}
)} <Space h='lg' />
<Space h='lg' /> </Group>
</Group> }
opened={opened}
onClose={close}
withCloseButton
closeOnEscape
closeOnClickOutside
styles={{
header: {
width: '100%'
},
title: {
width: '100%'
} }
opened={opened} }}
onClose={close} >
withCloseButton <Divider />
closeOnEscape <Paper p='md'>
closeOnClickOutside <BuildLineTable
styles={{ build={build}
header: { output={output}
width: '100%' params={{
}, tracked: true
title: { }}
width: '100%' />
} </Paper>
}} </Drawer>
>
<Divider />
<Paper p='md'>
<BuildLineTable
build={build}
output={output}
params={{
tracked: true
}}
/>
</Paper>
</Drawer>
</>
); );
} }

View File

@ -27,9 +27,9 @@ import { BuildLineSubTable } from '../build/BuildLineTable';
*/ */
export default function PartBuildAllocationsTable({ export default function PartBuildAllocationsTable({
partId partId
}: { }: Readonly<{
partId: number; partId: number;
}) { }>) {
const user = useUserState(); const user = useUserState();
const navigate = useNavigate(); const navigate = useNavigate();
const table = useTable('part-build-allocations'); const table = useTable('part-build-allocations');
@ -106,25 +106,23 @@ export default function PartBuildAllocationsTable({
}, [table.isRowExpanded]); }, [table.isRowExpanded]);
return ( return (
<> <InvenTreeTable
<InvenTreeTable url={apiUrl(ApiEndpoints.build_line_list)}
url={apiUrl(ApiEndpoints.build_line_list)} tableState={table}
tableState={table} columns={tableColumns}
columns={tableColumns} props={{
props={{ minHeight: 200,
minHeight: 200, params: {
params: { part: partId,
part: partId, consumable: false,
consumable: false, build_detail: true,
build_detail: true, order_outstanding: true
order_outstanding: true },
}, enableColumnSwitching: false,
enableColumnSwitching: false, enableSearch: false,
enableSearch: false, rowActions: rowActions,
rowActions: rowActions, rowExpansion: rowExpansion
rowExpansion: rowExpansion }}
}} />
/>
</>
); );
} }

View File

@ -24,9 +24,9 @@ import SalesOrderAllocationTable from '../sales/SalesOrderAllocationTable';
export default function PartSalesAllocationsTable({ export default function PartSalesAllocationsTable({
partId partId
}: { }: Readonly<{
partId: number; partId: number;
}) { }>) {
const user = useUserState(); const user = useUserState();
const navigate = useNavigate(); const navigate = useNavigate();
const table = useTable('part-sales-allocations'); const table = useTable('part-sales-allocations');
@ -109,24 +109,22 @@ export default function PartSalesAllocationsTable({
}, [table.isRowExpanded]); }, [table.isRowExpanded]);
return ( return (
<> <InvenTreeTable
<InvenTreeTable url={apiUrl(ApiEndpoints.sales_order_line_list)}
url={apiUrl(ApiEndpoints.sales_order_line_list)} tableState={table}
tableState={table} columns={tableColumns}
columns={tableColumns} props={{
props={{ minHeight: 200,
minHeight: 200, params: {
params: { part: partId,
part: partId, order_detail: true,
order_detail: true, order_outstanding: true
order_outstanding: true },
}, enableSearch: false,
enableSearch: false, enableColumnSwitching: false,
enableColumnSwitching: false, rowExpansion: rowExpansion,
rowExpansion: rowExpansion, rowActions: rowActions
rowActions: rowActions }}
}} />
/>
</>
); );
} }

View File

@ -35,7 +35,7 @@ import { RowDeleteAction } from '../RowActions';
/* /*
* Render detail information for a particular barcode scan result. * Render detail information for a particular barcode scan result.
*/ */
function BarcodeScanDetail({ scan }: { scan: any }) { function BarcodeScanDetail({ scan }: Readonly<{ scan: any }>) {
const dataStyle: MantineStyleProp = { const dataStyle: MantineStyleProp = {
textWrap: 'wrap', textWrap: 'wrap',
lineBreak: 'auto', lineBreak: 'auto',
@ -51,93 +51,91 @@ function BarcodeScanDetail({ scan }: { scan: any }) {
}, [scan.context]); }, [scan.context]);
return ( return (
<> <Stack gap='xs'>
<Stack gap='xs'> <Divider />
<Divider /> <Table>
<Table> <Table.Tbody>
<Table.Tbody> <Table.Tr>
<Table.Td colSpan={2}>
<StylishText size='sm'>{t`Barcode Information`}</StylishText>
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Barcode`}</Table.Th>
<Table.Td>
<Text size='sm' style={dataStyle}>
{scan.data}
</Text>
</Table.Td>
<Table.Td>
<CopyButton value={scan.data} size='xs' />
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Timestamp`}</Table.Th>
<Table.Td>{scan.timestamp}</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`User`}</Table.Th>
<Table.Td>
<RenderUser instance={scan.user_detail} />
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Endpoint`}</Table.Th>
<Table.Td>{scan.endpoint}</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Result`}</Table.Th>
<Table.Td>
<PassFailButton value={scan.result} />
</Table.Td>
</Table.Tr>
{hasContextData && (
<Table.Tr> <Table.Tr>
<Table.Td colSpan={2}> <Table.Td colSpan={2}>
<StylishText size='sm'>{t`Barcode Information`}</StylishText> <StylishText size='sm'>{t`Context`}</StylishText>
</Table.Td> </Table.Td>
</Table.Tr> </Table.Tr>
<Table.Tr> )}
<Table.Th>{t`Barcode`}</Table.Th> {hasContextData &&
<Table.Td> Object.keys(scan.context).map((key) => (
<Text size='sm' style={dataStyle}> <Table.Tr key={key}>
{scan.data} <Table.Th>{key}</Table.Th>
</Text> <Table.Td>
</Table.Td> <Text size='sm' style={dataStyle}>
<Table.Td> {scan.context[key]}
<CopyButton value={scan.data} size='xs' /> </Text>
</Table.Td> </Table.Td>
</Table.Tr> <Table.Td>
<Table.Tr> <CopyButton value={scan.context[key]} size='xs' />
<Table.Th>{t`Timestamp`}</Table.Th>
<Table.Td>{scan.timestamp}</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`User`}</Table.Th>
<Table.Td>
<RenderUser instance={scan.user_detail} />
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Endpoint`}</Table.Th>
<Table.Td>{scan.endpoint}</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Th>{t`Result`}</Table.Th>
<Table.Td>
<PassFailButton value={scan.result} />
</Table.Td>
</Table.Tr>
{hasContextData && (
<Table.Tr>
<Table.Td colSpan={2}>
<StylishText size='sm'>{t`Context`}</StylishText>
</Table.Td> </Table.Td>
</Table.Tr> </Table.Tr>
)} ))}
{hasContextData && {hasResponseData && (
Object.keys(scan.context).map((key) => ( <Table.Tr>
<Table.Tr key={key}> <Table.Td colSpan={2}>
<Table.Th>{key}</Table.Th> <StylishText size='sm'>{t`Response`}</StylishText>
<Table.Td> </Table.Td>
<Text size='sm' style={dataStyle}> </Table.Tr>
{scan.context[key]} )}
</Text> {hasResponseData &&
</Table.Td> Object.keys(scan.response).map((key) => (
<Table.Td> <Table.Tr key={key}>
<CopyButton value={scan.context[key]} size='xs' /> <Table.Th>{key}</Table.Th>
</Table.Td> <Table.Td>
</Table.Tr> <Text size='sm' style={dataStyle}>
))} {scan.response[key]}
{hasResponseData && ( </Text>
<Table.Tr> </Table.Td>
<Table.Td colSpan={2}> <Table.Td>
<StylishText size='sm'>{t`Response`}</StylishText> <CopyButton value={scan.response[key]} size='xs' />
</Table.Td> </Table.Td>
</Table.Tr> </Table.Tr>
)} ))}
{hasResponseData && </Table.Tbody>
Object.keys(scan.response).map((key) => ( </Table>
<Table.Tr key={key}> </Stack>
<Table.Th>{key}</Table.Th>
<Table.Td>
<Text size='sm' style={dataStyle}>
{scan.response[key]}
</Text>
</Table.Td>
<Table.Td>
<CopyButton value={scan.response[key]} size='xs' />
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
</Stack>
</>
); );
} }

View File

@ -15,7 +15,7 @@ import type { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import { type RowAction, RowDeleteAction } from '../RowActions'; import { type RowAction, RowDeleteAction } from '../RowActions';
function ErrorDetail({ errorId }: { errorId?: number }) { function ErrorDetail({ errorId }: Readonly<{ errorId?: number }>) {
const { id } = useParams(); const { id } = useParams();
const errorPrimaryKey = useMemo(() => { const errorPrimaryKey = useMemo(() => {

View File

@ -15,9 +15,9 @@ import { InvenTreeTable } from '../InvenTreeTable';
export default function FailedTasksTable({ export default function FailedTasksTable({
onRecordsUpdated onRecordsUpdated
}: { }: Readonly<{
onRecordsUpdated: () => void; onRecordsUpdated: () => void;
}) { }>) {
const table = useTable('tasks-failed'); const table = useTable('tasks-failed');
const user = useUserState(); const user = useUserState();

View File

@ -10,9 +10,9 @@ import { InvenTreeTable } from '../InvenTreeTable';
export default function PendingTasksTable({ export default function PendingTasksTable({
onRecordsUpdated onRecordsUpdated
}: { }: Readonly<{
onRecordsUpdated: () => void; onRecordsUpdated: () => void;
}) { }>) {
const table = useTable('tasks-pending'); const table = useTable('tasks-pending');
const user = useUserState(); const user = useUserState();