2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 19:46:46 +00:00

[PUI] Add "index" page for build orders (#8287)

* Add "index" page for build orders

- Make consistent with other pages
- Allow plugin panels here
- Prepare for future development

* Rearrange URLs for "manufacturing"

- Provide same format as other order types
- Allow for other sub-pages under "manufacturing" in the future

* Fix breadcrumbs

* Adjust playwright tests
This commit is contained in:
Oliver 2024-10-15 23:57:30 +11:00 committed by GitHub
parent fb9c117e37
commit e808fad98d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 41 additions and 16 deletions

View File

@ -105,8 +105,8 @@ export const ModelInformationDict: ModelDict = {
build: { build: {
label: () => t`Build`, label: () => t`Build`,
label_multiple: () => t`Builds`, label_multiple: () => t`Builds`,
url_overview: '/build', url_overview: '/manufacturing/build-order/',
url_detail: '/build/:pk/', url_detail: '/manufacturing/build-order/:pk/',
cui_detail: '/build/:pk/', cui_detail: '/build/:pk/',
api_endpoint: ApiEndpoints.build_order_list, api_endpoint: ApiEndpoints.build_order_list,
admin_url: '/build/build/' admin_url: '/build/build/'

View File

@ -28,7 +28,11 @@ export const navTabs = [
{ text: <Trans>Dashboard</Trans>, name: 'dashboard' }, { text: <Trans>Dashboard</Trans>, name: 'dashboard' },
{ text: <Trans>Parts</Trans>, name: 'part', role: UserRoles.part }, { text: <Trans>Parts</Trans>, name: 'part', role: UserRoles.part },
{ text: <Trans>Stock</Trans>, name: 'stock', role: UserRoles.stock }, { text: <Trans>Stock</Trans>, name: 'stock', role: UserRoles.stock },
{ text: <Trans>Build</Trans>, name: 'build', role: UserRoles.build }, {
text: <Trans>Manufacturing</Trans>,
name: 'manufacturing',
role: UserRoles.build
},
{ {
text: <Trans>Purchasing</Trans>, text: <Trans>Purchasing</Trans>,
name: 'purchasing', name: 'purchasing',

View File

@ -39,9 +39,9 @@ export const menuItems: menuItemsCollection = {
link: '/stock' link: '/stock'
}, },
build: { build: {
id: 'build', id: 'manufacturing',
text: <Trans>Build</Trans>, text: <Trans>Manufacturing</Trans>,
link: '/build/' link: '/manufacturing/'
}, },
purchasing: { purchasing: {
id: 'purchasing', id: 'purchasing',

View File

@ -522,7 +522,7 @@ export default function BuildDetail() {
editEnabled={user.hasChangePermission(ModelType.part)} editEnabled={user.hasChangePermission(ModelType.part)}
imageUrl={build.part_detail?.image ?? build.part_detail?.thumbnail} imageUrl={build.part_detail?.image ?? build.part_detail?.thumbnail}
breadcrumbs={[ breadcrumbs={[
{ name: t`Build Orders`, url: '/build' }, { name: t`Manufacturing`, url: '/manufacturing' },
{ name: build.reference, url: `/build/${build.pk}` } { name: build.reference, url: `/build/${build.pk}` }
]} ]}
actions={buildActions} actions={buildActions}

View File

@ -1,8 +1,11 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Stack } from '@mantine/core'; import { Stack } from '@mantine/core';
import { IconTools } from '@tabler/icons-react';
import { useMemo } from 'react';
import PermissionDenied from '../../components/errors/PermissionDenied'; import PermissionDenied from '../../components/errors/PermissionDenied';
import { PageDetail } from '../../components/nav/PageDetail'; import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup } from '../../components/panels/PanelGroup';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { BuildOrderTable } from '../../tables/build/BuildOrderTable'; import { BuildOrderTable } from '../../tables/build/BuildOrderTable';
@ -17,10 +20,26 @@ export default function BuildIndex() {
return <PermissionDenied />; return <PermissionDenied />;
} }
const panels = useMemo(() => {
return [
{
name: 'buildorders',
label: t`Build Orders`,
content: <BuildOrderTable />,
icon: <IconTools />
}
];
}, []);
return ( return (
<Stack> <Stack>
<PageDetail title={t`Build Orders`} actions={[]} /> <PageDetail title={t`Manufacturing`} actions={[]} />
<BuildOrderTable /> <PanelGroup
pageKey="build-index"
panels={panels}
model="manufacturing"
id={null}
/>
</Stack> </Stack>
); );
} }

View File

@ -51,6 +51,7 @@ export const StockDetail = Loadable(
export const BuildIndex = Loadable( export const BuildIndex = Loadable(
lazy(() => import('./pages/build/BuildIndex')) lazy(() => import('./pages/build/BuildIndex'))
); );
export const BuildDetail = Loadable( export const BuildDetail = Loadable(
lazy(() => import('./pages/build/BuildDetail')) lazy(() => import('./pages/build/BuildDetail'))
); );
@ -139,9 +140,10 @@ export const routes = (
<Route path="location/:id?/*" element={<LocationDetail />} /> <Route path="location/:id?/*" element={<LocationDetail />} />
<Route path="item/:id/*" element={<StockDetail />} /> <Route path="item/:id/*" element={<StockDetail />} />
</Route> </Route>
<Route path="build/"> <Route path="manufacturing/">
<Route index element={<BuildIndex />} /> <Route index element={<Navigate to="index/" />} />
<Route path=":id/*" element={<BuildDetail />} /> <Route path="index/*" element={<BuildIndex />} />
<Route path="build-order/:id/*" element={<BuildDetail />} />
</Route> </Route>
<Route path="purchasing/"> <Route path="purchasing/">
<Route index element={<Navigate to="index/" />} /> <Route index element={<Navigate to="index/" />} />

View File

@ -8,7 +8,7 @@ test('Pages - Build Order', async ({ page }) => {
await page.goto(`${baseUrl}/part/`); await page.goto(`${baseUrl}/part/`);
// Navigate to the correct build order // Navigate to the correct build order
await page.getByRole('tab', { name: 'Build', exact: true }).click(); await page.getByRole('tab', { name: 'Manufacturing', exact: true }).click();
// We have now loaded the "Build Order" table. Check for some expected texts // We have now loaded the "Build Order" table. Check for some expected texts
await page.getByText('On Hold').first().waitFor(); await page.getByText('On Hold').first().waitFor();
@ -30,7 +30,7 @@ test('Pages - Build Order', async ({ page }) => {
await page.getByRole('button', { name: 'Cancel' }).click(); await page.getByRole('button', { name: 'Cancel' }).click();
// Back to the build list // Back to the build list
await page.getByLabel('breadcrumb-0-build-orders').click(); await page.getByLabel('breadcrumb-0-manufacturing').click();
// Load a different build order // Load a different build order
await page.getByRole('cell', { name: 'BO0011' }).click(); await page.getByRole('cell', { name: 'BO0011' }).click();
@ -88,7 +88,7 @@ test('Pages - Build Order - Build Outputs', async ({ page }) => {
await page.goto(`${baseUrl}/part/`); await page.goto(`${baseUrl}/part/`);
// Navigate to the correct build order // Navigate to the correct build order
await page.getByRole('tab', { name: 'Build', exact: true }).click(); await page.getByRole('tab', { name: 'Manufacturing', exact: true }).click();
// We have now loaded the "Build Order" table. Check for some expected texts // We have now loaded the "Build Order" table. Check for some expected texts
await page.getByText('On Hold').first().waitFor(); await page.getByText('On Hold').first().waitFor();

View File

@ -24,7 +24,7 @@ test('Tables - Filters', async ({ page }) => {
await doQuickLogin(page); await doQuickLogin(page);
// Head to the "build order list" page // Head to the "build order list" page
await page.goto(`${baseUrl}/build/`); await page.goto(`${baseUrl}/manufacturing/index/`);
await setFilter(page, 'Status', 'Complete'); await setFilter(page, 'Status', 'Complete');
await setFilter(page, 'Responsible', 'allaccess'); await setFilter(page, 'Responsible', 'allaccess');