datastake-daf 0.6.438 → 0.6.440
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 +124 -132
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/PdfView/index.jsx +125 -142
package/dist/components/index.js
CHANGED
|
@@ -14536,149 +14536,113 @@ DAFFooter.propTypes = {
|
|
|
14536
14536
|
};
|
|
14537
14537
|
|
|
14538
14538
|
const PAGE_HEIGHT = 1587;
|
|
14539
|
-
// margin-top: 20, bottom: 20;
|
|
14540
|
-
const FOOTER_HEIGHT = 70;
|
|
14541
14539
|
const HEADER_HEIGHT = 100;
|
|
14540
|
+
const FOOTER_HEIGHT = 70;
|
|
14541
|
+
const GAP_BETWEEN_BLOCKS = 24; // vertical spacing inside page
|
|
14542
|
+
const FILL_RATIO = 0.80; // your "80% of page" rule
|
|
14543
|
+
|
|
14544
|
+
const CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
14542
14545
|
const Row = _ref => {
|
|
14543
14546
|
let {
|
|
14544
14547
|
widgets,
|
|
14545
14548
|
i,
|
|
14546
14549
|
onChangeHeight = () => {}
|
|
14547
14550
|
} = _ref;
|
|
14548
|
-
const ref = React.useRef();
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
const
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
observer.observe(ref.current);
|
|
14557
|
-
return () => observer.disconnect();
|
|
14558
|
-
}, []);
|
|
14559
|
-
React.useEffect(() => {
|
|
14560
|
-
if (height) {
|
|
14561
|
-
onChangeHeight(i, {
|
|
14562
|
-
height,
|
|
14551
|
+
const ref = React.useRef(null);
|
|
14552
|
+
React.useLayoutEffect(() => {
|
|
14553
|
+
if (!ref.current) return;
|
|
14554
|
+
const ro = new ResizeObserver(entries => {
|
|
14555
|
+
var _entries$0$contentRec, _entries$;
|
|
14556
|
+
const h = (_entries$0$contentRec = (_entries$ = entries[0]) === null || _entries$ === void 0 || (_entries$ = _entries$.contentRect) === null || _entries$ === void 0 ? void 0 : _entries$.height) !== null && _entries$0$contentRec !== void 0 ? _entries$0$contentRec : 0;
|
|
14557
|
+
if (h) onChangeHeight(i, {
|
|
14558
|
+
height: h,
|
|
14563
14559
|
ref
|
|
14564
14560
|
});
|
|
14565
|
-
}
|
|
14566
|
-
|
|
14561
|
+
});
|
|
14562
|
+
ro.observe(ref.current);
|
|
14563
|
+
return () => ro.disconnect();
|
|
14564
|
+
}, [i, onChangeHeight]);
|
|
14567
14565
|
return /*#__PURE__*/jsxRuntime.jsx("section", {
|
|
14568
14566
|
ref: ref,
|
|
14569
14567
|
style: widgets.style,
|
|
14570
|
-
children: typeof widgets.render ===
|
|
14568
|
+
children: typeof widgets.render === "function" ? widgets.render() : null
|
|
14571
14569
|
});
|
|
14572
14570
|
};
|
|
14573
14571
|
function PdfView(_ref2) {
|
|
14574
14572
|
let {
|
|
14575
14573
|
config = [],
|
|
14576
14574
|
customClassName,
|
|
14577
|
-
title =
|
|
14578
|
-
imgSrc =
|
|
14579
|
-
userId =
|
|
14580
|
-
accountId =
|
|
14581
|
-
documentId =
|
|
14582
|
-
downloadId =
|
|
14575
|
+
title = "Title",
|
|
14576
|
+
imgSrc = "",
|
|
14577
|
+
userId = "IDD-0000000",
|
|
14578
|
+
accountId = "IDD-0000000",
|
|
14579
|
+
documentId = "IDD-0000000",
|
|
14580
|
+
downloadId = "DWL-00000123"
|
|
14583
14581
|
} = _ref2;
|
|
14584
|
-
|
|
14585
|
-
const [
|
|
14586
|
-
|
|
14587
|
-
|
|
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';
|
|
14598
|
-
});
|
|
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);
|
|
14624
|
-
}
|
|
14625
|
-
} else {
|
|
14626
|
-
incrHeight = newHeight + 24;
|
|
14627
|
-
}
|
|
14628
|
-
// console.groupEnd();
|
|
14629
|
-
});
|
|
14630
|
-
setPages(_pages);
|
|
14631
|
-
}
|
|
14632
|
-
}, [sectionsConfig]);
|
|
14633
|
-
React.useEffect(() => {
|
|
14634
|
-
doSizing();
|
|
14635
|
-
}, [doSizing]);
|
|
14582
|
+
// index -> {height, ref}
|
|
14583
|
+
const [sections, setSections] = React.useState({});
|
|
14584
|
+
// pageMap is an array of arrays of indices, e.g. [[0,1,2],[3,4],...]
|
|
14585
|
+
const [pageMap, setPageMap] = React.useState([]);
|
|
14636
14586
|
const onChangeHeight = React.useCallback((index, conf) => {
|
|
14637
|
-
|
|
14638
|
-
|
|
14639
|
-
|
|
14640
|
-
|
|
14641
|
-
|
|
14642
|
-
const renderDashboard = React.useCallback(() => {
|
|
14643
|
-
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14644
|
-
className: "view-content",
|
|
14645
|
-
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
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
|
-
})
|
|
14655
|
-
})
|
|
14587
|
+
setSections(prev => {
|
|
14588
|
+
var _prev$index;
|
|
14589
|
+
return ((_prev$index = prev[index]) === null || _prev$index === void 0 ? void 0 : _prev$index.height) === conf.height ? prev : _objectSpread2(_objectSpread2({}, prev), {}, {
|
|
14590
|
+
[index]: conf
|
|
14591
|
+
});
|
|
14656
14592
|
});
|
|
14657
|
-
}, [
|
|
14658
|
-
|
|
14659
|
-
// <div className="daf-analysis">
|
|
14660
|
-
// <Header title={t('Dashboard Title')} />
|
|
14593
|
+
}, []);
|
|
14661
14594
|
|
|
14662
|
-
//
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14595
|
+
// Core paginator: greedy packing with 80% threshold
|
|
14596
|
+
const paginate = React.useCallback(() => {
|
|
14597
|
+
const keys = Object.keys(sections).map(k => Number(k)).sort((a, b) => a - b);
|
|
14598
|
+
if (keys.length !== config.length) return; // wait until all measured
|
|
14599
|
+
|
|
14600
|
+
const threshold = Math.floor(CONTENT_HEIGHT * FILL_RATIO);
|
|
14601
|
+
const pages = [];
|
|
14602
|
+
let current = [];
|
|
14603
|
+
let used = 0;
|
|
14604
|
+
for (let idx of keys) {
|
|
14605
|
+
const h = sections[idx].height;
|
|
14606
|
+
const hWithGap = (current.length === 0 ? 0 : GAP_BETWEEN_BLOCKS) + h;
|
|
14607
|
+
|
|
14608
|
+
// Oversized single block: start a new page but still place it alone
|
|
14609
|
+
if (h > threshold && current.length === 0) {
|
|
14610
|
+
current.push(idx);
|
|
14611
|
+
pages.push(current);
|
|
14612
|
+
current = [];
|
|
14613
|
+
used = 0;
|
|
14614
|
+
continue;
|
|
14615
|
+
}
|
|
14616
|
+
if (current.length === 0 || used + hWithGap <= threshold) {
|
|
14617
|
+
current.push(idx);
|
|
14618
|
+
used += hWithGap;
|
|
14619
|
+
} else {
|
|
14620
|
+
pages.push(current);
|
|
14621
|
+
current = [idx];
|
|
14622
|
+
used = h; // first item on a fresh page, no top gap
|
|
14623
|
+
}
|
|
14624
|
+
}
|
|
14625
|
+
if (current.length) pages.push(current);
|
|
14626
|
+
setPageMap(pages);
|
|
14627
|
+
}, [sections, config.length]);
|
|
14667
14628
|
|
|
14629
|
+
// Re-run pagination when sizes change
|
|
14630
|
+
React.useEffect(() => {
|
|
14631
|
+
paginate();
|
|
14632
|
+
}, [paginate]);
|
|
14633
|
+
const contClassName = formatClassname(["daf-analysis daf-pdf-view", customClassName]);
|
|
14668
14634
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14669
14635
|
className: contClassName,
|
|
14670
|
-
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
14636
|
+
children: [pageMap.map((indices, pageIdx) => /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14637
|
+
className: "pdf-page",
|
|
14638
|
+
style: {
|
|
14639
|
+
height: PAGE_HEIGHT,
|
|
14640
|
+
position: "relative",
|
|
14641
|
+
overflow: "hidden"
|
|
14642
|
+
},
|
|
14674
14643
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14675
14644
|
style: {
|
|
14676
|
-
|
|
14677
|
-
width: '100%',
|
|
14678
|
-
height: HEADER_HEIGHT - 24,
|
|
14679
|
-
position: 'absolute',
|
|
14680
|
-
left: 0,
|
|
14681
|
-
zIndex: 1000000
|
|
14645
|
+
height: HEADER_HEIGHT
|
|
14682
14646
|
},
|
|
14683
14647
|
className: "flex-row dashboard-header",
|
|
14684
14648
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -14693,39 +14657,53 @@ function PdfView(_ref2) {
|
|
|
14693
14657
|
alt: "logo"
|
|
14694
14658
|
})
|
|
14695
14659
|
})]
|
|
14696
|
-
}
|
|
14660
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14661
|
+
className: "pdf-body",
|
|
14697
14662
|
style: {
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14663
|
+
minHeight: CONTENT_HEIGHT,
|
|
14664
|
+
paddingTop: 0,
|
|
14665
|
+
paddingBottom: 0
|
|
14666
|
+
},
|
|
14667
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14668
|
+
style: {
|
|
14669
|
+
display: "flex",
|
|
14670
|
+
flexDirection: "column",
|
|
14671
|
+
gap: GAP_BETWEEN_BLOCKS
|
|
14672
|
+
},
|
|
14673
|
+
children: indices.map(i => /*#__PURE__*/jsxRuntime.jsx(Row, {
|
|
14674
|
+
widgets: config[i],
|
|
14675
|
+
i: i,
|
|
14676
|
+
onChangeHeight: onChangeHeight
|
|
14677
|
+
}, "row-".concat(i)))
|
|
14678
|
+
})
|
|
14679
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14680
|
+
style: {
|
|
14681
|
+
height: FOOTER_HEIGHT
|
|
14704
14682
|
},
|
|
14705
14683
|
className: "dashboard-footer flex-row",
|
|
14706
14684
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14707
14685
|
className: "flex flex-column justify-center",
|
|
14708
14686
|
children: /*#__PURE__*/jsxRuntime.jsx("h5", {
|
|
14709
|
-
children: moment__default["default"]().format(
|
|
14687
|
+
children: moment__default["default"]().format("DD MMM YYYY")
|
|
14710
14688
|
})
|
|
14711
14689
|
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14712
14690
|
className: "flex flex-column justify-center",
|
|
14713
14691
|
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
14714
14692
|
className: "flex gap-2",
|
|
14715
14693
|
children: [/*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14716
|
-
children: ["User ID:",
|
|
14694
|
+
children: ["User ID: ", /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14717
14695
|
children: userId
|
|
14718
14696
|
})]
|
|
14719
14697
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14720
|
-
children: ["Account ID:",
|
|
14698
|
+
children: ["Account ID: ", /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14721
14699
|
children: accountId
|
|
14722
14700
|
})]
|
|
14723
14701
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14724
|
-
children: ["Document ID:",
|
|
14702
|
+
children: ["Document ID: ", /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14725
14703
|
children: documentId
|
|
14726
14704
|
})]
|
|
14727
14705
|
}), /*#__PURE__*/jsxRuntime.jsxs("h5", {
|
|
14728
|
-
children: ["Download ID:",
|
|
14706
|
+
children: ["Download ID: ", /*#__PURE__*/jsxRuntime.jsx("strong", {
|
|
14729
14707
|
children: downloadId
|
|
14730
14708
|
})]
|
|
14731
14709
|
})]
|
|
@@ -14733,11 +14711,24 @@ function PdfView(_ref2) {
|
|
|
14733
14711
|
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14734
14712
|
className: "flex flex-column justify-center",
|
|
14735
14713
|
children: /*#__PURE__*/jsxRuntime.jsx("h5", {
|
|
14736
|
-
children:
|
|
14714
|
+
children: pageIdx + 1
|
|
14737
14715
|
})
|
|
14738
14716
|
})]
|
|
14739
|
-
}
|
|
14740
|
-
}))
|
|
14717
|
+
})]
|
|
14718
|
+
}, "page-".concat(pageIdx))), pageMap.length === 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14719
|
+
className: "view-content",
|
|
14720
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14721
|
+
className: "daf-analysis-layout",
|
|
14722
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
14723
|
+
className: "sections-cont",
|
|
14724
|
+
children: config.map((widgets, i) => /*#__PURE__*/jsxRuntime.jsx(Row, {
|
|
14725
|
+
widgets: widgets,
|
|
14726
|
+
i: i,
|
|
14727
|
+
onChangeHeight: onChangeHeight
|
|
14728
|
+
}, "measure-".concat(i)))
|
|
14729
|
+
})
|
|
14730
|
+
})
|
|
14731
|
+
})]
|
|
14741
14732
|
});
|
|
14742
14733
|
}
|
|
14743
14734
|
PdfView.propTypes = {
|
|
@@ -14747,7 +14738,8 @@ PdfView.propTypes = {
|
|
|
14747
14738
|
imgSrc: PropTypes__default["default"].string,
|
|
14748
14739
|
userId: PropTypes__default["default"].string,
|
|
14749
14740
|
accountId: PropTypes__default["default"].string,
|
|
14750
|
-
documentId: PropTypes__default["default"].string
|
|
14741
|
+
documentId: PropTypes__default["default"].string,
|
|
14742
|
+
downloadId: PropTypes__default["default"].string
|
|
14751
14743
|
};
|
|
14752
14744
|
|
|
14753
14745
|
const ajaxSelectFieldData = async (value, config, getApiBaseUrl = () => {}, getAppHeader = () => {}, app, formValues = {}) => {
|
package/package.json
CHANGED
|
@@ -1,152 +1,113 @@
|
|
|
1
1
|
import moment from "moment";
|
|
2
|
-
import PropTypes from
|
|
3
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { formatClassname } from "../../../../../helpers/ClassesHelper";
|
|
5
5
|
|
|
6
6
|
const PAGE_HEIGHT = 1587;
|
|
7
|
-
// margin-top: 20, bottom: 20;
|
|
8
|
-
const FOOTER_HEIGHT = 70;
|
|
9
7
|
const HEADER_HEIGHT = 100;
|
|
8
|
+
const FOOTER_HEIGHT = 70;
|
|
9
|
+
const GAP_BETWEEN_BLOCKS = 24; // vertical spacing inside page
|
|
10
|
+
const FILL_RATIO = 0.80; // your "80% of page" rule
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
-
const ref = useRef();
|
|
13
|
-
const [height, setHeight] = useState(0);
|
|
14
|
-
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
const observer = new ResizeObserver((entries) => {
|
|
17
|
-
for (const entry of entries) {
|
|
18
|
-
setHeight(entry.contentRect.height);
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
observer.observe(ref.current);
|
|
12
|
+
const CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
const Row = ({ widgets, i, onChangeHeight = () => {} }) => {
|
|
15
|
+
const ref = useRef(null);
|
|
26
16
|
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
if (!ref.current) return;
|
|
19
|
+
const ro = new ResizeObserver((entries) => {
|
|
20
|
+
const h = entries[0]?.contentRect?.height ?? 0;
|
|
21
|
+
if (h) onChangeHeight(i, { height: h, ref });
|
|
22
|
+
});
|
|
23
|
+
ro.observe(ref.current);
|
|
24
|
+
return () => ro.disconnect();
|
|
25
|
+
}, [i, onChangeHeight]);
|
|
32
26
|
|
|
33
27
|
return (
|
|
34
28
|
<section ref={ref} style={widgets.style}>
|
|
35
|
-
{typeof widgets.render ===
|
|
29
|
+
{typeof widgets.render === "function" ? widgets.render() : null}
|
|
36
30
|
</section>
|
|
37
|
-
)
|
|
31
|
+
);
|
|
38
32
|
};
|
|
39
33
|
|
|
40
34
|
export default function PdfView({
|
|
41
35
|
config = [],
|
|
42
36
|
customClassName,
|
|
43
|
-
title =
|
|
44
|
-
imgSrc =
|
|
45
|
-
userId =
|
|
46
|
-
accountId =
|
|
47
|
-
documentId =
|
|
48
|
-
downloadId =
|
|
37
|
+
title = "Title",
|
|
38
|
+
imgSrc = "",
|
|
39
|
+
userId = "IDD-0000000",
|
|
40
|
+
accountId = "IDD-0000000",
|
|
41
|
+
documentId = "IDD-0000000",
|
|
42
|
+
downloadId = "DWL-00000123",
|
|
49
43
|
}) {
|
|
50
|
-
|
|
51
|
-
const [
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const keys = Object.keys(sectionsConfig);
|
|
55
|
-
let _pages = [1];
|
|
56
|
-
let _page = 1;
|
|
57
|
-
|
|
58
|
-
if (keys.length === config.length) {
|
|
59
|
-
let incrHeight = 0;
|
|
60
|
-
|
|
61
|
-
keys.forEach(k => {
|
|
62
|
-
const { ref } = sectionsConfig[k];
|
|
63
|
-
ref.current.style.marginBottom = '0px';
|
|
64
|
-
// ref.current.style.marginTop = '15px';
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
keys.forEach((k, i) => {
|
|
68
|
-
const { height, ref } = sectionsConfig[k];
|
|
69
|
-
|
|
70
|
-
if (i === 0) {
|
|
71
|
-
ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
|
|
72
|
-
incrHeight += HEADER_HEIGHT;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const newHeight = incrHeight + height;
|
|
76
|
-
|
|
77
|
-
if (i === keys.length - 1) {
|
|
78
|
-
ref.current.style.paddingBottom = '30px';
|
|
79
|
-
}
|
|
80
|
-
|
|
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);
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
incrHeight = newHeight + 24;
|
|
95
|
-
}
|
|
96
|
-
// console.groupEnd();
|
|
97
|
-
})
|
|
98
|
-
setPages(_pages);
|
|
99
|
-
}
|
|
100
|
-
}, [sectionsConfig]);
|
|
101
|
-
|
|
102
|
-
useEffect(() => {
|
|
103
|
-
doSizing();
|
|
104
|
-
}, [doSizing]);
|
|
44
|
+
// index -> {height, ref}
|
|
45
|
+
const [sections, setSections] = useState({});
|
|
46
|
+
// pageMap is an array of arrays of indices, e.g. [[0,1,2],[3,4],...]
|
|
47
|
+
const [pageMap, setPageMap] = useState([]);
|
|
105
48
|
|
|
106
49
|
const onChangeHeight = useCallback((index, conf) => {
|
|
107
|
-
|
|
50
|
+
setSections((prev) => (prev[index]?.height === conf.height ? prev : { ...prev, [index]: conf }));
|
|
108
51
|
}, []);
|
|
109
52
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
53
|
+
// Core paginator: greedy packing with 80% threshold
|
|
54
|
+
const paginate = useCallback(() => {
|
|
55
|
+
const keys = Object.keys(sections)
|
|
56
|
+
.map((k) => Number(k))
|
|
57
|
+
.sort((a, b) => a - b);
|
|
58
|
+
|
|
59
|
+
if (keys.length !== config.length) return; // wait until all measured
|
|
60
|
+
|
|
61
|
+
const threshold = Math.floor(CONTENT_HEIGHT * FILL_RATIO);
|
|
62
|
+
const pages = [];
|
|
63
|
+
let current = [];
|
|
64
|
+
let used = 0;
|
|
65
|
+
|
|
66
|
+
for (let idx of keys) {
|
|
67
|
+
const h = sections[idx].height;
|
|
68
|
+
const hWithGap = (current.length === 0 ? 0 : GAP_BETWEEN_BLOCKS) + h;
|
|
69
|
+
|
|
70
|
+
// Oversized single block: start a new page but still place it alone
|
|
71
|
+
if (h > threshold && current.length === 0) {
|
|
72
|
+
current.push(idx);
|
|
73
|
+
pages.push(current);
|
|
74
|
+
current = [];
|
|
75
|
+
used = 0;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
130
78
|
|
|
131
|
-
|
|
132
|
-
|
|
79
|
+
if (current.length === 0 || used + hWithGap <= threshold) {
|
|
80
|
+
current.push(idx);
|
|
81
|
+
used += hWithGap;
|
|
82
|
+
} else {
|
|
83
|
+
pages.push(current);
|
|
84
|
+
current = [idx];
|
|
85
|
+
used = h; // first item on a fresh page, no top gap
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (current.length) pages.push(current);
|
|
90
|
+
setPageMap(pages);
|
|
91
|
+
}, [sections, config.length]);
|
|
92
|
+
|
|
93
|
+
// Re-run pagination when sizes change
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
paginate();
|
|
96
|
+
}, [paginate]);
|
|
133
97
|
|
|
134
|
-
|
|
135
|
-
// <div className="view-content">
|
|
136
|
-
// <div className="daf-analysis-layout">
|
|
137
|
-
// <div className='sections-cont w-pt'>
|
|
138
|
-
// <section>
|
|
98
|
+
const contClassName = formatClassname(["daf-analysis daf-pdf-view", customClassName]);
|
|
139
99
|
|
|
140
100
|
return (
|
|
141
|
-
<div className={contClassName}
|
|
142
|
-
{
|
|
143
|
-
{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
101
|
+
<div className={contClassName}>
|
|
102
|
+
{/* Render final paginated pages */}
|
|
103
|
+
{pageMap.map((indices, pageIdx) => (
|
|
104
|
+
<div
|
|
105
|
+
key={`page-${pageIdx}`}
|
|
106
|
+
className="pdf-page"
|
|
107
|
+
style={{ height: PAGE_HEIGHT, position: "relative", overflow: "hidden" }}
|
|
108
|
+
>
|
|
109
|
+
{/* Header */}
|
|
110
|
+
<div style={{ height: HEADER_HEIGHT }} className="flex-row dashboard-header">
|
|
150
111
|
<div className="flex flex-column justify-center flex-1">
|
|
151
112
|
<h2>{title}</h2>
|
|
152
113
|
</div>
|
|
@@ -154,44 +115,65 @@ export default function PdfView({
|
|
|
154
115
|
<img src={imgSrc} alt="logo" />
|
|
155
116
|
</div>
|
|
156
117
|
</div>
|
|
118
|
+
|
|
119
|
+
{/* Body */}
|
|
157
120
|
<div
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
121
|
+
className="pdf-body"
|
|
122
|
+
style={{
|
|
123
|
+
minHeight: CONTENT_HEIGHT,
|
|
124
|
+
paddingTop: 0,
|
|
125
|
+
paddingBottom: 0,
|
|
126
|
+
}}
|
|
161
127
|
>
|
|
128
|
+
<div style={{ display: "flex", flexDirection: "column", gap: GAP_BETWEEN_BLOCKS }}>
|
|
129
|
+
{indices.map((i) => (
|
|
130
|
+
<Row key={`row-${i}`} widgets={config[i]} i={i} onChangeHeight={onChangeHeight} />
|
|
131
|
+
))}
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
{/* Footer */}
|
|
136
|
+
<div style={{ height: FOOTER_HEIGHT }} className="dashboard-footer flex-row">
|
|
162
137
|
<div className="flex flex-column justify-center">
|
|
163
|
-
<h5>{moment().format(
|
|
138
|
+
<h5>{moment().format("DD MMM YYYY")}</h5>
|
|
164
139
|
</div>
|
|
165
140
|
<div className="flex flex-column justify-center">
|
|
166
141
|
<div className="flex gap-2">
|
|
167
142
|
<h5>
|
|
168
|
-
User ID:
|
|
169
|
-
{' '}
|
|
170
|
-
<strong>{userId}</strong>
|
|
143
|
+
User ID: <strong>{userId}</strong>
|
|
171
144
|
</h5>
|
|
172
145
|
<h5>
|
|
173
|
-
Account ID:
|
|
174
|
-
{' '}
|
|
175
|
-
<strong>{accountId}</strong>
|
|
146
|
+
Account ID: <strong>{accountId}</strong>
|
|
176
147
|
</h5>
|
|
177
148
|
<h5>
|
|
178
|
-
Document ID:
|
|
179
|
-
{' '}
|
|
180
|
-
<strong>{documentId}</strong>
|
|
149
|
+
Document ID: <strong>{documentId}</strong>
|
|
181
150
|
</h5>
|
|
182
151
|
<h5>
|
|
183
|
-
Download ID:
|
|
184
|
-
{' '}
|
|
185
|
-
<strong>{downloadId}</strong>
|
|
152
|
+
Download ID: <strong>{downloadId}</strong>
|
|
186
153
|
</h5>
|
|
187
154
|
</div>
|
|
188
155
|
</div>
|
|
189
156
|
<div className="flex flex-column justify-center">
|
|
190
|
-
<h5>{
|
|
157
|
+
<h5>{pageIdx + 1}</h5>
|
|
191
158
|
</div>
|
|
192
159
|
</div>
|
|
193
|
-
|
|
160
|
+
</div>
|
|
194
161
|
))}
|
|
162
|
+
|
|
163
|
+
{/* Optional: first pass "measurement layer" for instant sizes (kept visible).
|
|
164
|
+
If you want to avoid double-render cost, keep as-is; if you want to hide it after pagination,
|
|
165
|
+
you can track a 'measured' flag and conditionally render. */}
|
|
166
|
+
{pageMap.length === 0 && (
|
|
167
|
+
<div className="view-content">
|
|
168
|
+
<div className="daf-analysis-layout">
|
|
169
|
+
<div className="sections-cont">
|
|
170
|
+
{config.map((widgets, i) => (
|
|
171
|
+
<Row key={`measure-${i}`} widgets={widgets} i={i} onChangeHeight={onChangeHeight} />
|
|
172
|
+
))}
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
)}
|
|
195
177
|
</div>
|
|
196
178
|
);
|
|
197
179
|
}
|
|
@@ -204,4 +186,5 @@ PdfView.propTypes = {
|
|
|
204
186
|
userId: PropTypes.string,
|
|
205
187
|
accountId: PropTypes.string,
|
|
206
188
|
documentId: PropTypes.string,
|
|
207
|
-
|
|
189
|
+
downloadId: PropTypes.string,
|
|
190
|
+
};
|