diff --git a/src/frontend/src/functions/icons.tsx b/src/frontend/src/functions/icons.tsx
index 712a9fa850..d702110dac 100644
--- a/src/frontend/src/functions/icons.tsx
+++ b/src/frontend/src/functions/icons.tsx
@@ -5,6 +5,7 @@ import {
IconBox,
IconBuilding,
IconBuildingFactory2,
+ IconBuildingStore,
IconCalendar,
IconCalendarStats,
IconCheck,
@@ -22,6 +23,7 @@ import {
IconLink,
IconList,
IconListTree,
+ IconMail,
IconMapPin,
IconMapPinHeart,
IconNotes,
@@ -30,6 +32,7 @@ import {
IconPackageImport,
IconPackages,
IconPaperclip,
+ IconPhone,
IconPhoto,
IconProgressCheck,
IconQuestionMark,
@@ -49,6 +52,7 @@ import {
IconUserStar,
IconUsersGroup,
IconVersions,
+ IconWorld,
IconWorldCode,
IconX
} from '@tabler/icons-react';
@@ -87,6 +91,7 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
used_in: IconStack2,
manufacturers: IconBuildingFactory2,
suppliers: IconBuilding,
+ customers: IconBuildingStore,
purchase_orders: IconShoppingCart,
sales_orders: IconTruckDelivery,
scheduling: IconCalendarStats,
@@ -121,6 +126,7 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
link: IconLink,
responsible: IconUserStar,
pricing: IconCurrencyDollar,
+ currency: IconCurrencyDollar,
stocktake: IconClipboardList,
user: IconUser,
group: IconUsersGroup,
@@ -128,7 +134,10 @@ const icons: { [key: string]: (props: TablerIconsProps) => React.JSX.Element } =
copy: IconCopy,
quantity: IconNumbers,
progress: IconProgressCheck,
- reference: IconHash
+ reference: IconHash,
+ website: IconWorld,
+ email: IconMail,
+ phone: IconPhone
};
/**
diff --git a/src/frontend/src/pages/company/CompanyDetail.tsx b/src/frontend/src/pages/company/CompanyDetail.tsx
index 6728cb1caf..d4f9e81c28 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 { LoadingOverlay, Skeleton, Stack } from '@mantine/core';
+import { Grid, LoadingOverlay, Skeleton, Stack } from '@mantine/core';
import {
IconBuildingFactory2,
IconBuildingWarehouse,
@@ -18,6 +18,8 @@ import {
import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
+import { DetailsImage } from '../../components/details/DetailsImage';
+import { ItemDetailsGrid } from '../../components/details/ItemDetails';
import {
ActionDropdown,
DeleteItemAction,
@@ -35,6 +37,7 @@ import { useEditApiFormModal } from '../../hooks/UseForm';
import { useInstance } from '../../hooks/UseInstance';
import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState';
+import { DetailsField, DetailsTable } from '../../tables/Details';
import { AddressTable } from '../../tables/company/AddressTable';
import { ContactTable } from '../../tables/company/ContactTable';
import { AttachmentTable } from '../../tables/general/AttachmentTable';
@@ -69,12 +72,99 @@ export default function CompanyDetail(props: CompanyDetailProps) {
refetchOnMount: true
});
+ const detailsPanel = useMemo(() => {
+ if (instanceQuery.isFetching) {
+ return ;
+ }
+
+ 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 (
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }, [company, instanceQuery]);
+
const companyPanels: PanelType[] = useMemo(() => {
return [
{
name: 'details',
label: t`Details`,
- icon:
+ icon: ,
+ content: detailsPanel
},
{
name: 'manufactured-parts',
diff --git a/src/frontend/src/tables/Details.tsx b/src/frontend/src/tables/Details.tsx
index 58932c979f..80ae1316c5 100644
--- a/src/frontend/src/tables/Details.tsx
+++ b/src/frontend/src/tables/Details.tsx
@@ -16,6 +16,7 @@ import { Suspense, useMemo } from 'react';
import { api } from '../App';
import { ProgressBar } from '../components/items/ProgressBar';
+import { YesNoButton } from '../components/items/YesNoButton';
import { getModelInfo } from '../components/render/ModelType';
import { StatusRenderer } from '../components/render/StatusRenderer';
import { ApiEndpoints } from '../enums/ApiEndpoints';
@@ -45,7 +46,13 @@ export type DetailsField =
badge?: BadgeType;
copy?: boolean;
value_formatter?: () => ValueFormatterReturn;
- } & (StringDetailField | LinkDetailField | ProgressBarfield | StatusField);
+ } & (
+ | StringDetailField
+ | BooleanField
+ | LinkDetailField
+ | ProgressBarfield
+ | StatusField
+ );
type BadgeType = 'owner' | 'user' | 'group';
type ValueFormatterReturn = string | number | null;
@@ -55,6 +62,10 @@ type StringDetailField = {
unit?: boolean;
};
+type BooleanField = {
+ type: 'boolean';
+};
+
type LinkDetailField = {
type: 'link';
} & (InternalLinkField | ExternalLinkField);
@@ -288,6 +299,10 @@ function TableStringValue(props: FieldProps) {
);
}
+function BooleanValue(props: FieldProps) {
+ return ;
+}
+
function TableAnchorValue(props: FieldProps) {
if (props.field_data.external) {
return (
@@ -404,6 +419,8 @@ export function DetailsTableField({
case 'text':
case 'string':
return TableStringValue;
+ case 'boolean':
+ return BooleanValue;
case 'link':
return TableAnchorValue;
case 'progressbar':