@evenicanpm/portal-table-ui 2.1.0 → 2.2.2
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/package.json +2 -2
- package/src/features/table/components/dashboard/table/details/details.tsx +18 -3
- package/src/features/table/components/dashboard/table/details/templates/invoice-details.tsx +86 -24
- package/src/features/table/components/dashboard/table/table.tsx +15 -1
- package/src/features/table/components/dashboard/table-dashboard.tsx +20 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evenicanpm/portal-table-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"@tanstack/react-query": "^5.90.11",
|
|
48
48
|
"date-fns": "^4.1.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "eb81763cdb511681ffaf1da5140e957afa149816"
|
|
51
51
|
}
|
|
@@ -87,13 +87,28 @@ const Details = ({
|
|
|
87
87
|
mb={2}
|
|
88
88
|
height="100%"
|
|
89
89
|
>
|
|
90
|
-
<Button
|
|
90
|
+
<Button
|
|
91
|
+
onClick={handleBack}
|
|
92
|
+
startIcon={<ArrowBackIcon />}
|
|
93
|
+
sx={{ "@media print": { display: "none" } }}
|
|
94
|
+
>
|
|
91
95
|
{documentTypeLabel}
|
|
92
96
|
</Button>
|
|
93
|
-
<H6 color="grey.800">
|
|
97
|
+
<H6 color="grey.800" sx={{ "@media print": { display: "none" } }}>
|
|
94
98
|
{documentTypeLabel}-{id}
|
|
95
99
|
</H6>
|
|
96
|
-
<
|
|
100
|
+
<H6
|
|
101
|
+
color="grey.800"
|
|
102
|
+
sx={{
|
|
103
|
+
display: "none",
|
|
104
|
+
"@media print": { display: "inline-block" },
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
{documentTypeLabel.slice(0, documentTypeLabel.length - 1)} #{id}
|
|
108
|
+
</H6>
|
|
109
|
+
<Subtitle sx={{ "@media print": { display: "none" } }}>
|
|
110
|
+
DETAILS
|
|
111
|
+
</Subtitle>
|
|
97
112
|
</FlexBox>
|
|
98
113
|
</Box>
|
|
99
114
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import FlagIcon from "@mui/icons-material/Flag";
|
|
3
3
|
import {
|
|
4
4
|
Box,
|
|
5
|
+
Button,
|
|
5
6
|
Card,
|
|
6
7
|
Divider,
|
|
7
8
|
Paper,
|
|
@@ -79,6 +80,12 @@ interface InvoiceData {
|
|
|
79
80
|
OrderedByCustomerName?: string;
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
interface TableColumn {
|
|
84
|
+
label: string;
|
|
85
|
+
width: number;
|
|
86
|
+
aligned: "inherit" | "left" | "center" | "right" | "justify";
|
|
87
|
+
}
|
|
88
|
+
|
|
82
89
|
const detailSkeletonKeys = ["from", "bill-to", "invoice-date", "due-date"];
|
|
83
90
|
const tableSkeletonRowKeys = ["line-1", "line-2", "line-3", "line-4"];
|
|
84
91
|
const totalSkeletonKeys = ["subtotal", "tax", "total"];
|
|
@@ -133,15 +140,15 @@ export const InvoiceDetailsTemplate = ({
|
|
|
133
140
|
const total = invoice?.Amount ?? 0;
|
|
134
141
|
|
|
135
142
|
// Fixed column definitions with specific widths
|
|
136
|
-
const columns = [
|
|
137
|
-
{ label: "#", width: 60 },
|
|
138
|
-
{ label: "Product", width: 200 },
|
|
139
|
-
{ label: "Qty", width: 60 },
|
|
140
|
-
{ label: "Unit", width: 60 },
|
|
141
|
-
{ label: "Unit Price", width: 120 },
|
|
142
|
-
{ label: "Discount", width: 100 },
|
|
143
|
-
{ label: "Line Total", width: 120 },
|
|
144
|
-
{ label: "", width: 40 },
|
|
143
|
+
const columns: TableColumn[] = [
|
|
144
|
+
{ label: "#", width: 60, aligned: "left" },
|
|
145
|
+
{ label: "Product", width: 200, aligned: "left" },
|
|
146
|
+
{ label: "Qty", width: 60, aligned: "right" },
|
|
147
|
+
{ label: "Unit", width: 60, aligned: "right" },
|
|
148
|
+
{ label: "Unit Price", width: 120, aligned: "right" },
|
|
149
|
+
{ label: "Discount", width: 100, aligned: "right" },
|
|
150
|
+
{ label: "Line Total", width: 120, aligned: "right" },
|
|
151
|
+
{ label: "", width: 40, aligned: "center" },
|
|
145
152
|
];
|
|
146
153
|
|
|
147
154
|
// Calculate total width for table container
|
|
@@ -221,8 +228,19 @@ export const InvoiceDetailsTemplate = ({
|
|
|
221
228
|
);
|
|
222
229
|
}
|
|
223
230
|
|
|
231
|
+
function handleOnClick() {
|
|
232
|
+
window.print();
|
|
233
|
+
}
|
|
234
|
+
|
|
224
235
|
return (
|
|
225
|
-
<Box
|
|
236
|
+
<Box
|
|
237
|
+
sx={{
|
|
238
|
+
p: { xs: 2, sm: 3 },
|
|
239
|
+
width: containerWidth,
|
|
240
|
+
mx: "auto",
|
|
241
|
+
"@media print": { p: 0, width: "100%" },
|
|
242
|
+
}}
|
|
243
|
+
>
|
|
226
244
|
{/* Header */}
|
|
227
245
|
<Box
|
|
228
246
|
display="flex"
|
|
@@ -239,7 +257,12 @@ export const InvoiceDetailsTemplate = ({
|
|
|
239
257
|
statusTextMap={statusTextMap}
|
|
240
258
|
/>
|
|
241
259
|
)}
|
|
242
|
-
<Box
|
|
260
|
+
<Box
|
|
261
|
+
display="flex"
|
|
262
|
+
gap={2}
|
|
263
|
+
alignItems="center"
|
|
264
|
+
sx={{ "@media print": { display: "none" } }}
|
|
265
|
+
>
|
|
243
266
|
{actions?.map((action) => {
|
|
244
267
|
const enabled = !action.isEnabled || action.isEnabled(row);
|
|
245
268
|
if (!enabled) {
|
|
@@ -263,14 +286,26 @@ export const InvoiceDetailsTemplate = ({
|
|
|
263
286
|
/>
|
|
264
287
|
);
|
|
265
288
|
})}
|
|
289
|
+
<Button
|
|
290
|
+
onClick={handleOnClick}
|
|
291
|
+
variant="outlined"
|
|
292
|
+
size="small"
|
|
293
|
+
sx={{ "@media print": { display: "none" } }}
|
|
294
|
+
>
|
|
295
|
+
Print Invoice
|
|
296
|
+
</Button>
|
|
266
297
|
</Box>
|
|
267
298
|
</Box>
|
|
268
299
|
|
|
269
300
|
{/* Notes Section */}
|
|
270
301
|
{invoice?.Notes && (
|
|
271
302
|
<Card
|
|
272
|
-
|
|
273
|
-
|
|
303
|
+
sx={{
|
|
304
|
+
p: { xs: 2, sm: 3 },
|
|
305
|
+
borderRadius: 3,
|
|
306
|
+
mb: 3,
|
|
307
|
+
"@media print": { border: "none", boxShadow: "none", p: 0 },
|
|
308
|
+
}}
|
|
274
309
|
>
|
|
275
310
|
<Typography variant="subtitle1" color="text.secondary" mb={1}>
|
|
276
311
|
Notes
|
|
@@ -286,7 +321,13 @@ export const InvoiceDetailsTemplate = ({
|
|
|
286
321
|
)}
|
|
287
322
|
|
|
288
323
|
{/* Main Invoice Card */}
|
|
289
|
-
<Card
|
|
324
|
+
<Card
|
|
325
|
+
sx={{
|
|
326
|
+
p: { xs: 2, sm: 3 },
|
|
327
|
+
borderRadius: 3,
|
|
328
|
+
"@media print": { border: "none", boxShadow: "none", p: 0 },
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
290
331
|
{/* Details Section */}
|
|
291
332
|
{(invoice?.CompanyName ||
|
|
292
333
|
invoice?.Name ||
|
|
@@ -400,7 +441,17 @@ export const InvoiceDetailsTemplate = ({
|
|
|
400
441
|
{items.length > 0 ? (
|
|
401
442
|
<>
|
|
402
443
|
<TableContainer>
|
|
403
|
-
<Table
|
|
444
|
+
<Table
|
|
445
|
+
sx={{
|
|
446
|
+
minWidth: totalTableWidth,
|
|
447
|
+
"@media print": {
|
|
448
|
+
p: 0,
|
|
449
|
+
scrollbarWidth: "none !important",
|
|
450
|
+
msOverflowStyle: "none !important",
|
|
451
|
+
overflow: "visible !important",
|
|
452
|
+
},
|
|
453
|
+
}}
|
|
454
|
+
>
|
|
404
455
|
<TableHead>
|
|
405
456
|
<TableRow>
|
|
406
457
|
{columns.map((col) => (
|
|
@@ -412,6 +463,7 @@ export const InvoiceDetailsTemplate = ({
|
|
|
412
463
|
fontWeight: 600,
|
|
413
464
|
backgroundColor: theme.palette.background.paper,
|
|
414
465
|
}}
|
|
466
|
+
align={col.aligned}
|
|
415
467
|
>
|
|
416
468
|
<Typography variant="body2" fontWeight={600}>
|
|
417
469
|
{col.label}
|
|
@@ -435,29 +487,35 @@ export const InvoiceDetailsTemplate = ({
|
|
|
435
487
|
].join("-");
|
|
436
488
|
|
|
437
489
|
return (
|
|
438
|
-
<TableRow key={
|
|
439
|
-
<TableCell
|
|
490
|
+
<TableRow key={`${item.ItemId}-${idx}`}>
|
|
491
|
+
<TableCell
|
|
492
|
+
sx={{
|
|
493
|
+
width: "100%",
|
|
494
|
+
textAlign: "left",
|
|
495
|
+
"@media print": { width: 60, px: 1 },
|
|
496
|
+
}}
|
|
497
|
+
>
|
|
440
498
|
<Typography variant="body2">
|
|
441
499
|
{item?.ItemId || idx + 1}
|
|
442
500
|
</Typography>
|
|
443
501
|
</TableCell>
|
|
444
|
-
<TableCell sx={{ width:
|
|
502
|
+
<TableCell sx={{ width: "100%", textAlign: "left" }}>
|
|
445
503
|
<Typography variant="body2">{productName}</Typography>
|
|
446
504
|
</TableCell>
|
|
447
|
-
<TableCell sx={{ width:
|
|
505
|
+
<TableCell sx={{ width: "100%", textAlign: "right" }}>
|
|
448
506
|
<Typography variant="body2">{quantity}</Typography>
|
|
449
507
|
</TableCell>
|
|
450
|
-
<TableCell sx={{ width:
|
|
508
|
+
<TableCell sx={{ width: "100%", textAlign: "right" }}>
|
|
451
509
|
<Typography variant="body2">
|
|
452
510
|
{item?.UnitOfMeasure || "—"}
|
|
453
511
|
</Typography>
|
|
454
512
|
</TableCell>
|
|
455
|
-
<TableCell sx={{ width:
|
|
513
|
+
<TableCell sx={{ width: "100%", textAlign: "right" }}>
|
|
456
514
|
<Typography variant="body2">
|
|
457
515
|
{formatCurrency(unitPrice)}
|
|
458
516
|
</Typography>
|
|
459
517
|
</TableCell>
|
|
460
|
-
<TableCell sx={{ width: 100,
|
|
518
|
+
<TableCell sx={{ width: "100%", textAlign: "right" }}>
|
|
461
519
|
<Typography
|
|
462
520
|
variant="body2"
|
|
463
521
|
color={
|
|
@@ -469,13 +527,17 @@ export const InvoiceDetailsTemplate = ({
|
|
|
469
527
|
: formatCurrency(0)}
|
|
470
528
|
</Typography>
|
|
471
529
|
</TableCell>
|
|
472
|
-
<TableCell sx={{ width: 100,
|
|
530
|
+
<TableCell sx={{ width: "100%", textAlign: "right" }}>
|
|
473
531
|
<Typography variant="body2" fontWeight={500}>
|
|
474
532
|
{formatCurrency(lineTotal)}
|
|
475
533
|
</Typography>
|
|
476
534
|
</TableCell>
|
|
477
535
|
<TableCell
|
|
478
|
-
sx={{
|
|
536
|
+
sx={{
|
|
537
|
+
width: "100%",
|
|
538
|
+
textAlign: "center",
|
|
539
|
+
"@media print": { width: "auto", minWidth: 0 },
|
|
540
|
+
}}
|
|
479
541
|
align="center"
|
|
480
542
|
>
|
|
481
543
|
{item.HasDiscount && (
|
|
@@ -32,6 +32,11 @@ export type DocumentTableProps = {
|
|
|
32
32
|
queryKey: QueryKey;
|
|
33
33
|
queryFn: () => Promise<Types.Queries.TableConfig>;
|
|
34
34
|
};
|
|
35
|
+
|
|
36
|
+
selectedDocument?: string | number | null;
|
|
37
|
+
setSelectedDocument?: React.Dispatch<
|
|
38
|
+
React.SetStateAction<string | number | null>
|
|
39
|
+
>;
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -44,11 +49,20 @@ export default function DocumentTable({
|
|
|
44
49
|
pageSize,
|
|
45
50
|
setPageSize,
|
|
46
51
|
viewConfigQuery,
|
|
52
|
+
selectedDocument: selectedDocumentProp,
|
|
53
|
+
setSelectedDocument: setSelectedDocumentProp,
|
|
47
54
|
}: Readonly<DocumentTableProps>) {
|
|
48
55
|
const [page, setPage] = useState(0);
|
|
49
|
-
const [
|
|
56
|
+
const [selectedDocumentLocal, setSelectedDocumentLocal] = useState<
|
|
50
57
|
string | number | null
|
|
51
58
|
>(null);
|
|
59
|
+
|
|
60
|
+
const selectedDocument =
|
|
61
|
+
selectedDocumentProp !== undefined
|
|
62
|
+
? selectedDocumentProp
|
|
63
|
+
: selectedDocumentLocal;
|
|
64
|
+
const setSelectedDocument =
|
|
65
|
+
setSelectedDocumentProp ?? setSelectedDocumentLocal;
|
|
52
66
|
const [filters, setFilters] = useState<Record<string, string>>({});
|
|
53
67
|
const [searchTerm, setSearchTerm] = useState("");
|
|
54
68
|
|
|
@@ -19,6 +19,11 @@ export interface TableProps {
|
|
|
19
19
|
queryFn: () => Promise<Types.Queries.TableConfig>;
|
|
20
20
|
};
|
|
21
21
|
resources: Types.Schemas.Resource[];
|
|
22
|
+
|
|
23
|
+
selectedDocument?: string | number | null;
|
|
24
|
+
setSelectedDocument?: React.Dispatch<
|
|
25
|
+
React.SetStateAction<string | number | null>
|
|
26
|
+
>;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
/**
|
|
@@ -28,7 +33,12 @@ export interface TableProps {
|
|
|
28
33
|
*
|
|
29
34
|
* @params props
|
|
30
35
|
*/
|
|
31
|
-
export const TableDashboard = ({
|
|
36
|
+
export const TableDashboard = ({
|
|
37
|
+
resources,
|
|
38
|
+
viewConfigQuery,
|
|
39
|
+
selectedDocument,
|
|
40
|
+
setSelectedDocument,
|
|
41
|
+
}: TableProps) => {
|
|
32
42
|
const [value, setValue] = useState(resources[0]?.name);
|
|
33
43
|
const [pageSize, setPageSize] = useState(5); // better if this is global to not reset when switching tables
|
|
34
44
|
|
|
@@ -39,7 +49,13 @@ export const TableDashboard = ({ resources, viewConfigQuery }: TableProps) => {
|
|
|
39
49
|
return (
|
|
40
50
|
<Box sx={{ width: "100%", minHeight: "70vh" }}>
|
|
41
51
|
<TabContext value={value}>
|
|
42
|
-
<Box
|
|
52
|
+
<Box
|
|
53
|
+
sx={{
|
|
54
|
+
borderBottom: 1,
|
|
55
|
+
borderColor: "divider",
|
|
56
|
+
"@media print": { display: "none" },
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
43
59
|
<TabList onChange={handleChange}>
|
|
44
60
|
{resources?.map((resource, i) => (
|
|
45
61
|
<Tab
|
|
@@ -61,6 +77,8 @@ export const TableDashboard = ({ resources, viewConfigQuery }: TableProps) => {
|
|
|
61
77
|
resource={resource}
|
|
62
78
|
pageSize={pageSize}
|
|
63
79
|
setPageSize={setPageSize}
|
|
80
|
+
selectedDocument={selectedDocument}
|
|
81
|
+
setSelectedDocument={setSelectedDocument}
|
|
64
82
|
/>
|
|
65
83
|
{/* CHILD TABLE */}
|
|
66
84
|
{resource.children?.length ? (
|