update crm and create new customer

main
alex 2023-12-07 22:58:57 +01:00
parent 831fa8e0ab
commit 4746e3e892
9 changed files with 4289 additions and 391 deletions

3514
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.0.1", "@ant-design/icons": "^5.0.1",
"@mdxeditor/editor": "^1.13.2",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",

View File

@ -277,6 +277,7 @@
"notes": "Notes" "notes": "Notes"
}, },
"buttonNew": "New", "buttonNew": "New",
"buttonUndo": "Undo",
"tabs": { "tabs": {
"dealInfo": "Deal Info", "dealInfo": "Deal Info",
"activities": "Activities", "activities": "Activities",

View File

@ -67,3 +67,7 @@
content: unset; content: unset;
} }
} }
.mdx-editor {
background: #f4f5f4;
}

View File

@ -1,8 +1,8 @@
import { Route, Routes } from "react-router-dom"; import { Route, Routes } from "react-router-dom";
import { Constants, hasOnePermission, hasPermission } from "../../utils"; import { Constants, hasOnePermission, hasPermission } from "../../utils";
import { useAppContext } from "../../Contexts/AppContext"; import { useAppContext } from "../../Contexts/AppContext";
import { Suspense, lazy } from "react"; import { lazy } from "react";
import { Spin } from "antd"; import { MySupsenseFallback } from "../MySupsenseFallback";
// Lazy-loaded components // Lazy-loaded components
const Dashboard = lazy(() => import("../../Pages/Dashboard")); const Dashboard = lazy(() => import("../../Pages/Dashboard"));
@ -25,30 +25,6 @@ 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"));
function SuspenseFallback({ children }) {
return (
<Suspense
fallback={
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignContent: "center",
alignItems: "center",
textAlign: "center",
height: "98.3vh",
}}
>
<Spin size="large" />
</div>
}
>
{children}
</Suspense>
);
}
export default function AppRoutes({ userSession, setUserSession }) { export default function AppRoutes({ userSession, setUserSession }) {
const appContext = useAppContext(); const appContext = useAppContext();
@ -59,9 +35,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path="/" path="/"
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<Dashboard /> <Dashboard />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
@ -72,9 +48,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION} path={Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<EquipmentDocumentationOverview /> <EquipmentDocumentationOverview />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -86,9 +62,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId`} path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<ViewEquipmentDocumentations /> <ViewEquipmentDocumentations />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -100,11 +76,11 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId/edit/:paramDocumentationId`} path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId/edit/:paramDocumentationId`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<ViewEquipmentDocumentations <ViewEquipmentDocumentations
isEditEquipmentDocumentationModalOpen={true} isEditEquipmentDocumentationModalOpen={true}
/> />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -116,11 +92,11 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId/create`} path={`${Constants.ROUTE_PATHS.EQUIPMENT_DOCUMENTATION_VIEW}:paramStockId/create`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<ViewEquipmentDocumentations <ViewEquipmentDocumentations
isCreateEquipmentDocumentationModalOpen={true} isCreateEquipmentDocumentationModalOpen={true}
/> />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -128,18 +104,18 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={`${Constants.ROUTE_PATHS.GROUP_TASKS}:paramCategory`} path={`${Constants.ROUTE_PATHS.GROUP_TASKS}:paramCategory`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<GroupTasks isGroupTasksViewModalOpen={false} /> <GroupTasks isGroupTasksViewModalOpen={false} />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
<Route <Route
path={`${Constants.ROUTE_PATHS.GROUP_TASKS}:paramCategory/view/:paramGroupTaskId`} path={`${Constants.ROUTE_PATHS.GROUP_TASKS}:paramCategory/view/:paramGroupTaskId`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<GroupTasks isGroupTasksViewModalOpen={true} /> <GroupTasks isGroupTasksViewModalOpen={true} />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
@ -150,9 +126,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.GROUP_TASKS_HISTORY} path={Constants.ROUTE_PATHS.GROUP_TASKS_HISTORY}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<GroupTasksHistory /> <GroupTasksHistory />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -160,30 +136,30 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.SCANNERS} path={Constants.ROUTE_PATHS.SCANNERS}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<Scanners /> <Scanners />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
<Route <Route
path={Constants.ROUTE_PATHS.USERS} path={Constants.ROUTE_PATHS.USERS}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<AllUsers /> <AllUsers />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
<Route <Route
path={Constants.ROUTE_PATHS.USER_PROFILE} path={Constants.ROUTE_PATHS.USER_PROFILE}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<UserProfile <UserProfile
userSession={userSession} userSession={userSession}
setUserSession={setUserSession} setUserSession={setUserSession}
/> />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
@ -197,9 +173,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.ADMIN_AREA_ROLES} path={Constants.ROUTE_PATHS.ADMIN_AREA_ROLES}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<AdminAreaRoles /> <AdminAreaRoles />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -211,9 +187,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.ADMIN_AREA_LOGS} path={Constants.ROUTE_PATHS.ADMIN_AREA_LOGS}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<AdminAreaLogs /> <AdminAreaLogs />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -230,9 +206,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.ADMIN_AREA_MANAGE} path={Constants.ROUTE_PATHS.ADMIN_AREA_MANAGE}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<AdminAreaManage /> <AdminAreaManage />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -244,9 +220,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.CONSOLES} path={Constants.ROUTE_PATHS.CONSOLES}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<Consoles /> <Consoles />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -258,9 +234,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={Constants.ROUTE_PATHS.ROBOTICS_ROBOTS} path={Constants.ROUTE_PATHS.ROBOTICS_ROBOTS}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<RoboticsRobots /> <RoboticsRobots />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -274,9 +250,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path={`${Constants.ROUTE_PATHS.CRM}:paramType/:paramDealPhase`} path={`${Constants.ROUTE_PATHS.CRM}:paramType/:paramDealPhase`}
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<Crm /> <Crm />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
)} )}
@ -284,9 +260,9 @@ export default function AppRoutes({ userSession, setUserSession }) {
<Route <Route
path="*" path="*"
element={ element={
<SuspenseFallback> <MySupsenseFallback>
<PageNotFound /> <PageNotFound />
</SuspenseFallback> </MySupsenseFallback>
} }
/> />
</Routes> </Routes>

View File

@ -0,0 +1,26 @@
import { Spin } from "antd";
import { Suspense } from "react";
export function MySupsenseFallback({ children }) {
return (
<Suspense
fallback={
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignContent: "center",
alignItems: "center",
textAlign: "center",
height: "98.3vh",
}}
>
<Spin size="large" />
</div>
}
>
{children}
</Suspense>
);
}

View File

@ -8,6 +8,7 @@ const preview = {
openDrawerCustomerId: null, openDrawerCustomerId: null,
currentDrawerCustomer: null, currentDrawerCustomer: null,
currentDrawerCustomerRef: null, currentDrawerCustomerRef: null,
changedDrawerCustomerFieldsRef: null,
}; };
const CrmContext = createContext(preview); const CrmContext = createContext(preview);
@ -24,8 +25,9 @@ export function CrmProvider({ children }) {
const openDrawerCustomerId = useRef(null); const openDrawerCustomerId = useRef(null);
// will be used to store the customer object that is currently being viewed in the drawer // will be used to store the customer object that is currently being viewed in the drawer
const [currentDrawerCustomer, setCurrentDrawerCustomer] = useState(null); const [currentDrawerCustomer, setCurrentDrawerCustomer] = useState(null);
// will be set on drawer open and used to check if the customer has changed // will be used to store the customer updated object that is currently being viewed in the drawer
const currentDrawerCustomerRef = useRef(null); const currentDrawerCustomerRef = useRef(null);
const changedDrawerCustomerFieldsRef = useRef([]);
return ( return (
<CrmContext.Provider <CrmContext.Provider
@ -41,6 +43,7 @@ export function CrmProvider({ children }) {
currentDrawerCustomer, currentDrawerCustomer,
setCurrentDrawerCustomer, setCurrentDrawerCustomer,
currentDrawerCustomerRef, currentDrawerCustomerRef,
changedDrawerCustomerFieldsRef,
}} }}
> >
{children} {children}

View File

@ -49,6 +49,7 @@ export const ReceivedMessagesCommands = {
AdminAreaManageLogManagerServerConnectionAdded: 45, AdminAreaManageLogManagerServerConnectionAdded: 45,
AdminAreaManageLogManagerServerConnectionRemoved: 46, AdminAreaManageLogManagerServerConnectionRemoved: 46,
CrmCustomerUpdated: 47, CrmCustomerUpdated: 47,
CrmCustomerCreated: 48,
}; };
// commands sent to the backend server // commands sent to the backend server
@ -1030,14 +1031,27 @@ export function handleWebSocketMessage(
); );
break; break;
case ReceivedMessagesCommands.CrmCustomerUpdated: case ReceivedMessagesCommands.CrmCustomerUpdated:
console.log("CrmCustomerUpdated", body);
console.log("current", crmContext.currentDrawerCustomerRef.current);
// update drawer customer if it is the same customer // update drawer customer if it is the same customer
if (crmContext.currentDrawerCustomerRef.current !== null) { if (crmContext.currentDrawerCustomerRef.current !== null) {
if (crmContext.currentDrawerCustomerRef.current.Id === body.Id) { if (crmContext.currentDrawerCustomerRef.current.Id === body.Id) {
crmContext.setCurrentDrawerCustomer(body); for (const property in body) {
if (
crmContext.changedDrawerCustomerFieldsRef.current.includes(
property
)
)
continue;
if (body[property] !== undefined && property !== "Id") {
crmContext.setCurrentDrawerCustomer((obj) => {
const newObj = { ...obj };
newObj[property] = body[property];
return newObj;
});
}
}
} }
} }
@ -1048,13 +1062,23 @@ export function handleWebSocketMessage(
const arrIndex = arr.findIndex((customer) => customer.Id === body.Id); const arrIndex = arr.findIndex((customer) => customer.Id === body.Id);
if (arrIndex !== -1) { if (arrIndex !== -1) {
newArr[arrIndex] = body; // only update the changed properties and if the property exists
for (const property in body) {
if (body[property] !== undefined && property !== "Id") {
newArr[arrIndex][property] = body[property];
}
}
} }
return newArr; return newArr;
}); });
break; break;
case ReceivedMessagesCommands.CrmCustomerCreated:
console.log("test");
crmContext.setCustomers((arr) => [...arr, body]);
break;
default: default:
console.error("unknown command", cmd); console.error("unknown command", cmd);

File diff suppressed because it is too large Load Diff