@paro.io/expert-shared-components 1.14.51 → 1.14.53
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/DocumentCenter/MultiFileUploadSection.js +220 -121
- package/lib/components/TaxAxis/TaxAxisApi.d.ts +1 -0
- package/lib/components/TaxAxis/TaxAxisShell.js +55 -12
- package/lib/index.d.ts +1 -14
- package/lib/index.js +1 -27
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.d.ts +6 -2
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +5 -3
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.d.ts +2 -1
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +163 -34
- package/lib/tax-axis/components/documents/DocumentCard.d.ts +3 -1
- package/lib/tax-axis/components/documents/DocumentCard.js +17 -5
- package/lib/tax-axis/components/documents/DocumentReviewModal.d.ts +13 -0
- package/lib/tax-axis/components/documents/DocumentReviewModal.js +248 -0
- package/lib/tax-axis/components/documents/DocumentTier.d.ts +3 -1
- package/lib/tax-axis/components/documents/DocumentTier.js +2 -2
- package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +7 -1
- package/lib/tax-axis/components/documents/TaxAxisDocuments.js +116 -53
- package/lib/tax-axis/components/extractionReview/TaxAxisExtractionReview.js +17 -17
- package/lib/tax-axis/components/intake/ClientParametersSection.js +1 -1
- package/lib/tax-axis/components/intake/intakeSchema.js +1 -1
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.d.ts +6 -2
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +5 -3
- package/lib/tax-axis/index.d.ts +4 -0
- package/lib/tax-axis/index.js +6 -1
- package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +144 -0
- package/lib/tax-axis/lib/adapters/useEngineOutput.js +155 -0
- package/lib/tax-axis/lib/data/documents.d.ts +3 -2
- package/lib/tax-axis/lib/data/documents.js +225 -25
- package/lib/tax-axis/lib/documentFieldCatalog.d.ts +13 -0
- package/lib/tax-axis/lib/documentFieldCatalog.js +808 -0
- package/lib/tax-axis/lib/types/index.d.ts +3 -0
- package/package.json +1 -1
|
@@ -38,6 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
38
38
|
exports.MultiFileUploadSection = void 0;
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
40
40
|
const core_1 = require("@material-ui/core");
|
|
41
|
+
const CheckCircle_1 = __importDefault(require("@material-ui/icons/CheckCircle"));
|
|
41
42
|
const ExpandMore_1 = __importDefault(require("@material-ui/icons/ExpandMore"));
|
|
42
43
|
const ExpandLess_1 = __importDefault(require("@material-ui/icons/ExpandLess"));
|
|
43
44
|
const date_fns_1 = require("date-fns");
|
|
@@ -70,15 +71,13 @@ const generateOptions = (array, clientOptions, isClientPortal) => {
|
|
|
70
71
|
? `${item === null || item === void 0 ? void 0 : item.id}_${index}`
|
|
71
72
|
: item === null || item === void 0 ? void 0 : item.split(" ").join("_").concat(index);
|
|
72
73
|
if (clientOptions) {
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
// Show only project name for project dropdown
|
|
75
|
+
if (projectName) {
|
|
76
|
+
newText = projectName;
|
|
75
77
|
}
|
|
76
78
|
else if (name) {
|
|
77
79
|
newText = name;
|
|
78
80
|
}
|
|
79
|
-
else if (projectName) {
|
|
80
|
-
newText = projectName;
|
|
81
|
-
}
|
|
82
81
|
else {
|
|
83
82
|
newText = "N/A";
|
|
84
83
|
}
|
|
@@ -94,7 +93,6 @@ const generateOptions = (array, clientOptions, isClientPortal) => {
|
|
|
94
93
|
});
|
|
95
94
|
};
|
|
96
95
|
const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadExpertClientFiles, uploadInternalFile, foldername, refetchFiles, legacyFreelancerId, freelancerName, freelancerEmail, isClientPortal = false, documentUploadUrl, showAsPage, }) => {
|
|
97
|
-
var _a;
|
|
98
96
|
const [uploadItems, setUploadItems] = (0, react_1.useState)([]);
|
|
99
97
|
const [isUploading, setIsUploading] = (0, react_1.useState)(false);
|
|
100
98
|
const [showUploadSection, setShowUploadSection] = (0, react_1.useState)(true);
|
|
@@ -122,7 +120,9 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
122
120
|
const excludedStatuses = ["complete", "completed", "doa", "churned"];
|
|
123
121
|
const isValidProject = projectStatus &&
|
|
124
122
|
!excludedStatuses.includes(projectStatus.toLowerCase());
|
|
125
|
-
|
|
123
|
+
// Filter out "System Fee" expert on client side
|
|
124
|
+
const isSystemFee = isClientPortal && (name === null || name === void 0 ? void 0 : name.toLowerCase()) === "system fee";
|
|
125
|
+
if (id && name && !isSystemFee) {
|
|
126
126
|
if (!groups.has(id)) {
|
|
127
127
|
groups.set(id, {
|
|
128
128
|
expert: { id, name },
|
|
@@ -193,7 +193,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
193
193
|
if (!selectedExpert)
|
|
194
194
|
return [];
|
|
195
195
|
return clientOptions.filter((opt) => {
|
|
196
|
-
var _a, _b;
|
|
196
|
+
var _a, _b, _c, _d;
|
|
197
197
|
const isMatch = isClientPortal
|
|
198
198
|
? ((_a = opt.freelancer) === null || _a === void 0 ? void 0 : _a.id) === selectedExpert.id
|
|
199
199
|
: ((_b = opt.client) === null || _b === void 0 ? void 0 : _b.id) === selectedExpert.id;
|
|
@@ -201,7 +201,12 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
201
201
|
const excludedStatuses = ["complete", "completed", "doa", "churned"];
|
|
202
202
|
const isValidProject = projectStatus &&
|
|
203
203
|
!excludedStatuses.includes(projectStatus.toLowerCase());
|
|
204
|
-
|
|
204
|
+
// Filter out System Fee projects on client side
|
|
205
|
+
const expertName = isClientPortal
|
|
206
|
+
? (_c = opt.freelancer) === null || _c === void 0 ? void 0 : _c.name
|
|
207
|
+
: (_d = opt.client) === null || _d === void 0 ? void 0 : _d.name;
|
|
208
|
+
const isSystemFee = isClientPortal && (expertName === null || expertName === void 0 ? void 0 : expertName.toLowerCase()) === "system fee";
|
|
209
|
+
return isMatch && isValidProject && !isSystemFee;
|
|
205
210
|
});
|
|
206
211
|
}, [selectedExpert, clientOptions, isClientPortal]);
|
|
207
212
|
// Check if all files have projects assigned (for multi-project experts/clients)
|
|
@@ -210,6 +215,15 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
210
215
|
return true;
|
|
211
216
|
return uploadItems.every((item) => { var _a; return (_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value; });
|
|
212
217
|
}, [uploadItems, hasMultipleProjects]);
|
|
218
|
+
// Count files that need projects
|
|
219
|
+
const filesNeedingProjects = react_1.default.useMemo(() => {
|
|
220
|
+
if (!selectedExpert)
|
|
221
|
+
return 0;
|
|
222
|
+
return uploadItems.filter((item) => { var _a; return !((_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) && item.status !== "success"; }).length;
|
|
223
|
+
}, [uploadItems, selectedExpert]);
|
|
224
|
+
// Determine step states
|
|
225
|
+
const step1Complete = selectedExpert !== null;
|
|
226
|
+
const step2Complete = step1Complete && uploadItems.length > 0 && allFilesHaveProjects;
|
|
213
227
|
const handleFilesSelected = (files) => {
|
|
214
228
|
const newItems = files.map((file) => ({
|
|
215
229
|
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -411,78 +425,198 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
411
425
|
".jpg",
|
|
412
426
|
".png",
|
|
413
427
|
], disabled: isUploading })),
|
|
414
|
-
uploadItems.length > 0 &&
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
428
|
+
uploadItems.length > 0 && (react_1.default.createElement(core_1.Box, { mb: 3 },
|
|
429
|
+
react_1.default.createElement(core_1.Typography, { variant: "h5", style: {
|
|
430
|
+
fontWeight: 700,
|
|
431
|
+
color: "#1a1a2e",
|
|
432
|
+
marginBottom: "4px",
|
|
433
|
+
} }, !paroDocuments
|
|
434
|
+
? isClientPortal
|
|
435
|
+
? "Send Files to Expert"
|
|
436
|
+
: "Send Files to Client"
|
|
437
|
+
: "Upload Documents"),
|
|
438
|
+
react_1.default.createElement(core_1.Typography, { variant: "body2", style: { color: "#8b8fa3" } }, "Choose a recipient, assign each file to a project, then upload."))),
|
|
439
|
+
!paroDocuments &&
|
|
440
|
+
expertGroups.length > 0 &&
|
|
441
|
+
uploadItems.length > 0 && (react_1.default.createElement(core_1.Paper, { elevation: 0, style: {
|
|
442
|
+
marginBottom: "24px",
|
|
443
|
+
borderRadius: "12px",
|
|
444
|
+
border: step1Complete
|
|
445
|
+
? "2px solid #248384"
|
|
446
|
+
: "2px solid #a8a8a8",
|
|
447
|
+
backgroundColor: step1Complete ? "#FDFEFD" : "#fafafa",
|
|
448
|
+
overflow: "hidden",
|
|
449
|
+
} },
|
|
450
|
+
react_1.default.createElement(core_1.Box, { p: 2, style: {
|
|
451
|
+
backgroundColor: step1Complete ? "#F0FAF0" : "#f7f7f9",
|
|
452
|
+
borderBottom: "1px solid #f0f0f5",
|
|
453
|
+
display: "flex",
|
|
454
|
+
alignItems: "center",
|
|
455
|
+
gap: "12px",
|
|
456
|
+
} },
|
|
418
457
|
react_1.default.createElement(core_1.Box, { style: {
|
|
419
|
-
width: "
|
|
420
|
-
height: "
|
|
458
|
+
width: "24px",
|
|
459
|
+
height: "24px",
|
|
421
460
|
borderRadius: "50%",
|
|
422
|
-
backgroundColor: "
|
|
423
|
-
color: "white",
|
|
461
|
+
backgroundColor: step1Complete ? "white" : "gray",
|
|
462
|
+
color: step1Complete ? "#248384" : "white",
|
|
424
463
|
display: "flex",
|
|
425
464
|
alignItems: "center",
|
|
426
465
|
justifyContent: "center",
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
: "
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
466
|
+
fontSize: "13px",
|
|
467
|
+
fontWeight: 700,
|
|
468
|
+
flexShrink: 0,
|
|
469
|
+
} }, step1Complete ? (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "28px" } })) : ("1")),
|
|
470
|
+
react_1.default.createElement(core_1.Box, null,
|
|
471
|
+
react_1.default.createElement(core_1.Typography, { variant: "subtitle1", style: {
|
|
472
|
+
fontSize: "14px",
|
|
473
|
+
fontWeight: 600,
|
|
474
|
+
color: "#1a1a2e",
|
|
475
|
+
} }, "Select recipient"),
|
|
476
|
+
react_1.default.createElement(core_1.Typography, { variant: "caption", style: { fontSize: "12px", color: "#8b8fa3" } }, "Who should receive these files?"))),
|
|
477
|
+
react_1.default.createElement(core_1.Box, { p: 2 },
|
|
478
|
+
react_1.default.createElement(core_1.Box, { display: "flex", flexWrap: "wrap", style: { gap: "10px" } }, expertGroups.map((group) => (react_1.default.createElement(core_1.Chip, { key: group.expert.id, label: react_1.default.createElement(core_1.Box, { display: "flex", alignItems: "center", style: { gap: "6px" } },
|
|
479
|
+
(selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id && (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "20px" } })),
|
|
480
|
+
react_1.default.createElement("span", { style: { fontWeight: 600 } }, group.expert.name),
|
|
481
|
+
react_1.default.createElement("span", { style: {
|
|
482
|
+
fontSize: "11px",
|
|
483
|
+
fontWeight: 500,
|
|
484
|
+
padding: "2px 7px",
|
|
485
|
+
borderRadius: "10px",
|
|
486
|
+
backgroundColor: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
|
|
487
|
+
? "#e2e8f0"
|
|
488
|
+
: "#f0f1f4",
|
|
489
|
+
color: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
|
|
490
|
+
? "#248384"
|
|
491
|
+
: "#8b8fa3",
|
|
492
|
+
} },
|
|
493
|
+
group.projects.length,
|
|
494
|
+
" ",
|
|
495
|
+
group.projects.length === 1
|
|
496
|
+
? "project"
|
|
497
|
+
: "projects")), onClick: () => handleExpertSelection(group.expert), clickable: true, disabled: group.projects.length === 0, style: {
|
|
498
|
+
padding: "10px 18px",
|
|
499
|
+
height: "auto",
|
|
500
|
+
borderRadius: "8px",
|
|
501
|
+
border: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
|
|
502
|
+
? "2px solid #248384"
|
|
503
|
+
: "2px solid #e2e4ea",
|
|
504
|
+
backgroundColor: "#fff",
|
|
505
|
+
color: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
|
|
506
|
+
? "#248384"
|
|
507
|
+
: "#3d3f4a",
|
|
508
|
+
opacity: group.projects.length === 0 ? 0.5 : 1,
|
|
509
|
+
cursor: group.projects.length === 0
|
|
510
|
+
? "not-allowed"
|
|
511
|
+
: "pointer",
|
|
512
|
+
} }))))))),
|
|
513
|
+
uploadItems.length > 0 && (react_1.default.createElement(core_1.Paper, { elevation: 0, style: {
|
|
514
|
+
marginBottom: "24px",
|
|
515
|
+
borderRadius: "12px",
|
|
516
|
+
border: step2Complete
|
|
517
|
+
? "2px solid #248384"
|
|
518
|
+
: !paroDocuments && !step1Complete
|
|
519
|
+
? "2px solid #e2e4ea"
|
|
520
|
+
: "2px solid #006cff",
|
|
521
|
+
backgroundColor: step2Complete
|
|
522
|
+
? "#FDFEFD"
|
|
523
|
+
: !paroDocuments && !step1Complete
|
|
524
|
+
? "#fafafa"
|
|
525
|
+
: "#ffffff",
|
|
526
|
+
overflow: "hidden",
|
|
527
|
+
opacity: !paroDocuments && !step1Complete ? 0.5 : 1,
|
|
528
|
+
pointerEvents: !paroDocuments && !step1Complete ? "none" : "auto",
|
|
529
|
+
} },
|
|
530
|
+
react_1.default.createElement(core_1.Box, { p: 2, style: {
|
|
531
|
+
backgroundColor: step2Complete
|
|
532
|
+
? "#F0FAF0"
|
|
533
|
+
: !paroDocuments && !step1Complete
|
|
534
|
+
? "#f7f7f9"
|
|
535
|
+
: "#f2f2f25e",
|
|
536
|
+
borderBottom: "1px solid #f0f0f5",
|
|
537
|
+
display: "flex",
|
|
538
|
+
alignItems: "center",
|
|
539
|
+
gap: "12px",
|
|
540
|
+
} },
|
|
541
|
+
react_1.default.createElement(core_1.Box, { style: {
|
|
542
|
+
width: "24px",
|
|
543
|
+
height: "24px",
|
|
544
|
+
borderRadius: "50%",
|
|
545
|
+
backgroundColor: step2Complete
|
|
546
|
+
? "white"
|
|
547
|
+
: !paroDocuments && !step1Complete
|
|
548
|
+
? "#ccc"
|
|
549
|
+
: "#006cff",
|
|
550
|
+
color: step2Complete ? "#248384" : "white",
|
|
551
|
+
display: "flex",
|
|
552
|
+
alignItems: "center",
|
|
553
|
+
justifyContent: "center",
|
|
554
|
+
fontSize: "13px",
|
|
555
|
+
fontWeight: 700,
|
|
556
|
+
flexShrink: 0,
|
|
557
|
+
} }, step2Complete ? (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "28px" } })) : paroDocuments ? ("1") : ("2")),
|
|
558
|
+
react_1.default.createElement(core_1.Box, { flex: 1 },
|
|
559
|
+
react_1.default.createElement(core_1.Typography, { variant: "subtitle1", style: {
|
|
560
|
+
fontSize: "14px",
|
|
561
|
+
fontWeight: 600,
|
|
562
|
+
color: "#1a1a2e",
|
|
563
|
+
} }, "Assign files to projects"),
|
|
564
|
+
react_1.default.createElement(core_1.Typography, { variant: "caption", style: { fontSize: "12px", color: "#8b8fa3" } }, "Categorize each file and select its project")),
|
|
565
|
+
!paroDocuments && filesNeedingProjects > 0 && (react_1.default.createElement(core_1.Chip, { label: `${filesNeedingProjects} need${filesNeedingProjects === 1 ? "s" : ""} a project`, size: "small", style: {
|
|
566
|
+
fontSize: "11px",
|
|
469
567
|
fontWeight: 600,
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
568
|
+
padding: "4px 10px",
|
|
569
|
+
backgroundColor: "#FFF3E0",
|
|
570
|
+
color: "#E65100",
|
|
571
|
+
} }))),
|
|
572
|
+
react_1.default.createElement(core_1.Box, { p: 2 },
|
|
474
573
|
react_1.default.createElement(core_1.Grid, { container: true, spacing: 2 }, uploadItems.map((item, index) => {
|
|
475
|
-
var _a;
|
|
574
|
+
var _a, _b, _c;
|
|
575
|
+
const needsProject = !paroDocuments && !((_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value);
|
|
476
576
|
return (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, key: item.id },
|
|
477
577
|
react_1.default.createElement(core_1.Paper, { elevation: 1, style: {
|
|
478
578
|
padding: "12px 16px",
|
|
479
|
-
backgroundColor: "white",
|
|
480
|
-
border:
|
|
481
|
-
|
|
579
|
+
backgroundColor: needsProject ? "#FFFBF5" : "white",
|
|
580
|
+
border: needsProject
|
|
581
|
+
? "2px solid #FFE0B2"
|
|
582
|
+
: "1.5px solid #f0f1f4",
|
|
583
|
+
borderRadius: "10px",
|
|
482
584
|
} },
|
|
483
585
|
react_1.default.createElement(core_1.Grid, { container: true, spacing: 2 },
|
|
484
|
-
react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: "auto", style: {
|
|
485
|
-
|
|
586
|
+
react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: "auto", style: {
|
|
587
|
+
display: "flex",
|
|
588
|
+
alignItems: "center",
|
|
589
|
+
} },
|
|
590
|
+
react_1.default.createElement(core_1.Box, { style: {
|
|
591
|
+
width: "36px",
|
|
592
|
+
height: "42px",
|
|
593
|
+
borderRadius: "4px",
|
|
594
|
+
display: "flex",
|
|
595
|
+
alignItems: "flex-end",
|
|
596
|
+
justifyContent: "center",
|
|
597
|
+
paddingBottom: "4px",
|
|
598
|
+
fontSize: "10px",
|
|
599
|
+
fontWeight: 700,
|
|
600
|
+
letterSpacing: "0.5px",
|
|
601
|
+
textTransform: "uppercase",
|
|
602
|
+
backgroundColor: item.file.name.endsWith(".csv")
|
|
603
|
+
? "#E8F5E9"
|
|
604
|
+
: item.file.name.endsWith(".pdf")
|
|
605
|
+
? "#FFF3E0"
|
|
606
|
+
: "#E3F2FD",
|
|
607
|
+
border: item.file.name.endsWith(".csv")
|
|
608
|
+
? "1.5px solid #A5D6A7"
|
|
609
|
+
: item.file.name.endsWith(".pdf")
|
|
610
|
+
? "1.5px solid #FFCC80"
|
|
611
|
+
: "1.5px solid #90CAF9",
|
|
612
|
+
color: item.file.name.endsWith(".csv")
|
|
613
|
+
? "#248384"
|
|
614
|
+
: item.file.name.endsWith(".pdf")
|
|
615
|
+
? "#E65100"
|
|
616
|
+
: "#1976D2",
|
|
617
|
+
} }, ((_b = item.file.name
|
|
618
|
+
.split(".")
|
|
619
|
+
.pop()) === null || _b === void 0 ? void 0 : _b.toUpperCase()) || "FILE")),
|
|
486
620
|
react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: true },
|
|
487
621
|
react_1.default.createElement(base_ui_1.Input, { type: "text", value: item.documentName, onChange: (e) => updateItem(item.id, {
|
|
488
622
|
documentName: e.target.value,
|
|
@@ -511,7 +645,8 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
511
645
|
}
|
|
512
646
|
}, options: documentTypeOptions, disabled: item.status === "uploading" ||
|
|
513
647
|
item.status === "success", required: false })),
|
|
514
|
-
paroDocuments &&
|
|
648
|
+
paroDocuments &&
|
|
649
|
+
item.docType === "EO Insurance" && (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: 3, style: { marginTop: "5px" } },
|
|
515
650
|
react_1.default.createElement(core_1.TextField, { type: "date", label: "Expiration Date", value: item.expiryDate
|
|
516
651
|
? new Date(item.expiryDate)
|
|
517
652
|
.toISOString()
|
|
@@ -546,7 +681,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
546
681
|
}, disabled: item.status === "uploading" ||
|
|
547
682
|
item.status === "success", fullWidth: true, variant: "outlined", size: "small", required: true, error: !!item.dateError, helperText: item.dateError }))),
|
|
548
683
|
!paroDocuments && !hasSingleProject && (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: 3 },
|
|
549
|
-
react_1.default.createElement(base_ui_1.Select, { value: ((
|
|
684
|
+
react_1.default.createElement(base_ui_1.Select, { value: ((_c = item.clientAndProject) === null || _c === void 0 ? void 0 : _c.value) || "", onChange: (e) => {
|
|
550
685
|
// Handle empty selection
|
|
551
686
|
if (e.target.value === "") {
|
|
552
687
|
updateItem(item.id, {
|
|
@@ -562,7 +697,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
562
697
|
{
|
|
563
698
|
id: "placeholder",
|
|
564
699
|
value: "",
|
|
565
|
-
label: "
|
|
700
|
+
label: "Select project",
|
|
566
701
|
},
|
|
567
702
|
...filteredProjectOptions,
|
|
568
703
|
], disabled: item.status === "uploading" ||
|
|
@@ -585,55 +720,19 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
|
|
|
585
720
|
react_1.default.createElement(core_1.Typography, { variant: "caption", style: { color: "#38A169" } }, "\u2713 Upload successful"))),
|
|
586
721
|
item.status === "error" && (react_1.default.createElement(core_1.Box, { mt: 1, ml: { xs: 0, sm: 6 } },
|
|
587
722
|
react_1.default.createElement(core_1.Typography, { variant: "caption", style: { color: "#E53E3E" } }, "\u2717 Upload failed"))))));
|
|
588
|
-
}))),
|
|
589
|
-
|
|
590
|
-
react_1.default.createElement(
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
.length),
|
|
602
|
-
" ",
|
|
603
|
-
"files \u2022",
|
|
604
|
-
" ",
|
|
605
|
-
react_1.default.createElement("span", { style: { color: "#718096" } },
|
|
606
|
-
react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => {
|
|
607
|
-
var _a;
|
|
608
|
-
return ((_a = i.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) &&
|
|
609
|
-
i.status !== "success";
|
|
610
|
-
}).length),
|
|
611
|
-
" ",
|
|
612
|
-
"project-assigned"),
|
|
613
|
-
" ",
|
|
614
|
-
"\u2022",
|
|
615
|
-
" ",
|
|
616
|
-
react_1.default.createElement("span", { style: { color: "#D97706" } },
|
|
617
|
-
react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => {
|
|
618
|
-
var _a;
|
|
619
|
-
return !((_a = i.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) &&
|
|
620
|
-
i.status !== "success";
|
|
621
|
-
}).length),
|
|
622
|
-
" ",
|
|
623
|
-
"need project"))))),
|
|
624
|
-
react_1.default.createElement(core_1.Box, null,
|
|
625
|
-
react_1.default.createElement(core_1.Box, { component: "span", ml: 1 },
|
|
626
|
-
react_1.default.createElement(base_ui_1.Button, { label: isUploading
|
|
627
|
-
? "Uploading..."
|
|
628
|
-
: `Upload ${uploadItems.filter((i) => i.status !== "success").length} Files`, onClick: handleUploadAll, disabled: uploadItems.length === 0 ||
|
|
629
|
-
isUploading ||
|
|
630
|
-
uploadItems.every((i) => i.status === "success") ||
|
|
631
|
-
(!paroDocuments && !selectedExpert) ||
|
|
632
|
-
(hasMultipleProjects && !allFilesHaveProjects) ||
|
|
633
|
-
uploadItems.some((i) => paroDocuments &&
|
|
634
|
-
i.docType === "EO Insurance" &&
|
|
635
|
-
(!i.expiryDate || !!i.dateError) &&
|
|
636
|
-
i.status !== "success"), color: "primary", isLoading: isUploading }))))))))));
|
|
723
|
+
}))))),
|
|
724
|
+
uploadItems.length > 0 && (react_1.default.createElement(core_1.Box, { display: "flex", justifyContent: "flex-end" },
|
|
725
|
+
react_1.default.createElement(base_ui_1.Button, { label: isUploading
|
|
726
|
+
? "Uploading..."
|
|
727
|
+
: `Upload ${uploadItems.filter((i) => i.status !== "success").length} File${uploadItems.filter((i) => i.status !== "success").length !== 1 ? "s" : ""}`, onClick: handleUploadAll, disabled: uploadItems.length === 0 ||
|
|
728
|
+
isUploading ||
|
|
729
|
+
uploadItems.every((i) => i.status === "success") ||
|
|
730
|
+
(!paroDocuments && !selectedExpert) ||
|
|
731
|
+
(hasMultipleProjects && !allFilesHaveProjects) ||
|
|
732
|
+
uploadItems.some((i) => paroDocuments &&
|
|
733
|
+
i.docType === "EO Insurance" &&
|
|
734
|
+
(!i.expiryDate || !!i.dateError) &&
|
|
735
|
+
i.status !== "success"), color: "primary", isLoading: isUploading })))))));
|
|
637
736
|
};
|
|
638
737
|
exports.MultiFileUploadSection = MultiFileUploadSection;
|
|
639
738
|
exports.default = exports.MultiFileUploadSection;
|
|
@@ -47,6 +47,7 @@ export type TaxAxisApi = {
|
|
|
47
47
|
runLlm: (sessionId: string) => Promise<any>;
|
|
48
48
|
runEval: (llmRunId: string) => Promise<any>;
|
|
49
49
|
runReportGateways: (sessionId: string) => Promise<any>;
|
|
50
|
+
getLlmRun?: (sessionId: string, runType?: string) => Promise<any>;
|
|
50
51
|
getReports: (sessionId: string) => Promise<any[]>;
|
|
51
52
|
updateReport: (reportId: string, reviewedReport: Record<string, unknown>) => Promise<any>;
|
|
52
53
|
generatePdf: (sessionId: string) => Promise<any>;
|
|
@@ -46,6 +46,7 @@ const TaxAxisExtractionReview_1 = require("../../tax-axis/components/extractionR
|
|
|
46
46
|
const TaxAxisClientReport_1 = require("../../tax-axis/components/clientReport/TaxAxisClientReport");
|
|
47
47
|
const TaxAxisPreparerWorkpaper_1 = require("../../tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper");
|
|
48
48
|
const TaxAxisPresentationMode_1 = require("../../tax-axis/components/presentationMode/TaxAxisPresentationMode");
|
|
49
|
+
const useEngineOutput_1 = require("../../tax-axis/lib/adapters/useEngineOutput");
|
|
49
50
|
const UploadClient_1 = __importDefault(require("../shared/UploadClient"));
|
|
50
51
|
function sleep(ms) {
|
|
51
52
|
return new Promise((resolve) => {
|
|
@@ -56,6 +57,20 @@ function toInt(value) {
|
|
|
56
57
|
const parsed = Number(String(value || '0').replace(/[^\d.-]/g, ''));
|
|
57
58
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
58
59
|
}
|
|
60
|
+
const ENTITY_DISPLAY_TO_KEY = {
|
|
61
|
+
'S-Corporation': 'S_CORP',
|
|
62
|
+
'C-Corporation': 'C_CORP',
|
|
63
|
+
'LLC': 'LLC',
|
|
64
|
+
'Partnership': 'PARTNERSHIP',
|
|
65
|
+
'Sole Proprietor': 'SOLE_PROP',
|
|
66
|
+
'Sole Proprietorship': 'SOLE_PROP',
|
|
67
|
+
};
|
|
68
|
+
function entityTypeKey(entity) {
|
|
69
|
+
var _a;
|
|
70
|
+
if (!entity)
|
|
71
|
+
return undefined;
|
|
72
|
+
return (_a = ENTITY_DISPLAY_TO_KEY[entity]) !== null && _a !== void 0 ? _a : entity;
|
|
73
|
+
}
|
|
59
74
|
function buildSessionInput(profile) {
|
|
60
75
|
const taxYear = Number(profile.year) || new Date().getFullYear();
|
|
61
76
|
return {
|
|
@@ -87,6 +102,25 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
87
102
|
const [isBusy, setIsBusy] = (0, react_1.useState)(false);
|
|
88
103
|
const [error, setError] = (0, react_1.useState)(null);
|
|
89
104
|
const [busyMessage, setBusyMessage] = (0, react_1.useState)('Syncing Tax Axis session...');
|
|
105
|
+
// Derive live strategies from engineOutput so CLIENT_REPORT and PREPARER_WORKPAPER
|
|
106
|
+
// render real engine data instead of the static STRATEGIES catalog.
|
|
107
|
+
const engineOutput = (0, react_1.useMemo)(() => { var _a; return (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput) !== null && _a !== void 0 ? _a : null; }, [llmResult]);
|
|
108
|
+
const adapted = (0, useEngineOutput_1.useEngineOutput)(engineOutput);
|
|
109
|
+
// On mount: if a sessionId was injected (e.g. returning to an existing session),
|
|
110
|
+
// reload the last GENERATION llmRun so the report screens get live data.
|
|
111
|
+
(0, react_1.useEffect)(() => {
|
|
112
|
+
if (!initialSessionId || !taxAxisApi.getLlmRun)
|
|
113
|
+
return;
|
|
114
|
+
taxAxisApi.getLlmRun(initialSessionId, 'GENERATION')
|
|
115
|
+
.then((run) => {
|
|
116
|
+
if (run === null || run === void 0 ? void 0 : run.outputPayload) {
|
|
117
|
+
setLlmResult(run.outputPayload);
|
|
118
|
+
setStep('DASHBOARD');
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
.catch(() => { });
|
|
122
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
123
|
+
}, [initialSessionId]);
|
|
90
124
|
const updateSessionId = (0, react_1.useCallback)((nextSessionId) => {
|
|
91
125
|
setSessionId(nextSessionId);
|
|
92
126
|
if (onSessionChange) {
|
|
@@ -138,7 +172,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
138
172
|
setStep('DOCUMENT_UPLOAD');
|
|
139
173
|
}), [createSessionIfNeeded]);
|
|
140
174
|
const handleUploadDocument = (0, react_1.useCallback)((doc, file) => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
-
var _a;
|
|
175
|
+
var _a, _b;
|
|
142
176
|
const ensuredSessionId = sessionId || (profile ? yield createSessionIfNeeded(profile) : null);
|
|
143
177
|
if (!ensuredSessionId) {
|
|
144
178
|
throw new Error('Unable to upload without a session.');
|
|
@@ -168,7 +202,9 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
168
202
|
fileName: file.name,
|
|
169
203
|
fileType: file.type || 'application/octet-stream',
|
|
170
204
|
fileSize: file.size,
|
|
171
|
-
|
|
205
|
+
// doc.documentType is the canonical lowercase snake-case key (e.g. "profit_loss").
|
|
206
|
+
// doc.id equals doc.documentType for the v2 catalog.
|
|
207
|
+
documentType: (_b = doc.documentType) !== null && _b !== void 0 ? _b : doc.id,
|
|
172
208
|
s3Key: uploadClient.state.fileName,
|
|
173
209
|
};
|
|
174
210
|
return taxAxisApi.uploadFile(uploadInput);
|
|
@@ -252,19 +288,25 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
252
288
|
react_1.default.createElement(TaxAxisProspectReport_1.TaxAxisProspectReport, { profile: profile, userContext: userContext, onUpgrade: () => setStep('DOCUMENT_UPLOAD'), onPresent: () => setStep('PRESENTATION'), onReset: handleReset })));
|
|
253
289
|
case 'DOCUMENT_UPLOAD':
|
|
254
290
|
return (react_1.default.createElement(ShellContainer, null,
|
|
255
|
-
react_1.default.createElement(TaxAxisDocuments_1.TaxAxisDocuments, { profile: profile, userContext: userContext, onUploadDocument: handleUploadDocument, onDeleteDocument: handleDeleteDocument, fetchUploadedDocuments: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
291
|
+
react_1.default.createElement(TaxAxisDocuments_1.TaxAxisDocuments, { profile: profile, entityType: entityTypeKey(profile.entity), userContext: userContext, onUploadDocument: handleUploadDocument, onDeleteDocument: handleDeleteDocument, fetchUploadedDocuments: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
256
292
|
const ensuredSessionId = sessionId || (profile ? yield createSessionIfNeeded(profile) : null);
|
|
257
293
|
if (!ensuredSessionId) {
|
|
258
294
|
return [];
|
|
259
295
|
}
|
|
260
296
|
const docs = yield taxAxisApi.getDocuments(ensuredSessionId);
|
|
261
|
-
return docs.map((doc) =>
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
297
|
+
return docs.map((doc) => {
|
|
298
|
+
var _a;
|
|
299
|
+
return ({
|
|
300
|
+
fileName: doc.fileName,
|
|
301
|
+
status: doc.status,
|
|
302
|
+
documentType: doc.documentType,
|
|
303
|
+
parseError: doc.parseError,
|
|
304
|
+
updatedAt: doc.updatedAt,
|
|
305
|
+
parsedData: (_a = doc.parsedData) !== null && _a !== void 0 ? _a : null,
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
}), jobId: sessionId || undefined, onSaveReviewedField: (documentId, reviewedData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
309
|
+
yield taxAxisApi.saveReviewedData(documentId, reviewedData);
|
|
268
310
|
}), onContinue: handleAnalyzeDocuments, onBack: () => isProspectFlow ? setStep('PROSPECT_REPORT') : setStep('SESSION_SETUP') })));
|
|
269
311
|
case 'PROCESSING':
|
|
270
312
|
return (react_1.default.createElement(ShellContainer, null,
|
|
@@ -277,10 +319,10 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
277
319
|
react_1.default.createElement(TaxAxisDashboard_1.TaxAxisDashboard, { profile: profile, userContext: userContext, llmResult: llmResult, onDownloadClient: () => setStep('CLIENT_REPORT'), onDownloadPreparer: () => setStep('PREPARER_WORKPAPER'), onPresent: () => setStep('PRESENTATION'), onSend: handleSendReport, onReviewData: () => setStep('PARSED_REVIEW'), onReset: handleReset })));
|
|
278
320
|
case 'CLIENT_REPORT':
|
|
279
321
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
280
|
-
react_1.default.createElement(TaxAxisClientReport_1.TaxAxisClientReport, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onNavigatePreparer: () => setStep('PREPARER_WORKPAPER') })));
|
|
322
|
+
react_1.default.createElement(TaxAxisClientReport_1.TaxAxisClientReport, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onNavigatePreparer: () => setStep('PREPARER_WORKPAPER'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap })));
|
|
281
323
|
case 'PREPARER_WORKPAPER':
|
|
282
324
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
283
|
-
react_1.default.createElement(TaxAxisPreparerWorkpaper_1.TaxAxisPreparerWorkpaper, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onToggleToClient: () => setStep('CLIENT_REPORT') })));
|
|
325
|
+
react_1.default.createElement(TaxAxisPreparerWorkpaper_1.TaxAxisPreparerWorkpaper, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onToggleToClient: () => setStep('CLIENT_REPORT'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap })));
|
|
284
326
|
case 'PRESENTATION':
|
|
285
327
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
286
328
|
react_1.default.createElement(TaxAxisPresentationMode_1.TaxAxisPresentationMode, { profile: profile, userContext: userContext, onBack: () => setStep(isProspectFlow ? 'PROSPECT_REPORT' : 'DASHBOARD') })));
|
|
@@ -301,6 +343,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
301
343
|
handleReset,
|
|
302
344
|
handleSendReport,
|
|
303
345
|
llmResult,
|
|
346
|
+
adapted,
|
|
304
347
|
]);
|
|
305
348
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
306
349
|
error && (react_1.default.createElement("div", { className: 'fixed right-4 top-4 z-[200] max-w-sm rounded-lg border border-red-500/30 bg-tax-axis-surface px-4 py-3 text-xs text-red-200 shadow-lg' },
|
package/lib/index.d.ts
CHANGED
|
@@ -15,19 +15,6 @@ 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
|
|
19
|
-
export { SectionHeader } from './tax-axis';
|
|
20
|
-
export { TaxAxisBadge } from './tax-axis';
|
|
21
|
-
export { TaxAxisButton } from './tax-axis';
|
|
22
|
-
export { TaxAxisCard } from './tax-axis';
|
|
23
|
-
export { TaxAxisIntake } from './tax-axis';
|
|
24
|
-
export { TaxAxisDocuments } from './tax-axis';
|
|
25
|
-
export { TaxAxisProcessing } from './tax-axis';
|
|
26
|
-
export { TaxAxisDashboard } from './tax-axis';
|
|
27
|
-
export { TaxAxisClientReport } from './tax-axis';
|
|
28
|
-
export { TaxAxisPreparerWorkpaper } from './tax-axis';
|
|
29
|
-
export { TaxAxisExtractionReview } from './tax-axis';
|
|
30
|
-
export { TaxAxisProspectReport } from './tax-axis';
|
|
31
|
-
export { TaxAxisPresentationMode } from './tax-axis';
|
|
18
|
+
export { ProjectIntelligence } from "./components/ProjectIntelligence";
|
|
32
19
|
export { TaxAxisShell } from './components/TaxAxis';
|
|
33
20
|
export type { TaxAxisApi, TaxAxisSessionInput, TaxAxisUploadInput } from './components/TaxAxis';
|