@paro.io/expert-shared-components 1.13.10 → 1.13.12
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.
- package/lib/components/Escalations/AccountSuspensionModal.js +25 -49
- package/lib/components/Escalations/EscalationChat.js +10 -12
- package/lib/components/Escalations/EscalationIssueCard.d.ts +1 -0
- package/lib/components/Escalations/EscalationIssueCard.js +39 -4
- package/lib/components/Escalations/EscalationRespondForm.js +11 -13
- package/lib/components/Escalations/EscalationSubmitForm.js +15 -20
- package/lib/components/Escalations/EscalationTabsContent.d.ts +2 -1
- package/lib/components/Escalations/EscalationTabsContent.js +6 -2
- package/lib/components/Escalations/Escalations.d.ts +2 -1
- package/lib/components/Escalations/Escalations.js +22 -9
- package/lib/components/Escalations/MarkResolvedModal.d.ts +2 -1
- package/lib/components/Escalations/MarkResolvedModal.js +10 -9
- package/lib/components/ProjectIntelligence/EngagementHeader/index.d.ts +18 -0
- package/lib/components/ProjectIntelligence/EngagementHeader/index.js +47 -0
- package/lib/components/ProjectIntelligence/FocusAreas/index.d.ts +18 -0
- package/lib/components/ProjectIntelligence/FocusAreas/index.js +156 -0
- package/lib/components/ProjectIntelligence/KeyMetrics/index.d.ts +12 -0
- package/lib/components/ProjectIntelligence/KeyMetrics/index.js +148 -0
- package/lib/components/ProjectIntelligence/MissingInformation/index.d.ts +24 -0
- package/lib/components/ProjectIntelligence/MissingInformation/index.js +218 -0
- package/lib/components/ProjectIntelligence/ProgressTracker/index.d.ts +8 -0
- package/lib/components/ProjectIntelligence/ProgressTracker/index.js +21 -0
- package/lib/components/ProjectIntelligence/ProjectHealth/index.d.ts +25 -0
- package/lib/components/ProjectIntelligence/ProjectHealth/index.js +42 -0
- package/lib/components/ProjectIntelligence/TeamSection/index.d.ts +25 -0
- package/lib/components/ProjectIntelligence/TeamSection/index.js +41 -0
- package/lib/components/ProjectIntelligence/index.d.ts +17 -0
- package/lib/components/ProjectIntelligence/index.js +146 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.MissingInformation = void 0;
|
|
36
|
+
const react_1 = __importStar(require("react"));
|
|
37
|
+
const utils_1 = require("../../shared/utils");
|
|
38
|
+
const core_1 = require("@material-ui/core");
|
|
39
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
40
|
+
const base_ui_1 = require("@paro.io/base-ui");
|
|
41
|
+
const TeamSection_1 = require("../TeamSection");
|
|
42
|
+
// Category options for the dropdown
|
|
43
|
+
const INFORMATION_CATEGORIES = [
|
|
44
|
+
'Technical Integration Details',
|
|
45
|
+
'Financial Data Requirements',
|
|
46
|
+
'Process Documentation',
|
|
47
|
+
'Team Assessment',
|
|
48
|
+
'System Access Requirements',
|
|
49
|
+
'Compliance Information',
|
|
50
|
+
'Other'
|
|
51
|
+
];
|
|
52
|
+
// Priority levels for the dropdown
|
|
53
|
+
const PRIORITY_LEVELS = [
|
|
54
|
+
'Urgent - Blocks current work',
|
|
55
|
+
'High - Needed this week',
|
|
56
|
+
'Medium - Needed next week',
|
|
57
|
+
'Low - Needed eventually'
|
|
58
|
+
];
|
|
59
|
+
// Request Information Modal Component
|
|
60
|
+
const RequestInfoModal = ({ isOpen, missingInfoItem, onClose, onSubmit, documentCenterController, isInternal, handleRouteToDocuments, }) => {
|
|
61
|
+
const [submitting, setSubmitting] = (0, react_1.useState)(false);
|
|
62
|
+
const [formData, setFormData] = (0, react_1.useState)({
|
|
63
|
+
informationCategory: '',
|
|
64
|
+
priorityLevel: '',
|
|
65
|
+
specificInformation: '',
|
|
66
|
+
});
|
|
67
|
+
react_1.default.useEffect(() => {
|
|
68
|
+
if (missingInfoItem) {
|
|
69
|
+
setFormData({
|
|
70
|
+
informationCategory: missingInfoItem.category || '',
|
|
71
|
+
priorityLevel: missingInfoItem.priority === 'HIGH' ? 'Urgent - Blocks current work' :
|
|
72
|
+
missingInfoItem.priority === 'MEDIUM' ? 'High - Needed this week' :
|
|
73
|
+
'Medium - Needed next week',
|
|
74
|
+
specificInformation: missingInfoItem.description || '',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}, [missingInfoItem]);
|
|
78
|
+
const handleSubmit = () => {
|
|
79
|
+
setSubmitting(true);
|
|
80
|
+
try {
|
|
81
|
+
onSubmit(Object.assign(Object.assign({}, formData), { itemId: missingInfoItem === null || missingInfoItem === void 0 ? void 0 : missingInfoItem.id, itemTitle: missingInfoItem === null || missingInfoItem === void 0 ? void 0 : missingInfoItem.title }));
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
console.error("Error while submitting request", e);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
setSubmitting(false);
|
|
88
|
+
}
|
|
89
|
+
onClose();
|
|
90
|
+
};
|
|
91
|
+
const handleCancel = () => {
|
|
92
|
+
// Reset form data when canceling
|
|
93
|
+
if (missingInfoItem) {
|
|
94
|
+
setFormData({
|
|
95
|
+
informationCategory: missingInfoItem.category || '',
|
|
96
|
+
priorityLevel: missingInfoItem.priority === 'HIGH' ? 'Urgent - Blocks current work' :
|
|
97
|
+
missingInfoItem.priority === 'MEDIUM' ? 'High - Needed this week' :
|
|
98
|
+
'Medium - Needed next week',
|
|
99
|
+
specificInformation: missingInfoItem.description || '',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
onClose();
|
|
103
|
+
};
|
|
104
|
+
const handleOpenDocumentCenter = () => {
|
|
105
|
+
if (isInternal && handleRouteToDocuments) {
|
|
106
|
+
handleRouteToDocuments && handleRouteToDocuments();
|
|
107
|
+
onClose();
|
|
108
|
+
}
|
|
109
|
+
if (!isInternal && documentCenterController && documentCenterController.openDocumentCenter) {
|
|
110
|
+
documentCenterController.openDocumentCenter(true);
|
|
111
|
+
onClose();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
if (!isOpen || !missingInfoItem)
|
|
115
|
+
return null;
|
|
116
|
+
const isClientResponded = missingInfoItem.status === "CLIENT_RESPONDED";
|
|
117
|
+
const buttonText = isClientResponded ? "Update Request" : "Send Request";
|
|
118
|
+
const hasUploadedDocuments = missingInfoItem.clientResponse && missingInfoItem.clientResponse.includes("Client Uploaded");
|
|
119
|
+
return (react_1.default.createElement(core_1.Dialog, { open: isOpen, onClose: onClose, fullWidth: true },
|
|
120
|
+
react_1.default.createElement(core_1.DialogTitle, null,
|
|
121
|
+
react_1.default.createElement("div", { className: "text-black mb-1 p-2 pl-4 absolute top-0 left-0 w-full flex flex-row justify-between items-center z-50" },
|
|
122
|
+
isClientResponded ? "View Client Response" : "Request Additional Information",
|
|
123
|
+
react_1.default.createElement(core_1.IconButton, { onClick: onClose },
|
|
124
|
+
react_1.default.createElement(base_icons_1.IconX, null)))),
|
|
125
|
+
react_1.default.createElement(core_1.DialogContent, null,
|
|
126
|
+
react_1.default.createElement("div", { className: "space-y-4 mt-4" },
|
|
127
|
+
isClientResponded && missingInfoItem.clientResponse && (react_1.default.createElement("div", null,
|
|
128
|
+
react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Client Response"),
|
|
129
|
+
react_1.default.createElement("div", { className: "w-full px-3 py-2 border border-gray-300 rounded-md bg-gray-50 text-sm" },
|
|
130
|
+
react_1.default.createElement("p", { className: "whitespace-pre-wrap" }, missingInfoItem.clientResponse)),
|
|
131
|
+
hasUploadedDocuments && (react_1.default.createElement("div", { className: "mt-2" },
|
|
132
|
+
react_1.default.createElement("button", { onClick: handleOpenDocumentCenter, className: "text-blue-600 hover:text-blue-800 font-medium flex items-center text-sm" },
|
|
133
|
+
react_1.default.createElement("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" },
|
|
134
|
+
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" })),
|
|
135
|
+
isInternal ? 'View Documents under Documents tab' : 'View Documents in Document Center'))))),
|
|
136
|
+
react_1.default.createElement("div", null,
|
|
137
|
+
react_1.default.createElement("label", { htmlFor: "informationCategory", className: "block text-sm font-medium text-gray-700 mb-1" }, "Information Category"),
|
|
138
|
+
react_1.default.createElement(core_1.Select, { fullWidth: true, id: "informationCategory", value: formData.informationCategory, onChange: (e) => setFormData((prev) => (Object.assign(Object.assign({}, prev), { informationCategory: e.target.value }))), displayEmpty: true, variant: "outlined", placeholder: 'Select a category' },
|
|
139
|
+
react_1.default.createElement(core_1.MenuItem, { disabled: true, value: "" },
|
|
140
|
+
react_1.default.createElement("em", null, `Select a category`)),
|
|
141
|
+
INFORMATION_CATEGORIES.map((category) => (react_1.default.createElement(core_1.MenuItem, { key: category, value: category }, category))))),
|
|
142
|
+
react_1.default.createElement("div", null,
|
|
143
|
+
react_1.default.createElement("label", { htmlFor: "priorityLevel", className: "block text-sm font-medium text-gray-700 mb-1" }, "Priority Level"),
|
|
144
|
+
react_1.default.createElement(core_1.Select, { fullWidth: true, id: "priorityLevel", value: formData.priorityLevel, onChange: (e) => setFormData((prev) => (Object.assign(Object.assign({}, prev), { priorityLevel: e.target.value }))), displayEmpty: true, variant: "outlined", placeholder: 'Select priority level' },
|
|
145
|
+
react_1.default.createElement(core_1.MenuItem, { disabled: true, value: "" },
|
|
146
|
+
react_1.default.createElement("em", null, `Select priority level`)),
|
|
147
|
+
PRIORITY_LEVELS.map((level) => (react_1.default.createElement(core_1.MenuItem, { key: level, value: level }, level))))),
|
|
148
|
+
react_1.default.createElement("div", null,
|
|
149
|
+
react_1.default.createElement("label", { htmlFor: "specificInformation", className: "block text-sm font-medium text-gray-700 mb-1" }, "Specific Information Needed"),
|
|
150
|
+
react_1.default.createElement("textarea", { id: "specificInformation", value: formData.specificInformation, onChange: (e) => setFormData(prev => (Object.assign(Object.assign({}, prev), { specificInformation: e.target.value }))), rows: 4, className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm", placeholder: "Need NetSuite configuration details:\r\n\r\n1. US vs Colombian entity setup\r\n2. Consolidation process and requirements" }))),
|
|
151
|
+
react_1.default.createElement("div", { className: "px-6 py-4 flex justify-end space-x-3" },
|
|
152
|
+
react_1.default.createElement(base_ui_1.Button, { label: "cancel", onClick: handleCancel, disabled: submitting }),
|
|
153
|
+
react_1.default.createElement(base_ui_1.Button, { label: buttonText, onClick: handleSubmit, color: "primary", isLoading: submitting })))));
|
|
154
|
+
};
|
|
155
|
+
const MissingInformation = ({ items, className = '', opportunityId, GetOpportunityInsightsDocument, updateOpportunityMissingInformation, documentCenterController, isInternal, handleRouteToDocuments, }) => {
|
|
156
|
+
const [selectedItem, setSelectedItem] = (0, react_1.useState)(null);
|
|
157
|
+
const [isModalOpen, setIsModalOpen] = (0, react_1.useState)(false);
|
|
158
|
+
const [requestedItems, setRequestedItems] = (0, react_1.useState)({});
|
|
159
|
+
const handleRequestInfo = (item) => {
|
|
160
|
+
setSelectedItem(item);
|
|
161
|
+
setIsModalOpen(true);
|
|
162
|
+
};
|
|
163
|
+
const handleCloseModal = () => {
|
|
164
|
+
setIsModalOpen(false);
|
|
165
|
+
setSelectedItem(null);
|
|
166
|
+
};
|
|
167
|
+
const handleSubmitRequest = (requestData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
+
if (!selectedItem)
|
|
169
|
+
return;
|
|
170
|
+
try {
|
|
171
|
+
yield updateOpportunityMissingInformation({
|
|
172
|
+
variables: {
|
|
173
|
+
opportunityId,
|
|
174
|
+
input: {
|
|
175
|
+
id: selectedItem.id,
|
|
176
|
+
description: requestData.specificInformation,
|
|
177
|
+
category: requestData.informationCategory,
|
|
178
|
+
status: "EXPERT_REQUESTED",
|
|
179
|
+
priority: requestData.priority || "HIGH"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
refetchQueries: [
|
|
183
|
+
{ query: GetOpportunityInsightsDocument, variables: { opportunityId } }
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
(0, utils_1.showToast)('success', 'Information request submitted successfully');
|
|
187
|
+
// Update local state to reflect the change immediately
|
|
188
|
+
setRequestedItems(prev => (Object.assign(Object.assign({}, prev), { [selectedItem.id]: true })));
|
|
189
|
+
console.log('Information request submitted successfully');
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.error('Error submitting information request:', error);
|
|
193
|
+
(0, utils_1.showToast)('warning', 'Error submitting information request. Please try again.');
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
197
|
+
react_1.default.createElement("div", { className: `bg-white rounded-lg shadow-sm border border-gray-200 p-6 ${className}` },
|
|
198
|
+
react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconExclamation, { size: "sm", className: "mr-4" }), headerText: "Missing Information" }),
|
|
199
|
+
react_1.default.createElement("div", { className: "space-y-4 mt-2" }, items.map((item) => {
|
|
200
|
+
const isRequested = requestedItems[item.id] || item.status === "EXPERT_REQUESTED";
|
|
201
|
+
const isClientResponded = item.status === "CLIENT_RESPONDED";
|
|
202
|
+
let displayPriority = item.priority;
|
|
203
|
+
if (isRequested) {
|
|
204
|
+
displayPriority = "REQUESTED";
|
|
205
|
+
}
|
|
206
|
+
if (isClientResponded) {
|
|
207
|
+
displayPriority = "CLIENT_RESPONDED";
|
|
208
|
+
}
|
|
209
|
+
return (react_1.default.createElement("div", { key: item.id, className: "border border-gray-200 rounded-lg p-4 hover:shadow-sm transition-shadow" },
|
|
210
|
+
react_1.default.createElement("div", { className: "text-sm font-bold" }, item.title),
|
|
211
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, item.description),
|
|
212
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
213
|
+
react_1.default.createElement("span", { className: "text-xs text-gray-500" }, item.category),
|
|
214
|
+
isClientResponded ? (react_1.default.createElement(base_ui_1.Button, { label: "Show Response", iconRight: react_1.default.createElement(base_icons_1.IconArrowRight, { size: "sm" }), onClick: () => handleRequestInfo(item), color: "success", size: 'sm' })) : !isRequested ? (react_1.default.createElement(base_ui_1.Button, { label: "Request Info", iconRight: react_1.default.createElement(base_icons_1.IconArrowRight, { size: "sm" }), onClick: () => handleRequestInfo(item), color: "success", size: 'sm' })) : (react_1.default.createElement(base_ui_1.Button, { label: "Information Requested", iconLeft: react_1.default.createElement(base_icons_1.IconCheckCircle, { size: "sm" }), disabled: true, size: 'sm' })))));
|
|
215
|
+
}))),
|
|
216
|
+
react_1.default.createElement(RequestInfoModal, { isOpen: isModalOpen, missingInfoItem: selectedItem, onClose: handleCloseModal, onSubmit: handleSubmitRequest, documentCenterController: documentCenterController, isInternal: isInternal, handleRouteToDocuments: handleRouteToDocuments })));
|
|
217
|
+
};
|
|
218
|
+
exports.MissingInformation = MissingInformation;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ProgressTracker = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const base_ui_1 = require("@paro.io/base-ui");
|
|
9
|
+
const PHASE_TABS = [
|
|
10
|
+
{ id: 'discovery', label: 'Discovery', active: true },
|
|
11
|
+
{ id: 'kickoff', label: 'Kickoff', active: false },
|
|
12
|
+
{ id: 'setup', label: 'Setup', active: false },
|
|
13
|
+
{ id: 'active', label: 'Active', active: false },
|
|
14
|
+
{ id: 'renewal', label: 'Renewal', active: false },
|
|
15
|
+
];
|
|
16
|
+
const ProgressTracker = ({ percentage, currentPhase, nextSteps }) => {
|
|
17
|
+
return (react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 mt-6" },
|
|
18
|
+
react_1.default.createElement("div", { className: "px-6 py-4 border-b border-gray-200" },
|
|
19
|
+
react_1.default.createElement("div", { className: "flex space-x-2" }, PHASE_TABS.map((phase) => (react_1.default.createElement(base_ui_1.Button, { key: phase.id, disabled: !phase.active, label: phase.label, color: phase.active ? 'primary' : 'default' })))))));
|
|
20
|
+
};
|
|
21
|
+
exports.ProgressTracker = ProgressTracker;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ProjectHealthData {
|
|
3
|
+
communicationFlow: {
|
|
4
|
+
status: 'GOOD' | 'ATTENTION_NEEDED' | 'CRITICAL';
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
performanceTracking: {
|
|
8
|
+
status: 'GOOD' | 'ATTENTION_NEEDED' | 'CRITICAL';
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
processHealth: {
|
|
12
|
+
status: 'GOOD' | 'ATTENTION_NEEDED' | 'CRITICAL';
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
riskManagement: {
|
|
16
|
+
status: 'GOOD' | 'ATTENTION_NEEDED' | 'CRITICAL';
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
interface ProjectHealthProps {
|
|
21
|
+
healthData: ProjectHealthData;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const ProjectHealth: React.FC<ProjectHealthProps>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ProjectHealth = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const TeamSection_1 = require("../TeamSection");
|
|
9
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
10
|
+
const EscalationIssueCard_1 = require("../../Escalations/EscalationIssueCard");
|
|
11
|
+
const STATUS_COLORS = {
|
|
12
|
+
GOOD: "success",
|
|
13
|
+
CRITICAL: "danger",
|
|
14
|
+
ATTENTION_NEEDED: "warning",
|
|
15
|
+
};
|
|
16
|
+
const STATUS_ICONS = {
|
|
17
|
+
GOOD: react_1.default.createElement(base_icons_1.IconCheck, { size: "sm" }),
|
|
18
|
+
CRITICAL: react_1.default.createElement(base_icons_1.IconX, { size: "sm" }),
|
|
19
|
+
ATTENTION_NEEDED: react_1.default.createElement(base_icons_1.IconExclamation, { size: "sm" }),
|
|
20
|
+
};
|
|
21
|
+
const HealthIndicator = ({ title, status, description, icon }) => {
|
|
22
|
+
return (react_1.default.createElement("div", { className: "flex items-start space-x-3 p-3 rounded-lg border border-gray-200 hover:shadow-sm transition-shadow" },
|
|
23
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
24
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-2 mb-1" },
|
|
25
|
+
react_1.default.createElement("span", { className: "text-sm" }, icon),
|
|
26
|
+
react_1.default.createElement("div", { className: "text-sm font-bold" }, title),
|
|
27
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: status === 'GOOD' ? 'On track' : status === 'ATTENTION_NEEDED' ? 'Needs attention' : 'Critical', iconLeft: STATUS_ICONS[status], customColor: `bg-${STATUS_COLORS[status]} border-${STATUS_COLORS[status]}` })),
|
|
28
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, description))));
|
|
29
|
+
};
|
|
30
|
+
const ProjectHealth = ({ healthData, className = '' }) => {
|
|
31
|
+
return (react_1.default.createElement("div", { className: `bg-white rounded-lg shadow-sm border border-gray-200 ${className}` },
|
|
32
|
+
react_1.default.createElement("div", { className: "px-6 py-4 border-b border-gray-200 mb-2" },
|
|
33
|
+
react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconChartBar, { size: "sm", className: "mr-4" }), headerText: "Project Health" }),
|
|
34
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600 mt-1" }, "Automated insights from client communications and project data")),
|
|
35
|
+
react_1.default.createElement("div", { className: "p-6" },
|
|
36
|
+
react_1.default.createElement("div", { className: "space-y-4" },
|
|
37
|
+
react_1.default.createElement(HealthIndicator, { title: "Communication Flow", status: healthData.communicationFlow.status, description: healthData.communicationFlow.description, icon: react_1.default.createElement(base_icons_1.IconChat, { size: "sm" }) }),
|
|
38
|
+
react_1.default.createElement(HealthIndicator, { title: "Performance Tracking", status: healthData.performanceTracking.status, description: healthData.performanceTracking.description, icon: react_1.default.createElement(base_icons_1.IconLightningBolt, { size: "sm" }) }),
|
|
39
|
+
react_1.default.createElement(HealthIndicator, { title: "Process Health", status: healthData.processHealth.status, description: healthData.processHealth.description, icon: react_1.default.createElement(base_icons_1.IconCog, { size: "sm" }) }),
|
|
40
|
+
react_1.default.createElement(HealthIndicator, { title: "Risk Management", status: healthData.riskManagement.status, description: healthData.riskManagement.description, icon: react_1.default.createElement(base_icons_1.IconExclamationCircle, { size: "sm" }) })))));
|
|
41
|
+
};
|
|
42
|
+
exports.ProjectHealth = ProjectHealth;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface TeamMember {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
role: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
availability?: string;
|
|
8
|
+
}
|
|
9
|
+
interface Expert {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
title: string;
|
|
13
|
+
avatar: string;
|
|
14
|
+
}
|
|
15
|
+
interface TeamSectionProps {
|
|
16
|
+
clientTeam: TeamMember[];
|
|
17
|
+
expert: Expert;
|
|
18
|
+
paroTeam: TeamMember[];
|
|
19
|
+
}
|
|
20
|
+
export declare const Heading: ({ icon, headerText }: {
|
|
21
|
+
icon: any;
|
|
22
|
+
headerText: string;
|
|
23
|
+
}) => React.JSX.Element;
|
|
24
|
+
export declare const TeamSection: React.FC<TeamSectionProps>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TeamSection = exports.Heading = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
9
|
+
const base_ui_1 = require("@paro.io/base-ui");
|
|
10
|
+
const Heading = ({ icon, headerText }) => {
|
|
11
|
+
return (react_1.default.createElement("div", { className: "flex flex-row justify-start items-center" },
|
|
12
|
+
icon,
|
|
13
|
+
react_1.default.createElement("div", { className: "text-lg font-semibold" }, headerText)));
|
|
14
|
+
};
|
|
15
|
+
exports.Heading = Heading;
|
|
16
|
+
const TeamSection = ({ clientTeam, expert, paroTeam }) => {
|
|
17
|
+
return (react_1.default.createElement("div", { className: "space-y-6" },
|
|
18
|
+
react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
|
|
19
|
+
react_1.default.createElement(exports.Heading, { icon: react_1.default.createElement(base_icons_1.IconUserGroup, { size: "sm", className: "mr-4" }), headerText: "Client Team" }),
|
|
20
|
+
react_1.default.createElement("div", { className: "space-y-3 mt-2" }, clientTeam === null || clientTeam === void 0 ? void 0 : clientTeam.map((member) => (react_1.default.createElement("div", { key: member.id, className: "flex items-center space-x-3" },
|
|
21
|
+
react_1.default.createElement(base_ui_1.Avatar, { src: member.avatar || '', name: member.name }),
|
|
22
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
23
|
+
react_1.default.createElement("p", { className: "text-sm font-bold" }, member.name),
|
|
24
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, member.role),
|
|
25
|
+
member.availability && (react_1.default.createElement("p", { className: "text-xs text-gray-500" }, member.availability)))))))),
|
|
26
|
+
react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
|
|
27
|
+
react_1.default.createElement(exports.Heading, { icon: react_1.default.createElement(base_icons_1.IconStar, { size: "sm", className: "mr-4" }), headerText: "Your Expert" }),
|
|
28
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-3 mt-2" },
|
|
29
|
+
react_1.default.createElement(base_ui_1.Avatar, { src: expert.avatar, name: expert.name }),
|
|
30
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
31
|
+
react_1.default.createElement("p", { className: "text-sm font-bold" }, expert.name),
|
|
32
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, expert.title)))),
|
|
33
|
+
react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
|
|
34
|
+
react_1.default.createElement(exports.Heading, { icon: react_1.default.createElement(base_icons_1.IconUsers, { size: "sm", className: "mr-4" }), headerText: "Your Paro Team" }),
|
|
35
|
+
react_1.default.createElement("div", { className: "space-y-3 mt-2" }, paroTeam === null || paroTeam === void 0 ? void 0 : paroTeam.map((member) => (react_1.default.createElement("div", { key: member.id || member.name, className: "flex items-center space-x-3" },
|
|
36
|
+
react_1.default.createElement(base_ui_1.Avatar, { src: member.avatar || '', name: member.name }),
|
|
37
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
38
|
+
react_1.default.createElement("p", { className: "text-sm font-bold" }, member.name),
|
|
39
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600" }, member.role)))))))));
|
|
40
|
+
};
|
|
41
|
+
exports.TeamSection = TeamSection;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ProjectIntelligenceProps {
|
|
3
|
+
checkIfOpportunityInsightsExistData: any;
|
|
4
|
+
opportunityInsightsData: any;
|
|
5
|
+
selectedOpportunityId: string | null;
|
|
6
|
+
setSelectedOpportunityId: (id: string | null) => void;
|
|
7
|
+
GetOpportunityInsightsDocument: any;
|
|
8
|
+
updateOpportunityMissingInformation: any;
|
|
9
|
+
documentCenterController?: {
|
|
10
|
+
openDocumentCenter: ((open: boolean) => void) | null;
|
|
11
|
+
} | null;
|
|
12
|
+
updateOpportunityFocusArea: any;
|
|
13
|
+
isInternal?: boolean;
|
|
14
|
+
handleRouteToDocuments?: () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const ProjectIntelligence: React.FC<ProjectIntelligenceProps>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ProjectIntelligence = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const EngagementHeader_1 = require("./EngagementHeader");
|
|
9
|
+
const ProgressTracker_1 = require("./ProgressTracker");
|
|
10
|
+
const FocusAreas_1 = require("./FocusAreas");
|
|
11
|
+
const TeamSection_1 = require("./TeamSection");
|
|
12
|
+
const ProjectHealth_1 = require("./ProjectHealth");
|
|
13
|
+
const KeyMetrics_1 = require("./KeyMetrics");
|
|
14
|
+
const MissingInformation_1 = require("./MissingInformation");
|
|
15
|
+
const ProjectIntelligence = ({ checkIfOpportunityInsightsExistData, opportunityInsightsData, selectedOpportunityId, setSelectedOpportunityId, GetOpportunityInsightsDocument, updateOpportunityMissingInformation, documentCenterController = null, updateOpportunityFocusArea, isInternal = false, handleRouteToDocuments, }) => {
|
|
16
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
17
|
+
const opportunityInsights = opportunityInsightsData === null || opportunityInsightsData === void 0 ? void 0 : opportunityInsightsData.getOpportunityInsights;
|
|
18
|
+
// Create client tabs from checkIfOpportunityInsightsExistData
|
|
19
|
+
const clientTabs = ((_a = checkIfOpportunityInsightsExistData === null || checkIfOpportunityInsightsExistData === void 0 ? void 0 : checkIfOpportunityInsightsExistData.checkIfOpportunityInsightsExist) === null || _a === void 0 ? void 0 : _a.map((insight) => ({
|
|
20
|
+
id: insight.opportunityId,
|
|
21
|
+
label: insight.clientName || `Client ${insight.clientId}`,
|
|
22
|
+
clientId: insight.clientId
|
|
23
|
+
}))) || [];
|
|
24
|
+
// Handle client tab change
|
|
25
|
+
const handleClientChange = (opportunityId) => {
|
|
26
|
+
setSelectedOpportunityId(opportunityId);
|
|
27
|
+
};
|
|
28
|
+
// Map status values from API to component expected values
|
|
29
|
+
const mapFocusAreaStatus = (status) => {
|
|
30
|
+
if (!status)
|
|
31
|
+
return 'IN_PROGRESS';
|
|
32
|
+
switch (status.toUpperCase()) {
|
|
33
|
+
case 'NEEDS_INPUT':
|
|
34
|
+
return 'AT_RISK';
|
|
35
|
+
case 'BLOCKED':
|
|
36
|
+
return 'AT_RISK';
|
|
37
|
+
case 'CONFIRMED':
|
|
38
|
+
return 'CONFIRMED';
|
|
39
|
+
case 'COMPLETED':
|
|
40
|
+
return 'COMPLETED';
|
|
41
|
+
case 'IN_PROGRESS':
|
|
42
|
+
default:
|
|
43
|
+
return 'IN_PROGRESS';
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
// Map health status from API to component expected values
|
|
47
|
+
const mapHealthStatus = (status) => {
|
|
48
|
+
if (!status)
|
|
49
|
+
return 'ATTENTION_NEEDED';
|
|
50
|
+
switch (status.toUpperCase()) {
|
|
51
|
+
case 'ON_TRACK':
|
|
52
|
+
return 'GOOD';
|
|
53
|
+
case 'NEEDS_ATTENTION':
|
|
54
|
+
return 'ATTENTION_NEEDED';
|
|
55
|
+
case 'CRITICAL':
|
|
56
|
+
return 'CRITICAL';
|
|
57
|
+
default:
|
|
58
|
+
return 'ATTENTION_NEEDED';
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
// Helper function to map API priority to component priority
|
|
62
|
+
const mapPriority = (priority) => {
|
|
63
|
+
if (!priority)
|
|
64
|
+
return 'MEDIUM';
|
|
65
|
+
if (typeof priority === 'string') {
|
|
66
|
+
switch (priority.toUpperCase()) {
|
|
67
|
+
case 'HIGH':
|
|
68
|
+
return 'HIGH';
|
|
69
|
+
case 'LOW':
|
|
70
|
+
return 'LOW';
|
|
71
|
+
case 'MEDIUM':
|
|
72
|
+
default:
|
|
73
|
+
return 'MEDIUM';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return 'MEDIUM';
|
|
77
|
+
};
|
|
78
|
+
// Convert API focus areas to component format
|
|
79
|
+
const convertFocusAreas = () => {
|
|
80
|
+
if (!(opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.focusAreas))
|
|
81
|
+
return [];
|
|
82
|
+
return opportunityInsights.focusAreas.map((area, index) => ({
|
|
83
|
+
id: (area === null || area === void 0 ? void 0 : area.id) || `focus-${index}`,
|
|
84
|
+
title: (area === null || area === void 0 ? void 0 : area.title) || 'N/A',
|
|
85
|
+
description: (area === null || area === void 0 ? void 0 : area.description) || 'N/A',
|
|
86
|
+
status: mapFocusAreaStatus(area === null || area === void 0 ? void 0 : area.status),
|
|
87
|
+
dueDate: (area === null || area === void 0 ? void 0 : area.date) || new Date().toISOString(),
|
|
88
|
+
priority: mapPriority(area === null || area === void 0 ? void 0 : area.priority)
|
|
89
|
+
}));
|
|
90
|
+
};
|
|
91
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
92
|
+
react_1.default.createElement("div", { className: "w-full bg-info-light py-6 px-4 rounded-lg shadow mb-8" },
|
|
93
|
+
react_1.default.createElement("h1", { className: "text-2xl font-bold" }, (opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityName) || 'Client Engagement Dashboard'),
|
|
94
|
+
react_1.default.createElement("p", { className: "text-gray-600 mt-1" },
|
|
95
|
+
"Engagement dashboard for ",
|
|
96
|
+
(opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityName) || 'this client')),
|
|
97
|
+
react_1.default.createElement("div", { className: "max-w-[80%] mx-auto px-4 py-8" },
|
|
98
|
+
react_1.default.createElement(EngagementHeader_1.EngagementHeader, { clientName: (opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityName) || '', expertName: ((_b = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.expertInfo) === null || _b === void 0 ? void 0 : _b.name) || '', expertTitle: ((_c = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.expertInfo) === null || _c === void 0 ? void 0 : _c.role) || '', startDate: (opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.startDate) || '', status: (opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.phase) || 'In_Progress', clientTabs: clientTabs, selectedClientId: selectedOpportunityId, onClientChange: handleClientChange }),
|
|
99
|
+
react_1.default.createElement(ProgressTracker_1.ProgressTracker, { percentage: 0, currentPhase: "Kickoff Phase (Day 1 of 3)", nextSteps: "System access & team introductions" }),
|
|
100
|
+
react_1.default.createElement("div", { className: "flex flex-row space-x-4 mt-8" },
|
|
101
|
+
react_1.default.createElement("div", { className: "w-2/3 space-7-4" },
|
|
102
|
+
react_1.default.createElement(FocusAreas_1.FocusAreas, { focusAreas: convertFocusAreas(), onEditFocusAreas: () => { }, updateOpportunityFocusArea: updateOpportunityFocusArea, GetOpportunityInsightsDocument: GetOpportunityInsightsDocument, opportunityId: selectedOpportunityId }),
|
|
103
|
+
react_1.default.createElement(ProjectHealth_1.ProjectHealth, { healthData: {
|
|
104
|
+
communicationFlow: {
|
|
105
|
+
status: mapHealthStatus((_e = (_d = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _d === void 0 ? void 0 : _d.communicationFlow) === null || _e === void 0 ? void 0 : _e.status),
|
|
106
|
+
description: ((_g = (_f = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _f === void 0 ? void 0 : _f.communicationFlow) === null || _g === void 0 ? void 0 : _g.description) || 'N/A'
|
|
107
|
+
},
|
|
108
|
+
performanceTracking: {
|
|
109
|
+
status: mapHealthStatus((_j = (_h = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _h === void 0 ? void 0 : _h.performanceTracking) === null || _j === void 0 ? void 0 : _j.status),
|
|
110
|
+
description: ((_l = (_k = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _k === void 0 ? void 0 : _k.performanceTracking) === null || _l === void 0 ? void 0 : _l.description) || 'N/A'
|
|
111
|
+
},
|
|
112
|
+
processHealth: {
|
|
113
|
+
status: mapHealthStatus((_o = (_m = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _m === void 0 ? void 0 : _m.processHealth) === null || _o === void 0 ? void 0 : _o.status),
|
|
114
|
+
description: ((_q = (_p = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _p === void 0 ? void 0 : _p.processHealth) === null || _q === void 0 ? void 0 : _q.description) || 'N/A'
|
|
115
|
+
},
|
|
116
|
+
riskManagement: {
|
|
117
|
+
status: mapHealthStatus((_s = (_r = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _r === void 0 ? void 0 : _r.riskManagement) === null || _s === void 0 ? void 0 : _s.status),
|
|
118
|
+
description: ((_u = (_t = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.opportunityHealth) === null || _t === void 0 ? void 0 : _t.riskManagement) === null || _u === void 0 ? void 0 : _u.description) || 'N/A'
|
|
119
|
+
}
|
|
120
|
+
}, className: "mt-8" }),
|
|
121
|
+
react_1.default.createElement(MissingInformation_1.MissingInformation, { items: (opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.missingInformation) ?
|
|
122
|
+
opportunityInsights.missingInformation.map((item, index) => ({
|
|
123
|
+
id: (item === null || item === void 0 ? void 0 : item.id) || `missing-${index}`,
|
|
124
|
+
title: (item === null || item === void 0 ? void 0 : item.title) || 'N/A',
|
|
125
|
+
description: (item === null || item === void 0 ? void 0 : item.description) || 'N/A',
|
|
126
|
+
priority: mapPriority(item === null || item === void 0 ? void 0 : item.priority),
|
|
127
|
+
category: (item === null || item === void 0 ? void 0 : item.category) || 'N/A',
|
|
128
|
+
status: (item === null || item === void 0 ? void 0 : item.status) || undefined,
|
|
129
|
+
clientResponse: (item === null || item === void 0 ? void 0 : item.clientResponse) || undefined
|
|
130
|
+
})) : [], className: "mt-8", opportunityId: selectedOpportunityId, GetOpportunityInsightsDocument: GetOpportunityInsightsDocument, updateOpportunityMissingInformation: updateOpportunityMissingInformation, documentCenterController: documentCenterController, isInternal: isInternal, handleRouteToDocuments: handleRouteToDocuments })),
|
|
131
|
+
react_1.default.createElement("div", { className: "w-1/3 space-y-4" },
|
|
132
|
+
react_1.default.createElement(TeamSection_1.TeamSection, { clientTeam: opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.clientTeam, expert: {
|
|
133
|
+
id: 'expert-1',
|
|
134
|
+
name: ((_v = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.expertInfo) === null || _v === void 0 ? void 0 : _v.name) || '',
|
|
135
|
+
title: ((_w = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.expertInfo) === null || _w === void 0 ? void 0 : _w.role) || '',
|
|
136
|
+
avatar: ''
|
|
137
|
+
}, paroTeam: opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.paroTeam }),
|
|
138
|
+
react_1.default.createElement(KeyMetrics_1.KeyMetrics, { metrics: {
|
|
139
|
+
targetAchievements: ((_x = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.engagementMetrics) === null || _x === void 0 ? void 0 : _x.targetHours) || 0,
|
|
140
|
+
hourlyRate: ((_y = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.engagementMetrics) === null || _y === void 0 ? void 0 : _y.hourlyRate) || 0,
|
|
141
|
+
daysSinceGoal: ((_z = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.engagementMetrics) === null || _z === void 0 ? void 0 : _z.dayCloseGoal) ?
|
|
142
|
+
parseInt(opportunityInsights.engagementMetrics.dayCloseGoal) : 0,
|
|
143
|
+
totalContractLength: ((_0 = opportunityInsights === null || opportunityInsights === void 0 ? void 0 : opportunityInsights.engagementMetrics) === null || _0 === void 0 ? void 0 : _0.contractLength) || 0
|
|
144
|
+
} }))))));
|
|
145
|
+
};
|
|
146
|
+
exports.ProjectIntelligence = ProjectIntelligence;
|
package/lib/index.d.ts
CHANGED
|
@@ -15,3 +15,4 @@ export { fileUploader } from './components/FileUploader';
|
|
|
15
15
|
export { DiscussionSection } from './components/Invoices/DiscussionSection';
|
|
16
16
|
export { fileDownloader } from './components/FileDownloader';
|
|
17
17
|
export { Escalations } from './components/Escalations';
|
|
18
|
+
export { ProjectIntelligence } from "./components/ProjectIntelligence";
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Escalations = exports.fileDownloader = exports.DiscussionSection = exports.fileUploader = exports.InvoiceCard = exports.ActiveProjectCard = exports.sharedUtils = exports.ServiceLinesTemplate = exports.HeaderNavBar = exports.DocumentCenter = exports.ProfileCompletedPercentage = exports.ExpertProfileHeader = exports.OrganizationChart = exports.FirmEmployeeSection = exports.ClientReferenceSection = exports.Reviews = exports.ReviewsTab = void 0;
|
|
3
|
+
exports.ProjectIntelligence = exports.Escalations = exports.fileDownloader = exports.DiscussionSection = exports.fileUploader = exports.InvoiceCard = exports.ActiveProjectCard = exports.sharedUtils = exports.ServiceLinesTemplate = exports.HeaderNavBar = exports.DocumentCenter = exports.ProfileCompletedPercentage = exports.ExpertProfileHeader = exports.OrganizationChart = exports.FirmEmployeeSection = exports.ClientReferenceSection = exports.Reviews = exports.ReviewsTab = void 0;
|
|
4
4
|
var ReviewsTab_1 = require("./components/ReviewsTab");
|
|
5
5
|
Object.defineProperty(exports, "ReviewsTab", { enumerable: true, get: function () { return ReviewsTab_1.ReviewsTab; } });
|
|
6
6
|
var Reviews_1 = require("./components/Reviews");
|
|
@@ -35,3 +35,5 @@ var FileDownloader_1 = require("./components/FileDownloader");
|
|
|
35
35
|
Object.defineProperty(exports, "fileDownloader", { enumerable: true, get: function () { return FileDownloader_1.fileDownloader; } });
|
|
36
36
|
var Escalations_1 = require("./components/Escalations");
|
|
37
37
|
Object.defineProperty(exports, "Escalations", { enumerable: true, get: function () { return Escalations_1.Escalations; } });
|
|
38
|
+
var ProjectIntelligence_1 = require("./components/ProjectIntelligence");
|
|
39
|
+
Object.defineProperty(exports, "ProjectIntelligence", { enumerable: true, get: function () { return ProjectIntelligence_1.ProjectIntelligence; } });
|