datastake-daf 0.6.441 → 0.6.443
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/dist/components/index.js +129 -206
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/PdfView/index.jsx +150 -210
package/dist/components/index.js
CHANGED
|
@@ -14536,206 +14536,149 @@ DAFFooter.propTypes = {
|
|
|
14536
14536
|
};
|
|
14537
14537
|
|
|
14538
14538
|
const PAGE_HEIGHT = 1587;
|
|
14539
|
-
|
|
14539
|
+
// margin-top: 20, bottom: 20;
|
|
14540
14540
|
const FOOTER_HEIGHT = 70;
|
|
14541
|
-
const
|
|
14542
|
-
const FILL_RATIO = 0.80;
|
|
14543
|
-
const CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
14541
|
+
const HEADER_HEIGHT = 100;
|
|
14544
14542
|
const Row = _ref => {
|
|
14545
14543
|
let {
|
|
14546
14544
|
widgets,
|
|
14547
14545
|
i,
|
|
14548
14546
|
onChangeHeight = () => {}
|
|
14549
14547
|
} = _ref;
|
|
14550
|
-
const ref = React.useRef(
|
|
14548
|
+
const ref = React.useRef();
|
|
14549
|
+
const [height, setHeight] = React.useState(0);
|
|
14551
14550
|
React.useLayoutEffect(() => {
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
|
|
14551
|
+
const observer = new ResizeObserver(entries => {
|
|
14552
|
+
for (const entry of entries) {
|
|
14553
|
+
setHeight(entry.contentRect.height);
|
|
14554
|
+
}
|
|
14555
|
+
});
|
|
14556
|
+
observer.observe(ref.current);
|
|
14557
|
+
return () => observer.disconnect();
|
|
14558
|
+
}, [ref]);
|
|
14559
|
+
React.useEffect(() => {
|
|
14560
|
+
if (height) {
|
|
14561
|
+
onChangeHeight(i, {
|
|
14562
|
+
height,
|
|
14558
14563
|
ref
|
|
14559
14564
|
});
|
|
14560
|
-
}
|
|
14561
|
-
|
|
14562
|
-
return () => ro.disconnect();
|
|
14563
|
-
}, [i, onChangeHeight]);
|
|
14565
|
+
}
|
|
14566
|
+
}, [height]);
|
|
14564
14567
|
return /*#__PURE__*/jsxRuntime.jsx("section", {
|
|
14565
14568
|
ref: ref,
|
|
14566
14569
|
style: widgets.style,
|
|
14567
|
-
children: typeof widgets.render ===
|
|
14570
|
+
children: typeof widgets.render === 'function' ? widgets.render() : null
|
|
14568
14571
|
});
|
|
14569
14572
|
};
|
|
14570
14573
|
function PdfView(_ref2) {
|
|
14571
14574
|
let {
|
|
14572
14575
|
config = [],
|
|
14573
14576
|
customClassName,
|
|
14574
|
-
title =
|
|
14575
|
-
imgSrc =
|
|
14576
|
-
userId =
|
|
14577
|
-
accountId =
|
|
14578
|
-
documentId =
|
|
14579
|
-
downloadId =
|
|
14577
|
+
title = 'Title',
|
|
14578
|
+
imgSrc = '',
|
|
14579
|
+
userId = 'IDD-0000000',
|
|
14580
|
+
accountId = 'IDD-0000000',
|
|
14581
|
+
documentId = 'IDD-0000000',
|
|
14582
|
+
downloadId = 'DWL-00000123'
|
|
14580
14583
|
} = _ref2;
|
|
14581
|
-
|
|
14582
|
-
const [
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14595
|
-
setSections(prev => {
|
|
14596
|
-
var _prev$index;
|
|
14597
|
-
return ((_prev$index = prev[index]) === null || _prev$index === void 0 ? void 0 : _prev$index.height) === conf.height ? prev : _objectSpread2(_objectSpread2({}, prev), {}, {
|
|
14598
|
-
[index]: conf
|
|
14584
|
+
const [sectionsConfig, setSectionsConfig] = React.useState({});
|
|
14585
|
+
const [pages, setPages] = React.useState([1]);
|
|
14586
|
+
const doSizing = React.useCallback(() => {
|
|
14587
|
+
const keys = Object.keys(sectionsConfig);
|
|
14588
|
+
let _pages = [1];
|
|
14589
|
+
let _page = 1;
|
|
14590
|
+
if (keys.length === config.length) {
|
|
14591
|
+
let incrHeight = 0;
|
|
14592
|
+
keys.forEach(k => {
|
|
14593
|
+
const {
|
|
14594
|
+
ref
|
|
14595
|
+
} = sectionsConfig[k];
|
|
14596
|
+
ref.current.style.marginBottom = '0px';
|
|
14597
|
+
// ref.current.style.marginTop = '15px';
|
|
14599
14598
|
});
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14613
|
-
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
|
|
14620
|
-
|
|
14621
|
-
|
|
14622
|
-
|
|
14623
|
-
|
|
14624
|
-
|
|
14625
|
-
// --- Step 2: Paginate with per-block hints (priority + keepWithNext) ---
|
|
14626
|
-
const paginate = React.useCallback(() => {
|
|
14627
|
-
const keys = Object.keys(sections).map(k => Number(k)).sort((a, b) => a - b);
|
|
14628
|
-
if (keys.length !== expandedConfig.length) return;
|
|
14629
|
-
|
|
14630
|
-
// Build meta (read hints from config)
|
|
14631
|
-
const meta = keys.map(i => {
|
|
14632
|
-
var _expandedConfig$i$pri, _expandedConfig$i, _expandedConfig$i2;
|
|
14633
|
-
return {
|
|
14634
|
-
i,
|
|
14635
|
-
h: sections[i].height,
|
|
14636
|
-
priority: (_expandedConfig$i$pri = (_expandedConfig$i = expandedConfig[i]) === null || _expandedConfig$i === void 0 ? void 0 : _expandedConfig$i.priority) !== null && _expandedConfig$i$pri !== void 0 ? _expandedConfig$i$pri : 2,
|
|
14637
|
-
// 1 > 2 > 3 (1 is most important)
|
|
14638
|
-
keepWithNext: !!((_expandedConfig$i2 = expandedConfig[i]) !== null && _expandedConfig$i2 !== void 0 && _expandedConfig$i2.keepWithNext)
|
|
14639
|
-
};
|
|
14640
|
-
});
|
|
14641
|
-
const threshold = Math.floor(CONTENT_HEIGHT * FILL_RATIO);
|
|
14642
|
-
const pages = [];
|
|
14643
|
-
let current = [];
|
|
14644
|
-
let used = 0;
|
|
14645
|
-
let carryKeep = false;
|
|
14646
|
-
for (let k = 0; k < meta.length; k++) {
|
|
14647
|
-
const curr = meta[k];
|
|
14648
|
-
const hWithGap = (current.length === 0 ? 0 : GAP_BETWEEN_BLOCKS) + curr.h;
|
|
14649
|
-
|
|
14650
|
-
// Honor keep-with-next from the previous block
|
|
14651
|
-
if (carryKeep) {
|
|
14652
|
-
// start current on a fresh page
|
|
14653
|
-
if (current.length) pages.push(current);
|
|
14654
|
-
current = [curr.i];
|
|
14655
|
-
used = curr.h;
|
|
14656
|
-
carryKeep = false;
|
|
14657
|
-
if (curr.keepWithNext) carryKeep = true;
|
|
14658
|
-
continue;
|
|
14659
|
-
}
|
|
14660
|
-
|
|
14661
|
-
// Oversized singleton: own page
|
|
14662
|
-
if (curr.h > threshold && current.length === 0) {
|
|
14663
|
-
pages.push([curr.i]);
|
|
14664
|
-
current = [];
|
|
14665
|
-
used = 0;
|
|
14666
|
-
carryKeep = false;
|
|
14667
|
-
continue;
|
|
14668
|
-
}
|
|
14669
|
-
|
|
14670
|
-
// Fits on current page?
|
|
14671
|
-
if (current.length === 0 || used + hWithGap <= threshold) {
|
|
14672
|
-
current.push(curr.i);
|
|
14673
|
-
used += hWithGap;
|
|
14674
|
-
} else {
|
|
14675
|
-
// Rebalance: try pushing a lower-priority block from current to next page to make room
|
|
14676
|
-
let moved = false;
|
|
14677
|
-
for (let j = current.length - 1; j >= 0; j--) {
|
|
14678
|
-
const prevIdx = current[j];
|
|
14679
|
-
const prev = meta.find(m => m.i === prevIdx);
|
|
14680
|
-
if (prev.priority > curr.priority) {
|
|
14681
|
-
// lower priority number = higher importance
|
|
14682
|
-
const tentativeUsed = used - (j === 0 ? prev.h : prev.h + GAP_BETWEEN_BLOCKS);
|
|
14683
|
-
if (tentativeUsed + hWithGap <= threshold) {
|
|
14684
|
-
// move prev off this page
|
|
14685
|
-
current.splice(j, 1);
|
|
14686
|
-
used = tentativeUsed;
|
|
14687
|
-
moved = true;
|
|
14688
|
-
break;
|
|
14689
|
-
}
|
|
14599
|
+
keys.forEach((k, i) => {
|
|
14600
|
+
const {
|
|
14601
|
+
height,
|
|
14602
|
+
ref
|
|
14603
|
+
} = sectionsConfig[k];
|
|
14604
|
+
if (i === 0) {
|
|
14605
|
+
ref.current.style.marginTop = "".concat(HEADER_HEIGHT, "px");
|
|
14606
|
+
incrHeight += HEADER_HEIGHT;
|
|
14607
|
+
}
|
|
14608
|
+
const newHeight = incrHeight + height;
|
|
14609
|
+
if (i === keys.length - 1) {
|
|
14610
|
+
ref.current.style.paddingBottom = '30px';
|
|
14611
|
+
}
|
|
14612
|
+
if (newHeight > PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT) {
|
|
14613
|
+
const dif = Math.abs(PAGE_HEIGHT - incrHeight);
|
|
14614
|
+
ref.current.style.marginTop = '30px';
|
|
14615
|
+
_page += 1;
|
|
14616
|
+
_pages.push(_page);
|
|
14617
|
+
if (sectionsConfig[keys[i - 1]]) {
|
|
14618
|
+
const {
|
|
14619
|
+
ref: topRef
|
|
14620
|
+
} = sectionsConfig[keys[i - 1]];
|
|
14621
|
+
topRef.current.style.marginBottom = "".concat(dif + HEADER_HEIGHT - 24, "px");
|
|
14622
|
+
incrHeight = height + 24 + HEADER_HEIGHT;
|
|
14623
|
+
// console.log('margin', dif);
|
|
14690
14624
|
}
|
|
14691
|
-
}
|
|
14692
|
-
if (!moved) {
|
|
14693
|
-
pages.push(current);
|
|
14694
|
-
current = [curr.i];
|
|
14695
|
-
used = curr.h; // first element on new page (no top gap)
|
|
14696
14625
|
} else {
|
|
14697
|
-
|
|
14698
|
-
current.push(curr.i);
|
|
14699
|
-
used += hWithGap;
|
|
14626
|
+
incrHeight = newHeight + 24;
|
|
14700
14627
|
}
|
|
14701
|
-
|
|
14702
|
-
|
|
14628
|
+
// console.groupEnd();
|
|
14629
|
+
});
|
|
14630
|
+
setPages(_pages);
|
|
14703
14631
|
}
|
|
14704
|
-
|
|
14705
|
-
setPageMap(pages); // <-- unlimited pages; grows as needed
|
|
14706
|
-
}, [expandedConfig, sections]);
|
|
14632
|
+
}, [sectionsConfig]);
|
|
14707
14633
|
React.useEffect(() => {
|
|
14708
|
-
|
|
14709
|
-
}, [
|
|
14710
|
-
const
|
|
14711
|
-
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14634
|
+
doSizing();
|
|
14635
|
+
}, [doSizing]);
|
|
14636
|
+
const onChangeHeight = React.useCallback((index, conf) => {
|
|
14637
|
+
setSectionsConfig(prev => _objectSpread2(_objectSpread2({}, prev), {}, {
|
|
14638
|
+
[index]: conf
|
|
14639
|
+
}));
|
|
14640
|
+
}, []);
|
|
14641
|
+
const contClassName = formatClassname(['daf-analysis daf-pdf-view', customClassName]);
|
|
14642
|
+
const renderDashboard = React.useCallback(() => {
|
|
14643
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14644
|
+
className: "view-content",
|
|
14717
14645
|
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14718
|
-
className: "
|
|
14719
|
-
children:
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14646
|
+
className: "daf-analysis-layout",
|
|
14647
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14648
|
+
className: "sections-cont",
|
|
14649
|
+
children: config.map((widgets, i) => /*#__PURE__*/jsxRuntime.jsx(Row, {
|
|
14650
|
+
widgets: widgets,
|
|
14651
|
+
i: i,
|
|
14652
|
+
onChangeHeight: onChangeHeight
|
|
14653
|
+
}, "dashboard-sections=".concat(i + 1)))
|
|
14654
|
+
})
|
|
14724
14655
|
})
|
|
14725
|
-
})
|
|
14726
|
-
}
|
|
14727
|
-
|
|
14656
|
+
});
|
|
14657
|
+
}, [config, onChangeHeight]);
|
|
14658
|
+
|
|
14659
|
+
// <div className="daf-analysis">
|
|
14660
|
+
// <Header title={t('Dashboard Title')} />
|
|
14661
|
+
|
|
14662
|
+
// <div className="content">
|
|
14663
|
+
// <div className="view-content">
|
|
14664
|
+
// <div className="daf-analysis-layout">
|
|
14665
|
+
// <div className='sections-cont w-pt'>
|
|
14666
|
+
// <section>
|
|
14667
|
+
|
|
14668
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14728
14669
|
className: contClassName,
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
position: "relative",
|
|
14734
|
-
overflow: "hidden"
|
|
14735
|
-
},
|
|
14670
|
+
style: {
|
|
14671
|
+
position: 'relative'
|
|
14672
|
+
},
|
|
14673
|
+
children: [renderDashboard(), pages.map(page => /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
14736
14674
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14737
14675
|
style: {
|
|
14738
|
-
|
|
14676
|
+
top: (page - 1) * PAGE_HEIGHT,
|
|
14677
|
+
width: '100%',
|
|
14678
|
+
height: HEADER_HEIGHT - 24,
|
|
14679
|
+
position: 'absolute',
|
|
14680
|
+
left: 0,
|
|
14681
|
+
zIndex: 1000000
|
|
14739
14682
|
},
|
|
14740
14683
|
className: "flex-row dashboard-header",
|
|
14741
14684
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -14750,51 +14693,39 @@ function PdfView(_ref2) {
|
|
|
14750
14693
|
alt: "logo"
|
|
14751
14694
|
})
|
|
14752
14695
|
})]
|
|
14753
|
-
}), /*#__PURE__*/jsxRuntime.
|
|
14754
|
-
className: "pdf-body",
|
|
14696
|
+
}, "headers-".concat(page)), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14755
14697
|
style: {
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
gap: GAP_BETWEEN_BLOCKS
|
|
14763
|
-
},
|
|
14764
|
-
children: indices.map(i => /*#__PURE__*/jsxRuntime.jsx(Row, {
|
|
14765
|
-
widgets: expandedConfig[i],
|
|
14766
|
-
i: i,
|
|
14767
|
-
onChangeHeight: onChangeHeight
|
|
14768
|
-
}, "row-".concat(i)))
|
|
14769
|
-
})
|
|
14770
|
-
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14771
|
-
style: {
|
|
14772
|
-
height: FOOTER_HEIGHT
|
|
14698
|
+
top: page * PAGE_HEIGHT - FOOTER_HEIGHT,
|
|
14699
|
+
width: '100%',
|
|
14700
|
+
height: FOOTER_HEIGHT,
|
|
14701
|
+
position: 'absolute',
|
|
14702
|
+
left: 0,
|
|
14703
|
+
zIndex: 1000000
|
|
14773
14704
|
},
|
|
14774
14705
|
className: "dashboard-footer flex-row",
|
|
14775
14706
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14776
14707
|
className: "flex flex-column justify-center",
|
|
14777
14708
|
children: /*#__PURE__*/jsxRuntime.jsx("h5", {
|
|
14778
|
-
children: moment__default["default"]().format(
|
|
14709
|
+
children: moment__default["default"]().format('DD MMM YYYY')
|
|
14779
14710
|
})
|
|
14780
14711
|
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14781
14712
|
className: "flex flex-column justify-center",
|
|
14782
14713
|
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14783
14714
|
className: "flex gap-2",
|
|
14784
14715
|
children: [/*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14785
|
-
children: ["User ID:
|
|
14716
|
+
children: ["User ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14786
14717
|
children: userId
|
|
14787
14718
|
})]
|
|
14788
14719
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14789
|
-
children: ["Account ID:
|
|
14720
|
+
children: ["Account ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14790
14721
|
children: accountId
|
|
14791
14722
|
})]
|
|
14792
14723
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14793
|
-
children: ["Document ID:
|
|
14724
|
+
children: ["Document ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14794
14725
|
children: documentId
|
|
14795
14726
|
})]
|
|
14796
14727
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14797
|
-
children: ["Download ID:
|
|
14728
|
+
children: ["Download ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14798
14729
|
children: downloadId
|
|
14799
14730
|
})]
|
|
14800
14731
|
})]
|
|
@@ -14802,29 +14733,21 @@ function PdfView(_ref2) {
|
|
|
14802
14733
|
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14803
14734
|
className: "flex flex-column justify-center",
|
|
14804
14735
|
children: /*#__PURE__*/jsxRuntime.jsx("h5", {
|
|
14805
|
-
children:
|
|
14736
|
+
children: page
|
|
14806
14737
|
})
|
|
14807
14738
|
})]
|
|
14808
|
-
})]
|
|
14809
|
-
}
|
|
14739
|
+
}, "footers-".concat(page))]
|
|
14740
|
+
}))]
|
|
14810
14741
|
});
|
|
14811
14742
|
}
|
|
14812
14743
|
PdfView.propTypes = {
|
|
14813
|
-
config: PropTypes__default["default"].
|
|
14814
|
-
render: PropTypes__default["default"].func.isRequired,
|
|
14815
|
-
style: PropTypes__default["default"].object,
|
|
14816
|
-
priority: PropTypes__default["default"].oneOf([1, 2, 3]),
|
|
14817
|
-
keepWithNext: PropTypes__default["default"].bool,
|
|
14818
|
-
splittable: PropTypes__default["default"].bool,
|
|
14819
|
-
splitInto: PropTypes__default["default"].func // (maxHeightPx) => WidgetConfig[]
|
|
14820
|
-
})),
|
|
14744
|
+
config: PropTypes__default["default"].array,
|
|
14821
14745
|
customClassName: PropTypes__default["default"].any,
|
|
14822
14746
|
title: PropTypes__default["default"].string,
|
|
14823
14747
|
imgSrc: PropTypes__default["default"].string,
|
|
14824
14748
|
userId: PropTypes__default["default"].string,
|
|
14825
14749
|
accountId: PropTypes__default["default"].string,
|
|
14826
|
-
documentId: PropTypes__default["default"].string
|
|
14827
|
-
downloadId: PropTypes__default["default"].string
|
|
14750
|
+
documentId: PropTypes__default["default"].string
|
|
14828
14751
|
};
|
|
14829
14752
|
|
|
14830
14753
|
const ajaxSelectFieldData = async (value, config, getApiBaseUrl = () => {}, getAppHeader = () => {}, app, formValues = {}) => {
|
package/package.json
CHANGED
|
@@ -1,267 +1,207 @@
|
|
|
1
1
|
import moment from "moment";
|
|
2
|
-
import PropTypes from
|
|
3
|
-
import { useCallback, useEffect,
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { useCallback, useEffect, useRef, useState, useLayoutEffect } from "react";
|
|
4
4
|
import { formatClassname } from "../../../../../helpers/ClassesHelper";
|
|
5
5
|
|
|
6
6
|
const PAGE_HEIGHT = 1587;
|
|
7
|
-
|
|
7
|
+
// margin-top: 20, bottom: 20;
|
|
8
8
|
const FOOTER_HEIGHT = 70;
|
|
9
|
-
const
|
|
10
|
-
const FILL_RATIO = 0.80;
|
|
11
|
-
|
|
12
|
-
const CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
9
|
+
const HEADER_HEIGHT = 100;
|
|
13
10
|
|
|
14
|
-
const Row = ({ widgets, i, onChangeHeight = () => {} }) => {
|
|
15
|
-
const ref = useRef(
|
|
11
|
+
const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
|
|
12
|
+
const ref = useRef();
|
|
13
|
+
const [height, setHeight] = useState(0);
|
|
16
14
|
|
|
17
15
|
useLayoutEffect(() => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const observer = new ResizeObserver((entries) => {
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
setHeight(entry.contentRect.height);
|
|
19
|
+
}
|
|
22
20
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
|
|
22
|
+
observer.observe(ref.current);
|
|
23
|
+
|
|
24
|
+
return () => observer.disconnect();
|
|
25
|
+
}, [ref]);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (height) {
|
|
29
|
+
onChangeHeight(i, { height, ref });
|
|
30
|
+
}
|
|
31
|
+
}, [height])
|
|
26
32
|
|
|
27
33
|
return (
|
|
28
34
|
<section ref={ref} style={widgets.style}>
|
|
29
|
-
{typeof widgets.render ===
|
|
35
|
+
{typeof widgets.render === 'function' ? widgets.render() : null}
|
|
30
36
|
</section>
|
|
31
|
-
)
|
|
37
|
+
)
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
export default function PdfView({
|
|
35
41
|
config = [],
|
|
36
42
|
customClassName,
|
|
37
|
-
title =
|
|
38
|
-
imgSrc =
|
|
39
|
-
userId =
|
|
40
|
-
accountId =
|
|
41
|
-
documentId =
|
|
42
|
-
downloadId =
|
|
43
|
+
title = 'Title',
|
|
44
|
+
imgSrc = '',
|
|
45
|
+
userId = 'IDD-0000000',
|
|
46
|
+
accountId = 'IDD-0000000',
|
|
47
|
+
documentId = 'IDD-0000000',
|
|
48
|
+
downloadId = 'DWL-00000123',
|
|
43
49
|
}) {
|
|
44
|
-
|
|
45
|
-
const [
|
|
46
|
-
// index -> {height, ref}
|
|
47
|
-
const [sections, setSections] = useState({});
|
|
48
|
-
// [[indices for page 1], [indices for page 2], ...]
|
|
49
|
-
const [pageMap, setPageMap] = useState([]);
|
|
50
|
-
|
|
51
|
-
// Reset expansion when the external config changes
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
setExpandedConfig(config);
|
|
54
|
-
setSections({});
|
|
55
|
-
setPageMap([]);
|
|
56
|
-
}, [config]);
|
|
50
|
+
const [sectionsConfig, setSectionsConfig] = useState({});
|
|
51
|
+
const [pages, setPages] = useState([1]);
|
|
57
52
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
const doSizing = useCallback(() => {
|
|
54
|
+
const keys = Object.keys(sectionsConfig);
|
|
55
|
+
let _pages = [1];
|
|
56
|
+
let _page = 1;
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const keys = Object.keys(sections)
|
|
65
|
-
.map((k) => Number(k))
|
|
66
|
-
.sort((a, b) => a - b);
|
|
58
|
+
if (keys.length === config.length) {
|
|
59
|
+
let incrHeight = 0;
|
|
67
60
|
|
|
68
|
-
|
|
61
|
+
keys.forEach(k => {
|
|
62
|
+
const { ref } = sectionsConfig[k];
|
|
63
|
+
ref.current.style.marginBottom = '0px';
|
|
64
|
+
// ref.current.style.marginTop = '15px';
|
|
65
|
+
})
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const item = expandedConfig[idx];
|
|
73
|
-
const canSplit = item?.splittable && typeof item?.splitInto === "function";
|
|
74
|
-
if (canSplit && h > CONTENT_HEIGHT) {
|
|
75
|
-
// Split it and re-measure
|
|
76
|
-
const chunks = item.splitInto(CONTENT_HEIGHT);
|
|
77
|
-
const next = [
|
|
78
|
-
...expandedConfig.slice(0, idx),
|
|
79
|
-
...chunks,
|
|
80
|
-
...expandedConfig.slice(idx + 1),
|
|
81
|
-
];
|
|
82
|
-
setExpandedConfig(next);
|
|
83
|
-
setSections({}); // force re-measure since indices changed
|
|
84
|
-
setPageMap([]);
|
|
85
|
-
return; // do one split per layout pass to avoid loops
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}, [sections, expandedConfig]);
|
|
67
|
+
keys.forEach((k, i) => {
|
|
68
|
+
const { height, ref } = sectionsConfig[k];
|
|
89
69
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.sort((a, b) => a - b);
|
|
95
|
-
if (keys.length !== expandedConfig.length) return;
|
|
96
|
-
|
|
97
|
-
// Build meta (read hints from config)
|
|
98
|
-
const meta = keys.map((i) => ({
|
|
99
|
-
i,
|
|
100
|
-
h: sections[i].height,
|
|
101
|
-
priority: expandedConfig[i]?.priority ?? 2, // 1 > 2 > 3 (1 is most important)
|
|
102
|
-
keepWithNext: !!expandedConfig[i]?.keepWithNext,
|
|
103
|
-
}));
|
|
104
|
-
|
|
105
|
-
const threshold = Math.floor(CONTENT_HEIGHT * FILL_RATIO);
|
|
106
|
-
const pages = [];
|
|
107
|
-
let current = [];
|
|
108
|
-
let used = 0;
|
|
109
|
-
let carryKeep = false;
|
|
110
|
-
|
|
111
|
-
for (let k = 0; k < meta.length; k++) {
|
|
112
|
-
const curr = meta[k];
|
|
113
|
-
const hWithGap = (current.length === 0 ? 0 : GAP_BETWEEN_BLOCKS) + curr.h;
|
|
70
|
+
if (i === 0) {
|
|
71
|
+
ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
|
|
72
|
+
incrHeight += HEADER_HEIGHT;
|
|
73
|
+
}
|
|
114
74
|
|
|
115
|
-
|
|
116
|
-
if (carryKeep) {
|
|
117
|
-
// start current on a fresh page
|
|
118
|
-
if (current.length) pages.push(current);
|
|
119
|
-
current = [curr.i];
|
|
120
|
-
used = curr.h;
|
|
121
|
-
carryKeep = false;
|
|
122
|
-
if (curr.keepWithNext) carryKeep = true;
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
75
|
+
const newHeight = incrHeight + height;
|
|
125
76
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
current = [];
|
|
130
|
-
used = 0;
|
|
131
|
-
carryKeep = false;
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
77
|
+
if (i === keys.length - 1) {
|
|
78
|
+
ref.current.style.paddingBottom = '30px';
|
|
79
|
+
}
|
|
134
80
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const tentativeUsed = used - (j === 0 ? prev.h : (prev.h + GAP_BETWEEN_BLOCKS));
|
|
147
|
-
if (tentativeUsed + hWithGap <= threshold) {
|
|
148
|
-
// move prev off this page
|
|
149
|
-
current.splice(j, 1);
|
|
150
|
-
used = tentativeUsed;
|
|
151
|
-
moved = true;
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
81
|
+
if (newHeight > PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT) {
|
|
82
|
+
const dif = Math.abs(PAGE_HEIGHT - incrHeight);
|
|
83
|
+
ref.current.style.marginTop = '30px';
|
|
84
|
+
_page += 1;
|
|
85
|
+
_pages.push(_page);
|
|
86
|
+
|
|
87
|
+
if (sectionsConfig[keys[i - 1]]) {
|
|
88
|
+
const { ref: topRef } = sectionsConfig[keys[i - 1]];
|
|
89
|
+
topRef.current.style.marginBottom = `${dif + HEADER_HEIGHT - 24}px`;
|
|
90
|
+
incrHeight = height + 24 + HEADER_HEIGHT;
|
|
91
|
+
// console.log('margin', dif);
|
|
154
92
|
}
|
|
155
|
-
}
|
|
156
|
-
if (!moved) {
|
|
157
|
-
pages.push(current);
|
|
158
|
-
current = [curr.i];
|
|
159
|
-
used = curr.h; // first element on new page (no top gap)
|
|
160
93
|
} else {
|
|
161
|
-
|
|
162
|
-
current.push(curr.i);
|
|
163
|
-
used += hWithGap;
|
|
94
|
+
incrHeight = newHeight + 24;
|
|
164
95
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
96
|
+
// console.groupEnd();
|
|
97
|
+
})
|
|
98
|
+
setPages(_pages);
|
|
168
99
|
}
|
|
169
|
-
|
|
170
|
-
if (current.length) pages.push(current);
|
|
171
|
-
setPageMap(pages); // <-- unlimited pages; grows as needed
|
|
172
|
-
}, [expandedConfig, sections]);
|
|
100
|
+
}, [sectionsConfig]);
|
|
173
101
|
|
|
174
102
|
useEffect(() => {
|
|
175
|
-
|
|
176
|
-
}, [
|
|
103
|
+
doSizing();
|
|
104
|
+
}, [doSizing]);
|
|
177
105
|
|
|
178
|
-
const
|
|
106
|
+
const onChangeHeight = useCallback((index, conf) => {
|
|
107
|
+
setSectionsConfig((prev) => ({ ...prev, [index]: conf }))
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
const contClassName = formatClassname(['daf-analysis daf-pdf-view', customClassName]);
|
|
179
111
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
() => (
|
|
112
|
+
const renderDashboard = useCallback(() => {
|
|
113
|
+
return (
|
|
183
114
|
<div className="view-content">
|
|
184
115
|
<div className="daf-analysis-layout">
|
|
185
|
-
<div className=
|
|
186
|
-
{
|
|
187
|
-
<Row
|
|
116
|
+
<div className='sections-cont'>
|
|
117
|
+
{config.map((widgets, i) => (
|
|
118
|
+
<Row
|
|
119
|
+
widgets={widgets}
|
|
120
|
+
key={`dashboard-sections=${i + 1}`}
|
|
121
|
+
i={i}
|
|
122
|
+
onChangeHeight={onChangeHeight}
|
|
123
|
+
/>
|
|
188
124
|
))}
|
|
189
125
|
</div>
|
|
190
126
|
</div>
|
|
191
127
|
</div>
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
);
|
|
128
|
+
);
|
|
129
|
+
}, [config, onChangeHeight]);
|
|
195
130
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
{/* Render paginated pages (unlimited) */}
|
|
199
|
-
{pageMap.length > 0
|
|
200
|
-
? pageMap.map((indices, pageIdx) => (
|
|
201
|
-
<div
|
|
202
|
-
key={`page-${pageIdx}`}
|
|
203
|
-
className="pdf-page"
|
|
204
|
-
style={{ height: PAGE_HEIGHT, position: "relative", overflow: "hidden" }}
|
|
205
|
-
>
|
|
206
|
-
{/* Header */}
|
|
207
|
-
<div style={{ height: HEADER_HEIGHT }} className="flex-row dashboard-header">
|
|
208
|
-
<div className="flex flex-column justify-center flex-1">
|
|
209
|
-
<h2>{title}</h2>
|
|
210
|
-
</div>
|
|
211
|
-
<div className="flex flex-column justify-center">
|
|
212
|
-
<img src={imgSrc} alt="logo" />
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
131
|
+
// <div className="daf-analysis">
|
|
132
|
+
// <Header title={t('Dashboard Title')} />
|
|
215
133
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
))}
|
|
222
|
-
</div>
|
|
223
|
-
</div>
|
|
134
|
+
// <div className="content">
|
|
135
|
+
// <div className="view-content">
|
|
136
|
+
// <div className="daf-analysis-layout">
|
|
137
|
+
// <div className='sections-cont w-pt'>
|
|
138
|
+
// <section>
|
|
224
139
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
140
|
+
return (
|
|
141
|
+
<div className={contClassName} style={{ position: 'relative' }}>
|
|
142
|
+
{renderDashboard()}
|
|
143
|
+
{pages.map((page) => (
|
|
144
|
+
<>
|
|
145
|
+
<div
|
|
146
|
+
style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT - 24, position: 'absolute', left: 0, zIndex: 1000000 }}
|
|
147
|
+
key={`headers-${page}`}
|
|
148
|
+
className="flex-row dashboard-header"
|
|
149
|
+
>
|
|
150
|
+
<div className="flex flex-column justify-center flex-1">
|
|
151
|
+
<h2>{title}</h2>
|
|
152
|
+
</div>
|
|
153
|
+
<div className="flex flex-column justify-center">
|
|
154
|
+
<img src={imgSrc} alt="logo" />
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
<div
|
|
158
|
+
style={{ top: (page * PAGE_HEIGHT) - FOOTER_HEIGHT, width: '100%', height: FOOTER_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }}
|
|
159
|
+
key={`footers-${page}`}
|
|
160
|
+
className="dashboard-footer flex-row"
|
|
161
|
+
>
|
|
162
|
+
<div className="flex flex-column justify-center">
|
|
163
|
+
<h5>{moment().format('DD MMM YYYY')}</h5>
|
|
164
|
+
</div>
|
|
165
|
+
<div className="flex flex-column justify-center">
|
|
166
|
+
<div className="flex gap-2">
|
|
167
|
+
<h5>
|
|
168
|
+
User ID:
|
|
169
|
+
{' '}
|
|
170
|
+
<strong>{userId}</strong>
|
|
171
|
+
</h5>
|
|
172
|
+
<h5>
|
|
173
|
+
Account ID:
|
|
174
|
+
{' '}
|
|
175
|
+
<strong>{accountId}</strong>
|
|
176
|
+
</h5>
|
|
177
|
+
<h5>
|
|
178
|
+
Document ID:
|
|
179
|
+
{' '}
|
|
180
|
+
<strong>{documentId}</strong>
|
|
181
|
+
</h5>
|
|
182
|
+
<h5>
|
|
183
|
+
Download ID:
|
|
184
|
+
{' '}
|
|
185
|
+
<strong>{downloadId}</strong>
|
|
186
|
+
</h5>
|
|
241
187
|
</div>
|
|
242
188
|
</div>
|
|
243
|
-
|
|
244
|
-
|
|
189
|
+
<div className="flex flex-column justify-center">
|
|
190
|
+
<h5>{page}</h5>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</>
|
|
194
|
+
))}
|
|
245
195
|
</div>
|
|
246
196
|
);
|
|
247
197
|
}
|
|
248
198
|
|
|
249
199
|
PdfView.propTypes = {
|
|
250
|
-
config: PropTypes.
|
|
251
|
-
PropTypes.shape({
|
|
252
|
-
render: PropTypes.func.isRequired,
|
|
253
|
-
style: PropTypes.object,
|
|
254
|
-
priority: PropTypes.oneOf([1, 2, 3]),
|
|
255
|
-
keepWithNext: PropTypes.bool,
|
|
256
|
-
splittable: PropTypes.bool,
|
|
257
|
-
splitInto: PropTypes.func, // (maxHeightPx) => WidgetConfig[]
|
|
258
|
-
})
|
|
259
|
-
),
|
|
200
|
+
config: PropTypes.array,
|
|
260
201
|
customClassName: PropTypes.any,
|
|
261
202
|
title: PropTypes.string,
|
|
262
203
|
imgSrc: PropTypes.string,
|
|
263
204
|
userId: PropTypes.string,
|
|
264
205
|
accountId: PropTypes.string,
|
|
265
206
|
documentId: PropTypes.string,
|
|
266
|
-
|
|
267
|
-
};
|
|
207
|
+
}
|