ui-soxo-bootstrap-core 2.6.1-dev.26 → 2.6.1-dev.28
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/core/lib/Store.js +5 -1
- package/core/lib/components/global-header/global-header.js +37 -9
- package/core/lib/models/forms/components/form-creator/form-creator.js +525 -468
- package/core/lib/models/forms/components/form-creator/form-creator.scss +29 -26
- package/core/lib/modules/generic/generic-list/ExportReactCSV.js +28 -2
- package/core/lib/utils/generic/generic.utils.js +2 -1
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js +70 -43
- package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.scss +2 -2
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.js +134 -250
- package/core/modules/reporting/components/reporting-dashboard/reporting-dashboard.scss +36 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useContext, useRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Table, Skeleton, Input, Modal, message, Pagination } from 'antd';
|
|
3
|
+
import { Table, Skeleton, Input, Modal, message, Pagination, Tag } from 'antd';
|
|
4
4
|
|
|
5
5
|
import { QrcodeOutlined } from '@ant-design/icons';
|
|
6
6
|
|
|
@@ -56,7 +56,7 @@ export default function ReportingDashboard({
|
|
|
56
56
|
const [config, setConfig] = useState({});
|
|
57
57
|
|
|
58
58
|
// State to manage the layout of the form
|
|
59
|
-
const [formLayout, setFormLayout] = useState('
|
|
59
|
+
const [formLayout, setFormLayout] = useState('vertical');
|
|
60
60
|
|
|
61
61
|
const [loading, setLoading] = useState(true);
|
|
62
62
|
|
|
@@ -69,6 +69,7 @@ export default function ReportingDashboard({
|
|
|
69
69
|
const [dashboardVisible, setDashBoardVisible] = useState(false);
|
|
70
70
|
|
|
71
71
|
const [formContents, setformContents] = useState({});
|
|
72
|
+
const [liveFormContents, setLiveFormContents] = useState({});
|
|
72
73
|
|
|
73
74
|
const scriptId = useRef(null);
|
|
74
75
|
|
|
@@ -116,7 +117,7 @@ export default function ReportingDashboard({
|
|
|
116
117
|
}
|
|
117
118
|
setColumns(parsedColumns);
|
|
118
119
|
|
|
119
|
-
await prepareInputParameters(result, parsedColumns);
|
|
120
|
+
await prepareInputParameters(result, parsedColumns, fetchId);
|
|
120
121
|
|
|
121
122
|
if (result.summary_columns) {
|
|
122
123
|
setSummaryColumns(JSON.parse(result.summary_columns));
|
|
@@ -161,7 +162,7 @@ export default function ReportingDashboard({
|
|
|
161
162
|
*/
|
|
162
163
|
|
|
163
164
|
//Prepare input parameters by mapping default values and binding models if needed
|
|
164
|
-
async function prepareInputParameters(record, parsedColumns) {
|
|
165
|
+
async function prepareInputParameters(record, parsedColumns, fetchId) {
|
|
165
166
|
setLoading(true);
|
|
166
167
|
let urlParams = Location.search();
|
|
167
168
|
|
|
@@ -170,10 +171,10 @@ export default function ReportingDashboard({
|
|
|
170
171
|
|
|
171
172
|
let otherDetails = record.other_details1 ? JSON.parse(record.other_details1) : null;
|
|
172
173
|
|
|
173
|
-
parameters = record.input_parameters ? JSON.parse(record.input_parameters) :
|
|
174
|
+
parameters = record.input_parameters ? JSON.parse(record.input_parameters) : [];
|
|
174
175
|
|
|
175
176
|
let formContent = {};
|
|
176
|
-
const searchFields = parameters.filter((p) => p.type === 'search' && p.search_enabled === 'yes');
|
|
177
|
+
const searchFields = (parameters || []).filter((p) => p.type === 'search' && p.search_enabled === 'yes');
|
|
177
178
|
setSearchParameters([...searchFields]);
|
|
178
179
|
|
|
179
180
|
parameters = await parameters?.map((record) => {
|
|
@@ -218,13 +219,15 @@ export default function ReportingDashboard({
|
|
|
218
219
|
if (record.type === 'date' && !formContent[record.field]) {
|
|
219
220
|
formContent[record.field] = moment().tz(process.env.REACT_APP_TIMEZONE);
|
|
220
221
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
if (record.type === 'search') {
|
|
223
|
+
if (!formContent[record.field]) formContent[record.field] = [];
|
|
224
|
+
return {
|
|
225
|
+
...record,
|
|
226
|
+
reportId: fetchId,
|
|
227
|
+
onReset: () => getPatientDetails(fetchId),
|
|
228
|
+
required: record.required,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
228
231
|
if (['reference-select', 'reference-search', 'select'].indexOf(record.type) !== -1) {
|
|
229
232
|
// let model = "";
|
|
230
233
|
let model = CustomModels[record.modelName];
|
|
@@ -243,6 +246,7 @@ export default function ReportingDashboard({
|
|
|
243
246
|
});
|
|
244
247
|
// Update form content state
|
|
245
248
|
setformContents(formContent);
|
|
249
|
+
setLiveFormContents(formContent);
|
|
246
250
|
|
|
247
251
|
// Trigger form submission
|
|
248
252
|
onFinish(formContent, null, record.input_parameters, parsedColumns);
|
|
@@ -254,12 +258,8 @@ export default function ReportingDashboard({
|
|
|
254
258
|
// If enabled, clear the details array
|
|
255
259
|
setDetails([]);
|
|
256
260
|
} else {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
let filter = parameters.filter((ele) => ele.type && ele.type !== 'search');
|
|
260
|
-
// Update the "details" state with the filtered results
|
|
261
|
-
|
|
262
|
-
setDetails([...filter]);
|
|
261
|
+
// Keep all parameters with a type (including search) to render in FormCreator
|
|
262
|
+
setDetails([...parameters.filter((ele) => ele.type)]);
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
@@ -345,16 +345,29 @@ export default function ReportingDashboard({
|
|
|
345
345
|
};
|
|
346
346
|
|
|
347
347
|
const handleSubmit = (values) => {
|
|
348
|
-
|
|
348
|
+
// Extract search fields from the form values
|
|
349
|
+
const searchKeys = searchParameters.map((p) => p.field);
|
|
350
|
+
const currentSearchValues = {};
|
|
351
|
+
const formValues = {};
|
|
352
|
+
|
|
353
|
+
Object.keys(values).forEach((key) => {
|
|
354
|
+
if (searchKeys.includes(key)) {
|
|
355
|
+
currentSearchValues[key] = values[key];
|
|
356
|
+
} else {
|
|
357
|
+
formValues[key] = values[key];
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const hasSearchValues = Object.values(currentSearchValues).some((v) => Array.isArray(v) && v.length > 0);
|
|
349
362
|
|
|
350
363
|
if (!hasSearchValues) {
|
|
351
|
-
runSubmit(
|
|
364
|
+
runSubmit(formValues);
|
|
352
365
|
return;
|
|
353
366
|
}
|
|
354
367
|
|
|
355
|
-
// Check if form values
|
|
356
|
-
const formChanged = Object.keys(
|
|
357
|
-
const newVal =
|
|
368
|
+
// Check if main form values (non-search) changed
|
|
369
|
+
const formChanged = Object.keys(formValues).some((key) => {
|
|
370
|
+
const newVal = formValues[key];
|
|
358
371
|
const oldVal = formContents[key];
|
|
359
372
|
|
|
360
373
|
if (moment.isMoment(newVal) && moment.isMoment(oldVal)) {
|
|
@@ -374,8 +387,8 @@ export default function ReportingDashboard({
|
|
|
374
387
|
onOk() {
|
|
375
388
|
// YES → send form values + search condition
|
|
376
389
|
const finalValues = {
|
|
377
|
-
...
|
|
378
|
-
search_values:
|
|
390
|
+
...formValues,
|
|
391
|
+
search_values: currentSearchValues,
|
|
379
392
|
};
|
|
380
393
|
|
|
381
394
|
runSubmit(finalValues);
|
|
@@ -384,13 +397,13 @@ export default function ReportingDashboard({
|
|
|
384
397
|
onCancel() {
|
|
385
398
|
// NO → reset form values
|
|
386
399
|
const resetValues = {};
|
|
387
|
-
Object.keys(
|
|
400
|
+
Object.keys(formValues).forEach((key) => {
|
|
388
401
|
resetValues[key] = null;
|
|
389
402
|
});
|
|
390
403
|
|
|
391
404
|
const finalValues = {
|
|
392
405
|
...resetValues,
|
|
393
|
-
search_values:
|
|
406
|
+
search_values: currentSearchValues,
|
|
394
407
|
};
|
|
395
408
|
|
|
396
409
|
runSubmit(finalValues);
|
|
@@ -399,13 +412,13 @@ export default function ReportingDashboard({
|
|
|
399
412
|
} else {
|
|
400
413
|
// no form change
|
|
401
414
|
const resetValues = {};
|
|
402
|
-
Object.keys(
|
|
415
|
+
Object.keys(formValues).forEach((key) => {
|
|
403
416
|
resetValues[key] = null;
|
|
404
417
|
});
|
|
405
418
|
|
|
406
419
|
const finalValues = {
|
|
407
420
|
...resetValues,
|
|
408
|
-
search_values:
|
|
421
|
+
search_values: currentSearchValues,
|
|
409
422
|
};
|
|
410
423
|
|
|
411
424
|
runSubmit(finalValues);
|
|
@@ -436,6 +449,24 @@ export default function ReportingDashboard({
|
|
|
436
449
|
|
|
437
450
|
onFinish(finalValues, resetPage);
|
|
438
451
|
};
|
|
452
|
+
|
|
453
|
+
const selectedSearchFields = details.filter((field) => {
|
|
454
|
+
if (field.type !== 'search') return false;
|
|
455
|
+
|
|
456
|
+
const value = liveFormContents[field.field];
|
|
457
|
+
return Array.isArray(value) ? value.length > 0 : !!value;
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const handleRemoveSearchField = (fieldName) => {
|
|
461
|
+
const updatedValues = {
|
|
462
|
+
...liveFormContents,
|
|
463
|
+
[fieldName]: [],
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
setLiveFormContents(updatedValues);
|
|
467
|
+
handleSubmit(updatedValues);
|
|
468
|
+
};
|
|
469
|
+
|
|
439
470
|
/**
|
|
440
471
|
*
|
|
441
472
|
* @param {*} values
|
|
@@ -468,6 +499,12 @@ export default function ReportingDashboard({
|
|
|
468
499
|
//Getting url friendly value by matching the url values and input_parameter values
|
|
469
500
|
let value = values[parameter.field];
|
|
470
501
|
|
|
502
|
+
// If the value is missing at the root level (which happens when search fields are moved
|
|
503
|
+
// into search_values during submission), try to retrieve it from the nested object.
|
|
504
|
+
if (value === undefined && values.search_values && values.search_values[parameter.field] !== undefined) {
|
|
505
|
+
value = values.search_values[parameter.field];
|
|
506
|
+
}
|
|
507
|
+
|
|
471
508
|
// Keep Moment object in state for picker
|
|
472
509
|
if (parameter.type === 'date' && value) {
|
|
473
510
|
formContent[parameter.field] = value.isValid ? value : moment(value); // ensure Moment
|
|
@@ -489,6 +526,7 @@ export default function ReportingDashboard({
|
|
|
489
526
|
);
|
|
490
527
|
|
|
491
528
|
setformContents(formContent);
|
|
529
|
+
setLiveFormContents(formContent);
|
|
492
530
|
Location.search({ ...Location.search(), ...filteredParams });
|
|
493
531
|
}
|
|
494
532
|
|
|
@@ -584,62 +622,18 @@ export default function ReportingDashboard({
|
|
|
584
622
|
}}
|
|
585
623
|
styles={{ paddingRight: '15px', alignItems: 'center' }}
|
|
586
624
|
fields={details}
|
|
625
|
+
reportId={id}
|
|
587
626
|
formContent={formContents}
|
|
588
627
|
// formContent={{ [model]: {} }}
|
|
589
628
|
modelIndex="requestId"
|
|
590
629
|
model={model}
|
|
591
630
|
onSubmit={handleSubmit}
|
|
631
|
+
onFormValuesChange={setLiveFormContents}
|
|
592
632
|
callback={() => {
|
|
593
633
|
// history.goBack();
|
|
594
634
|
}}
|
|
595
635
|
/>
|
|
596
636
|
) : null}
|
|
597
|
-
{/* </Card> */}
|
|
598
|
-
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>
|
|
599
|
-
{searchParameters.length > 0
|
|
600
|
-
? searchParameters.map((param) => (
|
|
601
|
-
<AdvancedSearchSelect
|
|
602
|
-
key={param.field}
|
|
603
|
-
parameter={param}
|
|
604
|
-
field={param}
|
|
605
|
-
reportId={reportId}
|
|
606
|
-
value={searchValues[param.field] || []}
|
|
607
|
-
onChange={(value) => {
|
|
608
|
-
setSearchValues((prev) => ({
|
|
609
|
-
...prev,
|
|
610
|
-
[param.field]: value,
|
|
611
|
-
}));
|
|
612
|
-
}}
|
|
613
|
-
onReset={() => {
|
|
614
|
-
setSearchValues((prev) => {
|
|
615
|
-
const updated = {
|
|
616
|
-
...prev,
|
|
617
|
-
[param.field]: [],
|
|
618
|
-
};
|
|
619
|
-
|
|
620
|
-
// const finalValues = {
|
|
621
|
-
// ...formContents,
|
|
622
|
-
// search_values: updated,
|
|
623
|
-
// };
|
|
624
|
-
// console.log(finalValues);
|
|
625
|
-
// runSubmit(finalValues); // 🔥 refresh report correctly
|
|
626
|
-
getPatientDetails();
|
|
627
|
-
|
|
628
|
-
return updated;
|
|
629
|
-
});
|
|
630
|
-
}}
|
|
631
|
-
// onReset={() => {
|
|
632
|
-
// setSearchValues((prev) => ({
|
|
633
|
-
// ...prev,
|
|
634
|
-
// [param.field]: [],
|
|
635
|
-
// }));
|
|
636
|
-
|
|
637
|
-
// handleSubmit(formContents); // 🔥 refresh report
|
|
638
|
-
// }}
|
|
639
|
-
/>
|
|
640
|
-
))
|
|
641
|
-
: null}
|
|
642
|
-
</div>
|
|
643
637
|
</div>
|
|
644
638
|
|
|
645
639
|
{/** GuestList component start*/}
|
|
@@ -657,6 +651,8 @@ export default function ReportingDashboard({
|
|
|
657
651
|
pagination={pagination}
|
|
658
652
|
handlePagination={handlePagination}
|
|
659
653
|
attributes={attributes}
|
|
654
|
+
selectedSearchFields={selectedSearchFields}
|
|
655
|
+
handleRemoveSearchField={handleRemoveSearchField}
|
|
660
656
|
fetchReportData={(paginationUpdate) => fetchReportData(id, formContents, dbPtr, paginationUpdate || pagination)}
|
|
661
657
|
/>
|
|
662
658
|
{/** GuestList component end*/}
|
|
@@ -690,6 +686,8 @@ function GuestList({
|
|
|
690
686
|
pagination,
|
|
691
687
|
handlePagination,
|
|
692
688
|
attributes,
|
|
689
|
+
selectedSearchFields,
|
|
690
|
+
handleRemoveSearchField,
|
|
693
691
|
fetchReportData,
|
|
694
692
|
}) {
|
|
695
693
|
/**
|
|
@@ -722,7 +720,6 @@ function GuestList({
|
|
|
722
720
|
|
|
723
721
|
const { isMobile, dispatch } = useContext(GlobalContext);
|
|
724
722
|
const [single, setSingle] = useState({});
|
|
725
|
-
const otherDetails = config.other_details1 ? JSON.parse(config.other_details1) : {};
|
|
726
723
|
|
|
727
724
|
// const [view, setView] = useState(isMobile ? true : false); //Need to check this condition
|
|
728
725
|
const cols = buildDisplayColumns({
|
|
@@ -731,7 +728,6 @@ function GuestList({
|
|
|
731
728
|
isFixedIndex,
|
|
732
729
|
CustomComponents,
|
|
733
730
|
refresh,
|
|
734
|
-
otherDetails,
|
|
735
731
|
});
|
|
736
732
|
|
|
737
733
|
/**
|
|
@@ -863,51 +859,35 @@ function GuestList({
|
|
|
863
859
|
const handleCloseEdit = () => {
|
|
864
860
|
setShowEdit(false);
|
|
865
861
|
};
|
|
866
|
-
/**
|
|
867
|
-
*
|
|
868
|
-
*/
|
|
869
|
-
function calculateSummaryValues(summaryCols, pageData) {
|
|
870
|
-
const summaryValues = {};
|
|
871
|
-
|
|
872
|
-
summaryCols.forEach((col) => {
|
|
873
|
-
const field = col.field;
|
|
874
|
-
|
|
875
|
-
if (col.function === 'sum') {
|
|
876
|
-
summaryValues[field] = pageData.reduce((total, row) => total + Number(row[field] || 0), 0);
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
if (col.function === 'count') {
|
|
880
|
-
summaryValues[field] = pageData.length;
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
if (col.function === 'avg') {
|
|
884
|
-
const total = pageData.reduce((sum, row) => sum + Number(row[field] || 0), 0);
|
|
885
|
-
summaryValues[field] = pageData.length ? total / pageData.length : 0;
|
|
886
|
-
}
|
|
887
|
-
if (col.function === 'min') {
|
|
888
|
-
const values = pageData.map((row) => Number(row[field] || 0));
|
|
889
|
-
summaryValues[field] = values.length ? Math.min(...values) : 0;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (col.function === 'max') {
|
|
893
|
-
const values = pageData.map((row) => Number(row[field] || 0));
|
|
894
|
-
summaryValues[field] = values.length ? Math.max(...values) : 0;
|
|
895
|
-
}
|
|
896
|
-
});
|
|
897
|
-
|
|
898
|
-
return summaryValues;
|
|
899
|
-
}
|
|
900
862
|
return (
|
|
901
863
|
<>
|
|
902
864
|
<div className="table-header">
|
|
903
865
|
<div className="table-left">
|
|
904
|
-
{/*
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
866
|
+
{/* {selectedSearchFields?.length > 0 ? (
|
|
867
|
+
<div className="search-tags-container">
|
|
868
|
+
{selectedSearchFields.map((field) => (
|
|
869
|
+
<Tag key={field.field} closable color="blue" onClose={() => handleRemoveSearchField(field.field)}>
|
|
870
|
+
{field.caption}
|
|
871
|
+
</Tag>
|
|
872
|
+
))}
|
|
873
|
+
</div>
|
|
874
|
+
) : null} */}
|
|
908
875
|
</div>
|
|
909
876
|
|
|
910
877
|
<div className="table-right">
|
|
878
|
+
{/* shwoing caption is not correct so this commented */}
|
|
879
|
+
{/* <span className="menu-caption">{config.caption}</span> */}
|
|
880
|
+
<Search className="table-search-input" placeholder="Enter Search Value" allowClear onChange={onSearch} />
|
|
881
|
+
<div className="table-export-button">
|
|
882
|
+
{exportData.exportDatas && (
|
|
883
|
+
<ExportReactCSV
|
|
884
|
+
title={config.caption}
|
|
885
|
+
headers={exportData.exportDatas.exportDataHeaders}
|
|
886
|
+
csvData={exportData.exportDatas.exportDataColumns}
|
|
887
|
+
/>
|
|
888
|
+
)}
|
|
889
|
+
</div>
|
|
890
|
+
|
|
911
891
|
{/* QR Scan start */}
|
|
912
892
|
{showScanner ? (
|
|
913
893
|
<Button size="small" type="primary" icon={<QrcodeOutlined />} onClick={() => setScannerVisible(true)}>
|
|
@@ -940,18 +920,7 @@ function GuestList({
|
|
|
940
920
|
<Modal open={isScannerVisible} title="Scan QR Code" footer={null} onCancel={() => setScannerVisible(false)} destroyOnClose>
|
|
941
921
|
<QrScanner onScanSuccess={handleScanSuccess} onClose={() => setScannerVisible(false)} />
|
|
942
922
|
</Modal>
|
|
943
|
-
|
|
944
|
-
<div>
|
|
945
|
-
{/* QR Scan End */}
|
|
946
|
-
{/*table data export to csc component*/}
|
|
947
|
-
{exportData.exportDatas && (
|
|
948
|
-
<ExportReactCSV
|
|
949
|
-
title={config.caption}
|
|
950
|
-
headers={exportData.exportDatas.exportDataHeaders}
|
|
951
|
-
csvData={exportData.exportDatas.exportDataColumns}
|
|
952
|
-
/>
|
|
953
|
-
)}
|
|
954
|
-
</div>
|
|
923
|
+
{/* QR Scan End */}
|
|
955
924
|
</div>
|
|
956
925
|
</div>
|
|
957
926
|
|
|
@@ -972,131 +941,46 @@ function GuestList({
|
|
|
972
941
|
sticky
|
|
973
942
|
pagination={false}
|
|
974
943
|
// title={config.caption}
|
|
975
|
-
// summary={(pageData) => {
|
|
976
|
-
// // Variable to save the summary data
|
|
977
|
-
// let summary = {};
|
|
978
|
-
|
|
979
|
-
// let summaryColumns = [
|
|
980
|
-
// { field: 'opb_amt', title: 'Amount' },
|
|
981
|
-
// { field: 'opb_netamt', title: 'Net Amount' },
|
|
982
|
-
// ];
|
|
983
|
-
|
|
984
|
-
// let tableColumns = cols;
|
|
985
|
-
|
|
986
|
-
// // Creating a copy of columns to append the summary configuration that is needed to set
|
|
987
|
-
// tableColumns.forEach((record, index) => {
|
|
988
|
-
// summaryColumns.forEach((inner) => {
|
|
989
|
-
// if (record.field === inner.field) {
|
|
990
|
-
// tableColumns[index].summary = inner;
|
|
991
|
-
// }
|
|
992
|
-
// });
|
|
993
|
-
// });
|
|
994
|
-
|
|
995
|
-
// // Initialize
|
|
996
|
-
// summaryColumns.map((item) => {
|
|
997
|
-
// return (summary[item.field] = 0);
|
|
998
|
-
// });
|
|
999
|
-
|
|
1000
|
-
// // Find the total
|
|
1001
|
-
// summaryColumns.map((item) => {
|
|
1002
|
-
// pageData.forEach((entry) => {
|
|
1003
|
-
// return (summary[item.field] = summary[item.field] + entry[item.field]);
|
|
1004
|
-
// });
|
|
1005
|
-
// });
|
|
1006
|
-
|
|
1007
|
-
// return (
|
|
1008
|
-
// <>
|
|
1009
|
-
// <Table.Summary.Row>
|
|
1010
|
-
// {tableColumns.map((column, key) => {
|
|
1011
|
-
// return <Table.Summary.Cell key={key}>{column.summary ? <>{summary[column.summary.field]}</> : null}</Table.Summary.Cell>;
|
|
1012
|
-
// })}
|
|
1013
|
-
// </Table.Summary.Row>
|
|
1014
|
-
// </>
|
|
1015
|
-
// );
|
|
1016
|
-
// }}
|
|
1017
|
-
// summary={(pageData) => {
|
|
1018
|
-
// const summaryCols = columns.filter((col) => col.enable_summary);
|
|
1019
|
-
// if (!summaryCols.length) return null;
|
|
1020
|
-
|
|
1021
|
-
// const summaryValues = {};
|
|
1022
|
-
|
|
1023
|
-
// summaryCols.forEach((col) => {
|
|
1024
|
-
// const field = col.field;
|
|
1025
|
-
|
|
1026
|
-
// if (col.function === 'sum') {
|
|
1027
|
-
// summaryValues[field] = pageData.reduce((total, row) => total + Number(row[field] || 0), 0);
|
|
1028
|
-
// }
|
|
1029
|
-
|
|
1030
|
-
// if (col.function === 'count') {
|
|
1031
|
-
// summaryValues[field] = pageData.length;
|
|
1032
|
-
// }
|
|
1033
|
-
|
|
1034
|
-
// if (col.function === 'avg') {
|
|
1035
|
-
// const total = pageData.reduce((sum, row) => sum + Number(row[field] || 0), 0);
|
|
1036
|
-
// summaryValues[field] = pageData.length ? total / pageData.length : 0;
|
|
1037
|
-
// }
|
|
1038
|
-
// });
|
|
1039
|
-
|
|
1040
|
-
// return (
|
|
1041
|
-
// <Table.Summary.Row className="report-summary-row">
|
|
1042
|
-
// {cols.map((col, index) => {
|
|
1043
|
-
// // show summary value
|
|
1044
|
-
// if (summaryValues[col.field] !== undefined) {
|
|
1045
|
-
// return (
|
|
1046
|
-
// <Table.Summary.Cell key={index}>
|
|
1047
|
-
// <strong>{summaryValues[col.field]}</strong>
|
|
1048
|
-
// </Table.Summary.Cell>
|
|
1049
|
-
// );
|
|
1050
|
-
// }
|
|
1051
|
-
|
|
1052
|
-
// // caption before summary column
|
|
1053
|
-
// const nextCol = cols[index + 1];
|
|
1054
|
-
// if (nextCol && summaryValues[nextCol.field] !== undefined) {
|
|
1055
|
-
// const configCol = columns.find((c) => c.field === nextCol.field);
|
|
1056
|
-
// return (
|
|
1057
|
-
// <Table.Summary.Cell key={index}>
|
|
1058
|
-
// <strong>{configCol?.summary_caption || 'Total'}</strong>
|
|
1059
|
-
// </Table.Summary.Cell>
|
|
1060
|
-
// );
|
|
1061
|
-
// }
|
|
1062
|
-
|
|
1063
|
-
// return <Table.Summary.Cell key={index} />;
|
|
1064
|
-
// })}
|
|
1065
|
-
// </Table.Summary.Row>
|
|
1066
|
-
// );
|
|
1067
|
-
// }}
|
|
1068
|
-
|
|
1069
944
|
summary={(pageData) => {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
945
|
+
// Variable to save the summary data
|
|
946
|
+
let summary = {};
|
|
947
|
+
|
|
948
|
+
let summaryColumns = [
|
|
949
|
+
{ field: 'opb_amt', title: 'Amount' },
|
|
950
|
+
{ field: 'opb_netamt', title: 'Net Amount' },
|
|
951
|
+
];
|
|
952
|
+
|
|
953
|
+
let tableColumns = cols;
|
|
954
|
+
|
|
955
|
+
// Creating a copy of columns to append the summary configuration that is needed to set
|
|
956
|
+
tableColumns.forEach((record, index) => {
|
|
957
|
+
summaryColumns.forEach((inner) => {
|
|
958
|
+
if (record.field === inner.field) {
|
|
959
|
+
tableColumns[index].summary = inner;
|
|
960
|
+
}
|
|
961
|
+
});
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
// Initialize
|
|
965
|
+
summaryColumns.map((item) => {
|
|
966
|
+
return (summary[item.field] = 0);
|
|
967
|
+
});
|
|
968
|
+
|
|
969
|
+
// Find the total
|
|
970
|
+
summaryColumns.map((item) => {
|
|
971
|
+
pageData.forEach((entry) => {
|
|
972
|
+
return (summary[item.field] = summary[item.field] + entry[item.field]);
|
|
973
|
+
});
|
|
974
|
+
});
|
|
1074
975
|
|
|
1075
976
|
return (
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
);
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
const nextCol = cols[index + 1];
|
|
1087
|
-
if (nextCol && summaryValues[nextCol.field] !== undefined) {
|
|
1088
|
-
const configCol = columns.find((c) => c.field === nextCol.field);
|
|
1089
|
-
|
|
1090
|
-
return (
|
|
1091
|
-
<Table.Summary.Cell key={index}>
|
|
1092
|
-
<strong>{configCol?.summary_caption || 'Total'}</strong>
|
|
1093
|
-
</Table.Summary.Cell>
|
|
1094
|
-
);
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
return <Table.Summary.Cell key={index} />;
|
|
1098
|
-
})}
|
|
1099
|
-
</Table.Summary.Row>
|
|
977
|
+
<>
|
|
978
|
+
<Table.Summary.Row>
|
|
979
|
+
{tableColumns.map((column, key) => {
|
|
980
|
+
return <Table.Summary.Cell key={key}>{column.summary ? <>{summary[column.summary.field]}</> : null}</Table.Summary.Cell>;
|
|
981
|
+
})}
|
|
982
|
+
</Table.Summary.Row>
|
|
983
|
+
</>
|
|
1100
984
|
);
|
|
1101
985
|
}}
|
|
1102
986
|
/>
|
|
@@ -16,12 +16,17 @@
|
|
|
16
16
|
display: flex;
|
|
17
17
|
justify-content: space-between;
|
|
18
18
|
align-items: center;
|
|
19
|
+
gap: 12px;
|
|
19
20
|
padding-bottom: 10px;
|
|
20
21
|
padding-top: 10px;
|
|
21
22
|
|
|
22
23
|
.table-left {
|
|
23
24
|
display: flex;
|
|
24
25
|
align-items: center;
|
|
26
|
+
gap: 8px;
|
|
27
|
+
flex: 1;
|
|
28
|
+
min-width: 0;
|
|
29
|
+
margin-left: 6px;
|
|
25
30
|
|
|
26
31
|
.menu-caption {
|
|
27
32
|
min-width: 100px;
|
|
@@ -31,9 +36,23 @@
|
|
|
31
36
|
|
|
32
37
|
.table-right{
|
|
33
38
|
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: flex-end;
|
|
41
|
+
flex-wrap: nowrap;
|
|
34
42
|
gap: 4px;
|
|
35
43
|
}
|
|
36
44
|
}
|
|
45
|
+
|
|
46
|
+
.table-search-input {
|
|
47
|
+
width: 220px;
|
|
48
|
+
min-width: 220px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.table-export-button {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
}
|
|
37
56
|
|
|
38
57
|
|
|
39
58
|
.form-card {
|
|
@@ -48,6 +67,23 @@
|
|
|
48
67
|
padding: 0px;
|
|
49
68
|
}
|
|
50
69
|
|
|
70
|
+
.search-tags-container {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
flex-wrap: nowrap;
|
|
74
|
+
gap: 8px;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
max-width: 100%;
|
|
77
|
+
overflow-x: auto;
|
|
78
|
+
overflow-y: hidden;
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.search-tags-container .ant-tag {
|
|
83
|
+
flex-shrink: 0;
|
|
84
|
+
margin-inline-end: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
51
87
|
// margin: 0px 10px;
|
|
52
88
|
|
|
53
89
|
.ant-skeleton {
|