@paro.io/expert-shared-components 1.11.4 → 1.11.6
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/FileUploader/index.d.ts +12 -0
- package/lib/components/FileUploader/index.js +55 -0
- package/lib/components/Invoices/DecisionSection.d.ts +0 -1
- package/lib/components/Invoices/DecisionSection.js +4 -4
- package/lib/components/Invoices/DiscussionSection.d.ts +2 -1
- package/lib/components/Invoices/DiscussionSection.js +8 -7
- package/lib/components/Invoices/DisputeSection.d.ts +3 -3
- package/lib/components/Invoices/DisputeSection.js +65 -19
- package/lib/components/Invoices/InvoiceCard.d.ts +4 -3
- package/lib/components/Invoices/InvoiceCard.js +6 -6
- package/lib/components/Invoices/InvoiceDetails.js +8 -6
- package/lib/components/shared/UploadClient.d.ts +1 -0
- package/lib/components/shared/UploadClient.js +5 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface UploadFileParams {
|
|
2
|
+
file: File;
|
|
3
|
+
documentName: string;
|
|
4
|
+
disputeId?: number;
|
|
5
|
+
projectId: number;
|
|
6
|
+
documentUploadUrl: string;
|
|
7
|
+
updateClientInvoiceDisputeMutation: any;
|
|
8
|
+
previousFiles: string[];
|
|
9
|
+
isExpert: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const fileUploader: ({ file, projectId, documentUploadUrl, updateClientInvoiceDisputeMutation, disputeId, previousFiles, isExpert, }: UploadFileParams) => Promise<boolean>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.fileUploader = void 0;
|
|
16
|
+
const UploadClient_1 = __importDefault(require("../shared/UploadClient"));
|
|
17
|
+
const utils_1 = require("../shared/utils");
|
|
18
|
+
const fileUploader = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, projectId, documentUploadUrl, updateClientInvoiceDisputeMutation, disputeId, previousFiles, isExpert, }) {
|
|
19
|
+
try {
|
|
20
|
+
(0, utils_1.showToast)('success', 'Starting Document Upload');
|
|
21
|
+
const uploadClient = new UploadClient_1.default({
|
|
22
|
+
fileSelected: file,
|
|
23
|
+
fileName: file.name,
|
|
24
|
+
projectId,
|
|
25
|
+
documentUploadUrl,
|
|
26
|
+
bucketName: 'expert-client-dispute-files',
|
|
27
|
+
});
|
|
28
|
+
yield uploadClient.triggerMultipartUpload().then((res) => {
|
|
29
|
+
const resParsed = JSON.parse(res);
|
|
30
|
+
const documentLink = resParsed === null || resParsed === void 0 ? void 0 : resParsed.Location;
|
|
31
|
+
updateClientInvoiceDisputeMutation({
|
|
32
|
+
variables: {
|
|
33
|
+
input: {
|
|
34
|
+
disputeId: disputeId,
|
|
35
|
+
projectDisputes: [
|
|
36
|
+
Object.assign({ projectId: projectId }, (isExpert ? {
|
|
37
|
+
expertDocumentLinks: [...previousFiles, documentLink].join(',')
|
|
38
|
+
} : {
|
|
39
|
+
clientDocumentLinks: [...previousFiles, documentLink].join(',')
|
|
40
|
+
}))
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
console.log(`Multipart File uploaded successfully with ${res}`);
|
|
46
|
+
(0, utils_1.showToast)('success', 'Document Upload Successful');
|
|
47
|
+
});
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
(0, utils_1.showToast)('warning', 'Error uploading file. Please try again.');
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
exports.fileUploader = fileUploader;
|
|
@@ -40,9 +40,9 @@ const react_1 = __importStar(require("react"));
|
|
|
40
40
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
41
41
|
const react_hot_toast_1 = __importDefault(require("react-hot-toast"));
|
|
42
42
|
const RESOLUTION_OPTIONS = [
|
|
43
|
-
{ value: '
|
|
44
|
-
{ value: '
|
|
45
|
-
{ value: '
|
|
43
|
+
{ value: 'APPROVED', label: 'Approve Dispute' },
|
|
44
|
+
{ value: 'DECLINED', label: 'Decline Dispute' },
|
|
45
|
+
{ value: 'PARTIAL', label: 'Partial Approval' },
|
|
46
46
|
];
|
|
47
47
|
const DecisionSection = ({ dispute, onUpdateDispute, }) => {
|
|
48
48
|
const [resolution, setResolution] = (0, react_1.useState)('');
|
|
@@ -57,7 +57,7 @@ const DecisionSection = ({ dispute, onUpdateDispute, }) => {
|
|
|
57
57
|
variables: {
|
|
58
58
|
input: {
|
|
59
59
|
disputeId: dispute.disputeId,
|
|
60
|
-
status:
|
|
60
|
+
status: "Resolved",
|
|
61
61
|
approvedAmount: amount ? parseFloat(amount) : undefined,
|
|
62
62
|
},
|
|
63
63
|
},
|
|
@@ -14,6 +14,7 @@ interface DiscussionSectionProps {
|
|
|
14
14
|
currentUser: any;
|
|
15
15
|
messages: Message[];
|
|
16
16
|
onCreateMessage: (variables: any) => Promise<any>;
|
|
17
|
+
isInternal?: boolean;
|
|
17
18
|
}
|
|
18
|
-
export declare const DiscussionSection: ({ disputeId, currentUser, messages, onCreateMessage, }: DiscussionSectionProps) => JSX.Element;
|
|
19
|
+
export declare const DiscussionSection: ({ disputeId, currentUser, messages, onCreateMessage, isInternal }: DiscussionSectionProps) => JSX.Element;
|
|
19
20
|
export {};
|
|
@@ -39,11 +39,11 @@ exports.DiscussionSection = void 0;
|
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
40
40
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
41
41
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
42
|
-
const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage, }) => {
|
|
43
|
-
var _a;
|
|
42
|
+
const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage, isInternal }) => {
|
|
44
43
|
const [newMessage, setNewMessage] = (0, react_1.useState)('');
|
|
45
44
|
const [visibility, setVisibility] = (0, react_1.useState)('ALL');
|
|
46
45
|
const [isLoading, setIsLoading] = (0, react_1.useState)(false);
|
|
46
|
+
const threadsEndRef = (0, react_1.useRef)(null);
|
|
47
47
|
// Get the sequence of unique userTypeIds to determine alignment
|
|
48
48
|
const userSequence = (0, react_1.useMemo)(() => {
|
|
49
49
|
const uniqueUsers = Array.from(new Set(messages.map(m => m.sender.userTypeId)));
|
|
@@ -82,11 +82,11 @@ const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage,
|
|
|
82
82
|
const getSenderTextColor = (userTypeId) => {
|
|
83
83
|
switch (userTypeId) {
|
|
84
84
|
case 1:
|
|
85
|
-
return '#
|
|
85
|
+
return '#643E0C';
|
|
86
86
|
case 2:
|
|
87
87
|
return '#2196F3';
|
|
88
88
|
case 3:
|
|
89
|
-
return '#
|
|
89
|
+
return '#195C5C';
|
|
90
90
|
default:
|
|
91
91
|
return '#333333';
|
|
92
92
|
}
|
|
@@ -94,11 +94,11 @@ const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage,
|
|
|
94
94
|
const getSenderBackgroundColor = (userTypeId) => {
|
|
95
95
|
switch (userTypeId) {
|
|
96
96
|
case 1:
|
|
97
|
-
return '#
|
|
97
|
+
return '#FDD7A5';
|
|
98
98
|
case 2:
|
|
99
99
|
return '#E4F0FF';
|
|
100
100
|
case 3:
|
|
101
|
-
return '#
|
|
101
|
+
return '#D9EFEF';
|
|
102
102
|
default:
|
|
103
103
|
return '#F8F9FA';
|
|
104
104
|
}
|
|
@@ -138,12 +138,13 @@ const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage,
|
|
|
138
138
|
react_1.default.createElement("span", { className: "text-xs text-[#666666]" }, (0, dayjs_1.default)(message.createdAt).format('MMM D, YYYY • h:mm A'))),
|
|
139
139
|
react_1.default.createElement("div", { style: { backgroundColor: getSenderBackgroundColor(message.sender.userTypeId) }, className: "mt-1 p-3 rounded-lg" },
|
|
140
140
|
react_1.default.createElement("p", { className: `text-sm ${getHeaderAlignment(message.sender.userTypeId)}`, style: { color: getSenderTextColor(message.sender.userTypeId) } }, message.messageText)))))))),
|
|
141
|
+
react_1.default.createElement("div", { ref: threadsEndRef }),
|
|
141
142
|
react_1.default.createElement("div", { className: "space-y-4 p-6 space-y-6 rounded mt-4", style: { backgroundColor: '#F5F7F9' } },
|
|
142
143
|
react_1.default.createElement("div", null,
|
|
143
144
|
react_1.default.createElement("div", { className: "font-bold text-[#333333] mb-2" }, "Add Comment"),
|
|
144
145
|
react_1.default.createElement("textarea", { value: newMessage, onChange: (e) => setNewMessage(e.target.value), placeholder: "Type your comment here...", className: "w-full h-24 p-3 border border-[#CCCCCC] rounded-lg text-sm resize-none focus:outline-none focus:ring-2 focus:ring-[#248384]" })),
|
|
145
146
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
146
|
-
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
147
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-4" }, isInternal && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
147
148
|
react_1.default.createElement("span", { className: "text-sm text-[#666666]" }, "Visible to:"),
|
|
148
149
|
react_1.default.createElement("div", { className: "flex items-center space-x-2" },
|
|
149
150
|
react_1.default.createElement("label", { className: "flex items-center space-x-2 cursor-pointer" },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
interface DisputeSectionProps {
|
|
2
2
|
dispute: any;
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
documentUploadUrl: string;
|
|
4
|
+
updateClientInvoiceDisputeMutation: (variables: any) => Promise<any>;
|
|
5
5
|
}
|
|
6
|
-
export declare const DisputeSection: ({ dispute,
|
|
6
|
+
export declare const DisputeSection: ({ dispute, documentUploadUrl, updateClientInvoiceDisputeMutation, }: DisputeSectionProps) => JSX.Element;
|
|
7
7
|
export {};
|
|
@@ -22,11 +22,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
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
|
+
};
|
|
25
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
35
|
exports.DisputeSection = void 0;
|
|
27
36
|
const react_1 = __importStar(require("react"));
|
|
28
37
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
29
38
|
const base_icons_1 = require("@paro.io/base-icons");
|
|
39
|
+
const FileUploader_1 = require("../FileUploader");
|
|
40
|
+
const core_1 = require("@material-ui/core");
|
|
30
41
|
const ACCEPTED_FILE_TYPES = [
|
|
31
42
|
'application/pdf',
|
|
32
43
|
'application/msword',
|
|
@@ -35,31 +46,50 @@ const ACCEPTED_FILE_TYPES = [
|
|
|
35
46
|
'image/png',
|
|
36
47
|
'text/csv',
|
|
37
48
|
];
|
|
38
|
-
const DisputeSection = ({ dispute,
|
|
49
|
+
const DisputeSection = ({ dispute, documentUploadUrl, updateClientInvoiceDisputeMutation, }) => {
|
|
39
50
|
var _a, _b, _c;
|
|
40
|
-
const [files, setFiles] = (0, react_1.useState)((dispute === null || dispute === void 0 ? void 0 : dispute.clientDocumentLinks) || []);
|
|
41
51
|
const fileInputRef = (0, react_1.useRef)(null);
|
|
52
|
+
const disputeProject = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a[0];
|
|
53
|
+
const clientDocumentLinks = (_b = disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.clientDocumentLinks) === null || _b === void 0 ? void 0 : _b.split(',');
|
|
54
|
+
const expertDocumentLinks = (_c = disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.expertDocumentLinks) === null || _c === void 0 ? void 0 : _c.split(',');
|
|
42
55
|
const validateFileUpload = (file) => {
|
|
43
56
|
return ACCEPTED_FILE_TYPES.includes(file.type);
|
|
44
57
|
};
|
|
45
|
-
const handleUpload = (event) => {
|
|
58
|
+
const handleUpload = (event, isExpert) => {
|
|
46
59
|
const selectedFiles = event.target.files;
|
|
47
60
|
if (!selectedFiles)
|
|
48
61
|
return;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
const getFileNames = selectedFiles && Array.from(selectedFiles).map((file) => {
|
|
63
|
+
if (!validateFileUpload(file)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
if (file) {
|
|
67
|
+
return file.name;
|
|
68
|
+
}
|
|
69
|
+
}).filter((name) => name !== null);
|
|
70
|
+
if (getFileNames && getFileNames.length > 0) {
|
|
71
|
+
Array.from(selectedFiles).forEach((selectedFile) => {
|
|
72
|
+
const reader = new FileReader();
|
|
73
|
+
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
var _a, _b;
|
|
75
|
+
yield (0, FileUploader_1.fileUploader)({
|
|
76
|
+
file: selectedFile,
|
|
77
|
+
documentName: selectedFile.name,
|
|
78
|
+
projectId: Number((_b = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.projectId),
|
|
79
|
+
documentUploadUrl: documentUploadUrl,
|
|
80
|
+
updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation,
|
|
81
|
+
disputeId: dispute === null || dispute === void 0 ? void 0 : dispute.disputeId,
|
|
82
|
+
previousFiles: isExpert ? expertDocumentLinks : clientDocumentLinks,
|
|
83
|
+
isExpert: isExpert,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
reader.readAsDataURL(selectedFile);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
55
89
|
if (fileInputRef.current) {
|
|
56
90
|
fileInputRef.current.value = '';
|
|
57
91
|
}
|
|
58
92
|
};
|
|
59
|
-
const handleRemoveFile = (fileName) => {
|
|
60
|
-
setFiles(prev => prev.filter(f => f !== fileName));
|
|
61
|
-
};
|
|
62
|
-
const disputeProject = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a[0];
|
|
63
93
|
return (react_1.default.createElement("div", { className: "grid grid-cols-2 gap-6" },
|
|
64
94
|
react_1.default.createElement("div", { className: "space-y-4" },
|
|
65
95
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
@@ -74,9 +104,17 @@ const DisputeSection = ({ dispute, onUpdateDispute, onRefetch, }) => {
|
|
|
74
104
|
react_1.default.createElement("div", null,
|
|
75
105
|
react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Supporting Documents:"),
|
|
76
106
|
react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
77
|
-
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: handleUpload }),
|
|
78
|
-
react_1.default.createElement(
|
|
79
|
-
|
|
107
|
+
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: (e) => handleUpload(e, false) }),
|
|
108
|
+
react_1.default.createElement("div", { className: "flex flex-wrap gap-2" }, expertDocumentLinks === null || expertDocumentLinks === void 0 ? void 0 : expertDocumentLinks.map((file, index) => (
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
react_1.default.createElement(core_1.Chip, { key: index, label: file.split('%2F').pop(), variant: "outlined", onClick: () => { window.open(file, '_blank'); }, sx: {
|
|
111
|
+
'&:hover': {
|
|
112
|
+
cursor: 'pointer',
|
|
113
|
+
backgroundColor: 'rgba(76, 175, 80, 0.1)'
|
|
114
|
+
}
|
|
115
|
+
} })))),
|
|
116
|
+
react_1.default.createElement("div", { className: "w-full mt-2" },
|
|
117
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Add File", 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(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]" })))))),
|
|
80
118
|
react_1.default.createElement("div", { className: "space-y-4" },
|
|
81
119
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
82
120
|
react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Expert Rebuttal")),
|
|
@@ -87,8 +125,16 @@ const DisputeSection = ({ dispute, onUpdateDispute, onRefetch, }) => {
|
|
|
87
125
|
react_1.default.createElement("div", null,
|
|
88
126
|
react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Supporting Documents:"),
|
|
89
127
|
react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
90
|
-
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: handleUpload }),
|
|
91
|
-
react_1.default.createElement(
|
|
92
|
-
|
|
128
|
+
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: (e) => handleUpload(e, true) }),
|
|
129
|
+
react_1.default.createElement("div", { className: "flex flex-wrap gap-2" }, clientDocumentLinks === null || clientDocumentLinks === void 0 ? void 0 : clientDocumentLinks.map((file, index) => (
|
|
130
|
+
// @ts-ignore
|
|
131
|
+
react_1.default.createElement(core_1.Chip, { key: index, label: file.split('%2F').pop(), variant: "outlined", onClick: () => { window.open(file, '_blank'); }, sx: {
|
|
132
|
+
'&:hover': {
|
|
133
|
+
cursor: 'pointer',
|
|
134
|
+
backgroundColor: 'rgba(76, 175, 80, 0.1)'
|
|
135
|
+
}
|
|
136
|
+
} })))),
|
|
137
|
+
react_1.default.createElement("div", { className: "w-full mt-2" },
|
|
138
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Add File", 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(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]" }))))))));
|
|
93
139
|
};
|
|
94
140
|
exports.DisputeSection = DisputeSection;
|
|
@@ -3,8 +3,9 @@ interface InvoiceCardProps {
|
|
|
3
3
|
createDisputeChatMessage: any;
|
|
4
4
|
user: any;
|
|
5
5
|
chatMessages: any[];
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
updateClientInvoiceDisputeMutation: any;
|
|
7
|
+
documentUploadUrl: string;
|
|
8
|
+
isInternal?: boolean;
|
|
8
9
|
}
|
|
9
|
-
export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages,
|
|
10
|
+
export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, documentUploadUrl, isInternal }: InvoiceCardProps) => JSX.Element;
|
|
10
11
|
export {};
|
|
@@ -11,15 +11,15 @@ const InvoiceDetails_1 = require("./InvoiceDetails");
|
|
|
11
11
|
const DisputeSection_1 = require("./DisputeSection");
|
|
12
12
|
const DiscussionSection_1 = require("./DiscussionSection");
|
|
13
13
|
const DecisionSection_1 = require("./DecisionSection");
|
|
14
|
-
const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessages,
|
|
15
|
-
var _a, _b
|
|
14
|
+
const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, documentUploadUrl, isInternal }) => {
|
|
15
|
+
var _a, _b;
|
|
16
16
|
return (react_1.default.createElement(base_ui_1.Card, { className: "w-full bg-white rounded-lg shadow-sm overflow-hidden" },
|
|
17
17
|
react_1.default.createElement(InvoiceHeader_1.InvoiceHeader, { invoice: clientInvoice }),
|
|
18
18
|
react_1.default.createElement("div", { className: "p-6 space-y-6" },
|
|
19
19
|
react_1.default.createElement(InvoiceDetails_1.InvoiceDetails, { invoice: clientInvoice }),
|
|
20
|
-
react_1.default.createElement(DisputeSection_1.DisputeSection, { dispute: clientInvoice,
|
|
21
|
-
(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.chatEnabled) && (react_1.default.createElement(DiscussionSection_1.DiscussionSection, { disputeId: (_b = (_a = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id, currentUser: user, messages: chatMessages, onCreateMessage: createDisputeChatMessage })),
|
|
22
|
-
|
|
23
|
-
react_1.default.createElement(DecisionSection_1.DecisionSection, { dispute: clientInvoice, onUpdateDispute:
|
|
20
|
+
react_1.default.createElement(DisputeSection_1.DisputeSection, { dispute: clientInvoice, documentUploadUrl: documentUploadUrl, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation }),
|
|
21
|
+
(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.chatEnabled) && (react_1.default.createElement(DiscussionSection_1.DiscussionSection, { disputeId: (_b = (_a = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id, currentUser: user, messages: chatMessages, onCreateMessage: createDisputeChatMessage, isInternal: isInternal })),
|
|
22
|
+
isInternal &&
|
|
23
|
+
react_1.default.createElement(DecisionSection_1.DecisionSection, { dispute: clientInvoice, onUpdateDispute: updateClientInvoiceDisputeMutation }))));
|
|
24
24
|
};
|
|
25
25
|
exports.InvoiceCard = InvoiceCard;
|
|
@@ -5,29 +5,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.InvoiceDetails = void 0;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const base_ui_1 = require("@paro.io/base-ui");
|
|
9
8
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
10
9
|
const DisputeProjectCard_1 = require("./DisputeProjectCard");
|
|
10
|
+
const core_1 = require("@material-ui/core");
|
|
11
11
|
const InvoiceDetails = ({ invoice }) => {
|
|
12
12
|
var _a;
|
|
13
13
|
const getStatusColor = (status) => {
|
|
14
14
|
switch (status) {
|
|
15
15
|
case 'InProgress':
|
|
16
|
-
return '
|
|
16
|
+
return 'primary';
|
|
17
17
|
case 'UnderReview':
|
|
18
|
-
return '
|
|
18
|
+
return 'primary';
|
|
19
19
|
case 'Resolved':
|
|
20
20
|
return 'success';
|
|
21
21
|
default:
|
|
22
|
-
return '
|
|
22
|
+
return 'primary';
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
return (react_1.default.createElement("div", { className: "space-y-6" },
|
|
26
26
|
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
27
|
-
react_1.default.createElement(
|
|
27
|
+
react_1.default.createElement(core_1.Chip, { label: invoice === null || invoice === void 0 ? void 0 : invoice.status, size: "small", variant: "outlined",
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
color: getStatusColor(invoice === null || invoice === void 0 ? void 0 : invoice.status) }),
|
|
28
30
|
react_1.default.createElement("span", { className: "text-xs text-[#666666]" },
|
|
29
31
|
"Last updated: ",
|
|
30
|
-
(0, dayjs_1.default)(invoice === null || invoice === void 0 ? void 0 : invoice.disputeUpdatedDate).format('YYYY
|
|
32
|
+
(0, dayjs_1.default)(invoice === null || invoice === void 0 ? void 0 : invoice.disputeUpdatedDate).format('MMM D, YYYY'))),
|
|
31
33
|
((_a = invoice === null || invoice === void 0 ? void 0 : invoice.disputeProjects) === null || _a === void 0 ? void 0 : _a.length) > 0 && (react_1.default.createElement("div", { className: "space-y-4" },
|
|
32
34
|
react_1.default.createElement("div", { className: "grid grid-cols-1 gap-4" }, invoice.disputeProjects.map((project) => (react_1.default.createElement(DisputeProjectCard_1.DisputeProjectCard, { key: project.id, project: project, client: invoice === null || invoice === void 0 ? void 0 : invoice.client, disputeDate: invoice === null || invoice === void 0 ? void 0 : invoice.disputeDate, disputeUpdatedDate: invoice === null || invoice === void 0 ? void 0 : invoice.disputeUpdatedDate }))))))));
|
|
33
35
|
};
|
|
@@ -17,6 +17,7 @@ class UploadClient {
|
|
|
17
17
|
fileName: props.fileName,
|
|
18
18
|
documentUploadUrl: props.documentUploadUrl,
|
|
19
19
|
projectId: props.projectId,
|
|
20
|
+
bucketName: props.bucketName,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
generateS3Key(projectId, fileName) {
|
|
@@ -34,6 +35,7 @@ class UploadClient {
|
|
|
34
35
|
const params = {
|
|
35
36
|
fileName: this.state.fileName,
|
|
36
37
|
fileType: this.state.fileSelected.type,
|
|
38
|
+
bucketName: this.state.bucketName,
|
|
37
39
|
method: 'start-upload',
|
|
38
40
|
};
|
|
39
41
|
const response = yield fetch(`${this.state.documentUploadUrl}`, {
|
|
@@ -67,7 +69,7 @@ class UploadClient {
|
|
|
67
69
|
// Get presigned URL for each part from backend lambda
|
|
68
70
|
let presignedUrlResponse = yield fetch(`${this.state.documentUploadUrl}`, {
|
|
69
71
|
method: 'POST',
|
|
70
|
-
body: JSON.stringify({ fileName: this.state.fileName, uploadId: this.state.uploadId, partNumber: index, method: 'get-presigned-url' }),
|
|
72
|
+
body: JSON.stringify({ fileName: this.state.fileName, uploadId: this.state.uploadId, partNumber: index, method: 'get-presigned-url', bucketName: this.state.bucketName }),
|
|
71
73
|
});
|
|
72
74
|
const { responseData } = yield presignedUrlResponse.json();
|
|
73
75
|
// Add each upload part to promise array using presigned URL
|
|
@@ -100,11 +102,11 @@ class UploadClient {
|
|
|
100
102
|
headers: {
|
|
101
103
|
'Content-Type': 'application/json',
|
|
102
104
|
},
|
|
103
|
-
body: JSON.stringify({ fileName: this.state.fileName, uploadId: this.state.uploadId, parts: partsArray, method: 'complete-upload' }),
|
|
105
|
+
body: JSON.stringify({ fileName: this.state.fileName, uploadId: this.state.uploadId, parts: partsArray, method: 'complete-upload', bucketName: this.state.bucketName }),
|
|
104
106
|
});
|
|
105
107
|
const { responseData } = yield response.json();
|
|
106
108
|
console.log('Upload Complete', responseData);
|
|
107
|
-
return
|
|
109
|
+
return `${JSON.stringify(responseData)}`;
|
|
108
110
|
}
|
|
109
111
|
catch (error) {
|
|
110
112
|
console.log(`Error Completing Multipart Upload ${error}`);
|
package/lib/index.d.ts
CHANGED
|
@@ -12,3 +12,4 @@ export { sharedUtils } from './components/shared/utils';
|
|
|
12
12
|
export { ActiveProjectCard } from './components/ProjectCard/ActiveProjectCard';
|
|
13
13
|
export { InvoiceCard } from './components/Invoices/InvoiceCard';
|
|
14
14
|
export { DiscussionThread } from './components/DiscussionThread';
|
|
15
|
+
export { fileUploader } from './components/FileUploader';
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DiscussionThread = 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.fileUploader = exports.DiscussionThread = 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");
|
|
@@ -29,3 +29,5 @@ var InvoiceCard_1 = require("./components/Invoices/InvoiceCard");
|
|
|
29
29
|
Object.defineProperty(exports, "InvoiceCard", { enumerable: true, get: function () { return InvoiceCard_1.InvoiceCard; } });
|
|
30
30
|
var DiscussionThread_1 = require("./components/DiscussionThread");
|
|
31
31
|
Object.defineProperty(exports, "DiscussionThread", { enumerable: true, get: function () { return DiscussionThread_1.DiscussionThread; } });
|
|
32
|
+
var FileUploader_1 = require("./components/FileUploader");
|
|
33
|
+
Object.defineProperty(exports, "fileUploader", { enumerable: true, get: function () { return FileUploader_1.fileUploader; } });
|