diff --git a/src/frontend/src/components/details/Details.tsx b/src/frontend/src/components/details/Details.tsx index ab9872afddc2..d1ab9f8b4d7e 100644 --- a/src/frontend/src/components/details/Details.tsx +++ b/src/frontend/src/components/details/Details.tsx @@ -183,14 +183,14 @@ function NameBadge({ pk, type }: { pk: string | number; type: BadgeType }) { function TableStringValue(props: Readonly) { let value = props?.field_value; - if (value === undefined) { - return '---'; - } - if (props.field_data?.value_formatter) { value = props.field_data.value_formatter(); } + if (value === undefined) { + return '---'; + } + if (props.field_data?.badge) { return ; } diff --git a/src/frontend/src/hooks/UseTable.tsx b/src/frontend/src/hooks/UseTable.tsx index a75671550166..48d583ccf50e 100644 --- a/src/frontend/src/hooks/UseTable.tsx +++ b/src/frontend/src/hooks/UseTable.tsx @@ -17,6 +17,8 @@ export type TableState = { tableKey: string; refreshTable: () => void; activeFilters: TableFilter[]; + isLoading: boolean; + setIsLoading: (value: boolean) => void; setActiveFilters: (filters: TableFilter[]) => void; clearActiveFilters: () => void; expandedRecords: any[]; @@ -120,9 +122,13 @@ export function useTable(tableName: string): TableState { [records] ); + const [isLoading, setIsLoading] = useState(false); + return { tableKey, refreshTable, + isLoading, + setIsLoading, activeFilters, setActiveFilters, clearActiveFilters, diff --git a/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx b/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx index e431905eb64b..64911a98318b 100644 --- a/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx +++ b/src/frontend/src/pages/part/pricing/BomPricingPanel.tsx @@ -34,7 +34,7 @@ import { apiUrl } from '../../../states/ApiState'; import { TableColumn } from '../../../tables/Column'; import { DateColumn, PartColumn } from '../../../tables/ColumnRenderers'; import { InvenTreeTable } from '../../../tables/InvenTreeTable'; -import { NoPricingData } from './PricingPanel'; +import { LoadingPricingData, NoPricingData } from './PricingPanel'; // Display BOM data as a pie chart function BomPieChart({ @@ -209,6 +209,10 @@ export default function BomPricingPanel({ const [chartType, setChartType] = useState('pie'); + const hasData: boolean = useMemo(() => { + return !table.isLoading && bomPricingData.length > 0; + }, [table.isLoading, bomPricingData.length]); + return ( @@ -227,26 +231,34 @@ export default function BomPricingPanel({ modelField: 'sub_part' }} /> - {bomPricingData.length > 0 ? ( - - {chartType == 'bar' && ( - - )} - {chartType == 'pie' && ( - - )} - - - ) : ( - - )} + + {table.isLoading && } + {hasData && ( + + {chartType == 'bar' && ( + + )} + {chartType == 'pie' && ( + + )} + + + )} + {!hasData && !table.isLoading && } + ); diff --git a/src/frontend/src/pages/part/pricing/PricingPanel.tsx b/src/frontend/src/pages/part/pricing/PricingPanel.tsx index f3ffdf773994..81b4781e4e8a 100644 --- a/src/frontend/src/pages/part/pricing/PricingPanel.tsx +++ b/src/frontend/src/pages/part/pricing/PricingPanel.tsx @@ -4,6 +4,8 @@ import { AccordionControlProps, Alert, Box, + Center, + Loader, Space, Stack, Text, @@ -68,3 +70,14 @@ export function NoPricingData() { ); } + +export function LoadingPricingData() { + return ( +
+ + {t`Loading pricing data`} + + +
+ ); +} diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx index 083a3d551193..41c37e53e124 100644 --- a/src/frontend/src/tables/InvenTreeTable.tsx +++ b/src/frontend/src/tables/InvenTreeTable.tsx @@ -454,6 +454,10 @@ export function InvenTreeTable({ refetchOnMount: true }); + useEffect(() => { + tableState.setIsLoading(isFetching); + }, [isFetching]); + // Update tableState.records when new data received useEffect(() => { tableState.setRecords(data ?? []);