@paro.io/expert-shared-components 1.14.33 → 1.14.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -2
  3. package/lib/components/ClientReferencesSection/DeleteButton.js +11 -11
  4. package/lib/components/ClientReferencesSection/ParoError.js +10 -10
  5. package/lib/components/ClientReferencesSection/TagsSection.js +2 -2
  6. package/lib/components/ClientReferencesSection/styles/BrandedTypography.js +2 -2
  7. package/lib/components/ClientReferencesSection/styles/Buttons.js +15 -15
  8. package/lib/components/ClientReferencesSection/styles/Name.js +5 -5
  9. package/lib/components/ClientReferencesSection/styles/NullContentConditionalColor.js +4 -4
  10. package/lib/components/ClientReferencesSection/styles/SectionBody.js +11 -11
  11. package/lib/components/ClientReferencesSection/styles/SectionTitle.js +6 -6
  12. package/lib/components/ClientReferencesSection/styles/Tags.js +2 -2
  13. package/lib/components/DiscussionThread/DiscussionThread.d.ts +25 -25
  14. package/lib/components/DiscussionThread/DiscussionThread.js +137 -137
  15. package/lib/components/DiscussionThread/chat.d.ts +22 -22
  16. package/lib/components/DiscussionThread/chat.js +106 -106
  17. package/lib/components/DiscussionThread/index.d.ts +1 -1
  18. package/lib/components/DiscussionThread/index.js +5 -5
  19. package/lib/components/DocumentCenter/DocumentTable.d.ts +15 -15
  20. package/lib/components/DocumentCenter/DocumentTable.js +350 -350
  21. package/lib/components/DocumentCenter/UploadFilesButton.d.ts +6 -6
  22. package/lib/components/DocumentCenter/UploadFilesButton.js +29 -29
  23. package/lib/components/EarningsTracker/ActiveProjectCard.d.ts +52 -52
  24. package/lib/components/EarningsTracker/ActiveProjectCard.js +161 -161
  25. package/lib/components/EarningsTracker/CenterCardUI.d.ts +13 -13
  26. package/lib/components/EarningsTracker/CenterCardUI.js +134 -134
  27. package/lib/components/EarningsTracker/EarningsTracker.d.ts +52 -52
  28. package/lib/components/EarningsTracker/EarningsTracker.js +508 -508
  29. package/lib/components/EarningsTracker/EditDateModal.d.ts +22 -22
  30. package/lib/components/EarningsTracker/EditDateModal.js +149 -149
  31. package/lib/components/EarningsTracker/EmailModal.d.ts +14 -14
  32. package/lib/components/EarningsTracker/EmailModal.js +79 -79
  33. package/lib/components/EarningsTracker/EndProjectModal.d.ts +56 -56
  34. package/lib/components/EarningsTracker/EndProjectModal.js +221 -221
  35. package/lib/components/EarningsTracker/LeftCardUI.d.ts +18 -18
  36. package/lib/components/EarningsTracker/LeftCardUI.js +189 -189
  37. package/lib/components/EarningsTracker/LogTimeModalAuthenticated.d.ts +52 -52
  38. package/lib/components/EarningsTracker/LogTimeModalAuthenticated.js +358 -358
  39. package/lib/components/EarningsTracker/ProgressBar.d.ts +4 -4
  40. package/lib/components/EarningsTracker/ProgressBar.js +66 -66
  41. package/lib/components/EarningsTracker/ReviewRequestModal.d.ts +17 -17
  42. package/lib/components/EarningsTracker/ReviewRequestModal.js +135 -135
  43. package/lib/components/EarningsTracker/RightCardUI.d.ts +46 -46
  44. package/lib/components/EarningsTracker/RightCardUI.js +231 -231
  45. package/lib/components/EarningsTracker/index.d.ts +1 -1
  46. package/lib/components/EarningsTracker/index.js +5 -5
  47. package/lib/components/Escalations/CustomTag.d.ts +3 -3
  48. package/lib/components/Escalations/CustomTag.js +25 -25
  49. package/lib/components/Escalations/ViewReponseModal.d.ts +8 -8
  50. package/lib/components/Escalations/ViewReponseModal.js +27 -27
  51. package/lib/components/ExpertProfileHeader/ActionButtonSection.js +6 -6
  52. package/lib/components/ExpertProfileHeader/ProfileSection.js +7 -7
  53. package/lib/components/HeaderNavBar/index.d.ts +2 -1
  54. package/lib/components/HeaderNavBar/index.js +2 -2
  55. package/lib/components/Invoices/DiscussionSection.js +10 -3
  56. package/lib/components/Invoices/TestDecisionSection.d.ts +1 -1
  57. package/lib/components/Invoices/TestDecisionSection.js +126 -126
  58. package/lib/components/OrganizationChart/OrganizationChart.d.ts +15 -15
  59. package/lib/components/OrganizationChart/OrganizationChart.js +312 -312
  60. package/lib/components/OrganizationChart/PersonCard.js +5 -5
  61. package/lib/components/OrganizationChart/utils.js +79 -79
  62. package/lib/components/ProjectCard/ProgressBar.js +4 -4
  63. package/lib/components/ProjectCard/ReviewRequestModal.js +5 -5
  64. package/lib/components/ProjectIntelligence/MissingInformation/index.js +1 -1
  65. package/lib/components/Reviews/Pagination.js +6 -6
  66. package/lib/components/ReviewsTab/RatingHeader.js +6 -6
  67. package/lib/components/ReviewsTab/expert-shared-components.code-workspace +20 -20
  68. package/lib/components/ReviewsTab/reviewRequestModal.js +5 -5
  69. package/lib/components/shared/Image.js +13 -13
  70. package/lib/components/shared/ProfileTextField.d.ts +18 -18
  71. package/lib/components/shared/ProfileTextField.js +16 -16
  72. package/lib/components/shared/StyledActionButtons.d.ts +7 -7
  73. package/lib/components/shared/StyledActionButtons.js +15 -15
  74. package/lib/components/shared/ToastNotification.d.ts +10 -10
  75. package/lib/components/shared/ToastNotification.js +63 -63
  76. package/package.json +67 -67
@@ -1,312 +1,312 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.OrganizationChart = void 0;
30
- const react_1 = __importStar(require("react"));
31
- const core_1 = require("@material-ui/core");
32
- const Dialog_1 = __importDefault(require("@material-ui/core/Dialog"));
33
- const Close_1 = __importDefault(require("@material-ui/icons/Close"));
34
- const cdn_1 = require("../shared/constants/cdn");
35
- const styled_components_1 = __importDefault(require("styled-components"));
36
- const defaultAvatar = cdn_1.CDN_URL + 'defaultAvatar.png';
37
- const ProfilePhotoPreview = styled_components_1.default.img `
38
- height: 86px;
39
- width: 86px;
40
- border: 1px solid #e4e5e4;
41
- border-radius: 50%;
42
- object-fit: cover;
43
- object-position: top;
44
- `;
45
- const CustomDialog = (0, core_1.styled)(Dialog_1.default)(({ theme }) => ({
46
- '& .MuiDialog-paper': {
47
- backgroundColor: '#060821',
48
- width: '50vw',
49
- maxWidth: '80vw',
50
- height: '80vh',
51
- justifyContent: 'center',
52
- alignItems: 'center',
53
- overflow: 'hidden',
54
- [theme.breakpoints.down('md')]: {
55
- width: '100vw',
56
- maxWidth: '100vw',
57
- },
58
- }
59
- }));
60
- const InformationRow = ({ label, value }) => {
61
- return (react_1.default.createElement(core_1.Grid, { item: true, container: true, justify: "flex-start", alignItems: "center" },
62
- react_1.default.createElement(core_1.Box, { style: {
63
- backgroundColor: '#248384',
64
- color: 'white',
65
- textAlign: 'center',
66
- margin: '2px',
67
- padding: '4px',
68
- width: '120px',
69
- borderRadius: '6px',
70
- fontSize: '10px'
71
- } },
72
- react_1.default.createElement("b", null, label)),
73
- react_1.default.createElement(core_1.Box, { ml: 0.5 }, value !== null && value !== void 0 ? value : 'N/A')));
74
- };
75
- const EmployeeCard = ({ name, role, experience, location, imageUrl }) => {
76
- return (react_1.default.createElement(core_1.Card, { style: {
77
- backgroundColor: '#d9efef',
78
- borderRadius: '12px',
79
- width: 'max-content',
80
- padding: '4px 20px',
81
- margin: '8px'
82
- } },
83
- imageUrl && (react_1.default.createElement(core_1.Grid, { item: true, justify: "center", style: { display: 'flex', justifyContent: 'center' } },
84
- react_1.default.createElement(ProfilePhotoPreview, { src: imageUrl || defaultAvatar, alt: 'Profile Photo' }))),
85
- react_1.default.createElement(core_1.Typography, { variant: "subtitle2", align: "center" },
86
- react_1.default.createElement("b", null, name)),
87
- react_1.default.createElement(core_1.Grid, { item: true, justify: "center", alignItems: "center" },
88
- react_1.default.createElement(InformationRow, { label: "Role", value: role }),
89
- react_1.default.createElement(InformationRow, { label: "Experience", value: experience }),
90
- react_1.default.createElement(InformationRow, { label: "Location", value: location }))));
91
- };
92
- const HorizontalLine = () => (react_1.default.createElement(core_1.Grid, { item: true, alignContent: "center", style: {
93
- position: 'relative',
94
- background: '#FFFFFF',
95
- width: 'calc(105% - 1px)',
96
- height: '2px',
97
- top: 0,
98
- right: 0,
99
- left: '50%',
100
- transform: 'translateX(0)'
101
- } }));
102
- const VerticalLine = ({ isBottomLine }) => (react_1.default.createElement(core_1.Grid, { item: true, style: {
103
- position: 'relative',
104
- background: '#FFFFFF',
105
- width: '2px',
106
- height: '30px',
107
- top: 0,
108
- left: '50%',
109
- transform: 'translateX(-50%)'
110
- } }, !isBottomLine && react_1.default.createElement("div", { style: {
111
- content: '',
112
- position: 'absolute',
113
- bottom: 0,
114
- left: '50%',
115
- transform: 'translateX(-50%)',
116
- borderStyle: 'solid',
117
- borderWidth: '6px 6px 0 6px',
118
- borderColor: '#FFFFFF transparent transparent transparent'
119
- } })));
120
- const parseServices = (services) => {
121
- var _a;
122
- const uniqueArray = (_a = Array.from(new Set(services === null || services === void 0 ? void 0 : services.map(item => JSON.stringify(item))))) === null || _a === void 0 ? void 0 : _a.map(str => JSON.parse(str));
123
- return uniqueArray;
124
- };
125
- const checkEmployeeLocation = (data) => {
126
- let hasOffshore = false;
127
- let hasOnshore = false;
128
- data === null || data === void 0 ? void 0 : data.forEach(employee => {
129
- var _a;
130
- const location = (_a = employee === null || employee === void 0 ? void 0 : employee.employeeLocation) === null || _a === void 0 ? void 0 : _a.toLowerCase();
131
- if (location === null || location === void 0 ? void 0 : location.includes("offshore")) {
132
- hasOffshore = true;
133
- }
134
- if (location === null || location === void 0 ? void 0 : location.includes("onshore")) {
135
- hasOnshore = true;
136
- }
137
- });
138
- if (hasOffshore && hasOnshore) {
139
- return "Offshore & Onshore Team";
140
- }
141
- else if (hasOffshore) {
142
- return "Offshore Team";
143
- }
144
- else if (hasOnshore) {
145
- return "Onshore Team";
146
- }
147
- else {
148
- return "none";
149
- }
150
- };
151
- const getTotalYearsWithFirm = (data) => {
152
- return data === null || data === void 0 ? void 0 : data.reduce((total, employee) => total + employee.yearsWithFirm, 0);
153
- };
154
- const OrganizationChart = ({ openModal, setOpenModal, expertFirms, firstName, lastName, imageUrl, primaryServiceLine, city, stateAbbreviation, paroTenure, isPublicProfile }) => {
155
- var _a, _b;
156
- const services = (_a = expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmClientReferences) === null || _a === void 0 ? void 0 : _a.flatMap((obj) => { var _a; return (_a = obj === null || obj === void 0 ? void 0 : obj.services) !== null && _a !== void 0 ? _a : []; });
157
- const uniqueServices = parseServices(services);
158
- const employeeLocation = checkEmployeeLocation(expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees);
159
- const getTotalYears = getTotalYearsWithFirm(expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees);
160
- let firmMemberCounter = 1;
161
- const groupedEmployees = (_b = expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees) === null || _b === void 0 ? void 0 : _b.reduce((acc, obj) => {
162
- if (!acc[obj.level]) {
163
- acc[obj.level] = [];
164
- }
165
- acc[obj.level].push(obj);
166
- return acc;
167
- }, {});
168
- const [scale, setScale] = (0, react_1.useState)((groupedEmployees === null || groupedEmployees === void 0 ? void 0 : groupedEmployees.length) >= 2 ? 0.3 : 0.5); // checking no of levels & zooming out to fit content
169
- const [position, setPosition] = (0, react_1.useState)({ x: 0, y: (groupedEmployees === null || groupedEmployees === void 0 ? void 0 : groupedEmployees.length) >= 2 ? -100 : 0 }); // negative value to align content maximum zoom out and center
170
- const [isDragging, setIsDragging] = (0, react_1.useState)(false);
171
- const [lastMousePos, setLastMousePos] = (0, react_1.useState)(null);
172
- const sortedLevels = Object.keys(groupedEmployees || {})
173
- .map(Number)
174
- .sort((a, b) => a - b);
175
- const MAX_ZOOM_IN = 5;
176
- const MAX_ZOOM_OUT = 0.2;
177
- const CONTENT_SIZE = 10;
178
- // to center the content
179
- const centerContent = (newScale) => {
180
- const centerX = (CONTENT_SIZE * newScale) / 2;
181
- const centerY = (CONTENT_SIZE * newScale) / 2;
182
- setPosition({ x: centerX, y: centerY });
183
- };
184
- const handleWheel = (event) => {
185
- event.preventDefault();
186
- const zoomFactor = 0.1;
187
- if (event.deltaY < 0) {
188
- setScale((prev) => Math.min(prev + zoomFactor, MAX_ZOOM_IN));
189
- }
190
- else {
191
- setScale((prev) => {
192
- const newScale = Math.max(prev - zoomFactor, MAX_ZOOM_OUT);
193
- if (newScale === MAX_ZOOM_OUT) {
194
- centerContent(newScale); // Center content when zoomed out fully
195
- }
196
- return newScale;
197
- });
198
- }
199
- };
200
- const handleMouseDown = (event) => {
201
- setIsDragging(true);
202
- setLastMousePos({ x: event.clientX, y: event.clientY });
203
- };
204
- const handleMouseMove = (event) => {
205
- if (isDragging && lastMousePos) {
206
- const dx = event.clientX - lastMousePos.x;
207
- const dy = event.clientY - lastMousePos.y;
208
- setPosition((prev) => ({
209
- x: prev.x + dx,
210
- y: prev.y + dy,
211
- }));
212
- setLastMousePos({ x: event.clientX, y: event.clientY });
213
- }
214
- };
215
- const handleMouseUp = () => {
216
- setIsDragging(false);
217
- };
218
- // to center the content on double click
219
- const handleDoubleClick = () => {
220
- const newScale = 1;
221
- setScale(newScale);
222
- centerContent(newScale);
223
- };
224
- const highlightsExists = ((expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.employeeCount) > 0 || employeeLocation !== 'none' || getTotalYears > 0);
225
- const uniqueServicesExists = (uniqueServices === null || uniqueServices === void 0 ? void 0 : uniqueServices.length) > 1;
226
- return (react_1.default.createElement(CustomDialog, { open: openModal, onClose: () => setOpenModal(false), fullScreen: true, scroll: 'paper' },
227
- react_1.default.createElement(react_1.default.Fragment, null,
228
- react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: "row", justify: "space-between", alignItems: "center" },
229
- react_1.default.createElement(core_1.Box, { p: 2 },
230
- react_1.default.createElement(core_1.Typography, { variant: "subtitle1" },
231
- react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Organizational Structure & Services")),
232
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
233
- react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "See what services the organization offers and where they're located"))),
234
- react_1.default.createElement(core_1.Box, { style: { alignSelf: 'flex-end' } },
235
- react_1.default.createElement(core_1.IconButton, { onClick: () => setOpenModal(false) },
236
- react_1.default.createElement(core_1.Box, { style: { color: 'white' } },
237
- react_1.default.createElement(Close_1.default, null))))),
238
- react_1.default.createElement(core_1.DialogContent, { onWheel: handleWheel, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onDoubleClick: handleDoubleClick, style: {
239
- overflow: 'hidden',
240
- width: '100%',
241
- height: '100vh',
242
- position: 'relative',
243
- } },
244
- react_1.default.createElement("div", { onMouseDown: handleMouseDown, style: {
245
- transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,
246
- transformOrigin: 'center',
247
- transition: 'transform 0.1s',
248
- width: '100%',
249
- height: '100%',
250
- position: 'relative',
251
- cursor: isDragging ? 'grabbing' : 'grab',
252
- userSelect: 'none',
253
- } },
254
- isPublicProfile ?
255
- react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: "row", justify: "flex-start", alignItems: 'center', wrap: 'nowrap', spacing: 4, style: { width: '100%' } },
256
- react_1.default.createElement(core_1.Box, { style: { width: '25%' } }, highlightsExists &&
257
- react_1.default.createElement(core_1.Box, null,
258
- react_1.default.createElement(core_1.Grid, { item: true },
259
- react_1.default.createElement(core_1.Typography, { variant: "subtitle1" },
260
- react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Highlights:")),
261
- react_1.default.createElement("ul", null,
262
- (expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.employeeCount) > 0 && react_1.default.createElement("li", { style: { color: 'white' } },
263
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
264
- react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, expertFirms === null || expertFirms === void 0 ? void 0 :
265
- expertFirms.employeeCount,
266
- " Team Members"))),
267
- employeeLocation !== 'none' && react_1.default.createElement("li", { style: { color: 'white' } },
268
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
269
- react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, employeeLocation))),
270
- getTotalYears > 0 && react_1.default.createElement("li", { style: { color: 'white' } },
271
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
272
- react_1.default.createElement(core_1.Box, { style: { color: 'white', } },
273
- getTotalYears,
274
- " years of combined experience"))))))),
275
- react_1.default.createElement(core_1.Box, { style: { width: '50%' } },
276
- react_1.default.createElement(core_1.Grid, { item: true },
277
- react_1.default.createElement(core_1.Box, null,
278
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
279
- react_1.default.createElement(core_1.Box, { style: { color: 'white', textAlign: 'center' }, mt: 4, ml: 2 }, "Level 1")),
280
- react_1.default.createElement(core_1.Grid, { item: true, direction: "row", justify: "center", alignItems: "center", style: { margin: 'auto', width: 'fit-content' } },
281
- react_1.default.createElement(EmployeeCard, { name: `${firstName} ${lastName}`, role: primaryServiceLine, experience: paroTenure, location: `${city}, ${stateAbbreviation}`, imageUrl: imageUrl }))))),
282
- react_1.default.createElement(core_1.Box, { style: { width: '25%' } }, uniqueServicesExists &&
283
- react_1.default.createElement(core_1.Box, null,
284
- react_1.default.createElement(core_1.Grid, { item: true },
285
- react_1.default.createElement(core_1.Typography, { variant: "body1" },
286
- react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Services Offered:")),
287
- react_1.default.createElement("ul", null, uniqueServices === null || uniqueServices === void 0 ? void 0 : uniqueServices.map((service) => {
288
- return react_1.default.createElement("li", { style: { color: 'white' } },
289
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
290
- react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, service)));
291
- }))))))
292
- :
293
- react_1.default.createElement(react_1.default.Fragment, null,
294
- react_1.default.createElement(core_1.Typography, { variant: "caption" },
295
- react_1.default.createElement(core_1.Box, { style: { color: 'white', textAlign: 'center' }, mt: 4, ml: 2 }, "Level 1")),
296
- react_1.default.createElement(core_1.Grid, { item: true, direction: "row", justify: "center", alignItems: "center", style: { margin: 'auto', width: 'fit-content' } },
297
- react_1.default.createElement(EmployeeCard, { name: `${firstName} ${lastName}`, role: primaryServiceLine, experience: paroTenure, location: `${city}, ${stateAbbreviation}`, imageUrl: imageUrl }))), sortedLevels === null || sortedLevels === void 0 ? void 0 :
298
- sortedLevels.map((level, levelIndex) => {
299
- var _a;
300
- return (react_1.default.createElement(core_1.Grid, { item: true, key: level, justify: "center", alignItems: "center", style: { width: 'auto' } },
301
- react_1.default.createElement(core_1.Grid, { container: true, direction: "row", justify: "center", alignItems: "center", spacing: 2, wrap: "nowrap" }, (_a = groupedEmployees[level]) === null || _a === void 0 ? void 0 : _a.map((obj, index) => {
302
- var _a, _b, _c, _d, _e, _f;
303
- return (react_1.default.createElement(core_1.Grid, { item: true, key: obj.id, style: { flexShrink: 0 } },
304
- ((_a = groupedEmployees[level]) === null || _a === void 0 ? void 0 : _a.length) > 1 && index < ((_b = groupedEmployees[level]) === null || _b === void 0 ? void 0 : _b.length) - 1 && (react_1.default.createElement(HorizontalLine, null)),
305
- react_1.default.createElement(VerticalLine, { isBottomLine: false }),
306
- react_1.default.createElement(EmployeeCard, { name: isPublicProfile ? `Firm Member ${firmMemberCounter++}` : obj === null || obj === void 0 ? void 0 : obj.employeeName, role: obj === null || obj === void 0 ? void 0 : obj.firmRole, experience: `${obj === null || obj === void 0 ? void 0 : obj.yearsWithFirm} years`, location: obj === null || obj === void 0 ? void 0 : obj.employeeLocation }),
307
- levelIndex !== (sortedLevels === null || sortedLevels === void 0 ? void 0 : sortedLevels.length) - 1 && react_1.default.createElement(VerticalLine, { isBottomLine: true }),
308
- ((_c = groupedEmployees[level]) === null || _c === void 0 ? void 0 : _c.length) > 1 && index < ((_d = groupedEmployees[level]) === null || _d === void 0 ? void 0 : _d.length) - 1 && levelIndex !== (sortedLevels === null || sortedLevels === void 0 ? void 0 : sortedLevels.length) - 1 && ((_e = groupedEmployees[level]) === null || _e === void 0 ? void 0 : _e.length) !== ((_f = groupedEmployees[level + 1]) === null || _f === void 0 ? void 0 : _f.length) && (react_1.default.createElement(HorizontalLine, null))));
309
- }))));
310
- }))))));
311
- };
312
- exports.OrganizationChart = OrganizationChart;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.OrganizationChart = void 0;
30
+ const react_1 = __importStar(require("react"));
31
+ const core_1 = require("@material-ui/core");
32
+ const Dialog_1 = __importDefault(require("@material-ui/core/Dialog"));
33
+ const Close_1 = __importDefault(require("@material-ui/icons/Close"));
34
+ const cdn_1 = require("../shared/constants/cdn");
35
+ const styled_components_1 = __importDefault(require("styled-components"));
36
+ const defaultAvatar = cdn_1.CDN_URL + 'defaultAvatar.png';
37
+ const ProfilePhotoPreview = styled_components_1.default.img `
38
+ height: 86px;
39
+ width: 86px;
40
+ border: 1px solid #e4e5e4;
41
+ border-radius: 50%;
42
+ object-fit: cover;
43
+ object-position: top;
44
+ `;
45
+ const CustomDialog = (0, core_1.styled)(Dialog_1.default)(({ theme }) => ({
46
+ '& .MuiDialog-paper': {
47
+ backgroundColor: '#060821',
48
+ width: '50vw',
49
+ maxWidth: '80vw',
50
+ height: '80vh',
51
+ justifyContent: 'center',
52
+ alignItems: 'center',
53
+ overflow: 'hidden',
54
+ [theme.breakpoints.down('md')]: {
55
+ width: '100vw',
56
+ maxWidth: '100vw',
57
+ },
58
+ }
59
+ }));
60
+ const InformationRow = ({ label, value }) => {
61
+ return (react_1.default.createElement(core_1.Grid, { item: true, container: true, justify: "flex-start", alignItems: "center" },
62
+ react_1.default.createElement(core_1.Box, { style: {
63
+ backgroundColor: '#248384',
64
+ color: 'white',
65
+ textAlign: 'center',
66
+ margin: '2px',
67
+ padding: '4px',
68
+ width: '120px',
69
+ borderRadius: '6px',
70
+ fontSize: '10px'
71
+ } },
72
+ react_1.default.createElement("b", null, label)),
73
+ react_1.default.createElement(core_1.Box, { ml: 0.5 }, value !== null && value !== void 0 ? value : 'N/A')));
74
+ };
75
+ const EmployeeCard = ({ name, role, experience, location, imageUrl }) => {
76
+ return (react_1.default.createElement(core_1.Card, { style: {
77
+ backgroundColor: '#d9efef',
78
+ borderRadius: '12px',
79
+ width: 'max-content',
80
+ padding: '4px 20px',
81
+ margin: '8px'
82
+ } },
83
+ imageUrl && (react_1.default.createElement(core_1.Grid, { item: true, justify: "center", style: { display: 'flex', justifyContent: 'center' } },
84
+ react_1.default.createElement(ProfilePhotoPreview, { src: imageUrl || defaultAvatar, alt: 'Profile Photo' }))),
85
+ react_1.default.createElement(core_1.Typography, { variant: "subtitle2", align: "center" },
86
+ react_1.default.createElement("b", null, name)),
87
+ react_1.default.createElement(core_1.Grid, { item: true, justify: "center", alignItems: "center" },
88
+ react_1.default.createElement(InformationRow, { label: "Role", value: role }),
89
+ react_1.default.createElement(InformationRow, { label: "Experience", value: experience }),
90
+ react_1.default.createElement(InformationRow, { label: "Location", value: location }))));
91
+ };
92
+ const HorizontalLine = () => (react_1.default.createElement(core_1.Grid, { item: true, alignContent: "center", style: {
93
+ position: 'relative',
94
+ background: '#FFFFFF',
95
+ width: 'calc(105% - 1px)',
96
+ height: '2px',
97
+ top: 0,
98
+ right: 0,
99
+ left: '50%',
100
+ transform: 'translateX(0)'
101
+ } }));
102
+ const VerticalLine = ({ isBottomLine }) => (react_1.default.createElement(core_1.Grid, { item: true, style: {
103
+ position: 'relative',
104
+ background: '#FFFFFF',
105
+ width: '2px',
106
+ height: '30px',
107
+ top: 0,
108
+ left: '50%',
109
+ transform: 'translateX(-50%)'
110
+ } }, !isBottomLine && react_1.default.createElement("div", { style: {
111
+ content: '',
112
+ position: 'absolute',
113
+ bottom: 0,
114
+ left: '50%',
115
+ transform: 'translateX(-50%)',
116
+ borderStyle: 'solid',
117
+ borderWidth: '6px 6px 0 6px',
118
+ borderColor: '#FFFFFF transparent transparent transparent'
119
+ } })));
120
+ const parseServices = (services) => {
121
+ var _a;
122
+ const uniqueArray = (_a = Array.from(new Set(services === null || services === void 0 ? void 0 : services.map(item => JSON.stringify(item))))) === null || _a === void 0 ? void 0 : _a.map(str => JSON.parse(str));
123
+ return uniqueArray;
124
+ };
125
+ const checkEmployeeLocation = (data) => {
126
+ let hasOffshore = false;
127
+ let hasOnshore = false;
128
+ data === null || data === void 0 ? void 0 : data.forEach(employee => {
129
+ var _a;
130
+ const location = (_a = employee === null || employee === void 0 ? void 0 : employee.employeeLocation) === null || _a === void 0 ? void 0 : _a.toLowerCase();
131
+ if (location === null || location === void 0 ? void 0 : location.includes("offshore")) {
132
+ hasOffshore = true;
133
+ }
134
+ if (location === null || location === void 0 ? void 0 : location.includes("onshore")) {
135
+ hasOnshore = true;
136
+ }
137
+ });
138
+ if (hasOffshore && hasOnshore) {
139
+ return "Offshore & Onshore Team";
140
+ }
141
+ else if (hasOffshore) {
142
+ return "Offshore Team";
143
+ }
144
+ else if (hasOnshore) {
145
+ return "Onshore Team";
146
+ }
147
+ else {
148
+ return "none";
149
+ }
150
+ };
151
+ const getTotalYearsWithFirm = (data) => {
152
+ return data === null || data === void 0 ? void 0 : data.reduce((total, employee) => total + employee.yearsWithFirm, 0);
153
+ };
154
+ const OrganizationChart = ({ openModal, setOpenModal, expertFirms, firstName, lastName, imageUrl, primaryServiceLine, city, stateAbbreviation, paroTenure, isPublicProfile }) => {
155
+ var _a, _b;
156
+ const services = (_a = expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmClientReferences) === null || _a === void 0 ? void 0 : _a.flatMap((obj) => { var _a; return (_a = obj === null || obj === void 0 ? void 0 : obj.services) !== null && _a !== void 0 ? _a : []; });
157
+ const uniqueServices = parseServices(services);
158
+ const employeeLocation = checkEmployeeLocation(expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees);
159
+ const getTotalYears = getTotalYearsWithFirm(expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees);
160
+ let firmMemberCounter = 1;
161
+ const groupedEmployees = (_b = expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.expertFirmEmployees) === null || _b === void 0 ? void 0 : _b.reduce((acc, obj) => {
162
+ if (!acc[obj.level]) {
163
+ acc[obj.level] = [];
164
+ }
165
+ acc[obj.level].push(obj);
166
+ return acc;
167
+ }, {});
168
+ const [scale, setScale] = (0, react_1.useState)((groupedEmployees === null || groupedEmployees === void 0 ? void 0 : groupedEmployees.length) >= 2 ? 0.3 : 0.5); // checking no of levels & zooming out to fit content
169
+ const [position, setPosition] = (0, react_1.useState)({ x: 0, y: (groupedEmployees === null || groupedEmployees === void 0 ? void 0 : groupedEmployees.length) >= 2 ? -100 : 0 }); // negative value to align content maximum zoom out and center
170
+ const [isDragging, setIsDragging] = (0, react_1.useState)(false);
171
+ const [lastMousePos, setLastMousePos] = (0, react_1.useState)(null);
172
+ const sortedLevels = Object.keys(groupedEmployees || {})
173
+ .map(Number)
174
+ .sort((a, b) => a - b);
175
+ const MAX_ZOOM_IN = 5;
176
+ const MAX_ZOOM_OUT = 0.2;
177
+ const CONTENT_SIZE = 10;
178
+ // to center the content
179
+ const centerContent = (newScale) => {
180
+ const centerX = (CONTENT_SIZE * newScale) / 2;
181
+ const centerY = (CONTENT_SIZE * newScale) / 2;
182
+ setPosition({ x: centerX, y: centerY });
183
+ };
184
+ const handleWheel = (event) => {
185
+ event.preventDefault();
186
+ const zoomFactor = 0.1;
187
+ if (event.deltaY < 0) {
188
+ setScale((prev) => Math.min(prev + zoomFactor, MAX_ZOOM_IN));
189
+ }
190
+ else {
191
+ setScale((prev) => {
192
+ const newScale = Math.max(prev - zoomFactor, MAX_ZOOM_OUT);
193
+ if (newScale === MAX_ZOOM_OUT) {
194
+ centerContent(newScale); // Center content when zoomed out fully
195
+ }
196
+ return newScale;
197
+ });
198
+ }
199
+ };
200
+ const handleMouseDown = (event) => {
201
+ setIsDragging(true);
202
+ setLastMousePos({ x: event.clientX, y: event.clientY });
203
+ };
204
+ const handleMouseMove = (event) => {
205
+ if (isDragging && lastMousePos) {
206
+ const dx = event.clientX - lastMousePos.x;
207
+ const dy = event.clientY - lastMousePos.y;
208
+ setPosition((prev) => ({
209
+ x: prev.x + dx,
210
+ y: prev.y + dy,
211
+ }));
212
+ setLastMousePos({ x: event.clientX, y: event.clientY });
213
+ }
214
+ };
215
+ const handleMouseUp = () => {
216
+ setIsDragging(false);
217
+ };
218
+ // to center the content on double click
219
+ const handleDoubleClick = () => {
220
+ const newScale = 1;
221
+ setScale(newScale);
222
+ centerContent(newScale);
223
+ };
224
+ const highlightsExists = ((expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.employeeCount) > 0 || employeeLocation !== 'none' || getTotalYears > 0);
225
+ const uniqueServicesExists = (uniqueServices === null || uniqueServices === void 0 ? void 0 : uniqueServices.length) > 1;
226
+ return (react_1.default.createElement(CustomDialog, { open: openModal, onClose: () => setOpenModal(false), fullScreen: true, scroll: 'paper' },
227
+ react_1.default.createElement(react_1.default.Fragment, null,
228
+ react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: "row", justify: "space-between", alignItems: "center" },
229
+ react_1.default.createElement(core_1.Box, { p: 2 },
230
+ react_1.default.createElement(core_1.Typography, { variant: "subtitle1" },
231
+ react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Organizational Structure & Services")),
232
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
233
+ react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "See what services the organization offers and where they're located"))),
234
+ react_1.default.createElement(core_1.Box, { style: { alignSelf: 'flex-end' } },
235
+ react_1.default.createElement(core_1.IconButton, { onClick: () => setOpenModal(false) },
236
+ react_1.default.createElement(core_1.Box, { style: { color: 'white' } },
237
+ react_1.default.createElement(Close_1.default, null))))),
238
+ react_1.default.createElement(core_1.DialogContent, { onWheel: handleWheel, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onDoubleClick: handleDoubleClick, style: {
239
+ overflow: 'hidden',
240
+ width: '100%',
241
+ height: '100vh',
242
+ position: 'relative',
243
+ } },
244
+ react_1.default.createElement("div", { onMouseDown: handleMouseDown, style: {
245
+ transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,
246
+ transformOrigin: 'center',
247
+ transition: 'transform 0.1s',
248
+ width: '100%',
249
+ height: '100%',
250
+ position: 'relative',
251
+ cursor: isDragging ? 'grabbing' : 'grab',
252
+ userSelect: 'none',
253
+ } },
254
+ isPublicProfile ?
255
+ react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: "row", justify: "flex-start", alignItems: 'center', wrap: 'nowrap', spacing: 4, style: { width: '100%' } },
256
+ react_1.default.createElement(core_1.Box, { style: { width: '25%' } }, highlightsExists &&
257
+ react_1.default.createElement(core_1.Box, null,
258
+ react_1.default.createElement(core_1.Grid, { item: true },
259
+ react_1.default.createElement(core_1.Typography, { variant: "subtitle1" },
260
+ react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Highlights:")),
261
+ react_1.default.createElement("ul", null,
262
+ (expertFirms === null || expertFirms === void 0 ? void 0 : expertFirms.employeeCount) > 0 && react_1.default.createElement("li", { style: { color: 'white' } },
263
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
264
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, expertFirms === null || expertFirms === void 0 ? void 0 :
265
+ expertFirms.employeeCount,
266
+ " Team Members"))),
267
+ employeeLocation !== 'none' && react_1.default.createElement("li", { style: { color: 'white' } },
268
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
269
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, employeeLocation))),
270
+ getTotalYears > 0 && react_1.default.createElement("li", { style: { color: 'white' } },
271
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
272
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', } },
273
+ getTotalYears,
274
+ " years of combined experience"))))))),
275
+ react_1.default.createElement(core_1.Box, { style: { width: '50%' } },
276
+ react_1.default.createElement(core_1.Grid, { item: true },
277
+ react_1.default.createElement(core_1.Box, null,
278
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
279
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', textAlign: 'center' }, mt: 4, ml: 2 }, "Level 1")),
280
+ react_1.default.createElement(core_1.Grid, { item: true, direction: "row", justify: "center", alignItems: "center", style: { margin: 'auto', width: 'fit-content' } },
281
+ react_1.default.createElement(EmployeeCard, { name: `${firstName} ${lastName}`, role: primaryServiceLine, experience: paroTenure, location: `${city}, ${stateAbbreviation}`, imageUrl: imageUrl }))))),
282
+ react_1.default.createElement(core_1.Box, { style: { width: '25%' } }, uniqueServicesExists &&
283
+ react_1.default.createElement(core_1.Box, null,
284
+ react_1.default.createElement(core_1.Grid, { item: true },
285
+ react_1.default.createElement(core_1.Typography, { variant: "body1" },
286
+ react_1.default.createElement(core_1.Box, { style: { color: 'white' } }, "Services Offered:")),
287
+ react_1.default.createElement("ul", null, uniqueServices === null || uniqueServices === void 0 ? void 0 : uniqueServices.map((service) => {
288
+ return react_1.default.createElement("li", { style: { color: 'white' } },
289
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
290
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', } }, service)));
291
+ }))))))
292
+ :
293
+ react_1.default.createElement(react_1.default.Fragment, null,
294
+ react_1.default.createElement(core_1.Typography, { variant: "caption" },
295
+ react_1.default.createElement(core_1.Box, { style: { color: 'white', textAlign: 'center' }, mt: 4, ml: 2 }, "Level 1")),
296
+ react_1.default.createElement(core_1.Grid, { item: true, direction: "row", justify: "center", alignItems: "center", style: { margin: 'auto', width: 'fit-content' } },
297
+ react_1.default.createElement(EmployeeCard, { name: `${firstName} ${lastName}`, role: primaryServiceLine, experience: paroTenure, location: `${city}, ${stateAbbreviation}`, imageUrl: imageUrl }))), sortedLevels === null || sortedLevels === void 0 ? void 0 :
298
+ sortedLevels.map((level, levelIndex) => {
299
+ var _a;
300
+ return (react_1.default.createElement(core_1.Grid, { item: true, key: level, justify: "center", alignItems: "center", style: { width: 'auto' } },
301
+ react_1.default.createElement(core_1.Grid, { container: true, direction: "row", justify: "center", alignItems: "center", spacing: 2, wrap: "nowrap" }, (_a = groupedEmployees[level]) === null || _a === void 0 ? void 0 : _a.map((obj, index) => {
302
+ var _a, _b, _c, _d, _e, _f;
303
+ return (react_1.default.createElement(core_1.Grid, { item: true, key: obj.id, style: { flexShrink: 0 } },
304
+ ((_a = groupedEmployees[level]) === null || _a === void 0 ? void 0 : _a.length) > 1 && index < ((_b = groupedEmployees[level]) === null || _b === void 0 ? void 0 : _b.length) - 1 && (react_1.default.createElement(HorizontalLine, null)),
305
+ react_1.default.createElement(VerticalLine, { isBottomLine: false }),
306
+ react_1.default.createElement(EmployeeCard, { name: isPublicProfile ? `Firm Member ${firmMemberCounter++}` : obj === null || obj === void 0 ? void 0 : obj.employeeName, role: obj === null || obj === void 0 ? void 0 : obj.firmRole, experience: `${obj === null || obj === void 0 ? void 0 : obj.yearsWithFirm} years`, location: obj === null || obj === void 0 ? void 0 : obj.employeeLocation }),
307
+ levelIndex !== (sortedLevels === null || sortedLevels === void 0 ? void 0 : sortedLevels.length) - 1 && react_1.default.createElement(VerticalLine, { isBottomLine: true }),
308
+ ((_c = groupedEmployees[level]) === null || _c === void 0 ? void 0 : _c.length) > 1 && index < ((_d = groupedEmployees[level]) === null || _d === void 0 ? void 0 : _d.length) - 1 && levelIndex !== (sortedLevels === null || sortedLevels === void 0 ? void 0 : sortedLevels.length) - 1 && ((_e = groupedEmployees[level]) === null || _e === void 0 ? void 0 : _e.length) !== ((_f = groupedEmployees[level + 1]) === null || _f === void 0 ? void 0 : _f.length) && (react_1.default.createElement(HorizontalLine, null))));
309
+ }))));
310
+ }))))));
311
+ };
312
+ exports.OrganizationChart = OrganizationChart;