mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Implement CompanyDetails page
This commit is contained in:
parent
64109a7974
commit
b674fc980d
@ -5,6 +5,7 @@ import {
|
|||||||
IconBox,
|
IconBox,
|
||||||
IconBuilding,
|
IconBuilding,
|
||||||
IconBuildingFactory2,
|
IconBuildingFactory2,
|
||||||
|
IconBuildingStore,
|
||||||
IconCalendar,
|
IconCalendar,
|
||||||
IconCalendarStats,
|
IconCalendarStats,
|
||||||
IconCheck,
|
IconCheck,
|
||||||
@ -22,6 +23,7 @@ import {
|
|||||||
IconLink,
|
IconLink,
|
||||||
IconList,
|
IconList,
|
||||||
IconListTree,
|
IconListTree,
|
||||||
|
IconMail,
|
||||||
IconMapPin,
|
IconMapPin,
|
||||||
IconMapPinHeart,
|
IconMapPinHeart,
|
||||||
IconNotes,
|
IconNotes,
|
||||||
@ -30,6 +32,7 @@ import {
|
|||||||
IconPackageImport,
|
IconPackageImport,
|
||||||
IconPackages,
|
IconPackages,
|
||||||
IconPaperclip,
|
IconPaperclip,
|
||||||
|
IconPhone,
|
||||||
IconPhoto,
|
IconPhoto,
|
||||||
IconProgressCheck,
|
IconProgressCheck,
|
||||||
IconQuestionMark,
|
IconQuestionMark,
|
||||||
@ -49,6 +52,7 @@ import {
|
|||||||
IconUserStar,
|
IconUserStar,
|
||||||
IconUsersGroup,
|
IconUsersGroup,
|
||||||
IconVersions,
|
IconVersions,
|
||||||
|
IconWorld,
|
||||||
IconWorldCode,
|
IconWorldCode,
|
||||||
IconX
|
IconX
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
@ -87,6 +91,7 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
|
|||||||
used_in: IconStack2,
|
used_in: IconStack2,
|
||||||
manufacturers: IconBuildingFactory2,
|
manufacturers: IconBuildingFactory2,
|
||||||
suppliers: IconBuilding,
|
suppliers: IconBuilding,
|
||||||
|
customers: IconBuildingStore,
|
||||||
purchase_orders: IconShoppingCart,
|
purchase_orders: IconShoppingCart,
|
||||||
sales_orders: IconTruckDelivery,
|
sales_orders: IconTruckDelivery,
|
||||||
scheduling: IconCalendarStats,
|
scheduling: IconCalendarStats,
|
||||||
@ -121,6 +126,7 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
|
|||||||
link: IconLink,
|
link: IconLink,
|
||||||
responsible: IconUserStar,
|
responsible: IconUserStar,
|
||||||
pricing: IconCurrencyDollar,
|
pricing: IconCurrencyDollar,
|
||||||
|
currency: IconCurrencyDollar,
|
||||||
stocktake: IconClipboardList,
|
stocktake: IconClipboardList,
|
||||||
user: IconUser,
|
user: IconUser,
|
||||||
group: IconUsersGroup,
|
group: IconUsersGroup,
|
||||||
@ -128,7 +134,10 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
|
|||||||
copy: IconCopy,
|
copy: IconCopy,
|
||||||
quantity: IconNumbers,
|
quantity: IconNumbers,
|
||||||
progress: IconProgressCheck,
|
progress: IconProgressCheck,
|
||||||
reference: IconHash
|
reference: IconHash,
|
||||||
|
website: IconWorld,
|
||||||
|
email: IconMail,
|
||||||
|
phone: IconPhone
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { LoadingOverlay, Skeleton, Stack } from '@mantine/core';
|
import { Grid, LoadingOverlay, Skeleton, Stack } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
IconBuildingFactory2,
|
IconBuildingFactory2,
|
||||||
IconBuildingWarehouse,
|
IconBuildingWarehouse,
|
||||||
@ -18,6 +18,8 @@ import {
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { DetailsImage } from '../../components/details/DetailsImage';
|
||||||
|
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||||
import {
|
import {
|
||||||
ActionDropdown,
|
ActionDropdown,
|
||||||
DeleteItemAction,
|
DeleteItemAction,
|
||||||
@ -35,6 +37,7 @@ import { useEditApiFormModal } from '../../hooks/UseForm';
|
|||||||
import { useInstance } from '../../hooks/UseInstance';
|
import { useInstance } from '../../hooks/UseInstance';
|
||||||
import { apiUrl } from '../../states/ApiState';
|
import { apiUrl } from '../../states/ApiState';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
|
import { DetailsField, DetailsTable } from '../../tables/Details';
|
||||||
import { AddressTable } from '../../tables/company/AddressTable';
|
import { AddressTable } from '../../tables/company/AddressTable';
|
||||||
import { ContactTable } from '../../tables/company/ContactTable';
|
import { ContactTable } from '../../tables/company/ContactTable';
|
||||||
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
import { AttachmentTable } from '../../tables/general/AttachmentTable';
|
||||||
@ -69,12 +72,99 @@ export default function CompanyDetail(props: CompanyDetailProps) {
|
|||||||
refetchOnMount: true
|
refetchOnMount: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const detailsPanel = useMemo(() => {
|
||||||
|
if (instanceQuery.isFetching) {
|
||||||
|
return <Skeleton />;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tl: DetailsField[] = [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'description',
|
||||||
|
label: t`Description`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
name: 'website',
|
||||||
|
label: t`Website`,
|
||||||
|
external: true,
|
||||||
|
copy: true,
|
||||||
|
hidden: !company.website
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'phone',
|
||||||
|
label: t`Phone Number`,
|
||||||
|
copy: true,
|
||||||
|
hidden: !company.phone
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'email',
|
||||||
|
label: t`Email Address`,
|
||||||
|
copy: true,
|
||||||
|
hidden: !company.email
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let tr: DetailsField[] = [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'currency',
|
||||||
|
label: t`Default Currency`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'boolean',
|
||||||
|
name: 'is_supplier',
|
||||||
|
label: t`Supplier`,
|
||||||
|
icon: 'suppliers'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'boolean',
|
||||||
|
name: 'is_manufacturer',
|
||||||
|
label: t`Manufacturer`,
|
||||||
|
icon: 'manufacturers'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'boolean',
|
||||||
|
name: 'is_customer',
|
||||||
|
label: t`Customer`,
|
||||||
|
icon: 'customers'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ItemDetailsGrid>
|
||||||
|
<Grid>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<DetailsImage
|
||||||
|
appRole={UserRoles.purchase_order}
|
||||||
|
apiPath={ApiEndpoints.company_list}
|
||||||
|
src={company.image}
|
||||||
|
pk={company.pk}
|
||||||
|
refresh={refreshInstance}
|
||||||
|
imageActions={{
|
||||||
|
uploadFile: true,
|
||||||
|
deleteFile: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={8}>
|
||||||
|
<DetailsTable item={company} fields={tl} />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
<DetailsTable item={company} fields={tr} />
|
||||||
|
</ItemDetailsGrid>
|
||||||
|
);
|
||||||
|
}, [company, instanceQuery]);
|
||||||
|
|
||||||
const companyPanels: PanelType[] = useMemo(() => {
|
const companyPanels: PanelType[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: 'details',
|
name: 'details',
|
||||||
label: t`Details`,
|
label: t`Details`,
|
||||||
icon: <IconInfoCircle />
|
icon: <IconInfoCircle />,
|
||||||
|
content: detailsPanel
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'manufactured-parts',
|
name: 'manufactured-parts',
|
||||||
|
@ -16,6 +16,7 @@ import { Suspense, useMemo } from 'react';
|
|||||||
|
|
||||||
import { api } from '../App';
|
import { api } from '../App';
|
||||||
import { ProgressBar } from '../components/items/ProgressBar';
|
import { ProgressBar } from '../components/items/ProgressBar';
|
||||||
|
import { YesNoButton } from '../components/items/YesNoButton';
|
||||||
import { getModelInfo } from '../components/render/ModelType';
|
import { getModelInfo } from '../components/render/ModelType';
|
||||||
import { StatusRenderer } from '../components/render/StatusRenderer';
|
import { StatusRenderer } from '../components/render/StatusRenderer';
|
||||||
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
import { ApiEndpoints } from '../enums/ApiEndpoints';
|
||||||
@ -45,7 +46,13 @@ export type DetailsField =
|
|||||||
badge?: BadgeType;
|
badge?: BadgeType;
|
||||||
copy?: boolean;
|
copy?: boolean;
|
||||||
value_formatter?: () => ValueFormatterReturn;
|
value_formatter?: () => ValueFormatterReturn;
|
||||||
} & (StringDetailField | LinkDetailField | ProgressBarfield | StatusField);
|
} & (
|
||||||
|
| StringDetailField
|
||||||
|
| BooleanField
|
||||||
|
| LinkDetailField
|
||||||
|
| ProgressBarfield
|
||||||
|
| StatusField
|
||||||
|
);
|
||||||
|
|
||||||
type BadgeType = 'owner' | 'user' | 'group';
|
type BadgeType = 'owner' | 'user' | 'group';
|
||||||
type ValueFormatterReturn = string | number | null;
|
type ValueFormatterReturn = string | number | null;
|
||||||
@ -55,6 +62,10 @@ type StringDetailField = {
|
|||||||
unit?: boolean;
|
unit?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type BooleanField = {
|
||||||
|
type: 'boolean';
|
||||||
|
};
|
||||||
|
|
||||||
type LinkDetailField = {
|
type LinkDetailField = {
|
||||||
type: 'link';
|
type: 'link';
|
||||||
} & (InternalLinkField | ExternalLinkField);
|
} & (InternalLinkField | ExternalLinkField);
|
||||||
@ -288,6 +299,10 @@ function TableStringValue(props: FieldProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BooleanValue(props: FieldProps) {
|
||||||
|
return <YesNoButton value={props.field_value} />;
|
||||||
|
}
|
||||||
|
|
||||||
function TableAnchorValue(props: FieldProps) {
|
function TableAnchorValue(props: FieldProps) {
|
||||||
if (props.field_data.external) {
|
if (props.field_data.external) {
|
||||||
return (
|
return (
|
||||||
@ -404,6 +419,8 @@ export function DetailsTableField({
|
|||||||
case 'text':
|
case 'text':
|
||||||
case 'string':
|
case 'string':
|
||||||
return TableStringValue;
|
return TableStringValue;
|
||||||
|
case 'boolean':
|
||||||
|
return BooleanValue;
|
||||||
case 'link':
|
case 'link':
|
||||||
return TableAnchorValue;
|
return TableAnchorValue;
|
||||||
case 'progressbar':
|
case 'progressbar':
|
||||||
|
Loading…
Reference in New Issue
Block a user