diff --git a/src/frontend/src/components/images/ApiImage.tsx b/src/frontend/src/components/images/ApiImage.tsx
index 1b5ca4dd92..0221d04990 100644
--- a/src/frontend/src/components/images/ApiImage.tsx
+++ b/src/frontend/src/components/images/ApiImage.tsx
@@ -56,7 +56,7 @@ export function ApiImage(props: ImageProps) {
return (
-
+
{imgQuery.isError && }
);
diff --git a/src/frontend/src/components/items/ActionDropdown.tsx b/src/frontend/src/components/items/ActionDropdown.tsx
index d10ee66160..530019b47c 100644
--- a/src/frontend/src/components/items/ActionDropdown.tsx
+++ b/src/frontend/src/components/items/ActionDropdown.tsx
@@ -39,12 +39,12 @@ export function ActionDropdown({
- {actions.map((action, index) =>
+ {actions.map((action) =>
action.disabled ? null : (
-
+
{
if (action.onClick != undefined) {
action.onClick();
diff --git a/src/frontend/src/components/nav/BreadcrumbList.tsx b/src/frontend/src/components/nav/BreadcrumbList.tsx
index 4b59c6a00a..7223396b29 100644
--- a/src/frontend/src/components/nav/BreadcrumbList.tsx
+++ b/src/frontend/src/components/nav/BreadcrumbList.tsx
@@ -14,7 +14,7 @@ export function BreadcrumbList({ breadcrumbs }: { breadcrumbs: Breadcrumb[] }) {
return (
-
+
{breadcrumbs.map((breadcrumb, index) => {
return (
-
-
+
+
+ {imageUrl && (
+
+ )}
- {title && {title}}
- {subtitle && {subtitle}}
- {detail}
+ {title && {title}}
+ {subtitle && (
+
+ {subtitle}
+
+ )}
+ {detail}
+
{actions && (
{actions}
diff --git a/src/frontend/src/components/renderers/StatusRenderer.tsx b/src/frontend/src/components/renderers/StatusRenderer.tsx
index b0af1e1d76..f3a97ccf5d 100644
--- a/src/frontend/src/components/renderers/StatusRenderer.tsx
+++ b/src/frontend/src/components/renderers/StatusRenderer.tsx
@@ -72,11 +72,18 @@ export const StatusRenderer = ({
type: ModelType;
options?: renderStatusLabelOptionsInterface;
}) => {
- const [statusCodeList] = useServerApiState((state) => [state.status]);
+ const statusCodeList = useServerApiState.getState().status;
+
+ if (status === undefined) {
+ console.log('StatusRenderer: status is undefined');
+ return null;
+ }
+
if (statusCodeList === undefined) {
console.log('StatusRenderer: statusCodeList is undefined');
return null;
}
+
const statusCodes = statusCodeList[type];
if (statusCodes === undefined) {
console.log('StatusRenderer: statusCodes is undefined');
diff --git a/src/frontend/src/components/tables/InvenTreeTable.tsx b/src/frontend/src/components/tables/InvenTreeTable.tsx
index d04ccae5af..1af28739b7 100644
--- a/src/frontend/src/components/tables/InvenTreeTable.tsx
+++ b/src/frontend/src/components/tables/InvenTreeTable.tsx
@@ -423,12 +423,13 @@ export function InvenTreeTable({
/>
-
+
{tableProps.customActionGroups?.map(
(group: any, idx: number) => group
)}
{(tableProps.barcodeActions?.length ?? 0 > 0) && (
}
label={t`Barcode actions`}
tooltip={t`Barcode actions`}
@@ -437,6 +438,7 @@ export function InvenTreeTable({
)}
{(tableProps.printingActions?.length ?? 0 > 0) && (
}
label={t`Print actions`}
tooltip={t`Print actions`}
@@ -444,7 +446,10 @@ export function InvenTreeTable({
/>
)}
{tableProps.enableDownload && (
-
+
)}
diff --git a/src/frontend/src/components/tables/general/AttachmentTable.tsx b/src/frontend/src/components/tables/general/AttachmentTable.tsx
index 391be18191..ac7b3388ff 100644
--- a/src/frontend/src/components/tables/general/AttachmentTable.tsx
+++ b/src/frontend/src/components/tables/general/AttachmentTable.tsx
@@ -181,7 +181,7 @@ export function AttachmentTable({
if (allowEdit) {
actions.push(
-
+
{
@@ -200,7 +200,7 @@ export function AttachmentTable({
);
actions.push(
-
+
{
@@ -226,6 +226,7 @@ export function AttachmentTable({
{pk && pk > 0 && (
)}
{allowEdit && validPk && (
-
+
diff --git a/src/frontend/src/components/tables/general/CompanyTable.tsx b/src/frontend/src/components/tables/general/CompanyTable.tsx
index 2a7cfe0582..73a40c1b12 100644
--- a/src/frontend/src/components/tables/general/CompanyTable.tsx
+++ b/src/frontend/src/components/tables/general/CompanyTable.tsx
@@ -67,8 +67,10 @@ export function CompanyTable({
...params
},
onRowClick: (row: any) => {
- let base = path ?? 'company';
- navigate(`/${base}/${row.pk}`);
+ if (row.pk) {
+ let base = path ?? 'company';
+ navigate(`/${base}/${row.pk}`);
+ }
}
}}
/>
diff --git a/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx b/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
index 2f04bd4747..18e0783903 100644
--- a/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
+++ b/src/frontend/src/components/tables/purchasing/PurchaseOrderTable.tsx
@@ -1,6 +1,7 @@
import { t } from '@lingui/macro';
import { Group, Text } from '@mantine/core';
import { useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
@@ -9,7 +10,12 @@ import { ModelType } from '../../render/ModelType';
import { StatusRenderer } from '../../renderers/StatusRenderer';
import { InvenTreeTable } from '../InvenTreeTable';
+/**
+ * Display a table of purchase orders
+ */
export function PurchaseOrderTable({ params }: { params?: any }) {
+ const navigate = useNavigate();
+
const { tableKey } = useTableRefresh('purchase-order');
// TODO: Custom filters
@@ -100,6 +106,11 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
params: {
...params,
supplier_detail: true
+ },
+ onRowClick: (row: any) => {
+ if (row.pk) {
+ navigate(`/purchasing/purchase-order/${row.pk}`);
+ }
}
}}
/>
diff --git a/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx b/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
index 94bfcc523b..3c8a94cbe1 100644
--- a/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
+++ b/src/frontend/src/components/tables/sales/ReturnOrderTable.tsx
@@ -1,6 +1,7 @@
import { t } from '@lingui/macro';
import { Group, Text } from '@mantine/core';
import { useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
@@ -12,6 +13,8 @@ import { InvenTreeTable } from '../InvenTreeTable';
export function ReturnOrderTable({ params }: { params?: any }) {
const { tableKey } = useTableRefresh('return-orders');
+ const navigate = useNavigate();
+
// TODO: Custom filters
// TODO: Row actions
@@ -80,6 +83,11 @@ export function ReturnOrderTable({ params }: { params?: any }) {
params: {
...params,
customer_detail: true
+ },
+ onRowClick: (row: any) => {
+ if (row.pk) {
+ navigate(`/sales/return-order/${row.pk}/`);
+ }
}
}}
/>
diff --git a/src/frontend/src/components/tables/sales/SalesOrderTable.tsx b/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
index 3a25b75a5d..5f0589a366 100644
--- a/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
+++ b/src/frontend/src/components/tables/sales/SalesOrderTable.tsx
@@ -1,6 +1,7 @@
import { t } from '@lingui/macro';
import { Group, Text } from '@mantine/core';
import { useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
import { useTableRefresh } from '../../../hooks/TableRefresh';
import { ApiPaths, apiUrl } from '../../../states/ApiState';
@@ -12,6 +13,8 @@ import { InvenTreeTable } from '../InvenTreeTable';
export function SalesOrderTable({ params }: { params?: any }) {
const { tableKey } = useTableRefresh('sales-order');
+ const navigate = useNavigate();
+
// TODO: Custom filters
// TODO: Row actions
@@ -82,6 +85,11 @@ export function SalesOrderTable({ params }: { params?: any }) {
params: {
...params,
customer_detail: true
+ },
+ onRowClick: (row: any) => {
+ if (row.pk) {
+ navigate(`/sales/sales-order/${row.pk}/`);
+ }
}
}}
/>
diff --git a/src/frontend/src/components/tables/stock/StockItemTable.tsx b/src/frontend/src/components/tables/stock/StockItemTable.tsx
index c29e5792ee..776ac66f4c 100644
--- a/src/frontend/src/components/tables/stock/StockItemTable.tsx
+++ b/src/frontend/src/components/tables/stock/StockItemTable.tsx
@@ -70,7 +70,8 @@ function stockItemTableColumns(): TableColumn[] {
title: t`Location`,
render: function (record: any) {
// TODO: Custom renderer for location
- return record.location;
+ // TODO: Note, if not "In stock" we don't want to display the actual location here
+ return record?.location_detail?.pathstring ?? record.location ?? '-';
}
}
// TODO: stocktake column
@@ -142,7 +143,8 @@ export function StockItemTable({ params = {} }: { params?: any }) {
params: {
...params,
part_detail: true,
- location_detail: true
+ location_detail: true,
+ supplier_part_detail: true
}
}}
/>
diff --git a/src/frontend/src/hooks/UseInstance.tsx b/src/frontend/src/hooks/UseInstance.tsx
index 7dbf10bfa4..ed1077bd6f 100644
--- a/src/frontend/src/hooks/UseInstance.tsx
+++ b/src/frontend/src/hooks/UseInstance.tsx
@@ -19,7 +19,7 @@ export function useInstance({
params = {},
defaultValue = {},
hasPrimaryKey = true,
- refetchOnMount = false,
+ refetchOnMount = true,
refetchOnWindowFocus = false
}: {
endpoint: ApiPaths;
@@ -36,7 +36,7 @@ export function useInstance({
queryKey: ['instance', endpoint, pk, params],
queryFn: async () => {
if (hasPrimaryKey) {
- if (pk == null || pk == undefined || pk.length == 0) {
+ if (pk == null || pk == undefined || pk.length == 0 || pk == '-1') {
setInstance(defaultValue);
return null;
}
diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx
index 72e60b57eb..c58f3d6e7c 100644
--- a/src/frontend/src/pages/build/BuildDetail.tsx
+++ b/src/frontend/src/pages/build/BuildDetail.tsx
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
-import { Alert, LoadingOverlay, Stack, Text } from '@mantine/core';
+import { Group, LoadingOverlay, Stack, Table } from '@mantine/core';
import {
IconClipboardCheck,
IconClipboardList,
@@ -23,12 +23,10 @@ import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { ActionDropdown } from '../../components/items/ActionDropdown';
-import {
- PlaceholderPanel,
- PlaceholderPill
-} from '../../components/items/Placeholder';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
+import { ModelType } from '../../components/render/ModelType';
+import { StatusRenderer } from '../../components/renderers/StatusRenderer';
import { BuildOrderTable } from '../../components/tables/build/BuildOrderTable';
import { AttachmentTable } from '../../components/tables/general/AttachmentTable';
import { StockItemTable } from '../../components/tables/stock/StockItemTable';
@@ -43,6 +41,8 @@ import { useUserState } from '../../states/UserState';
export default function BuildDetail() {
const { id } = useParams();
+ const user = useUserState();
+
const {
instance: build,
refreshInstance,
@@ -52,37 +52,65 @@ export default function BuildDetail() {
pk: id,
params: {
part_detail: true
- }
+ },
+ refetchOnMount: true
});
- const user = useUserState();
+ const buildDetailsPanel = useMemo(() => {
+ return (
+
+
+
+
+ {t`Base Part`} |
+ {build.part_detail?.name} |
+
+
+ {t`Quantity`} |
+ {build.quantity} |
+
+
+ {t`Build Status`} |
+
+ {build.status && (
+
+ )}
+ |
+
+
+
+
+
+ );
+ }, [build]);
const buildPanels: PanelType[] = useMemo(() => {
return [
{
name: 'details',
label: t`Build Details`,
- icon: ,
- content:
+ icon: ,
+ content: buildDetailsPanel
},
{
name: 'allocate-stock',
label: t`Allocate Stock`,
- icon: ,
- content:
+ icon:
// TODO: Hide if build is complete
},
{
name: 'incomplete-outputs',
label: t`Incomplete Outputs`,
- icon: ,
- content:
+ icon:
// TODO: Hide if build is complete
},
{
name: 'complete-outputs',
label: t`Completed Outputs`,
- icon: ,
+ icon: ,
content: (
,
+ icon: ,
content: (
,
+ icon: ,
content: (
,
+ icon: ,
content: (
,
+ icon: ,
content: (
}
actions={[
@@ -170,6 +199,7 @@ export default function BuildDetail() {
]}
/>,
}
actions={[
@@ -181,6 +211,7 @@ export default function BuildDetail() {
]}
/>,
}
actions={[
@@ -204,19 +235,28 @@ export default function BuildDetail() {
];
}, [id, build, user]);
+ const buildDetail = useMemo(() => {
+ return StatusRenderer({
+ status: build.status,
+ type: ModelType.build
+ });
+ }, [build, id]);
+
return (
<>
+
-
>
diff --git a/src/frontend/src/pages/build/BuildIndex.tsx b/src/frontend/src/pages/build/BuildIndex.tsx
index 652cc6c160..7e6fafbd44 100644
--- a/src/frontend/src/pages/build/BuildIndex.tsx
+++ b/src/frontend/src/pages/build/BuildIndex.tsx
@@ -15,7 +15,11 @@ export default function BuildIndex() {
notYetImplemented()}>
+
]}
diff --git a/src/frontend/src/pages/company/CompanyDetail.tsx b/src/frontend/src/pages/company/CompanyDetail.tsx
index f080fbb6e2..304e219d6d 100644
--- a/src/frontend/src/pages/company/CompanyDetail.tsx
+++ b/src/frontend/src/pages/company/CompanyDetail.tsx
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
-import { Group, LoadingOverlay, Stack, Text } from '@mantine/core';
+import { LoadingOverlay, Stack } from '@mantine/core';
import {
IconBuildingFactory2,
IconBuildingWarehouse,
@@ -20,7 +20,6 @@ import {
import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
-import { Thumbnail } from '../../components/images/Thumbnail';
import { ActionDropdown } from '../../components/items/ActionDropdown';
import { Breadcrumb } from '../../components/nav/BreadcrumbList';
import { PageDetail } from '../../components/nav/PageDetail';
@@ -159,24 +158,6 @@ export default function CompanyDetail(props: CompanyDetailProps) {
];
}, [id, company]);
- const companyDetail = useMemo(() => {
- return (
-
-
-
-
- {company.name}
-
- {company.description}
-
-
- );
- }, [id, company]);
-
const companyActions = useMemo(() => {
// TODO: Finer fidelity on these permissions, perhaps?
let canEdit = user.checkUserRole('purchase_order', 'change');
@@ -184,6 +165,7 @@ export default function CompanyDetail(props: CompanyDetailProps) {
return [
}
actions={[
@@ -216,8 +198,10 @@ export default function CompanyDetail(props: CompanyDetailProps) {
diff --git a/src/frontend/src/pages/part/PartDetail.tsx b/src/frontend/src/pages/part/PartDetail.tsx
index 3179a65ae7..a154a9f5fa 100644
--- a/src/frontend/src/pages/part/PartDetail.tsx
+++ b/src/frontend/src/pages/part/PartDetail.tsx
@@ -30,7 +30,6 @@ import {
import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
-import { ApiImage } from '../../components/images/ApiImage';
import { ActionDropdown } from '../../components/items/ActionDropdown';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
@@ -203,17 +202,8 @@ export default function PartDetail() {
const partDetail = useMemo(() => {
return (
-
-
- {part.full_name}
-
- {part.description}
+ Stock: {part.in_stock}
);
@@ -223,6 +213,7 @@ export default function PartDetail() {
// TODO: Disable actions based on user permissions
return [
}
actions={[
@@ -246,6 +237,7 @@ export default function PartDetail() {
]}
/>,
}
actions={[
@@ -262,6 +254,7 @@ export default function PartDetail() {
]}
/>,
}
actions={[
@@ -297,6 +290,9 @@ export default function PartDetail() {
{
+ return [
+ {
+ name: 'detail',
+ label: t`Order Details`,
+ icon:
+ },
+ {
+ name: 'line-items',
+ label: t`Line Items`,
+ icon:
+ },
+ {
+ name: 'received-stock',
+ label: t`Received Stock`,
+ icon: ,
+ content: (
+
+ )
+ },
+ {
+ name: 'attachments',
+ label: t`Attachments`,
+ icon: ,
+ content: (
+
+ )
+ },
+ {
+ name: 'notes',
+ label: t`Notes`,
+ icon: ,
+ content: (
+
+ )
+ }
+ ];
+ }, [order, id]);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx
new file mode 100644
index 0000000000..55844b9d16
--- /dev/null
+++ b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx
@@ -0,0 +1,76 @@
+import { t } from '@lingui/macro';
+import { LoadingOverlay, Stack } from '@mantine/core';
+import { IconInfoCircle, IconNotes, IconPaperclip } from '@tabler/icons-react';
+import { useMemo } from 'react';
+import { useParams } from 'react-router-dom';
+
+import { PageDetail } from '../../components/nav/PageDetail';
+import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
+import { AttachmentTable } from '../../components/tables/general/AttachmentTable';
+import { NotesEditor } from '../../components/widgets/MarkdownEditor';
+import { useInstance } from '../../hooks/UseInstance';
+import { ApiPaths, apiUrl } from '../../states/ApiState';
+
+/**
+ * Detail page for a single ReturnOrder
+ */
+export default function ReturnOrderDetail() {
+ const { id } = useParams();
+
+ const { instance: order, instanceQuery } = useInstance({
+ endpoint: ApiPaths.return_order_list,
+ pk: id,
+ params: {
+ customer_detail: true
+ }
+ });
+
+ const orderPanels: PanelType[] = useMemo(() => {
+ return [
+ {
+ name: 'detail',
+ label: t`Order Details`,
+ icon:
+ },
+ {
+ name: 'attachments',
+ label: t`Attachments`,
+ icon: ,
+ content: (
+
+ )
+ },
+ {
+ name: 'notes',
+ label: t`Notes`,
+ icon: ,
+ content: (
+
+ )
+ }
+ ];
+ }, [order, id]);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/frontend/src/pages/sales/SalesOrderDetail.tsx b/src/frontend/src/pages/sales/SalesOrderDetail.tsx
new file mode 100644
index 0000000000..8fc3ca3b7c
--- /dev/null
+++ b/src/frontend/src/pages/sales/SalesOrderDetail.tsx
@@ -0,0 +1,104 @@
+import { t } from '@lingui/macro';
+import { LoadingOverlay, Stack } from '@mantine/core';
+import {
+ IconInfoCircle,
+ IconList,
+ IconNotes,
+ IconPaperclip,
+ IconTools,
+ IconTruckDelivery,
+ IconTruckLoading
+} from '@tabler/icons-react';
+import { useMemo } from 'react';
+import { useParams } from 'react-router-dom';
+
+import { PageDetail } from '../../components/nav/PageDetail';
+import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
+import { AttachmentTable } from '../../components/tables/general/AttachmentTable';
+import { NotesEditor } from '../../components/widgets/MarkdownEditor';
+import { useInstance } from '../../hooks/UseInstance';
+import { ApiPaths, apiUrl } from '../../states/ApiState';
+
+/**
+ * Detail page for a single SalesOrder
+ */
+export default function SalesOrderDetail() {
+ const { id } = useParams();
+
+ const { instance: order, instanceQuery } = useInstance({
+ endpoint: ApiPaths.sales_order_list,
+ pk: id,
+ params: {
+ customer_detail: true
+ }
+ });
+
+ const orderPanels: PanelType[] = useMemo(() => {
+ return [
+ {
+ name: 'detail',
+ label: t`Order Details`,
+ icon:
+ },
+ {
+ name: 'line-items',
+ label: t`Line Items`,
+ icon:
+ },
+ {
+ name: 'pending-shipments',
+ label: t`Pending Shipments`,
+ icon:
+ },
+ {
+ name: 'completed-shipments',
+ label: t`Completed Shipments`,
+ icon:
+ },
+ {
+ name: 'build-orders',
+ label: t`Build Orders`,
+ icon:
+ },
+ {
+ name: 'attachments',
+ label: t`Attachments`,
+ icon: ,
+ content: (
+
+ )
+ },
+ {
+ name: 'notes',
+ label: t`Notes`,
+ icon: ,
+ content: (
+
+ )
+ }
+ ];
+ }, [order, id]);
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/frontend/src/router.tsx b/src/frontend/src/router.tsx
index f67a85ece8..d044882ec7 100644
--- a/src/frontend/src/router.tsx
+++ b/src/frontend/src/router.tsx
@@ -54,10 +54,22 @@ export const PurchasingIndex = Loadable(
lazy(() => import('./pages/purchasing/PurchasingIndex'))
);
+export const PurchaseOrderDetail = Loadable(
+ lazy(() => import('./pages/purchasing/PurchaseOrderDetail'))
+);
+
export const SalesIndex = Loadable(
lazy(() => import('./pages/sales/SalesIndex'))
);
+export const SalesOrderDetail = Loadable(
+ lazy(() => import('./pages/sales/SalesOrderDetail'))
+);
+
+export const ReturnOrderDetail = Loadable(
+ lazy(() => import('./pages/sales/ReturnOrderDetail'))
+);
+
export const Scan = Loadable(lazy(() => import('./pages/Index/Scan')));
export const Dashboard = Loadable(
@@ -125,12 +137,15 @@ export const routes = (
} />
+ } />
} />
} />
} />
} />
+ } />
+ } />
} />
} />
diff --git a/src/frontend/src/states/ApiState.tsx b/src/frontend/src/states/ApiState.tsx
index bd87b697e6..703e377a0f 100644
--- a/src/frontend/src/states/ApiState.tsx
+++ b/src/frontend/src/states/ApiState.tsx
@@ -93,12 +93,15 @@ export enum ApiPaths {
// Purchase Order URLs
purchase_order_list = 'api-purchase-order-list',
+ purchase_order_attachment_list = 'api-purchase-order-attachment-list',
// Sales Order URLs
sales_order_list = 'api-sales-order-list',
+ sales_order_attachment_list = 'api-sales-order-attachment-list',
// Return Order URLs
return_order_list = 'api-return-order-list',
+ return_order_attachment_list = 'api-return-order-attachment-list',
// Plugin URLs
plugin_list = 'api-plugin-list',
@@ -180,10 +183,16 @@ export function apiEndpoint(path: ApiPaths): string {
return 'stock/attachment/';
case ApiPaths.purchase_order_list:
return 'order/po/';
+ case ApiPaths.purchase_order_attachment_list:
+ return 'order/po/attachment/';
case ApiPaths.sales_order_list:
return 'order/so/';
+ case ApiPaths.sales_order_attachment_list:
+ return 'order/so/attachment/';
case ApiPaths.return_order_list:
return 'order/ro/';
+ case ApiPaths.return_order_attachment_list:
+ return 'order/ro/attachment/';
case ApiPaths.plugin_list:
return 'plugins/';
case ApiPaths.project_code_list:
diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts
index 10e0bf949c..827d69da81 100644
--- a/src/frontend/vite.config.ts
+++ b/src/frontend/vite.config.ts
@@ -28,6 +28,16 @@ export default defineConfig({
target: 'http://localhost:8000',
changeOrigin: true,
secure: true
+ },
+ '/media': {
+ target: 'http://localhost:8000',
+ changeOrigin: true,
+ secure: true
+ },
+ '/static': {
+ target: 'http://localhost:8000',
+ changeOrigin: true,
+ secure: true
}
},
watch: {