[PUI] Edit shortcut (#7870)

* Adds shortcut to edit item on <PageDetail>

* Add hooks for shortcut key

* Add unit tests for edit shortcut
This commit is contained in:
Oliver 2024-08-14 20:12:51 +10:00 committed by GitHub
parent e1b0efaa12
commit 19ca7bffae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 55 additions and 1 deletions

View File

@ -1,4 +1,5 @@
import { Group, Paper, Space, Stack, Text } from '@mantine/core'; import { Group, Paper, Space, Stack, Text } from '@mantine/core';
import { useHotkeys } from '@mantine/hooks';
import { Fragment, ReactNode } from 'react'; import { Fragment, ReactNode } from 'react';
import { ApiImage } from '../images/ApiImage'; import { ApiImage } from '../images/ApiImage';
@ -15,6 +16,8 @@ interface PageDetailInterface {
breadcrumbs?: Breadcrumb[]; breadcrumbs?: Breadcrumb[];
breadcrumbAction?: () => void; breadcrumbAction?: () => void;
actions?: ReactNode[]; actions?: ReactNode[];
editAction?: () => void;
editEnabled?: boolean;
} }
/** /**
@ -32,8 +35,21 @@ export function PageDetail({
imageUrl, imageUrl,
breadcrumbs, breadcrumbs,
breadcrumbAction, breadcrumbAction,
actions actions,
editAction,
editEnabled
}: Readonly<PageDetailInterface>) { }: Readonly<PageDetailInterface>) {
useHotkeys([
[
'mod+E',
() => {
if (editEnabled ?? true) {
editAction?.();
}
}
]
]);
return ( return (
<Stack gap="xs"> <Stack gap="xs">
{breadcrumbs && breadcrumbs.length > 0 && ( {breadcrumbs && breadcrumbs.length > 0 && (

View File

@ -542,6 +542,8 @@ export default function BuildDetail() {
title={build.reference} title={build.reference}
subtitle={build.title} subtitle={build.title}
badges={buildBadges} badges={buildBadges}
editAction={editBuild.open}
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`Build Orders`, url: '/build' },

View File

@ -330,6 +330,8 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
imageUrl={company.image} imageUrl={company.image}
breadcrumbs={props.breadcrumbs} breadcrumbs={props.breadcrumbs}
badges={badges} badges={badges}
editAction={editCompany.open}
editEnabled={user.hasChangePermission(ModelType.company)}
/> />
<PanelGroup pageKey="company" panels={companyPanels} /> <PanelGroup pageKey="company" panels={companyPanels} />
</Stack> </Stack>

View File

@ -283,6 +283,8 @@ export default function ManufacturerPartDetail() {
breadcrumbs={breadcrumbs} breadcrumbs={breadcrumbs}
actions={manufacturerPartActions} actions={manufacturerPartActions}
imageUrl={manufacturerPart?.part_detail?.thumbnail} imageUrl={manufacturerPart?.part_detail?.thumbnail}
editAction={editManufacturerPart.open}
editEnabled={user.hasChangePermission(ModelType.manufacturerpart)}
/> />
<PanelGroup pageKey="manufacturerpart" panels={panels} /> <PanelGroup pageKey="manufacturerpart" panels={panels} />
</Stack> </Stack>

View File

@ -375,6 +375,8 @@ export default function SupplierPartDetail() {
badges={badges} badges={badges}
actions={supplierPartActions} actions={supplierPartActions}
imageUrl={supplierPart?.part_detail?.thumbnail} imageUrl={supplierPart?.part_detail?.thumbnail}
editAction={editSupplierPart.open}
editEnabled={user.hasChangePermission(ModelType.supplierpart)}
/> />
<PanelGroup pageKey="supplierpart" panels={panels} /> <PanelGroup pageKey="supplierpart" panels={panels} />
</Stack> </Stack>

View File

@ -310,6 +310,8 @@ export default function CategoryDetail() {
setTreeOpen(true); setTreeOpen(true);
}} }}
actions={categoryActions} actions={categoryActions}
editAction={editCategory.open}
editEnabled={user.hasChangePermission(ModelType.partcategory)}
/> />
<PanelGroup pageKey="partcategory" panels={categoryPanels} /> <PanelGroup pageKey="partcategory" panels={categoryPanels} />
</Stack> </Stack>

View File

@ -1057,6 +1057,8 @@ export default function PartDetail() {
breadcrumbAction={() => { breadcrumbAction={() => {
setTreeOpen(true); setTreeOpen(true);
}} }}
editAction={editPart.open}
editEnabled={user.hasChangeRole(UserRoles.part)}
actions={partActions} actions={partActions}
detail={ detail={
enableRevisionSelection ? ( enableRevisionSelection ? (

View File

@ -442,6 +442,8 @@ export default function PurchaseOrderDetail() {
breadcrumbs={[{ name: t`Purchasing`, url: '/purchasing/' }]} breadcrumbs={[{ name: t`Purchasing`, url: '/purchasing/' }]}
actions={poActions} actions={poActions}
badges={orderBadges} badges={orderBadges}
editAction={editPurchaseOrder.open}
editEnabled={user.hasChangePermission(ModelType.purchaseorder)}
/> />
<PanelGroup pageKey="purchaseorder" panels={orderPanels} /> <PanelGroup pageKey="purchaseorder" panels={orderPanels} />
</Stack> </Stack>

View File

@ -430,6 +430,8 @@ export default function ReturnOrderDetail() {
badges={orderBadges} badges={orderBadges}
actions={orderActions} actions={orderActions}
breadcrumbs={[{ name: t`Sales`, url: '/sales/' }]} breadcrumbs={[{ name: t`Sales`, url: '/sales/' }]}
editAction={editReturnOrder.open}
editEnabled={user.hasChangePermission(ModelType.returnorder)}
/> />
<PanelGroup pageKey="returnorder" panels={orderPanels} /> <PanelGroup pageKey="returnorder" panels={orderPanels} />
</Stack> </Stack>

View File

@ -482,6 +482,8 @@ export default function SalesOrderDetail() {
badges={orderBadges} badges={orderBadges}
actions={soActions} actions={soActions}
breadcrumbs={[{ name: t`Sales`, url: '/sales/' }]} breadcrumbs={[{ name: t`Sales`, url: '/sales/' }]}
editAction={editSalesOrder.open}
editEnabled={user.hasChangePermission(ModelType.salesorder)}
/> />
<PanelGroup pageKey="salesorder" panels={orderPanels} /> <PanelGroup pageKey="salesorder" panels={orderPanels} />
</Stack> </Stack>

View File

@ -388,6 +388,8 @@ export default function Stock() {
subtitle={location?.name} subtitle={location?.name}
icon={location?.icon && <ApiIcon name={location?.icon} />} icon={location?.icon && <ApiIcon name={location?.icon} />}
actions={locationActions} actions={locationActions}
editAction={editLocation.open}
editEnabled={user.hasChangePermission(ModelType.stocklocation)}
breadcrumbs={breadcrumbs} breadcrumbs={breadcrumbs}
breadcrumbAction={() => { breadcrumbAction={() => {
setTreeOpen(true); setTreeOpen(true);

View File

@ -621,6 +621,8 @@ export default function StockDetail() {
title={t`Stock Item`} title={t`Stock Item`}
subtitle={stockitem.part_detail?.full_name} subtitle={stockitem.part_detail?.full_name}
imageUrl={stockitem.part_detail?.thumbnail} imageUrl={stockitem.part_detail?.thumbnail}
editAction={editStockItem.open}
editEnabled={user.hasChangePermission(ModelType.stockitem)}
badges={stockBadges} badges={stockBadges}
breadcrumbs={breadcrumbs} breadcrumbs={breadcrumbs}
breadcrumbAction={() => { breadcrumbAction={() => {

View File

@ -19,6 +19,13 @@ test('PUI - Pages - Build Order', async ({ page }) => {
// This build order should be "on hold" // This build order should be "on hold"
await page.getByText('On Hold').first().waitFor(); await page.getByText('On Hold').first().waitFor();
// Edit the build order (via keyboard shortcut)
await page.keyboard.press('Control+E');
await page.getByLabel('text-field-title').waitFor();
await page.getByLabel('related-field-project_code').waitFor();
await page.getByRole('button', { name: 'Cancel' }).click();
await page.getByRole('button', { name: 'Issue Order' }).click(); await page.getByRole('button', { name: 'Issue Order' }).click();
await page.getByRole('button', { name: 'Cancel' }).click(); await page.getByRole('button', { name: 'Cancel' }).click();

View File

@ -226,6 +226,15 @@ test('PUI - Pages - Part - Notes', async ({ page }) => {
await page.goto(`${baseUrl}/part/69/notes`); await page.goto(`${baseUrl}/part/69/notes`);
// Enable editing // Enable editing
await page.getByLabel('toggle-notes-editing').waitFor();
// Use keyboard shortcut to "edit" the part
await page.keyboard.press('Control+E');
await page.getByLabel('text-field-name').waitFor();
await page.getByLabel('text-field-description').waitFor();
await page.getByLabel('related-field-category').waitFor();
await page.getByRole('button', { name: 'Cancel' }).click();
await page.getByLabel('toggle-notes-editing').click(); await page.getByLabel('toggle-notes-editing').click();
// Enter some text // Enter some text