main
alex 2024-03-06 19:32:01 +01:00
parent 19adacfcf6
commit 4628d56ac5
6 changed files with 883 additions and 46 deletions

View File

@ -24,6 +24,7 @@ const ViewEquipmentDocumentations = lazy(() =>
const Consoles = lazy(() => import("../../Pages/Consoles")); const Consoles = lazy(() => import("../../Pages/Consoles"));
const RoboticsRobots = lazy(() => import("../../Pages/Robotics/Robots")); const RoboticsRobots = lazy(() => import("../../Pages/Robotics/Robots"));
const Crm = lazy(() => import("../../Pages/Crm")); const Crm = lazy(() => import("../../Pages/Crm"));
const CrmTest = lazy(() => import("../../Pages/CrmTest/CrmTest"));
export default function AppRoutes({ userSession, setUserSession }) { export default function AppRoutes({ userSession, setUserSession }) {
const appContext = useAppContext(); const appContext = useAppContext();
@ -248,10 +249,10 @@ export default function AppRoutes({ userSession, setUserSession }) {
Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW
) && ( ) && (
<Route <Route
path={`${Constants.ROUTE_PATHS.CRM}:paramType/:paramDealPhase`} path={Constants.ROUTE_PATHS.CRM_TEST}
element={ element={
<MySupsenseFallback> <MySupsenseFallback>
<Crm /> <CrmTest />
</MySupsenseFallback> </MySupsenseFallback>
} }
/> />
@ -268,3 +269,24 @@ export default function AppRoutes({ userSession, setUserSession }) {
</Routes> </Routes>
); );
} }
/*
{hasOnePermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.CUSTOMERS.VIEW,
Constants.PERMISSIONS.CRM.DMC_PIPELINE.VIEW,
Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW
) && (
<Route
path={`${Constants.ROUTE_PATHS.CRM}:paramType/:paramDealPhase`}
element={
<MySupsenseFallback>
<Crm />
</MySupsenseFallback>
}
/>
)}
*/

View File

@ -169,6 +169,19 @@ export function SideMenuContent({
children: [], children: [],
}; };
if (
hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.CUSTOMERS.VIEW
)
) {
crmGroup.children.push({
label: t("sideMenu.crm.customers"),
icon: <FileTextOutlined />,
key: Constants.ROUTE_PATHS.CRM_TEST,
});
}
/*
if ( if (
hasPermission( hasPermission(
appContext.userPermissions, appContext.userPermissions,
@ -207,7 +220,7 @@ export function SideMenuContent({
key: `${Constants.ROUTE_PATHS.CRM}${Constants.CRM_TYPE.SETTER_CLOSER}/1`, key: `${Constants.ROUTE_PATHS.CRM}${Constants.CRM_TYPE.SETTER_CLOSER}/1`,
}); });
} }
*/
items.push(crmGroup); items.push(crmGroup);
} }

View File

@ -1061,6 +1061,8 @@ export function handleWebSocketMessage(
crmContext.setCustomers((arr) => { crmContext.setCustomers((arr) => {
const newArr = [...arr]; const newArr = [...arr];
console.log("before", arr);
const arrIndex = arr.findIndex((customer) => customer.Id === body.Id); const arrIndex = arr.findIndex((customer) => customer.Id === body.Id);
if (arrIndex !== -1) { if (arrIndex !== -1) {
@ -1068,10 +1070,14 @@ export function handleWebSocketMessage(
for (const property in body) { for (const property in body) {
if (body[property] !== undefined && property !== "Id") { if (body[property] !== undefined && property !== "Id") {
newArr[arrIndex][property] = body[property]; newArr[arrIndex][property] = body[property];
console.log("updated", property, body, body[property]);
} }
} }
} }
console.log("after", newArr);
return newArr; return newArr;
}); });

View File

@ -301,6 +301,24 @@ function CustomerDrawer({ isOpen, setIsOpen, onClose, notificationApi }) {
}); });
}; };
const handleRequestError = (status) => {
if (status === 409) {
notificationApi["error"]({
message: t("crm.tabContent.request.duplicateCompanyError.message"),
description: t(
"crm.tabContent.request.duplicateCompanyError.description"
),
});
} else {
notificationApi["error"]({
message: "test",
description: "here",
});
}
setIsOpen(true);
};
useEffect(() => { useEffect(() => {
if (crmContext.openDrawerCustomerId.current === null) return; if (crmContext.openDrawerCustomerId.current === null) return;
@ -315,25 +333,7 @@ function CustomerDrawer({ isOpen, setIsOpen, onClose, notificationApi }) {
crmContext.openDrawerCustomerId.current = false; crmContext.openDrawerCustomerId.current = false;
handleCloseDrawer(); handleCloseDrawer();
}) })
.catch((status) => { .catch((status) => handleRequestError(status));
if (status === 409) {
notificationApi["error"]({
message: t(
"crm.tabContent.request.duplicateCompanyError.message"
),
description: t(
"crm.tabContent.request.duplicateCompanyError.description"
),
});
} else {
notificationApi["error"]({
message: "test",
description: "here",
});
}
setIsOpen(true);
});
return; return;
} }
@ -362,31 +362,9 @@ function CustomerDrawer({ isOpen, setIsOpen, onClose, notificationApi }) {
"POST", "POST",
updatedCustomer updatedCustomer
) )
.then(() => { .then(() => handleCloseDrawer())
handleCloseDrawer(); .catch((status) => handleRequestError(status));
})
.catch((status) => {
if (status === 409) {
notificationApi["error"]({
message: t(
"crm.tabContent.request.duplicateCompanyError.message"
),
description: t(
"crm.tabContent.request.duplicateCompanyError.description"
),
});
} else {
notificationApi["error"]({
message: "test",
description: "here",
});
} }
setIsOpen(true);
});
}
//handleCloseDrawer();
} }
const handleCustomerRequest = () => customerRequest(); const handleCustomerRequest = () => customerRequest();

View File

@ -0,0 +1,816 @@
import {
Button,
Col,
Collapse,
Drawer,
Form,
Input,
Row,
Segmented,
Select,
Space,
Table,
Tabs,
Typography,
notification,
} from "antd";
import { useTranslation } from "react-i18next";
import {
AppStyle,
FormatDatetime,
myFetch,
showUnkownErrorNotification,
wsConnectionCustomEventName,
} from "../../utils";
import { useEffect, useState } from "react";
import { PlusOutlined } from "@ant-design/icons";
import { t } from "i18next";
import { useCrmContext } from "../../Contexts/CrmContext";
import "@mdxeditor/editor/style.css";
import { MDXEditor } from "@mdxeditor/editor/MDXEditor";
import { headingsPlugin } from "@mdxeditor/editor/plugins/headings";
import { listsPlugin } from "@mdxeditor/editor/plugins/lists";
import { quotePlugin } from "@mdxeditor/editor/plugins/quote";
import { thematicBreakPlugin } from "@mdxeditor/editor/plugins/thematic-break";
import { toolbarPlugin } from "@mdxeditor/editor/plugins/toolbar";
import { BoldItalicUnderlineToggles } from "@mdxeditor/editor/plugins/toolbar/components/BoldItalicUnderlineToggles";
import { UndoRedo } from "@mdxeditor/editor/plugins/toolbar/components/UndoRedo";
import { linkPlugin } from "@mdxeditor/editor/plugins/link";
import { markdownShortcutPlugin } from "@mdxeditor/editor/plugins/markdown-shortcut";
import { MySupsenseFallback } from "../../Components/MySupsenseFallback";
import { linkDialogPlugin } from "@mdxeditor/editor";
import { tablePlugin } from "@mdxeditor/editor";
import { frontmatterPlugin } from "@mdxeditor/editor";
const CRM_TYPE = {
CUSTOMERS: 0,
DMC_PIPELINE: 1,
SETTER_CLOSER: 2,
};
export default function CrmTest() {
const { t } = useTranslation();
const crmContext = useCrmContext();
const [isRequesting, setIsRequesting] = useState(false);
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [notificationApi, notificationContextHolder] =
notification.useNotification();
// used for the segmented component on top of the page
const [selectedSegmentedTypeValue, setSelectedSegmentedTypeValue] =
useState(0);
const title =
selectedSegmentedTypeValue === CRM_TYPE.CUSTOMERS
? "crm.customers.pageTitle"
: selectedSegmentedTypeValue === CRM_TYPE.DMC_PIPELINE
? "crm.dmcPipeline.pageTitle"
: "crm.setterCloser.pageTitle";
const segmentedOptions = t(
selectedSegmentedTypeValue === CRM_TYPE.DMC_PIPELINE
? "crm.dmcPipeline.segmentedOptions"
: "crm.setterCloser.segmentedOptions",
{
returnObjects: true,
}
);
const [
selectedDmcPipelineSegmentedValue,
setSelectedDmcPipelineSegmentedValue,
] = useState(0);
const [
selectedSetterCloserSegmentedValue,
setSelectedSetterCloserSegmentedValue,
] = useState(0);
const getTableContent = () => {
return [
{
title: t("crm.table.firstName"),
dataIndex: "firstName",
key: "firstName",
},
{
title: t("crm.table.lastName"),
dataIndex: "lastName",
key: "lastName",
},
{
title: t("crm.table.createdAt"),
dataIndex: "createdAt",
key: "createdAt",
},
{
title: t("crm.table.telephone"),
dataIndex: "telephone",
key: "telephone",
},
{
title: t("crm.table.email"),
dataIndex: "email",
key: "email",
},
{
title: t("crm.table.lastContact"),
dataIndex: "lastContact",
key: "lastContact",
},
{
title: t("crm.table.createdBy"),
dataIndex: "createdBy",
key: "createdBy",
},
];
};
const getTableItems = () => {
let data = crmContext.customers;
let items = [];
if (selectedSegmentedTypeValue === CRM_TYPE.DMC_PIPELINE) {
data = data.filter((item) => item.Pipeline === 1);
data = data.filter(
(item) => item.DealPhase === selectedDmcPipelineSegmentedValue + 1
);
} else if (selectedSegmentedTypeValue === CRM_TYPE.SETTER_CLOSER) {
data = data.filter((item) => item.Pipeline === 2);
data = data.filter(
(item) => item.DealPhase === selectedSetterCloserSegmentedValue + 1
);
}
data.forEach((item) => {
items.push({
key: item.Id,
id: item.Id,
firstName: item.FirstName,
lastName: item.LastName,
createdAt: FormatDatetime(item.CreatedAt),
telephone: item.Telephone,
email: item.Email,
lastContact: FormatDatetime(item.LastContact),
createdBy: item.CreatedBy,
});
});
return items;
};
useEffect(() => {
const customersRequest = () => {
setIsRequesting(true);
myFetch(`/crm/customers`, "GET").then((data) => {
if (data === undefined || data === null) return;
crmContext.setCustomers(data);
setIsRequesting(false);
});
};
customersRequest();
const handleCustomersRequest = () => customersRequest();
document.addEventListener(
wsConnectionCustomEventName,
handleCustomersRequest
);
return () =>
document.removeEventListener(
wsConnectionCustomEventName,
handleCustomersRequest
);
}, []);
return (
<>
{notificationContextHolder}
<Segmented
value={selectedSegmentedTypeValue}
onChange={(value) => {
setSelectedSegmentedTypeValue(value);
}}
options={[
{
value: CRM_TYPE.CUSTOMERS,
label: "All customers",
},
{
value: CRM_TYPE.DMC_PIPELINE,
label: "DMC Pipeline",
},
{
value: CRM_TYPE.SETTER_CLOSER,
label: "Setter Closer",
},
]}
block
/>
<div
style={{
display: "flex",
justifyContent: "space-between",
}}
>
<Typography.Title level={4}>{t(title)}</Typography.Title>
<Button
icon={<PlusOutlined />}
onClick={() => {
crmContext.openDrawerCustomerId.current = "new";
crmContext.currentDrawerCustomerRef.current = null;
setIsDrawerOpen(true);
}}
>
{t("crm.buttonNew")}
</Button>
</div>
{selectedSegmentedTypeValue !== CRM_TYPE.CUSTOMERS ? (
<Segmented
value={
selectedSegmentedTypeValue === CRM_TYPE.DMC_PIPELINE
? selectedDmcPipelineSegmentedValue
: selectedSetterCloserSegmentedValue
}
onChange={(value) => {
if (selectedSegmentedTypeValue === CRM_TYPE.DMC_PIPELINE) {
setSelectedDmcPipelineSegmentedValue(value);
} else {
setSelectedSetterCloserSegmentedValue(value);
}
}}
options={segmentedOptions.map((item, index) => {
return {
value: index,
label: item,
};
})}
style={{ marginBottom: AppStyle.app.margin }}
/>
) : (
<div style={{ height: 44 }} />
)}
<Table
scroll={{ x: "max-content" }}
columns={getTableContent()}
dataSource={getTableItems()}
loading={isRequesting}
pagination
onRow={(record) => {
return {
onClick: () => {
setIsDrawerOpen(true);
crmContext.openDrawerCustomerId.current = record.id;
},
};
}}
/>
<CustomerDrawer
isOpen={isDrawerOpen}
setIsOpen={setIsDrawerOpen}
onClose={() => setIsDrawerOpen(false)}
notificationApi={notificationApi}
/>
</>
);
}
function CustomerDrawer({ isOpen, setIsOpen, onClose, notificationApi }) {
const { t } = useTranslation();
const crmContext = useCrmContext();
const [formDealInfo] = Form.useForm();
const tabItems = [
{
key: "0",
label: t("crm.tabs.dealInfo"),
children: <TabContentDealInfo form={formDealInfo} />,
},
{
key: "1",
label: t("crm.tabs.activities"),
children: <TabContentActivities />,
},
{
key: "2",
label: t("crm.tabs.notes"),
children: (
<TabContentNotes
notes={
crmContext.currentDrawerCustomer === null ||
crmContext.currentDrawerCustomer.Notes === null
? ""
: crmContext.currentDrawerCustomer.Notes
}
/>
),
},
];
const [activeTab, setActiveTab] = useState(tabItems[0].key);
const customerRequest = () => {
if (!isOpen) return;
myFetch(
`/crm/customer/view/${crmContext.openDrawerCustomerId.current}`,
"GET"
).then((data) => {
crmContext.currentDrawerCustomerRef.current = data;
formDealInfo.setFieldsValue({
Pipeline: data.Pipeline,
DealPhase: data.DealPhase,
FirstName: data.FirstName,
LastName: data.LastName,
Telephone: data.Telephone,
Email: data.Email,
Company: data.Company,
ZipCode: data.ZipCode,
Address: data.Address,
City: data.City,
Country: data.Country,
FederalState: data.FederalState,
Website: data.Website,
LeadOrigin: data.LeadOrigin,
NumberOfEmployees: data.NumberOfEmployees,
NumberOfJobsSearchedFor: data.NumberOfJobsSearchedFor,
JobTitle: data.JobTitle,
NumberOfEmployeesRequired: data.NumberOfEmployeesRequired,
HowLongHadHeBeenSearching: data.HowLongHadHeBeenSearching,
Turnover: data.Turnover,
DateOfcompletion: data.DateOfcompletion,
OrderVolume: data.OrderVolume,
NumberOfInstallments: data.NumberOfInstallments,
AmountsOfTheInstallments: data.AmountsOfTheInstallments,
BookedPackages: data.BookedPackages,
AssignedEmployee: data.AssignedEmployee,
});
});
};
const handleRequestError = (status) => {
if (status === 409) {
notificationApi["error"]({
message: t("crm.tabContent.request.duplicateCompanyError.message"),
description: t(
"crm.tabContent.request.duplicateCompanyError.description"
),
});
} else {
showUnkownErrorNotification(notificationApi, t);
}
setIsOpen(true);
};
useEffect(() => {
if (crmContext.openDrawerCustomerId.current === null) return;
formDealInfo
.validateFields()
.then((values) => {
if (crmContext.openDrawerCustomerId.current === "new") {
if (isOpen) {
formDealInfo.resetFields();
formDealInfo.setFieldsValue({
Pipeline: 1,
DealPhase: 1,
});
return;
}
let changedFields = [];
Object.keys(values).forEach((key) => {
if (values[key] !== undefined) {
changedFields.push(key);
}
});
// check if something has changed (length 2 = only the pipeline and deal phase)
if (changedFields.length === 2) return;
let newCustomer = {};
Object.keys(values).forEach((key) => {
if (values[key] !== undefined) {
newCustomer[key] = values[key];
}
});
myFetch(`/crm/customer/create`, "POST", newCustomer)
.then(() => {
crmContext.openDrawerCustomerId.current = false;
handleCloseDrawer();
})
.catch((status) => handleRequestError(status));
return;
}
if (isOpen) {
customerRequest();
} else {
let changedFields = [];
Object.keys(values).forEach((key) => {
if (
values[key] !== crmContext.currentDrawerCustomerRef.current[key]
) {
changedFields.push(key);
}
});
// check if something has changed
if (changedFields.length > 0) {
// only updated changed fields
const updatedCustomer = {};
changedFields.forEach((key) => {
updatedCustomer[key] = values[key];
});
myFetch(
`/crm/customer/update/${crmContext.openDrawerCustomerId.current}`,
"POST",
updatedCustomer
)
.then(() => handleCloseDrawer())
.catch((status) => handleRequestError(status));
}
}
})
.catch(() => {});
const handleCustomerRequest = () => customerRequest();
document.addEventListener(
wsConnectionCustomEventName,
handleCustomerRequest
);
return () =>
document.removeEventListener(
wsConnectionCustomEventName,
handleCustomerRequest
);
}, [isOpen]);
const handleCloseDrawer = () => {
crmContext.openDrawerCustomerId.current = null;
crmContext.currentDrawerCustomerRef.current = null;
crmContext.changedDrawerCustomerFieldsRef.current = [];
formDealInfo.resetFields();
setActiveTab(tabItems[0].key);
};
const title =
crmContext.currentDrawerCustomer === null
? "loading..."
: `${crmContext.currentDrawerCustomer?.FirstName} ${crmContext.currentDrawerCustomer?.LastName}`;
return (
<Drawer
title={title}
placement="right"
open={isOpen}
onClose={onClose}
width={720}
extra={
<Button
onClick={() => {
onClose();
handleCloseDrawer();
}}
>
{t("crm.buttonUndo")}
</Button>
}
>
<Tabs
activeKey={activeTab}
onChange={(activeKey) => setActiveTab(activeKey)}
items={tabItems}
centered
/>
</Drawer>
);
}
function Content({ children }) {
return (
<Row gutter={16}>
<Col xs={24} sm={12}>
{children[0]}
</Col>
<Col xs={24} sm={12}>
{children[1]}
</Col>
</Row>
);
}
function CollapseContainer({ children, label }) {
return (
<Collapse
defaultActiveKey="1"
items={[
{
key: "1",
label: label,
children: children,
},
]}
/>
);
}
function TabContentDealInfo({ form }) {
const pipeline = Form.useWatch("Pipeline", form);
const FormItem = ({ name, label }) => (
<Form.Item name={name} label={t(label)}>
<Input />
</Form.Item>
);
const ContentBlock = ({ items }) => {
// Split items into chunks of two
const chunks = [];
for (let i = 0; i < items.length; i += 2) {
chunks.push(items.slice(i, i + 2));
}
// Render a Content component for each chunk
return (
<>
{chunks.map((chunk, index) => (
<Content key={index}>
{chunk.map((item) => (
<FormItem key={item.name} {...item} />
))}
</Content>
))}
</>
);
};
const CollapseContainerBlock = ({ label, items }) => (
<CollapseContainer label={t(label)}>
<ContentBlock items={items} />
</CollapseContainer>
);
return (
<MySupsenseFallback>
<Form form={form} layout="vertical">
<Space direction="vertical" style={{ display: "flex" }}>
<CollapseContainer
label={t("crm.tabContent.dealInfo.collapseDealStatus.label")}
>
<Content>
<Form.Item
name="Pipeline"
label={t("crm.tabContent.dealInfo.collapseDealStatus.pipeline")}
>
<Select
options={[
{
value: 1,
label: t("crm.dmcPipeline.pageTitle"),
},
{
value: 2,
label: t("crm.setterCloser.pageTitle"),
},
]}
/>
</Form.Item>
<Form.Item
name="DealPhase"
label={t(
"crm.tabContent.dealInfo.collapseDealStatus.dealPhase"
)}
>
<Select
options={t(
pipeline === 1
? "crm.dmcPipeline.segmentedOptions"
: "crm.setterCloser.segmentedOptions",
{ returnObjects: true }
).map((item, index) => {
return {
value: index + 1,
label: item,
};
})}
/>
</Form.Item>
</Content>
</CollapseContainer>
<CollapseContainerBlock
label="crm.tabContent.dealInfo.collapseMasterDataOfContact.label"
items={[
{
name: "FirstName",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.firstName",
},
{
name: "LastName",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.lastName",
},
{
name: "Telephone",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.telephone",
},
{
name: "Email",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.email",
},
{
name: "Company",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.company",
},
{
name: "ZipCode",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.zipCode",
},
{
name: "Address",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.address",
},
{
name: "City",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.city",
},
{
name: "Country",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.country",
},
{
name: "FederalState",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.federalState",
},
{
name: "Website",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.website",
},
{
name: "LeadOrigin",
label:
"crm.tabContent.dealInfo.collapseMasterDataOfContact.leadOrigin",
},
]}
/>
<CollapseContainerBlock
label="crm.tabContent.dealInfo.collapseSetterInfo.label"
items={[
{
name: "NumberOfEmployees",
label:
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfEmployees",
},
{
name: "NumberOfJobsSearchedFor",
label:
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfJobsSearchedFor",
},
{
name: "JobTitle",
label: "crm.tabContent.dealInfo.collapseSetterInfo.jobTitle",
},
{
name: "NumberOfEmployeesRequired",
label:
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfEmployeesRequired",
},
{
name: "HowLongHadHeBeenSearching",
label:
"crm.tabContent.dealInfo.collapseSetterInfo.howLongHadHeBeenSearching",
},
{
name: "Turnover",
label: "crm.tabContent.dealInfo.collapseSetterInfo.turnover",
},
]}
/>
<CollapseContainerBlock
label="crm.tabContent.dealInfo.collapseDealProperties.label"
items={[
{
name: "DateOfcompletion",
label:
"crm.tabContent.dealInfo.collapseDealProperties.dateOfcompletion",
},
{
name: "OrderVolume",
label:
"crm.tabContent.dealInfo.collapseDealProperties.orderVolume",
},
{
name: "NumberOfInstallments",
label:
"crm.tabContent.dealInfo.collapseDealProperties.numberOfInstallments",
},
{
name: "AmountsOfTheInstallments",
label:
"crm.tabContent.dealInfo.collapseDealProperties.amountsOfTheInstallments",
},
{
name: "BookedPackages",
label:
"crm.tabContent.dealInfo.collapseDealProperties.bookedPackages",
},
{
name: "AssignedEmployee",
label:
"crm.tabContent.dealInfo.collapseDealProperties.assignedEmployee",
},
]}
/>
</Space>
</Form>
</MySupsenseFallback>
);
}
function TabContentActivities() {
return (
<MySupsenseFallback>
<div>Coming soon</div>
</MySupsenseFallback>
);
}
function TabContentNotes({ notes }) {
const crmContext = useCrmContext();
return (
<MySupsenseFallback>
<MDXEditor
key={crmContext.currentDrawerCustomer?.Id}
className="mdx-editor"
markdown={notes}
onChange={(value) => {
crmContext.setCurrentDrawerCustomer({
...crmContext.currentDrawerCustomer,
Notes: value,
});
}}
plugins={[
listsPlugin(),
quotePlugin(),
headingsPlugin(),
linkPlugin(),
linkDialogPlugin(),
tablePlugin(),
thematicBreakPlugin(),
frontmatterPlugin(),
markdownShortcutPlugin(),
toolbarPlugin({
toolbarContents: () => (
<>
<UndoRedo />
<BoldItalicUnderlineToggles />
</>
),
}),
]}
/>
</MySupsenseFallback>
);
}

View File

@ -91,8 +91,10 @@ export const Constants = {
CONSOLES: "/consoles", CONSOLES: "/consoles",
ROBOTICS_ROBOTS: "/robotics/robots", ROBOTICS_ROBOTS: "/robotics/robots",
CRM: "/crm/", CRM: "/crm/",
CRM_TEST: "/crm/test",
}, },
CRM_TYPE: { CRM_TYPE: {
TEST_CUSTOMERS: "test-customers",
CUSTOMERS: "customers", CUSTOMERS: "customers",
DMC_PIPELINE: "dmc-pipeline", DMC_PIPELINE: "dmc-pipeline",
SETTER_CLOSER: "setter-closer", SETTER_CLOSER: "setter-closer",