mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 12:06:44 +00:00
[PUI] Make actions recognisable (#8005)
* Make dropdowns better recogniseable Closes https://github.com/invenhost/InvenTree/issues/98 * change to button with section * only draw border if needed * allign drowdowns in header * use light instead of subtle * refactor option dropdowns to reduce duplications
This commit is contained in:
parent
d81d1688bf
commit
355b4937da
@ -80,6 +80,7 @@ export default function AdminButton(props: AdminButtonProps) {
|
||||
tooltip={t`Open in admin interface`}
|
||||
hidden={!enabled}
|
||||
onClick={openAdmin}
|
||||
tooltipAlignment="bottom"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import {
|
||||
ActionIcon,
|
||||
Button,
|
||||
Indicator,
|
||||
IndicatorProps,
|
||||
Menu,
|
||||
@ -8,7 +8,9 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { modals } from '@mantine/modals';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconCopy,
|
||||
IconDotsVertical,
|
||||
IconEdit,
|
||||
IconLink,
|
||||
IconQrcode,
|
||||
@ -42,13 +44,15 @@ export function ActionDropdown({
|
||||
tooltip,
|
||||
actions,
|
||||
disabled = false,
|
||||
hidden = false
|
||||
hidden = false,
|
||||
noindicator = false
|
||||
}: {
|
||||
icon: ReactNode;
|
||||
tooltip: string;
|
||||
actions: ActionDropdownItem[];
|
||||
disabled?: boolean;
|
||||
hidden?: boolean;
|
||||
noindicator?: boolean;
|
||||
}) {
|
||||
const hasActions = useMemo(() => {
|
||||
return actions.some((action) => !action.hidden);
|
||||
@ -66,16 +70,25 @@ export function ActionDropdown({
|
||||
<Menu position="bottom-end" key={menuName}>
|
||||
<Indicator disabled={!indicatorProps} {...indicatorProps?.indicator}>
|
||||
<Menu.Target>
|
||||
<Tooltip label={tooltip} hidden={!tooltip}>
|
||||
<ActionIcon
|
||||
size="lg"
|
||||
<Tooltip label={tooltip} hidden={!tooltip} position="bottom">
|
||||
<Button
|
||||
radius="sm"
|
||||
variant="transparent"
|
||||
variant={noindicator ? 'transparent' : 'light'}
|
||||
disabled={disabled}
|
||||
aria-label={menuName}
|
||||
p="0"
|
||||
size="sm"
|
||||
rightSection={
|
||||
noindicator || disabled ? null : (
|
||||
<IconChevronDown stroke={1.5} />
|
||||
)
|
||||
}
|
||||
styles={{
|
||||
section: { margin: 0 }
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</ActionIcon>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Menu.Target>
|
||||
</Indicator>
|
||||
@ -110,6 +123,26 @@ export function ActionDropdown({
|
||||
) : null;
|
||||
}
|
||||
|
||||
export function OptionsActionDropdown({
|
||||
actions = [],
|
||||
tooltip = t`Options`,
|
||||
hidden = false
|
||||
}: {
|
||||
actions: ActionDropdownItem[];
|
||||
tooltip?: string;
|
||||
hidden?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<ActionDropdown
|
||||
icon={<IconDotsVertical />}
|
||||
tooltip={tooltip}
|
||||
actions={actions}
|
||||
hidden={hidden}
|
||||
noindicator
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Dropdown menu for barcode actions
|
||||
export function BarcodeActionDropdown({
|
||||
model,
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
IconChecklist,
|
||||
IconClipboardCheck,
|
||||
IconClipboardList,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconList,
|
||||
IconListCheck,
|
||||
@ -25,12 +24,12 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
CancelItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction,
|
||||
HoldItemAction
|
||||
HoldItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
import { PageDetail } from '../../components/nav/PageDetail';
|
||||
@ -474,9 +473,8 @@ export default function BuildDetail() {
|
||||
items={[build.pk]}
|
||||
enableReports
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Build Order Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
onClick: () => editBuild.open(),
|
||||
|
@ -3,7 +3,6 @@ import { Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconBuildingFactory2,
|
||||
IconBuildingWarehouse,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconMap2,
|
||||
IconNotes,
|
||||
@ -25,9 +24,9 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
DeleteItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { Breadcrumb } from '../../components/nav/BreadcrumbList';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -302,9 +301,8 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
|
||||
const companyActions = useMemo(() => {
|
||||
return [
|
||||
<AdminButton model={ModelType.company} pk={company.pk} />,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Company Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !user.hasChangeRole(UserRoles.purchase_order),
|
||||
|
@ -2,7 +2,6 @@ import { t } from '@lingui/macro';
|
||||
import { Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconBuildingWarehouse,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconList,
|
||||
IconNotes,
|
||||
@ -17,10 +16,10 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
DeleteItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
import { PageDetail } from '../../components/nav/PageDetail';
|
||||
@ -236,9 +235,8 @@ export default function ManufacturerPartDetail() {
|
||||
model={ModelType.manufacturerpart}
|
||||
pk={manufacturerPart.pk}
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Manufacturer Part Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
DuplicateItemAction({
|
||||
hidden: !user.hasAddRole(UserRoles.purchase_order),
|
||||
|
@ -2,7 +2,6 @@ import { t } from '@lingui/macro';
|
||||
import { Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconCurrencyDollar,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconNotes,
|
||||
IconPackages,
|
||||
@ -18,11 +17,11 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
DeleteItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
import { PageDetail } from '../../components/nav/PageDetail';
|
||||
@ -272,9 +271,8 @@ export default function SupplierPartDetail() {
|
||||
hash={supplierPart.barcode_hash}
|
||||
perm={user.hasChangeRole(UserRoles.purchase_order)}
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Supplier Part Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
DuplicateItemAction({
|
||||
hidden: !user.hasAddRole(UserRoles.purchase_order),
|
||||
|
@ -2,7 +2,6 @@ import { t } from '@lingui/macro';
|
||||
import { Group, LoadingOverlay, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import {
|
||||
IconCategory,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconListDetails,
|
||||
IconSitemap
|
||||
@ -14,9 +13,9 @@ import AdminButton from '../../components/buttons/AdminButton';
|
||||
import { DetailsField, DetailsTable } from '../../components/details/Details';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import {
|
||||
ActionDropdown,
|
||||
DeleteItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { ApiIcon } from '../../components/items/ApiIcon';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -212,9 +211,8 @@ export default function CategoryDetail() {
|
||||
const categoryActions = useMemo(() => {
|
||||
return [
|
||||
<AdminButton model={ModelType.partcategory} pk={category.pk} />,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Category Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !id || !user.hasChangeRole(UserRoles.part_category),
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
IconCalendarStats,
|
||||
IconClipboardList,
|
||||
IconCurrencyDollar,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconLayersLinked,
|
||||
IconList,
|
||||
@ -51,7 +50,8 @@ import {
|
||||
BarcodeActionDropdown,
|
||||
DeleteItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { PlaceholderPanel } from '../../components/items/Placeholder';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
@ -1030,9 +1030,8 @@ export default function PartDetail() {
|
||||
}
|
||||
]}
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Part Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
DuplicateItemAction({
|
||||
hidden: !user.hasAddRole(UserRoles.part),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { Accordion, Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconList,
|
||||
IconNotes,
|
||||
@ -19,12 +18,12 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
CancelItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction,
|
||||
HoldItemAction
|
||||
HoldItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -408,9 +407,8 @@ export default function PurchaseOrderDetail() {
|
||||
items={[order.pk]}
|
||||
enableReports
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Order Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !canEdit,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { Accordion, Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconList,
|
||||
IconNotes,
|
||||
@ -18,12 +17,12 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
CancelItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction,
|
||||
HoldItemAction
|
||||
HoldItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -409,9 +408,8 @@ export default function ReturnOrderDetail() {
|
||||
items={[order.pk]}
|
||||
enableReports
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Order Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !user.hasChangeRole(UserRoles.return_order),
|
||||
|
@ -2,7 +2,6 @@ import { t } from '@lingui/macro';
|
||||
import { Accordion, Grid, Skeleton, Stack } from '@mantine/core';
|
||||
import {
|
||||
IconBookmark,
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconList,
|
||||
IconNotes,
|
||||
@ -21,12 +20,12 @@ import { DetailsImage } from '../../components/details/DetailsImage';
|
||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||
import NotesEditor from '../../components/editors/NotesEditor';
|
||||
import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
CancelItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction,
|
||||
HoldItemAction
|
||||
HoldItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -449,9 +448,8 @@ export default function SalesOrderDetail() {
|
||||
items={[order.pk]}
|
||||
enableReports
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Order Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !canEdit,
|
||||
|
@ -1,11 +1,6 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { Group, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import {
|
||||
IconDots,
|
||||
IconInfoCircle,
|
||||
IconPackages,
|
||||
IconSitemap
|
||||
} from '@tabler/icons-react';
|
||||
import { IconInfoCircle, IconPackages, IconSitemap } from '@tabler/icons-react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
@ -18,7 +13,8 @@ import {
|
||||
ActionDropdown,
|
||||
BarcodeActionDropdown,
|
||||
DeleteItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { ApiIcon } from '../../components/items/ApiIcon';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -331,9 +327,8 @@ export default function Stock() {
|
||||
}
|
||||
]}
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Location Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
hidden: !id || !user.hasChangeRole(UserRoles.stock_location),
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
IconBookmark,
|
||||
IconBoxPadding,
|
||||
IconChecklist,
|
||||
IconDots,
|
||||
IconHistory,
|
||||
IconInfoCircle,
|
||||
IconNotes,
|
||||
@ -27,7 +26,8 @@ import {
|
||||
BarcodeActionDropdown,
|
||||
DeleteItemAction,
|
||||
DuplicateItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { StylishText } from '../../components/items/StylishText';
|
||||
import InstanceDetail from '../../components/nav/InstanceDetail';
|
||||
@ -526,9 +526,8 @@ export default function StockDetail() {
|
||||
}
|
||||
]}
|
||||
/>,
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Stock Item Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
DuplicateItemAction({
|
||||
hidden: !user.hasAddRole(UserRoles.stock),
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
Title
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconCheck, IconDots, IconRefresh } from '@tabler/icons-react';
|
||||
import { IconCheck, IconRefresh } from '@tabler/icons-react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
@ -25,9 +25,9 @@ import { api } from '../../App';
|
||||
import { AddItemButton } from '../../components/buttons/AddItemButton';
|
||||
import { YesNoButton } from '../../components/buttons/YesNoButton';
|
||||
import {
|
||||
ActionDropdown,
|
||||
DeleteItemAction,
|
||||
EditItemAction
|
||||
EditItemAction,
|
||||
OptionsActionDropdown
|
||||
} from '../../components/items/ActionDropdown';
|
||||
import { InfoItem } from '../../components/items/InfoItem';
|
||||
import { UnavailableIndicator } from '../../components/items/UnavailableIndicator';
|
||||
@ -255,9 +255,8 @@ function MachineDrawer({
|
||||
<Trans>Restart required</Trans>
|
||||
</Badge>
|
||||
)}
|
||||
<ActionDropdown
|
||||
<OptionsActionDropdown
|
||||
tooltip={t`Machine Actions`}
|
||||
icon={<IconDots />}
|
||||
actions={[
|
||||
EditItemAction({
|
||||
tooltip: t`Edit machine`,
|
||||
|
Loading…
x
Reference in New Issue
Block a user