diff --git a/src/frontend/src/components/nav/InstanceDetail.tsx b/src/frontend/src/components/nav/InstanceDetail.tsx
index 74584e0b10..d2a95e3a39 100644
--- a/src/frontend/src/components/nav/InstanceDetail.tsx
+++ b/src/frontend/src/components/nav/InstanceDetail.tsx
@@ -1,37 +1,44 @@
-import { LoadingOverlay } from '@mantine/core';
+import { Center, Container, Loader } from '@mantine/core';
import type { ModelType } from '@lib/enums/ModelType';
import type { UserRoles } from '@lib/enums/Roles';
+import type { UseQueryResult } from '@tanstack/react-query';
+import { useEffect, useState } from 'react';
import { useUserState } from '../../states/UserState';
import ClientError from '../errors/ClientError';
import PermissionDenied from '../errors/PermissionDenied';
import ServerError from '../errors/ServerError';
export default function InstanceDetail({
- status,
- loading,
+ query,
children,
requiredRole,
requiredPermission
}: Readonly<{
- status: number;
- loading: boolean;
+ query: UseQueryResult;
children: React.ReactNode;
requiredRole?: UserRoles;
requiredPermission?: ModelType;
}>) {
const user = useUserState();
- if (loading || !user.isLoggedIn()) {
- return ;
- }
+ const [loaded, setLoaded] = useState(false);
- if (status >= 500) {
- return ;
- }
+ useEffect(() => {
+ if (query.isSuccess) {
+ setLoaded(true);
+ }
+ }, [query.isSuccess]);
- if (status >= 400) {
- return ;
+ if (query.isError) {
+ const reason = query.failureReason as any;
+ const statusCode = reason?.response?.status ?? reason?.status ?? 0;
+
+ if (statusCode >= 500) {
+ return ;
+ }
+
+ return ;
}
if (requiredRole && !user.hasViewRole(requiredRole)) {
@@ -42,5 +49,16 @@ export default function InstanceDetail({
return ;
}
+ if (!loaded || !user.isLoggedIn()) {
+ // Return a loader for the first page load
+ return (
+
+
+
+
+
+ );
+ }
+
return <>{children}>;
}
diff --git a/src/frontend/src/hooks/UseInstance.tsx b/src/frontend/src/hooks/UseInstance.tsx
index b9a81a19ef..4ff36fbc97 100644
--- a/src/frontend/src/hooks/UseInstance.tsx
+++ b/src/frontend/src/hooks/UseInstance.tsx
@@ -12,7 +12,6 @@ export interface UseInstanceResult {
refreshInstance: () => void;
refreshInstancePromise: () => Promise>;
instanceQuery: any;
- requestStatus: number;
isLoaded: boolean;
}
@@ -35,7 +34,6 @@ export function useInstance({
hasPrimaryKey = true,
refetchOnMount = true,
refetchOnWindowFocus = false,
- throwError = false,
updateInterval
}: {
endpoint: ApiEndpoints;
@@ -46,15 +44,12 @@ export function useInstance({
defaultValue?: any;
refetchOnMount?: boolean;
refetchOnWindowFocus?: boolean;
- throwError?: boolean;
updateInterval?: number;
}): UseInstanceResult {
const api = useApi();
const [instance, setInstance] = useState(defaultValue);
- const [requestStatus, setRequestStatus] = useState(0);
-
const instanceQuery = useQuery({
queryKey: [
'instance',
@@ -84,7 +79,6 @@ export function useInstance({
params: params
})
.then((response) => {
- setRequestStatus(response.status);
switch (response.status) {
case 200:
setInstance(response.data);
@@ -93,15 +87,6 @@ export function useInstance({
setInstance(defaultValue);
return defaultValue;
}
- })
- .catch((error) => {
- setRequestStatus(error.response?.status || 0);
- setInstance(defaultValue);
- console.error(`ERR: Error fetching instance ${url}:`, error);
-
- if (throwError) throw error;
-
- return defaultValue;
});
},
refetchOnMount: refetchOnMount,
@@ -131,7 +116,6 @@ export function useInstance({
refreshInstance,
refreshInstancePromise,
instanceQuery,
- requestStatus,
isLoaded
};
}
diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx
index 3f1bf4073b..6d4c43e44b 100644
--- a/src/frontend/src/pages/build/BuildDetail.tsx
+++ b/src/frontend/src/pages/build/BuildDetail.tsx
@@ -75,8 +75,7 @@ export default function BuildDetail() {
const {
instance: build,
refreshInstance,
- instanceQuery,
- requestStatus
+ instanceQuery
} = useInstance({
endpoint: ApiEndpoints.build_order_list,
pk: id,
@@ -621,11 +620,7 @@ export default function BuildDetail() {
{holdOrder.modal}
{issueOrder.modal}
{completeOrder.modal}
-
+
) {
const {
instance: company,
refreshInstance,
- instanceQuery,
- requestStatus
+ instanceQuery
} = useInstance({
endpoint: ApiEndpoints.company_list,
pk: id,
@@ -326,7 +325,10 @@ export default function CompanyDetail(props: Readonly) {
<>
{editCompany.modal}
{deleteCompany.modal}
-
+
+
diff --git a/src/frontend/src/pages/core/GroupDetail.tsx b/src/frontend/src/pages/core/GroupDetail.tsx
index 2c14f99c7d..4344e36ec4 100644
--- a/src/frontend/src/pages/core/GroupDetail.tsx
+++ b/src/frontend/src/pages/core/GroupDetail.tsx
@@ -26,7 +26,7 @@ import { useInstance } from '../../hooks/UseInstance';
export default function GroupDetail() {
const { id } = useParams();
- const { instance, instanceQuery, requestStatus } = useInstance({
+ const { instance, instanceQuery } = useInstance({
endpoint: ApiEndpoints.group_list,
pk: id
});
@@ -72,7 +72,7 @@ export default function GroupDetail() {
}, [instance, id]);
return (
-
+
+
diff --git a/src/frontend/src/pages/part/PartDetail.tsx b/src/frontend/src/pages/part/PartDetail.tsx
index 4b4d7363bd..f14f748e02 100644
--- a/src/frontend/src/pages/part/PartDetail.tsx
+++ b/src/frontend/src/pages/part/PartDetail.tsx
@@ -130,8 +130,7 @@ export default function PartDetail() {
const {
instance: part,
refreshInstance,
- instanceQuery,
- requestStatus
+ instanceQuery
} = useInstance({
endpoint: ApiEndpoints.part_list,
pk: id,
@@ -1028,11 +1027,7 @@ export default function PartDetail() {
{orderPartsWizard.wizard}
{findBySerialNumber.modal}
{transferStockItems.modal}
-
+
{user.hasViewRole(UserRoles.part_category) && (
diff --git a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx
index 74ca9e92a8..10ed323bef 100644
--- a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx
+++ b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx
@@ -59,8 +59,7 @@ export default function ReturnOrderDetail() {
const {
instance: order,
instanceQuery,
- refreshInstance,
- requestStatus
+ refreshInstance
} = useInstance({
endpoint: ApiEndpoints.return_order_list,
pk: id,
@@ -499,8 +498,7 @@ export default function ReturnOrderDetail() {
{completeOrder.modal}
{duplicateReturnOrder.modal}
diff --git a/src/frontend/src/pages/sales/SalesOrderDetail.tsx b/src/frontend/src/pages/sales/SalesOrderDetail.tsx
index dca6851ff5..11c7347519 100644
--- a/src/frontend/src/pages/sales/SalesOrderDetail.tsx
+++ b/src/frontend/src/pages/sales/SalesOrderDetail.tsx
@@ -68,8 +68,7 @@ export default function SalesOrderDetail() {
const {
instance: order,
instanceQuery,
- refreshInstance,
- requestStatus
+ refreshInstance
} = useInstance({
endpoint: ApiEndpoints.sales_order_list,
pk: id,
@@ -563,8 +562,7 @@ export default function SalesOrderDetail() {
{editSalesOrder.modal}
{duplicateSalesOrder.modal}
diff --git a/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx b/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
index 1a4e681e92..bef175b8a4 100644
--- a/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
+++ b/src/frontend/src/pages/sales/SalesOrderShipmentDetail.tsx
@@ -52,8 +52,7 @@ export default function SalesOrderShipmentDetail() {
const {
instance: shipment,
instanceQuery: shipmentQuery,
- refreshInstance: refreshShipment,
- requestStatus: shipmentStatus
+ refreshInstance: refreshShipment
} = useInstance({
endpoint: ApiEndpoints.sales_order_shipment_list,
pk: id,
@@ -65,8 +64,7 @@ export default function SalesOrderShipmentDetail() {
const {
instance: customer,
instanceQuery: customerQuery,
- refreshInstance: refreshCustomer,
- requestStatus: customerStatus
+ refreshInstance: refreshCustomer
} = useInstance({
endpoint: ApiEndpoints.company_list,
pk: shipment.order_detail?.customer,
@@ -351,8 +349,7 @@ export default function SalesOrderShipmentDetail() {
{editShipment.modal}
{deleteShipment.modal}
diff --git a/src/frontend/src/pages/stock/LocationDetail.tsx b/src/frontend/src/pages/stock/LocationDetail.tsx
index dcbcaf86d8..64d9d976cd 100644
--- a/src/frontend/src/pages/stock/LocationDetail.tsx
+++ b/src/frontend/src/pages/stock/LocationDetail.tsx
@@ -64,8 +64,7 @@ export default function Stock() {
const {
instance: location,
refreshInstance,
- instanceQuery,
- requestStatus
+ instanceQuery
} = useInstance({
endpoint: ApiEndpoints.stock_location_list,
hasPrimaryKey: true,
@@ -423,8 +422,7 @@ export default function Stock() {
{scanInStockItem.dialog}
{scanInStockLocation.dialog}
diff --git a/src/frontend/src/pages/stock/StockDetail.tsx b/src/frontend/src/pages/stock/StockDetail.tsx
index 56274de468..5abc143d75 100644
--- a/src/frontend/src/pages/stock/StockDetail.tsx
+++ b/src/frontend/src/pages/stock/StockDetail.tsx
@@ -114,8 +114,7 @@ export default function StockDetail() {
instance: stockitem,
refreshInstance,
refreshInstancePromise,
- instanceQuery,
- requestStatus
+ instanceQuery
} = useInstance({
endpoint: ApiEndpoints.stock_item_list,
pk: id,
@@ -1053,9 +1052,8 @@ export default function StockDetail() {
{findBySerialNumber.modal}
{scanIntoLocation.dialog}
{user.hasViewRole(UserRoles.stock_location) && (
diff --git a/src/frontend/src/tables/settings/GroupTable.tsx b/src/frontend/src/tables/settings/GroupTable.tsx
index a1be754ccf..110ac32f86 100644
--- a/src/frontend/src/tables/settings/GroupTable.tsx
+++ b/src/frontend/src/tables/settings/GroupTable.tsx
@@ -45,7 +45,6 @@ export function GroupDrawer({
} = useInstance({
endpoint: ApiEndpoints.group_list,
pk: id,
- throwError: true,
params: {
permission_detail: true,
role_detail: true,
diff --git a/src/frontend/src/tables/settings/TemplateTable.tsx b/src/frontend/src/tables/settings/TemplateTable.tsx
index 651219c1e8..3d82f460a1 100644
--- a/src/frontend/src/tables/settings/TemplateTable.tsx
+++ b/src/frontend/src/tables/settings/TemplateTable.tsx
@@ -80,8 +80,7 @@ export function TemplateDrawer({
} = useInstance({
endpoint: templateEndpoint,
hasPrimaryKey: true,
- pk: id,
- throwError: true
+ pk: id
});
// Editors
diff --git a/src/frontend/src/tables/settings/UserTable.tsx b/src/frontend/src/tables/settings/UserTable.tsx
index ac4469e51d..e5a3cc146b 100644
--- a/src/frontend/src/tables/settings/UserTable.tsx
+++ b/src/frontend/src/tables/settings/UserTable.tsx
@@ -68,8 +68,7 @@ export function UserDrawer({
instanceQuery: { isFetching, error }
} = useInstance({
endpoint: ApiEndpoints.user_list,
- pk: id,
- throwError: true
+ pk: id
});
const currentUserPk = useUserState(useShallow((s) => s.user?.pk));