diff --git a/src/frontend/src/components/render/Part.tsx b/src/frontend/src/components/render/Part.tsx index 78cd5aae42..fc11a73c86 100644 --- a/src/frontend/src/components/render/Part.tsx +++ b/src/frontend/src/components/render/Part.tsx @@ -26,6 +26,9 @@ export function RenderPart( if (instance.active == false) { badgeColor = 'red'; badgeText = t`Inactive`; + } else if (instance.virtual) { + badgeColor = 'blue'; + badgeText = t`Virtual`; } else if (stock != null && stock <= 0) { badgeColor = 'orange'; badgeText = t`No stock`; diff --git a/src/frontend/src/tables/bom/BomTable.tsx b/src/frontend/src/tables/bom/BomTable.tsx index 194d696e42..401b0c109b 100644 --- a/src/frontend/src/tables/bom/BomTable.tsx +++ b/src/frontend/src/tables/bom/BomTable.tsx @@ -285,10 +285,16 @@ export function BomTable({ render: (record: any) => { const extra: ReactNode[] = []; + const part = record.sub_part_detail; + const available_stock: number = availableStockQuantity(record); const on_order: number = record?.on_order ?? 0; const building: number = record?.building ?? 0; + if (part?.virtual) { + return {t`Virtual part`}; + } + const text = available_stock <= 0 ? ( {t`No stock`} @@ -352,10 +358,17 @@ export function BomTable({ title: t`Can Build`, sortable: true, render: (record: any) => { + // Virtual sub-part - the "can build" quantity does not make sense here + if (record.sub_part_detail?.virtual) { + return '-'; + } + + // No information available if (record.can_build === null || record.can_build === undefined) { return '-'; } + // NaN or infinite values if ( !Number.isFinite(record.can_build) || Number.isNaN(record.can_build) diff --git a/src/frontend/tests/pages/pui_part.spec.ts b/src/frontend/tests/pages/pui_part.spec.ts index 29cc43aa48..ac9eb973c5 100644 --- a/src/frontend/tests/pages/pui_part.spec.ts +++ b/src/frontend/tests/pages/pui_part.spec.ts @@ -604,7 +604,7 @@ test('Parts - Revision', async ({ browser }) => { .getByText('Green Round Table (revision B) | B', { exact: true }) .click(); await page - .getByRole('option', { name: 'Thumbnail Green Round Table No stock' }) + .getByRole('option', { name: 'Thumbnail Green Round Table Virtual' }) .click(); await page.waitForURL('**/web/part/101/**');