@paro.io/expert-shared-components 1.12.50 → 1.12.51
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/EscalationChat.js +10 -8
- package/lib/components/Escalations/EscalationIssueCard.d.ts +2 -1
- package/lib/components/Escalations/EscalationIssueCard.js +82 -57
- package/lib/components/Escalations/EscalationRespondForm.js +9 -4
- package/lib/components/Escalations/EscalationSubmitForm.js +1 -1
- package/lib/components/Escalations/EscalationTabsContent.js +13 -13
- package/lib/components/Escalations/Escalations.js +2 -2
- package/lib/components/Escalations/MarkResolvedModal.d.ts +9 -0
- package/lib/components/Escalations/MarkResolvedModal.js +86 -0
- package/lib/components/Escalations/ViewReponseModal.d.ts +8 -0
- package/lib/components/Escalations/ViewReponseModal.js +27 -0
- package/package.json +1 -1
|
@@ -41,8 +41,10 @@ const EscalationIssueCard_1 = require("./EscalationIssueCard");
|
|
|
41
41
|
const FileUploader_1 = require("../FileUploader");
|
|
42
42
|
const EscalationRespondForm_1 = require("./EscalationRespondForm");
|
|
43
43
|
const EscalationChat = ({ activeChatIssue, showEscalationChat, setShowEscalationChat, user, createEscalationChatMessage, documentUploadUrl, bucketName, uploadExpertClientFiles, createProjectEscalation, isExpert, }) => {
|
|
44
|
-
var _a, _b;
|
|
45
|
-
const [uploadFiles, setUploadFiles] = (0, react_1.useState)(
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
|
+
const [uploadFiles, setUploadFiles] = (0, react_1.useState)(isExpert
|
|
46
|
+
? (((_a = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.expertSupportingDocuments) === null || _a === void 0 ? void 0 : _a.split(",")) || [])
|
|
47
|
+
: (((_b = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.clientSupportingDocuments) === null || _b === void 0 ? void 0 : _b.split(",")) || []));
|
|
46
48
|
const [uploadingFile, setUploadingFile] = (0, react_1.useState)(false);
|
|
47
49
|
const fileInputRef = (0, react_1.useRef)(null);
|
|
48
50
|
const handleFileUpload = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -114,17 +116,17 @@ const EscalationChat = ({ activeChatIssue, showEscalationChat, setShowEscalation
|
|
|
114
116
|
.map(doc => doc.trim())
|
|
115
117
|
.filter(doc => doc !== '' || doc !== "NULL");
|
|
116
118
|
const project = activeChatIssue.projectDetails && Array.isArray(activeChatIssue.projectDetails) && activeChatIssue.projectDetails.length > 0
|
|
117
|
-
? `${(
|
|
119
|
+
? `${(_c = activeChatIssue.projectDetails[0]) === null || _c === void 0 ? void 0 : _c.projectName}${activeChatIssue.projectDetails.length > 1 ? ` +${activeChatIssue.projectDetails.length - 1} more` : ''} `
|
|
118
120
|
: '';
|
|
119
121
|
return (react_1.default.createElement(core_1.Dialog, { open: showEscalationChat, onClose: () => setShowEscalationChat(false), maxWidth: 'sm' },
|
|
120
122
|
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" },
|
|
123
|
+
react_1.default.createElement("div", { className: "text-black bg-white mb-1 p-2 pl-4 absolute top-0 left-0 w-full flex flex-row justify-between items-center z-50" },
|
|
122
124
|
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
123
125
|
react_1.default.createElement("div", { className: "flex flex-row items-center" },
|
|
124
126
|
react_1.default.createElement("h1", { className: "text-md font-bold mr-2" },
|
|
125
127
|
"Escalation Chat #",
|
|
126
128
|
activeChatIssue.escalationNumber),
|
|
127
|
-
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: activeChatIssue.status })),
|
|
129
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: activeChatIssue.status === "InProgress" ? "In Progress" : activeChatIssue.status })),
|
|
128
130
|
react_1.default.createElement("p", { className: "text-xs" },
|
|
129
131
|
activeChatIssue.problem,
|
|
130
132
|
" \u2022 ",
|
|
@@ -134,10 +136,10 @@ const EscalationChat = ({ activeChatIssue, showEscalationChat, setShowEscalation
|
|
|
134
136
|
react_1.default.createElement(base_icons_1.IconX, null))))),
|
|
135
137
|
react_1.default.createElement(core_1.DialogContent, null,
|
|
136
138
|
react_1.default.createElement("div", { className: "bg-white rounded-lg w-full overflow-hidden flex flex-col p-2 mt-12" },
|
|
137
|
-
react_1.default.createElement(DiscussionSection_1.DiscussionSection, { escalationNumber: activeChatIssue.escalationNumber, currentUser: user, messages: (
|
|
138
|
-
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
139
|
+
react_1.default.createElement(DiscussionSection_1.DiscussionSection, { escalationNumber: activeChatIssue.escalationNumber, currentUser: user, messages: (_d = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.chatMessages) !== null && _d !== void 0 ? _d : [], onCreateMessage: createEscalationChatMessage, isInternal: false }),
|
|
140
|
+
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2 mt-4 mb-2" },
|
|
139
141
|
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
140
|
-
processedDocs.map((d, idx) => (react_1.default.createElement(EscalationIssueCard_1.CustomTag, { key: idx, label: d.split('%2F')[1] }))))),
|
|
142
|
+
processedDocs.map((d, idx) => (react_1.default.createElement(EscalationIssueCard_1.CustomTag, { key: idx, label: d.split('%2F')[1], customColor: "success" }))))),
|
|
141
143
|
react_1.default.createElement("div", { className: "bg-white mt-2" },
|
|
142
144
|
react_1.default.createElement("div", { className: "space-y-3" },
|
|
143
145
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export declare const CustomTag: ({ label, iconLeft, onClick, }: {
|
|
2
|
+
export declare const CustomTag: ({ label, iconLeft, onClick, customColor, }: {
|
|
3
3
|
label: any;
|
|
4
4
|
iconLeft?: React.ReactNode;
|
|
5
5
|
onClick?: () => void;
|
|
6
|
+
customColor?: string;
|
|
6
7
|
}) => React.JSX.Element;
|
|
7
8
|
type EscalationIssueCardProps = {
|
|
8
9
|
issues: any[];
|
|
@@ -1,14 +1,39 @@
|
|
|
1
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
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
exports.CustomTag = void 0;
|
|
7
|
-
const react_1 =
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
8
31
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
9
32
|
const ClientDisputeProjectCard_1 = require("../Invoices/ClientDisputeProjectCard");
|
|
10
33
|
const base_icons_1 = require("@paro.io/base-icons");
|
|
11
34
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
35
|
+
const ViewReponseModal_1 = __importDefault(require("./ViewReponseModal"));
|
|
36
|
+
const MarkResolvedModal_1 = __importDefault(require("./MarkResolvedModal"));
|
|
12
37
|
const getBackgroundColor = (type) => {
|
|
13
38
|
switch (type) {
|
|
14
39
|
case 'Critical':
|
|
@@ -20,70 +45,70 @@ const getBackgroundColor = (type) => {
|
|
|
20
45
|
case 'Low':
|
|
21
46
|
return 'success';
|
|
22
47
|
default:
|
|
23
|
-
return '
|
|
48
|
+
return 'neutral';
|
|
24
49
|
}
|
|
25
50
|
};
|
|
26
|
-
const CustomTag = ({ label, iconLeft, onClick, }) => {
|
|
27
|
-
const color = getBackgroundColor(label);
|
|
28
|
-
return (react_1.default.createElement("div", { onClick: onClick, className: `flex flex-row gap-1 border box-border text-center px-4 pb-0.5 pt-1 text-sm inline-block break-words text-white rounded-full bg-${color} border-${color} ml-2 font-
|
|
51
|
+
const CustomTag = ({ label, iconLeft, onClick, customColor, }) => {
|
|
52
|
+
const color = customColor ? customColor : getBackgroundColor(label);
|
|
53
|
+
return (react_1.default.createElement("div", { onClick: onClick, className: `flex flex-row gap-1 border box-border text-center px-4 pb-0.5 pt-1 text-sm inline-block break-words text-white rounded-full bg-${color} border-${color} ml-2 font-medium ${onClick ? 'cursor-pointer' : ''}` },
|
|
29
54
|
iconLeft && react_1.default.createElement("span", null, iconLeft), label === null || label === void 0 ? void 0 :
|
|
30
55
|
label.toUpperCase()));
|
|
31
56
|
};
|
|
32
57
|
exports.CustomTag = CustomTag;
|
|
33
58
|
const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespondButton = false, setSelectedIssueId, showMarkResolvedButton = false, updateProjectEscalation, downloadDocumentUrl, bucketName, }) => {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
const [viewResponseModal, setViewResponseModal] = (0, react_1.useState)(null);
|
|
61
|
+
const [markAsResolved, setMarkAsResolved] = (0, react_1.useState)(null);
|
|
62
|
+
const getResponseButtonText = (issue) => {
|
|
63
|
+
const hasResponse = isExpert ? issue.clientResponse : issue.expertResponse;
|
|
64
|
+
return hasResponse ? "View Response" : "Awaiting Response";
|
|
65
|
+
};
|
|
34
66
|
if (!issues.length)
|
|
35
67
|
return react_1.default.createElement("div", null, "No issues.");
|
|
36
|
-
return (react_1.default.createElement("div", { className: "space-y-4" },
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
react_1.default.createElement("div", { className: "
|
|
49
|
-
react_1.default.createElement("div", { className: "flex-
|
|
50
|
-
react_1.default.createElement("div", { className: "flex
|
|
51
|
-
react_1.default.createElement("div", { className: "
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
react_1.default.createElement("div", { className: "
|
|
60
|
-
react_1.default.createElement("div", { className: "
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
react_1.default.createElement("
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
react_1.default.createElement(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}).then(() => { console.log("its marked as resolved"); }).catch((error) => {
|
|
84
|
-
console.error("Error updating escalation status:", error);
|
|
85
|
-
});
|
|
86
|
-
}, label: "Mark as Resolved", color: "primary" })))));
|
|
87
|
-
})));
|
|
68
|
+
return (react_1.default.createElement("div", { className: "space-y-4" },
|
|
69
|
+
issues.map((issue) => {
|
|
70
|
+
var _a;
|
|
71
|
+
const project = issue.projectDetails && Array.isArray(issue.projectDetails) && issue.projectDetails.length > 0
|
|
72
|
+
? `${(_a = issue.projectDetails[0]) === null || _a === void 0 ? void 0 : _a.projectName}${issue.projectDetails.length > 1 ? ` +${issue.projectDetails.length - 1} more` : ''} `
|
|
73
|
+
: '';
|
|
74
|
+
const docs = [issue.expertSupportingDocuments, issue.clientSupportingDocuments, issue.internalSupportingDocuments];
|
|
75
|
+
const processedDocs = docs
|
|
76
|
+
.filter(doc => doc !== null && doc !== undefined && doc !== '' && doc !== "NULL")
|
|
77
|
+
.flatMap(doc => doc.split(','))
|
|
78
|
+
.map(doc => doc.trim())
|
|
79
|
+
.filter(doc => doc !== '' || doc !== "NULL");
|
|
80
|
+
return (react_1.default.createElement("div", { key: issue.id, className: "border border-gray-200 rounded-lg bg-white p-4" },
|
|
81
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between mb-3" },
|
|
82
|
+
react_1.default.createElement("div", { className: "flex-1 ml-2" },
|
|
83
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-start gap-2" },
|
|
84
|
+
react_1.default.createElement("div", { className: "font-bold" }, issue.problem),
|
|
85
|
+
react_1.default.createElement(exports.CustomTag, { label: issue.severityLevel })),
|
|
86
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-500 font-bold" },
|
|
87
|
+
project,
|
|
88
|
+
" \u2022 Case #",
|
|
89
|
+
issue.escalationNumber)),
|
|
90
|
+
react_1.default.createElement(exports.CustomTag, { label: issue.escalationType })),
|
|
91
|
+
react_1.default.createElement("div", { className: "bg-gray-50 rounded-md p-3 mb-4 border" },
|
|
92
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between mb-2" },
|
|
93
|
+
react_1.default.createElement("div", { className: "text-sm text-gray-500" },
|
|
94
|
+
"Submitted by: ",
|
|
95
|
+
react_1.default.createElement("span", { className: "font-bold" }, issue.submittedByUser.firstName + " " + issue.submittedByUser.lastName),
|
|
96
|
+
issue.createdAt && react_1.default.createElement(react_1.default.Fragment, null,
|
|
97
|
+
" \u2022 Submitted on: ",
|
|
98
|
+
react_1.default.createElement("span", { className: "font-bold" }, (0, dayjs_1.default)(issue.createdAt).format("MM-DD-YYYY"))))),
|
|
99
|
+
react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-3" }, issue.outcome),
|
|
100
|
+
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
101
|
+
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
102
|
+
processedDocs.map((d, idx) => (react_1.default.createElement(exports.CustomTag, { key: idx, customColor: "success", label: d.split('%2F')[1], iconLeft: react_1.default.createElement(base_icons_1.IconDocumentDownload, { size: "xs" }), onClick: () => {
|
|
103
|
+
(0, ClientDisputeProjectCard_1.handleDownloadDocument)(issue.escalationId, d.split('%2F')[1], downloadDocumentUrl, bucketName);
|
|
104
|
+
} })))))),
|
|
105
|
+
react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
106
|
+
react_1.default.createElement(base_ui_1.Button, { onClick: () => openEscalationChat(issue), label: "Chat", color: "primary" }),
|
|
107
|
+
showRespondButton && setSelectedIssueId && (react_1.default.createElement(base_ui_1.Button, { label: "Respond to Escalation", onClick: () => setSelectedIssueId(issue.escalationNumber), color: 'primary' })),
|
|
108
|
+
showMarkResolvedButton && (react_1.default.createElement(base_ui_1.Button, { label: getResponseButtonText(issue), onClick: () => { setViewResponseModal(issue); }, color: 'primary', disabled: getResponseButtonText(issue) === 'Awaiting Response' })),
|
|
109
|
+
showMarkResolvedButton && !isExpert && (react_1.default.createElement(base_ui_1.Button, { onClick: () => { setMarkAsResolved(issue); }, label: "Mark as Resolved", color: "primary" })))));
|
|
110
|
+
}),
|
|
111
|
+
!!viewResponseModal && react_1.default.createElement(ViewReponseModal_1.default, { response: isExpert ? viewResponseModal.clientResponse : viewResponseModal.expertResponse, isExpert: isExpert, open: !!viewResponseModal, onClose: () => setViewResponseModal(null) }),
|
|
112
|
+
!!markAsResolved && react_1.default.createElement(MarkResolvedModal_1.default, { escalationId: markAsResolved.escalationId, expertName: (_b = (_a = markAsResolved === null || markAsResolved === void 0 ? void 0 : markAsResolved.freelancer) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'Expert', open: !!markAsResolved, onClose: () => setMarkAsResolved(false), updateProjectEscalation: updateProjectEscalation })));
|
|
88
113
|
};
|
|
89
114
|
exports.default = EscalationIssueCard;
|
|
@@ -75,9 +75,12 @@ const responseTypes = [
|
|
|
75
75
|
},
|
|
76
76
|
];
|
|
77
77
|
const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, updateProjectEscalation, bucketName, goHome, isExpert, }) => {
|
|
78
|
+
var _a, _b;
|
|
78
79
|
const [selectedType, setSelectedType] = (0, react_1.useState)(responseTypes[0].value);
|
|
79
80
|
const [responseInput, setResponseInput] = (0, react_1.useState)('');
|
|
80
|
-
const [uploadFiles, setUploadFiles] = (0, react_1.useState)(
|
|
81
|
+
const [uploadFiles, setUploadFiles] = (0, react_1.useState)(isExpert
|
|
82
|
+
? (((_a = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.expertSupportingDocuments) === null || _a === void 0 ? void 0 : _a.split(",")) || [])
|
|
83
|
+
: (((_b = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.clientSupportingDocuments) === null || _b === void 0 ? void 0 : _b.split(",")) || []));
|
|
81
84
|
const [uploadingFile, setUploadingFile] = (0, react_1.useState)(false);
|
|
82
85
|
const [submitting, setSubmitting] = (0, react_1.useState)(false);
|
|
83
86
|
const fileInputRef = (0, react_1.useRef)(null);
|
|
@@ -178,7 +181,9 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
178
181
|
react_1.default.createElement(base_icons_1.IconChevronLeft, { size: "xs" }),
|
|
179
182
|
" Back"),
|
|
180
183
|
react_1.default.createElement("div", { className: "mb-6" },
|
|
181
|
-
react_1.default.createElement("h2", { className: "text-xl font-bold" },
|
|
184
|
+
react_1.default.createElement("h2", { className: "text-xl font-bold" },
|
|
185
|
+
"Respond to engagement #",
|
|
186
|
+
selectedIssue.escalationNumber),
|
|
182
187
|
react_1.default.createElement("p", { className: "text-gray-600 mt-1" }, selectedIssue.problem)),
|
|
183
188
|
react_1.default.createElement("div", { className: "border rounded-lg overflow-hidden mb-6" },
|
|
184
189
|
react_1.default.createElement("div", { className: "bg-gray-50 p-3 border-b" },
|
|
@@ -206,9 +211,9 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
206
211
|
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, "Upload any supporting documentation"),
|
|
207
212
|
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: true, accept: ".pdf,.doc,.docx,.jpeg,.png,.gif,.csv", style: { display: 'none' }, ref: fileInputRef, onChange: handleFileUpload }),
|
|
208
213
|
react_1.default.createElement(base_ui_1.Button, { label: "Attach Files", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, color: "info", className: "mx-2", isLoading: uploadingFile, size: "sm" }),
|
|
209
|
-
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
214
|
+
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2 mt-4" },
|
|
210
215
|
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
211
|
-
processedDocs.map((d, idx) => (react_1.default.createElement(EscalationIssueCard_1.CustomTag, { key: idx, label: d.split('%2F')[1] }))))))),
|
|
216
|
+
processedDocs.map((d, idx) => (react_1.default.createElement(EscalationIssueCard_1.CustomTag, { key: idx, label: d.split('%2F')[1], customColor: "success" }))))))),
|
|
212
217
|
react_1.default.createElement("div", { className: "bg-blue-50 border border-blue-200 rounded-md p-3" },
|
|
213
218
|
react_1.default.createElement("div", { className: "flex items-center" },
|
|
214
219
|
react_1.default.createElement(base_icons_1.IconInfoCircle, { size: "md" }),
|
|
@@ -278,7 +278,7 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
278
278
|
issueTypeOptions
|
|
279
279
|
.filter(option => {
|
|
280
280
|
if (isExpert) {
|
|
281
|
-
return option.label !== 'Billing Concern';
|
|
281
|
+
return option.label !== 'Billing Concern' && option.label !== 'Quality Of Work';
|
|
282
282
|
}
|
|
283
283
|
else {
|
|
284
284
|
return option.label !== 'Scope Creep/Unauthorized Requests';
|
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
const react_1 = __importDefault(require("react"));
|
|
30
30
|
const EscalationIssueCard_1 = __importStar(require("./EscalationIssueCard"));
|
|
31
31
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
32
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
32
33
|
;
|
|
33
34
|
const EscalationTabsContent = ({ activeTab, openEscalationChat, setSelectedIssueId, activeIssues, inProgressIssues, resolvedIssues, isExpert, updateProjectEscalation, downloadDocumentUrl, bucketName, }) => {
|
|
34
35
|
if (activeTab === 'action-required') {
|
|
@@ -48,35 +49,34 @@ const EscalationTabsContent = ({ activeTab, openEscalationChat, setSelectedIssue
|
|
|
48
49
|
react_1.default.createElement("div", { className: "flex items-center justify-between mb-4" },
|
|
49
50
|
react_1.default.createElement("h3", { className: "text-lg font-semibold text-gray-900" }, "Recently Resolved Issues")),
|
|
50
51
|
resolvedIssues.length > 0 ? react_1.default.createElement("div", { className: "space-y-3" }, resolvedIssues.map((issue) => {
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
var _a;
|
|
53
|
+
const project = issue.projectDetails && Array.isArray(issue.projectDetails) && issue.projectDetails.length > 0
|
|
54
|
+
? `${(_a = issue.projectDetails[0]) === null || _a === void 0 ? void 0 : _a.projectName}${issue.projectDetails.length > 1 ? ` +${issue.projectDetails.length - 1} more` : ''} `
|
|
53
55
|
: '';
|
|
54
|
-
return (react_1.default.createElement("div", { key: issue.
|
|
56
|
+
return (react_1.default.createElement("div", { key: issue.escalationNumber, className: "border border-green-200 rounded-lg bg-green-50 p-4" },
|
|
55
57
|
react_1.default.createElement("div", { className: "flex items-start justify-between" },
|
|
56
58
|
react_1.default.createElement("div", { className: "flex items-start" },
|
|
57
59
|
react_1.default.createElement("div", null,
|
|
58
|
-
react_1.default.createElement("div", { className: "flex flex-row justify-
|
|
59
|
-
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-1" },
|
|
60
|
-
|
|
61
|
-
" ",
|
|
62
|
-
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: issue.severityLevel }))),
|
|
60
|
+
react_1.default.createElement("div", { className: "flex flex-row justify-start items-center mb-3" },
|
|
61
|
+
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-1 mr-4" }, issue.problem),
|
|
62
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: issue.severityLevel })),
|
|
63
63
|
react_1.default.createElement("div", { className: "flex items-center text-sm text-gray-600 mb-2" },
|
|
64
|
-
react_1.default.createElement("span", null, issue.
|
|
64
|
+
react_1.default.createElement("span", null, issue.submittedByUser.firstName + " " + issue.submittedByUser.lastName),
|
|
65
65
|
react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
|
|
66
66
|
react_1.default.createElement("span", null, project),
|
|
67
67
|
react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
|
|
68
68
|
react_1.default.createElement("span", null,
|
|
69
69
|
"Case #",
|
|
70
|
-
issue.
|
|
71
|
-
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-3" }, issue.
|
|
70
|
+
issue.escalationNumber)),
|
|
71
|
+
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-3" }, issue.internalResolution ? issue.internalResolution : isExpert ? issue.clientResolution : issue.expertResolution),
|
|
72
72
|
react_1.default.createElement("div", { className: "flex items-center text-sm text-gray-600 mb-2" },
|
|
73
73
|
react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
74
74
|
"Resolved ",
|
|
75
|
-
issue.
|
|
75
|
+
(0, dayjs_1.default)(issue.updatedAt).format("MM-DD-YYYY")),
|
|
76
76
|
react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
|
|
77
77
|
react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
78
78
|
"Resolved By ",
|
|
79
|
-
issue.
|
|
79
|
+
issue.statusChangedByUser.firstName + " " + issue.statusChangedByUser.lastName)))),
|
|
80
80
|
react_1.default.createElement(base_ui_1.Button, { onClick: () => openEscalationChat(issue), label: "Chat", color: "primary" }))));
|
|
81
81
|
}))
|
|
82
82
|
:
|
|
@@ -56,11 +56,11 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
|
|
|
56
56
|
const isRelevantEscalation = (isExpert
|
|
57
57
|
? (internalEscalationTo === 'expert' || internalEscalationTo === 'both')
|
|
58
58
|
: (internalEscalationTo === 'client' || internalEscalationTo === 'both'));
|
|
59
|
-
return ((userTypeId !== user.userTypeId ||
|
|
59
|
+
return (((userTypeId !== user.userTypeId && (isExpert ? issue.expertResponse === null : issue.clientResponse === null)) || //once responded will move to inProgress from active issues
|
|
60
60
|
(userTypeId === 2 && isRelevantEscalation)) &&
|
|
61
61
|
status === 'InProgress');
|
|
62
62
|
});
|
|
63
|
-
const inProgressIssues = escalations.filter(issue => { var _a; return ((_a = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _a === void 0 ? void 0 : _a.userTypeId) === user.userTypeId && (issue === null || issue === void 0 ? void 0 : issue.status) === 'InProgress'; });
|
|
63
|
+
const inProgressIssues = escalations.filter(issue => { var _a; return ((((_a = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _a === void 0 ? void 0 : _a.userTypeId) === user.userTypeId) || (isExpert ? issue.expertResponse !== null : issue.clientResponse !== null)) && (issue === null || issue === void 0 ? void 0 : issue.status) === 'InProgress'; });
|
|
64
64
|
const resolvedIssues = escalations.filter(issue => (issue === null || issue === void 0 ? void 0 : issue.status) === 'Resolved');
|
|
65
65
|
const goBack = () => {
|
|
66
66
|
if (selectedIssueId !== null) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const MarkResolvedModal: ({ escalationId, expertName, open, onClose, updateProjectEscalation, }: {
|
|
3
|
+
escalationId: string;
|
|
4
|
+
expertName: string;
|
|
5
|
+
open: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
updateProjectEscalation: any;
|
|
8
|
+
}) => React.JSX.Element;
|
|
9
|
+
export default MarkResolvedModal;
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
const react_1 = __importStar(require("react"));
|
|
36
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
37
|
+
const base_ui_1 = require("@paro.io/base-ui");
|
|
38
|
+
const core_1 = require("@material-ui/core");
|
|
39
|
+
const utils_1 = require("../shared/utils");
|
|
40
|
+
const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProjectEscalation, }) => {
|
|
41
|
+
const [resolutionText, setResolutionText] = (0, react_1.useState)(null);
|
|
42
|
+
const [submitting, setSubmitting] = (0, react_1.useState)(false);
|
|
43
|
+
const handleSubmit = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
|
+
setSubmitting(true);
|
|
45
|
+
try {
|
|
46
|
+
yield updateProjectEscalation({
|
|
47
|
+
variables: {
|
|
48
|
+
input: {
|
|
49
|
+
escalationId: escalationId,
|
|
50
|
+
clientResolution: resolutionText,
|
|
51
|
+
status: 'InProgress'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
(0, utils_1.showToast)("success", "Escalation marked as resolved!");
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error("Failed to update escalation!", error);
|
|
59
|
+
(0, utils_1.showToast)("warning", "Failed to update escalation!");
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
setSubmitting(false);
|
|
63
|
+
onClose();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return (react_1.default.createElement(core_1.Dialog, { open: open, onClose: onClose, maxWidth: 'sm' },
|
|
67
|
+
react_1.default.createElement(core_1.DialogTitle, null,
|
|
68
|
+
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" },
|
|
69
|
+
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
70
|
+
react_1.default.createElement("h1", { className: "text-md font-medium mr-2" },
|
|
71
|
+
"Engagement Issue with ",
|
|
72
|
+
expertName)),
|
|
73
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
74
|
+
react_1.default.createElement(core_1.IconButton, { onClick: onClose },
|
|
75
|
+
react_1.default.createElement(base_icons_1.IconX, null))))),
|
|
76
|
+
react_1.default.createElement(core_1.DialogContent, null,
|
|
77
|
+
react_1.default.createElement("div", { className: "mt-6 mb-4" },
|
|
78
|
+
react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Please provide additional details before marking this issue as resolved."),
|
|
79
|
+
react_1.default.createElement(base_ui_1.Input, { type: "text", value: resolutionText, placeholder: "Enter details here...", onChange: (e) => setResolutionText(e.target.value) })),
|
|
80
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
81
|
+
react_1.default.createElement("div", { className: "flex space-x-2" },
|
|
82
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Cancel", onClick: onClose, disabled: submitting })),
|
|
83
|
+
react_1.default.createElement("div", { className: "flex space-x-2" },
|
|
84
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Submit", color: "primary", onClick: handleSubmit, isLoading: submitting }))))));
|
|
85
|
+
};
|
|
86
|
+
exports.default = MarkResolvedModal;
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
8
|
+
const core_1 = require("@material-ui/core");
|
|
9
|
+
const ViewResponseModal = ({ response, open, onClose, isExpert }) => {
|
|
10
|
+
return (react_1.default.createElement(core_1.Dialog, { open: open, onClose: onClose, maxWidth: 'sm' },
|
|
11
|
+
react_1.default.createElement(core_1.DialogTitle, null,
|
|
12
|
+
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" },
|
|
13
|
+
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
14
|
+
react_1.default.createElement("h1", { className: "text-md font-bold mr-2" }, isExpert ? 'Client Response' : 'Expert Response')),
|
|
15
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
16
|
+
react_1.default.createElement(core_1.IconButton, { onClick: onClose },
|
|
17
|
+
react_1.default.createElement(base_icons_1.IconX, null))))),
|
|
18
|
+
react_1.default.createElement(core_1.DialogContent, null,
|
|
19
|
+
react_1.default.createElement("div", { className: "bg-green-50 border-green-800 border border-l-4 rounded p-4 mt-4 mb-4" },
|
|
20
|
+
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
21
|
+
"Status: ",
|
|
22
|
+
react_1.default.createElement("span", { className: "font-normal" }, "Responded")),
|
|
23
|
+
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
24
|
+
"Response: ",
|
|
25
|
+
react_1.default.createElement("span", { className: "font-normal" }, response))))));
|
|
26
|
+
};
|
|
27
|
+
exports.default = ViewResponseModal;
|