diff --git a/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx b/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx
index 4284e954df..98a561d6c0 100644
--- a/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx
+++ b/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx
@@ -1,5 +1,11 @@
import { t } from '@lingui/macro';
-import { SegmentedControl, SimpleGrid, Stack } from '@mantine/core';
+import {
+ Group,
+ SegmentedControl,
+ SimpleGrid,
+ Stack,
+ Text
+} from '@mantine/core';
import { ReactNode, useMemo, useState } from 'react';
import {
Bar,
@@ -17,6 +23,7 @@ import {
import { CHART_COLORS } from '../../../components/charts/colors';
import { formatDecimal, formatPriceRange } from '../../../defaults/formatters';
import { ApiEndpoints } from '../../../enums/ApiEndpoints';
+import { ModelType } from '../../../enums/ModelType';
import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState';
import { TableColumn } from '../../../tables/Column';
@@ -110,7 +117,17 @@ export default function BomPricingPanel({
title: t`Quantity`,
sortable: true,
switchable: false,
- render: (record: any) => formatDecimal(record.quantity)
+ render: (record: any) => {
+ let quantity = formatDecimal(record.quantity);
+ let units = record.sub_part_detail?.units;
+
+ return (
+
+ {quantity}
+ {units && [{units}]}
+
+ );
+ }
},
{
accessor: 'unit_price',
@@ -178,7 +195,9 @@ export default function BomPricingPanel({
sub_part_detail: true,
has_pricing: true
},
- enableSelection: false
+ enableSelection: false,
+ modelType: ModelType.part,
+ modelField: 'sub_part'
}}
/>
{bomPricingData.length > 0 ? (
diff --git a/src/frontend/src/pages/part/pricing/VariantPricingPanel.tsx b/src/frontend/src/pages/part/pricing/VariantPricingPanel.tsx
index 2c5c21a3c3..2aeea96bfb 100644
--- a/src/frontend/src/pages/part/pricing/VariantPricingPanel.tsx
+++ b/src/frontend/src/pages/part/pricing/VariantPricingPanel.tsx
@@ -14,6 +14,7 @@ import {
import { CHART_COLORS } from '../../../components/charts/colors';
import { formatCurrency } from '../../../defaults/formatters';
import { ApiEndpoints } from '../../../enums/ApiEndpoints';
+import { ModelType } from '../../../enums/ModelType';
import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState';
import { TableColumn } from '../../../tables/Column';
@@ -37,7 +38,7 @@ export default function VariantPricingPanel({
title: t`Variant Part`,
sortable: true,
switchable: false,
- render: (record: any) => PartColumn(record)
+ render: (record: any) => PartColumn(record, true)
},
{
accessor: 'pricing_min',
@@ -90,7 +91,8 @@ export default function VariantPricingPanel({
ancestor: part?.pk,
has_pricing: true
},
- enablePagination: false
+ enablePagination: true,
+ modelType: ModelType.part
}}
/>
{variantPricingData.length > 0 ? (
diff --git a/src/frontend/src/tables/ColumnRenderers.tsx b/src/frontend/src/tables/ColumnRenderers.tsx
index 5353a467b8..f1d39858cf 100644
--- a/src/frontend/src/tables/ColumnRenderers.tsx
+++ b/src/frontend/src/tables/ColumnRenderers.tsx
@@ -16,8 +16,13 @@ import { TableColumn } from './Column';
import { ProjectCodeHoverCard } from './TableHoverCard';
// Render a Part instance within a table
-export function PartColumn(part: any) {
- return ;
+export function PartColumn(part: any, full_name?: boolean) {
+ return (
+
+ );
}
export function BooleanColumn({
diff --git a/src/frontend/src/tables/bom/BomTable.tsx b/src/frontend/src/tables/bom/BomTable.tsx
index b2101897dc..6e2cea5b57 100644
--- a/src/frontend/src/tables/bom/BomTable.tsx
+++ b/src/frontend/src/tables/bom/BomTable.tsx
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
-import { Text } from '@mantine/core';
+import { Group, Text } from '@mantine/core';
import {
IconArrowRight,
IconCircleCheck,
@@ -10,7 +10,7 @@ import { useNavigate } from 'react-router-dom';
import { YesNoButton } from '../../components/buttons/YesNoButton';
import { Thumbnail } from '../../components/images/Thumbnail';
-import { formatPriceRange } from '../../defaults/formatters';
+import { formatDecimal, formatPriceRange } from '../../defaults/formatters';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
@@ -98,9 +98,19 @@ export function BomTable({
{
accessor: 'quantity',
switchable: false,
- sortable: true
- // TODO: Custom quantity renderer
- // TODO: see bom.js for existing implementation
+ sortable: true,
+ render: (record: any) => {
+ let quantity = formatDecimal(record.quantity);
+ let units = record.sub_part_detail?.units;
+
+ return (
+
+ {quantity}
+ {record.overage && +{record.overage}}
+ {units && {units}}
+
+ );
+ }
},
{
accessor: 'substitutes',
@@ -131,12 +141,22 @@ export function BomTable({
}),
{
accessor: 'price_range',
- title: t`Price Range`,
-
- sortable: false,
+ title: t`Unit Price`,
+ ordering: 'pricing_max',
+ sortable: true,
+ switchable: true,
render: (record: any) =>
formatPriceRange(record.pricing_min, record.pricing_max)
},
+ {
+ accessor: 'total_price',
+ title: t`Total Price`,
+ ordering: 'pricing_max_total',
+ sortable: true,
+ switchable: true,
+ render: (record: any) =>
+ formatPriceRange(record.pricing_min_total, record.pricing_max_total)
+ },
{
accessor: 'available_stock',
sortable: true,
diff --git a/src/frontend/src/tables/bom/UsedInTable.tsx b/src/frontend/src/tables/bom/UsedInTable.tsx
index 6f62a7ef31..69da8b651b 100644
--- a/src/frontend/src/tables/bom/UsedInTable.tsx
+++ b/src/frontend/src/tables/bom/UsedInTable.tsx
@@ -1,7 +1,9 @@
import { t } from '@lingui/macro';
+import { Group, Text } from '@mantine/core';
import { useMemo } from 'react';
import { PartHoverCard } from '../../components/images/Thumbnail';
+import { formatDecimal } from '../../defaults/formatters';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { useTable } from '../../hooks/UseTable';
@@ -39,8 +41,15 @@ export function UsedInTable({
{
accessor: 'quantity',
render: (record: any) => {
- // TODO: render units if appropriate
- return record.quantity;
+ let quantity = formatDecimal(record.quantity);
+ let units = record.sub_part_detail?.units;
+
+ return (
+
+ {quantity}
+ {units && {units}}
+
+ );
}
},
ReferenceColumn()
diff --git a/src/frontend/src/tables/part/PartTable.tsx b/src/frontend/src/tables/part/PartTable.tsx
index 856e88524b..f9d46cad23 100644
--- a/src/frontend/src/tables/part/PartTable.tsx
+++ b/src/frontend/src/tables/part/PartTable.tsx
@@ -158,7 +158,8 @@ function partTableColumns(): TableColumn[] {
{
accessor: 'price_range',
title: t`Price Range`,
- sortable: false,
+ sortable: true,
+ ordering: 'pricing_max',
render: (record: any) =>
formatPriceRange(record.pricing_min, record.pricing_max)
},