datastake-daf 0.6.423 → 0.6.425
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
CHANGED
|
@@ -13303,14 +13303,41 @@ DAFFooter.propTypes = {
|
|
|
13303
13303
|
};
|
|
13304
13304
|
|
|
13305
13305
|
const PAGE_HEIGHT = 1587;
|
|
13306
|
+
// margin-top: 20, bottom: 20;
|
|
13306
13307
|
const FOOTER_HEIGHT = 70;
|
|
13307
13308
|
const HEADER_HEIGHT = 100;
|
|
13308
|
-
const
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13309
|
+
const Row = _ref => {
|
|
13310
|
+
let {
|
|
13311
|
+
widgets,
|
|
13312
|
+
i,
|
|
13313
|
+
onChangeHeight = () => {}
|
|
13314
|
+
} = _ref;
|
|
13315
|
+
const ref = React.useRef();
|
|
13316
|
+
const [height, setHeight] = React.useState(0);
|
|
13317
|
+
React.useEffect(() => {
|
|
13318
|
+
const observer = new ResizeObserver(entries => {
|
|
13319
|
+
for (const entry of entries) {
|
|
13320
|
+
setHeight(entry.contentRect.height);
|
|
13321
|
+
}
|
|
13322
|
+
});
|
|
13323
|
+
observer.observe(ref.current);
|
|
13324
|
+
return () => observer.disconnect();
|
|
13325
|
+
}, []);
|
|
13326
|
+
React.useEffect(() => {
|
|
13327
|
+
if (height) {
|
|
13328
|
+
onChangeHeight(i, {
|
|
13329
|
+
height,
|
|
13330
|
+
ref
|
|
13331
|
+
});
|
|
13332
|
+
}
|
|
13333
|
+
}, [height]);
|
|
13334
|
+
return /*#__PURE__*/jsxRuntime.jsx("section", {
|
|
13335
|
+
ref: ref,
|
|
13336
|
+
style: widgets.style,
|
|
13337
|
+
children: typeof widgets.render === 'function' ? widgets.render() : null
|
|
13338
|
+
});
|
|
13339
|
+
};
|
|
13340
|
+
function PdfView(_ref2) {
|
|
13314
13341
|
let {
|
|
13315
13342
|
config = [],
|
|
13316
13343
|
customClassName,
|
|
@@ -13320,224 +13347,105 @@ function PdfView(_ref) {
|
|
|
13320
13347
|
accountId = 'IDD-0000000',
|
|
13321
13348
|
documentId = 'IDD-0000000',
|
|
13322
13349
|
downloadId = 'DWL-00000123'
|
|
13323
|
-
} =
|
|
13350
|
+
} = _ref2;
|
|
13351
|
+
const [sectionsConfig, setSectionsConfig] = React.useState({});
|
|
13324
13352
|
const [pages, setPages] = React.useState([1]);
|
|
13325
|
-
const
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
// Reset all children
|
|
13339
|
-
const allElements = section.querySelectorAll('*');
|
|
13340
|
-
allElements.forEach(el => {
|
|
13341
|
-
if (!isHTMLElement(el)) return;
|
|
13342
|
-
el.style.marginTop = '';
|
|
13343
|
-
el.style.marginBottom = '';
|
|
13344
|
-
el.style.pageBreakBefore = '';
|
|
13345
|
-
el.style.breakBefore = '';
|
|
13346
|
-
el.removeAttribute('data-pdf-page');
|
|
13347
|
-
});
|
|
13348
|
-
});
|
|
13349
|
-
}, []);
|
|
13350
|
-
const getAllBreakableElements = React.useCallback(section => {
|
|
13351
|
-
const elements = [];
|
|
13352
|
-
const shouldInclude = el => {
|
|
13353
|
-
if (!isHTMLElement(el)) return false;
|
|
13354
|
-
const style = window.getComputedStyle(el);
|
|
13355
|
-
if (style.display === 'inline' || style.display === 'contents') return false;
|
|
13356
|
-
if (style.position === 'absolute' || style.position === 'fixed') return false;
|
|
13357
|
-
if (el.offsetHeight === 0) return false;
|
|
13358
|
-
return true;
|
|
13359
|
-
};
|
|
13360
|
-
const traverse = parent => {
|
|
13361
|
-
Array.from(parent.children).forEach(child => {
|
|
13362
|
-
if (shouldInclude(child)) {
|
|
13363
|
-
elements.push(child);
|
|
13364
|
-
traverse(child);
|
|
13365
|
-
}
|
|
13353
|
+
const doSizing = React.useCallback(() => {
|
|
13354
|
+
const keys = Object.keys(sectionsConfig);
|
|
13355
|
+
let _pages = [1];
|
|
13356
|
+
let _page = 1;
|
|
13357
|
+
if (keys.length === config.length) {
|
|
13358
|
+
let incrHeight = 0;
|
|
13359
|
+
keys.forEach(k => {
|
|
13360
|
+
const {
|
|
13361
|
+
ref
|
|
13362
|
+
} = sectionsConfig[k];
|
|
13363
|
+
ref.current.style.marginBottom = '0px';
|
|
13364
|
+
// ref.current.style.marginTop = '15px';
|
|
13366
13365
|
});
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
// First item on page
|
|
13393
|
-
if (currentPage === 1) {
|
|
13394
|
-
// Very first section on first page - needs to be below header
|
|
13395
|
-
section.style.marginTop = '0px'; // Container padding handles this
|
|
13396
|
-
} else {
|
|
13397
|
-
// First section on subsequent pages - no margin (container padding handles it)
|
|
13398
|
-
section.style.marginTop = '0px';
|
|
13366
|
+
keys.forEach((k, i) => {
|
|
13367
|
+
const {
|
|
13368
|
+
height,
|
|
13369
|
+
ref
|
|
13370
|
+
} = sectionsConfig[k];
|
|
13371
|
+
if (i === 0) {
|
|
13372
|
+
ref.current.style.marginTop = "".concat(HEADER_HEIGHT, "px");
|
|
13373
|
+
incrHeight += HEADER_HEIGHT;
|
|
13374
|
+
}
|
|
13375
|
+
const newHeight = incrHeight + height;
|
|
13376
|
+
if (i === keys.length - 1) {
|
|
13377
|
+
ref.current.style.paddingBottom = '30px';
|
|
13378
|
+
}
|
|
13379
|
+
if (newHeight > PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT) {
|
|
13380
|
+
const dif = Math.abs(PAGE_HEIGHT - incrHeight);
|
|
13381
|
+
ref.current.style.marginTop = '30px';
|
|
13382
|
+
_page += 1;
|
|
13383
|
+
_pages.push(_page);
|
|
13384
|
+
if (sectionsConfig[keys[i - 1]]) {
|
|
13385
|
+
const {
|
|
13386
|
+
ref: topRef
|
|
13387
|
+
} = sectionsConfig[keys[i - 1]];
|
|
13388
|
+
topRef.current.style.marginBottom = "".concat(dif + HEADER_HEIGHT - 24, "px");
|
|
13389
|
+
incrHeight = height + 24 + HEADER_HEIGHT;
|
|
13390
|
+
// console.log('margin', dif);
|
|
13399
13391
|
}
|
|
13400
13392
|
} else {
|
|
13401
|
-
|
|
13402
|
-
section.style.marginTop = "".concat(SECTION_GAP, "px");
|
|
13393
|
+
incrHeight = newHeight + 24;
|
|
13403
13394
|
}
|
|
13404
|
-
|
|
13405
|
-
}
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
// Calculate margin needed to push this section to the next page
|
|
13410
|
-
// remainingSpace = space left on current page
|
|
13411
|
-
// Then we need to skip: footer margin + footer + header margin + header
|
|
13412
|
-
const pushMargin = remainingSpace + PAGE_MARGIN_BOTTOM + FOOTER_HEIGHT + PAGE_MARGIN_TOP + HEADER_HEIGHT;
|
|
13413
|
-
|
|
13414
|
-
// Move entire section to next page
|
|
13415
|
-
currentPage += 1;
|
|
13416
|
-
section.setAttribute('data-pdf-page', currentPage.toString());
|
|
13417
|
-
section.style.pageBreakBefore = 'always';
|
|
13418
|
-
section.style.breakBefore = 'page';
|
|
13419
|
-
section.style.marginTop = "".concat(pushMargin, "px");
|
|
13420
|
-
|
|
13421
|
-
// Start fresh height counter for new page
|
|
13422
|
-
currentPageHeight = sectionHeight;
|
|
13423
|
-
|
|
13424
|
-
// Check if section is too tall and needs internal breaks
|
|
13425
|
-
if (sectionHeight > CONTENT_HEIGHT) {
|
|
13426
|
-
// Try to break within section
|
|
13427
|
-
const innerElements = getAllBreakableElements(section);
|
|
13428
|
-
let pageHeightInSection = 0;
|
|
13429
|
-
let sectionPage = currentPage;
|
|
13430
|
-
for (const el of innerElements) {
|
|
13431
|
-
const rect = el.getBoundingClientRect();
|
|
13432
|
-
const sectionRect = section.getBoundingClientRect();
|
|
13433
|
-
const relativeTop = rect.top - sectionRect.top;
|
|
13434
|
-
const elHeight = rect.height;
|
|
13435
|
-
|
|
13436
|
-
// Check if this element would exceed the page
|
|
13437
|
-
if (pageHeightInSection + elHeight > CONTENT_HEIGHT && relativeTop > 50) {
|
|
13438
|
-
// Calculate remaining space on this page within the section
|
|
13439
|
-
const remainingInSection = CONTENT_HEIGHT - pageHeightInSection;
|
|
13440
|
-
const pushMarginInner = remainingInSection + PAGE_MARGIN_BOTTOM + FOOTER_HEIGHT + PAGE_MARGIN_TOP + HEADER_HEIGHT;
|
|
13441
|
-
sectionPage += 1;
|
|
13442
|
-
el.setAttribute('data-pdf-page', sectionPage.toString());
|
|
13443
|
-
el.style.pageBreakBefore = 'always';
|
|
13444
|
-
el.style.breakBefore = 'page';
|
|
13445
|
-
el.style.marginTop = "".concat(pushMarginInner, "px");
|
|
13446
|
-
|
|
13447
|
-
// Reset page height for new page within section
|
|
13448
|
-
pageHeightInSection = elHeight;
|
|
13449
|
-
} else {
|
|
13450
|
-
pageHeightInSection += elHeight;
|
|
13451
|
-
}
|
|
13452
|
-
}
|
|
13453
|
-
|
|
13454
|
-
// Update current page if we created additional pages
|
|
13455
|
-
if (sectionPage > currentPage) {
|
|
13456
|
-
currentPage = sectionPage;
|
|
13457
|
-
currentPageHeight = pageHeightInSection;
|
|
13458
|
-
}
|
|
13459
|
-
}
|
|
13460
|
-
}
|
|
13461
|
-
});
|
|
13462
|
-
setPages(Array.from({
|
|
13463
|
-
length: currentPage
|
|
13464
|
-
}, (_, idx) => idx + 1));
|
|
13465
|
-
|
|
13466
|
-
// Reset flag after a brief delay to allow next calculation
|
|
13467
|
-
setTimeout(() => {
|
|
13468
|
-
isCalculatingRef.current = false;
|
|
13469
|
-
}, 100);
|
|
13470
|
-
}, [getAllBreakableElements, resetPaginationStyles]);
|
|
13471
|
-
React.useLayoutEffect(() => {
|
|
13472
|
-
// Use requestAnimationFrame to ensure DOM is painted
|
|
13473
|
-
const rafId = requestAnimationFrame(() => {
|
|
13474
|
-
paginateContent();
|
|
13475
|
-
});
|
|
13476
|
-
return () => cancelAnimationFrame(rafId);
|
|
13477
|
-
}, [paginateContent, config]);
|
|
13395
|
+
// console.groupEnd();
|
|
13396
|
+
});
|
|
13397
|
+
setPages(_pages);
|
|
13398
|
+
}
|
|
13399
|
+
}, [sectionsConfig]);
|
|
13478
13400
|
React.useEffect(() => {
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
resizeTimeoutRef.current = setTimeout(() => {
|
|
13487
|
-
// Use requestAnimationFrame to avoid ResizeObserver loop warning
|
|
13488
|
-
requestAnimationFrame(() => {
|
|
13489
|
-
paginateContent();
|
|
13490
|
-
});
|
|
13491
|
-
}, 150);
|
|
13492
|
-
});
|
|
13493
|
-
sections.forEach(section => observer.observe(section));
|
|
13494
|
-
return () => {
|
|
13495
|
-
observer.disconnect();
|
|
13496
|
-
if (resizeTimeoutRef.current) {
|
|
13497
|
-
clearTimeout(resizeTimeoutRef.current);
|
|
13498
|
-
}
|
|
13499
|
-
};
|
|
13500
|
-
}, [paginateContent, config.length]);
|
|
13401
|
+
doSizing();
|
|
13402
|
+
}, [doSizing]);
|
|
13403
|
+
const onChangeHeight = React.useCallback((index, conf) => {
|
|
13404
|
+
setSectionsConfig(prev => _objectSpread2(_objectSpread2({}, prev), {}, {
|
|
13405
|
+
[index]: conf
|
|
13406
|
+
}));
|
|
13407
|
+
}, []);
|
|
13501
13408
|
const contClassName = formatClassname(['daf-analysis daf-pdf-view', customClassName]);
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
style: {
|
|
13505
|
-
position: 'relative',
|
|
13506
|
-
minHeight: "".concat(PAGE_HEIGHT, "px")
|
|
13507
|
-
},
|
|
13508
|
-
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
13409
|
+
const renderDashboard = React.useCallback(() => {
|
|
13410
|
+
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
13509
13411
|
className: "view-content",
|
|
13510
13412
|
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
13511
13413
|
className: "daf-analysis-layout",
|
|
13512
13414
|
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
13513
13415
|
className: "sections-cont",
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
position: 'relative'
|
|
13520
|
-
},
|
|
13521
|
-
children: config.map((widgets, index) => /*#__PURE__*/jsxRuntime.jsx("section", {
|
|
13522
|
-
ref: el => {
|
|
13523
|
-
sectionsRef.current[index] = el;
|
|
13524
|
-
},
|
|
13525
|
-
style: widgets.style,
|
|
13526
|
-
"data-pdf-section": "true",
|
|
13527
|
-
children: typeof widgets.render === 'function' ? widgets.render() : null
|
|
13528
|
-
}, "dashboard-section-".concat(index + 1)))
|
|
13416
|
+
children: config.map((widgets, i) => /*#__PURE__*/jsxRuntime.jsx(Row, {
|
|
13417
|
+
widgets: widgets,
|
|
13418
|
+
i: i,
|
|
13419
|
+
onChangeHeight: onChangeHeight
|
|
13420
|
+
}, "dashboard-sections=".concat(i + 1)))
|
|
13529
13421
|
})
|
|
13530
13422
|
})
|
|
13531
|
-
})
|
|
13423
|
+
});
|
|
13424
|
+
}, [config, onChangeHeight]);
|
|
13425
|
+
|
|
13426
|
+
// <div className="daf-analysis">
|
|
13427
|
+
// <Header title={t('Dashboard Title')} />
|
|
13428
|
+
|
|
13429
|
+
// <div className="content">
|
|
13430
|
+
// <div className="view-content">
|
|
13431
|
+
// <div className="daf-analysis-layout">
|
|
13432
|
+
// <div className='sections-cont w-pt'>
|
|
13433
|
+
// <section>
|
|
13434
|
+
|
|
13435
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
13436
|
+
className: contClassName,
|
|
13437
|
+
style: {
|
|
13438
|
+
position: 'relative'
|
|
13439
|
+
},
|
|
13440
|
+
children: [renderDashboard(), pages.map(page => /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
13532
13441
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
13533
13442
|
style: {
|
|
13534
|
-
top: (page - 1) * PAGE_HEIGHT
|
|
13443
|
+
top: (page - 1) * PAGE_HEIGHT,
|
|
13535
13444
|
width: '100%',
|
|
13536
|
-
height: HEADER_HEIGHT,
|
|
13445
|
+
height: HEADER_HEIGHT - 24,
|
|
13537
13446
|
position: 'absolute',
|
|
13538
13447
|
left: 0,
|
|
13539
|
-
zIndex: 1000000
|
|
13540
|
-
pointerEvents: 'none'
|
|
13448
|
+
zIndex: 1000000
|
|
13541
13449
|
},
|
|
13542
13450
|
className: "flex-row dashboard-header",
|
|
13543
13451
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -13552,15 +13460,14 @@ function PdfView(_ref) {
|
|
|
13552
13460
|
alt: "logo"
|
|
13553
13461
|
})
|
|
13554
13462
|
})]
|
|
13555
|
-
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
13463
|
+
}, "headers-".concat(page)), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
13556
13464
|
style: {
|
|
13557
|
-
top: page * PAGE_HEIGHT - FOOTER_HEIGHT
|
|
13465
|
+
top: page * PAGE_HEIGHT - FOOTER_HEIGHT,
|
|
13558
13466
|
width: '100%',
|
|
13559
13467
|
height: FOOTER_HEIGHT,
|
|
13560
13468
|
position: 'absolute',
|
|
13561
13469
|
left: 0,
|
|
13562
|
-
zIndex: 1000000
|
|
13563
|
-
pointerEvents: 'none'
|
|
13470
|
+
zIndex: 1000000
|
|
13564
13471
|
},
|
|
13565
13472
|
className: "dashboard-footer flex-row",
|
|
13566
13473
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -13596,8 +13503,8 @@ function PdfView(_ref) {
|
|
|
13596
13503
|
children: page
|
|
13597
13504
|
})
|
|
13598
13505
|
})]
|
|
13599
|
-
})]
|
|
13600
|
-
}
|
|
13506
|
+
}, "footers-".concat(page))]
|
|
13507
|
+
}))]
|
|
13601
13508
|
});
|
|
13602
13509
|
}
|
|
13603
13510
|
PdfView.propTypes = {
|
package/package.json
CHANGED
|
@@ -189,15 +189,5 @@ export const Primary = {
|
|
|
189
189
|
},
|
|
190
190
|
],
|
|
191
191
|
},
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
height: '100vh',
|
|
195
|
-
overflowY: 'auto',
|
|
196
|
-
background: "#f8f8f8",
|
|
197
|
-
padding: "20px",
|
|
198
|
-
}}
|
|
199
|
-
>
|
|
200
|
-
<PdfView {...args} />
|
|
201
|
-
</div>
|
|
202
|
-
),
|
|
203
|
-
};
|
|
192
|
+
}
|
|
193
|
+
|
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
import moment from "moment";
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { useCallback, useEffect, 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;
|
|
7
8
|
const FOOTER_HEIGHT = 70;
|
|
8
9
|
const HEADER_HEIGHT = 100;
|
|
9
|
-
const PAGE_MARGIN_TOP = 20;
|
|
10
|
-
const PAGE_MARGIN_BOTTOM = 20;
|
|
11
|
-
const CONTENT_HEIGHT = 1200; // 1397px
|
|
12
|
-
const SECTION_GAP = 24;
|
|
13
10
|
|
|
14
|
-
const
|
|
11
|
+
const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
|
|
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);
|
|
23
|
+
|
|
24
|
+
return () => observer.disconnect();
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (height) {
|
|
29
|
+
onChangeHeight(i, { height, ref });
|
|
30
|
+
}
|
|
31
|
+
}, [height])
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<section ref={ref} style={widgets.style}>
|
|
35
|
+
{typeof widgets.render === 'function' ? widgets.render() : null}
|
|
36
|
+
</section>
|
|
37
|
+
)
|
|
38
|
+
};
|
|
15
39
|
|
|
16
40
|
export default function PdfView({
|
|
17
41
|
config = [],
|
|
@@ -23,251 +47,104 @@ export default function PdfView({
|
|
|
23
47
|
documentId = 'IDD-0000000',
|
|
24
48
|
downloadId = 'DWL-00000123',
|
|
25
49
|
}) {
|
|
50
|
+
const [sectionsConfig, setSectionsConfig] = useState({});
|
|
26
51
|
const [pages, setPages] = useState([1]);
|
|
27
|
-
const contentRef = useRef(null);
|
|
28
|
-
const sectionsRef = useRef([]);
|
|
29
|
-
const resizeTimeoutRef = useRef(null);
|
|
30
|
-
const isCalculatingRef = useRef(false);
|
|
31
|
-
|
|
32
|
-
const resetPaginationStyles = useCallback((sections) => {
|
|
33
|
-
sections.forEach((section) => {
|
|
34
|
-
if (!section) return;
|
|
35
|
-
section.style.marginTop = '';
|
|
36
|
-
section.style.marginBottom = '';
|
|
37
|
-
section.style.pageBreakBefore = '';
|
|
38
|
-
section.style.breakBefore = '';
|
|
39
|
-
section.removeAttribute('data-pdf-page');
|
|
40
|
-
|
|
41
|
-
// Reset all children
|
|
42
|
-
const allElements = section.querySelectorAll('*');
|
|
43
|
-
allElements.forEach((el) => {
|
|
44
|
-
if (!isHTMLElement(el)) return;
|
|
45
|
-
el.style.marginTop = '';
|
|
46
|
-
el.style.marginBottom = '';
|
|
47
|
-
el.style.pageBreakBefore = '';
|
|
48
|
-
el.style.breakBefore = '';
|
|
49
|
-
el.removeAttribute('data-pdf-page');
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
}, []);
|
|
53
|
-
|
|
54
|
-
const getAllBreakableElements = useCallback((section) => {
|
|
55
|
-
const elements = [];
|
|
56
|
-
|
|
57
|
-
const shouldInclude = (el) => {
|
|
58
|
-
if (!isHTMLElement(el)) return false;
|
|
59
|
-
const style = window.getComputedStyle(el);
|
|
60
|
-
if (style.display === 'inline' || style.display === 'contents') return false;
|
|
61
|
-
if (style.position === 'absolute' || style.position === 'fixed') return false;
|
|
62
|
-
if (el.offsetHeight === 0) return false;
|
|
63
|
-
return true;
|
|
64
|
-
};
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
traverse(child);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
};
|
|
53
|
+
const doSizing = useCallback(() => {
|
|
54
|
+
const keys = Object.keys(sectionsConfig);
|
|
55
|
+
let _pages = [1];
|
|
56
|
+
let _page = 1;
|
|
74
57
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}, []);
|
|
58
|
+
if (keys.length === config.length) {
|
|
59
|
+
let incrHeight = 0;
|
|
78
60
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (sections.length === 0) return;
|
|
61
|
+
keys.forEach(k => {
|
|
62
|
+
const { ref } = sectionsConfig[k];
|
|
63
|
+
ref.current.style.marginBottom = '0px';
|
|
64
|
+
// ref.current.style.marginTop = '15px';
|
|
65
|
+
})
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
keys.forEach((k, i) => {
|
|
68
|
+
const { height, ref } = sectionsConfig[k];
|
|
87
69
|
|
|
88
|
-
|
|
70
|
+
if (i === 0) {
|
|
71
|
+
ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
|
|
72
|
+
incrHeight += HEADER_HEIGHT;
|
|
73
|
+
}
|
|
89
74
|
|
|
90
|
-
|
|
91
|
-
sections.forEach(s => s.offsetHeight);
|
|
75
|
+
const newHeight = incrHeight + height;
|
|
92
76
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
if (i === keys.length - 1) {
|
|
78
|
+
ref.current.style.paddingBottom = '30px';
|
|
79
|
+
}
|
|
96
80
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// First item on page
|
|
109
|
-
if (currentPage === 1) {
|
|
110
|
-
// Very first section on first page - needs to be below header
|
|
111
|
-
section.style.marginTop = '0px'; // Container padding handles this
|
|
112
|
-
} else {
|
|
113
|
-
// First section on subsequent pages - no margin (container padding handles it)
|
|
114
|
-
section.style.marginTop = '0px';
|
|
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);
|
|
115
92
|
}
|
|
116
93
|
} else {
|
|
117
|
-
|
|
118
|
-
section.style.marginTop = `${SECTION_GAP}px`;
|
|
119
|
-
}
|
|
120
|
-
currentPageHeight += gapBefore + sectionHeight;
|
|
121
|
-
} else {
|
|
122
|
-
// Doesn't fit - need to move to next page
|
|
123
|
-
const remainingSpace = CONTENT_HEIGHT - currentPageHeight;
|
|
124
|
-
|
|
125
|
-
// Calculate margin needed to push this section to the next page
|
|
126
|
-
// remainingSpace = space left on current page
|
|
127
|
-
// Then we need to skip: footer margin + footer + header margin + header
|
|
128
|
-
const pushMargin = remainingSpace + PAGE_MARGIN_BOTTOM + FOOTER_HEIGHT + PAGE_MARGIN_TOP + HEADER_HEIGHT;
|
|
129
|
-
|
|
130
|
-
// Move entire section to next page
|
|
131
|
-
currentPage += 1;
|
|
132
|
-
breaks.push({ section, type: 'section', page: currentPage });
|
|
133
|
-
section.setAttribute('data-pdf-page', currentPage.toString());
|
|
134
|
-
section.style.pageBreakBefore = 'always';
|
|
135
|
-
section.style.breakBefore = 'page';
|
|
136
|
-
section.style.marginTop = `${pushMargin}px`;
|
|
137
|
-
|
|
138
|
-
// Start fresh height counter for new page
|
|
139
|
-
currentPageHeight = sectionHeight;
|
|
140
|
-
|
|
141
|
-
// Check if section is too tall and needs internal breaks
|
|
142
|
-
if (sectionHeight > CONTENT_HEIGHT) {
|
|
143
|
-
// Try to break within section
|
|
144
|
-
const innerElements = getAllBreakableElements(section);
|
|
145
|
-
let pageHeightInSection = 0;
|
|
146
|
-
let sectionPage = currentPage;
|
|
147
|
-
|
|
148
|
-
for (const el of innerElements) {
|
|
149
|
-
const rect = el.getBoundingClientRect();
|
|
150
|
-
const sectionRect = section.getBoundingClientRect();
|
|
151
|
-
const relativeTop = rect.top - sectionRect.top;
|
|
152
|
-
const elHeight = rect.height;
|
|
153
|
-
|
|
154
|
-
// Check if this element would exceed the page
|
|
155
|
-
if (pageHeightInSection + elHeight > CONTENT_HEIGHT && relativeTop > 50) {
|
|
156
|
-
// Calculate remaining space on this page within the section
|
|
157
|
-
const remainingInSection = CONTENT_HEIGHT - pageHeightInSection;
|
|
158
|
-
const pushMarginInner = remainingInSection + PAGE_MARGIN_BOTTOM + FOOTER_HEIGHT + PAGE_MARGIN_TOP + HEADER_HEIGHT;
|
|
159
|
-
|
|
160
|
-
sectionPage += 1;
|
|
161
|
-
breaks.push({ element: el, type: 'inner', page: sectionPage });
|
|
162
|
-
el.setAttribute('data-pdf-page', sectionPage.toString());
|
|
163
|
-
el.style.pageBreakBefore = 'always';
|
|
164
|
-
el.style.breakBefore = 'page';
|
|
165
|
-
el.style.marginTop = `${pushMarginInner}px`;
|
|
166
|
-
|
|
167
|
-
// Reset page height for new page within section
|
|
168
|
-
pageHeightInSection = elHeight;
|
|
169
|
-
} else {
|
|
170
|
-
pageHeightInSection += elHeight;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Update current page if we created additional pages
|
|
175
|
-
if (sectionPage > currentPage) {
|
|
176
|
-
currentPage = sectionPage;
|
|
177
|
-
currentPageHeight = pageHeightInSection;
|
|
178
|
-
}
|
|
94
|
+
incrHeight = newHeight + 24;
|
|
179
95
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// Reset flag after a brief delay to allow next calculation
|
|
186
|
-
setTimeout(() => {
|
|
187
|
-
isCalculatingRef.current = false;
|
|
188
|
-
}, 100);
|
|
189
|
-
}, [getAllBreakableElements, resetPaginationStyles]);
|
|
190
|
-
|
|
191
|
-
useLayoutEffect(() => {
|
|
192
|
-
// Use requestAnimationFrame to ensure DOM is painted
|
|
193
|
-
const rafId = requestAnimationFrame(() => {
|
|
194
|
-
paginateContent();
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
return () => cancelAnimationFrame(rafId);
|
|
198
|
-
}, [paginateContent, config]);
|
|
96
|
+
// console.groupEnd();
|
|
97
|
+
})
|
|
98
|
+
setPages(_pages);
|
|
99
|
+
}
|
|
100
|
+
}, [sectionsConfig]);
|
|
199
101
|
|
|
200
102
|
useEffect(() => {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const observer = new ResizeObserver(() => {
|
|
205
|
-
// Debounce the pagination calculation
|
|
206
|
-
if (resizeTimeoutRef.current) {
|
|
207
|
-
clearTimeout(resizeTimeoutRef.current);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
resizeTimeoutRef.current = setTimeout(() => {
|
|
211
|
-
// Use requestAnimationFrame to avoid ResizeObserver loop warning
|
|
212
|
-
requestAnimationFrame(() => {
|
|
213
|
-
paginateContent();
|
|
214
|
-
});
|
|
215
|
-
}, 150);
|
|
216
|
-
});
|
|
103
|
+
doSizing();
|
|
104
|
+
}, [doSizing]);
|
|
217
105
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
observer.disconnect();
|
|
222
|
-
if (resizeTimeoutRef.current) {
|
|
223
|
-
clearTimeout(resizeTimeoutRef.current);
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}, [paginateContent, config.length]);
|
|
106
|
+
const onChangeHeight = useCallback((index, conf) => {
|
|
107
|
+
setSectionsConfig((prev) => ({ ...prev, [index]: conf }))
|
|
108
|
+
}, []);
|
|
227
109
|
|
|
228
110
|
const contClassName = formatClassname(['daf-analysis daf-pdf-view', customClassName]);
|
|
229
111
|
|
|
230
|
-
|
|
231
|
-
|
|
112
|
+
const renderDashboard = useCallback(() => {
|
|
113
|
+
return (
|
|
232
114
|
<div className="view-content">
|
|
233
115
|
<div className="daf-analysis-layout">
|
|
234
|
-
<div
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}}
|
|
243
|
-
>
|
|
244
|
-
{config.map((widgets, index) => (
|
|
245
|
-
<section
|
|
246
|
-
key={`dashboard-section-${index + 1}`}
|
|
247
|
-
ref={(el) => {
|
|
248
|
-
sectionsRef.current[index] = el;
|
|
249
|
-
}}
|
|
250
|
-
style={widgets.style}
|
|
251
|
-
data-pdf-section="true"
|
|
252
|
-
>
|
|
253
|
-
{typeof widgets.render === 'function' ? widgets.render() : null}
|
|
254
|
-
</section>
|
|
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
|
+
/>
|
|
255
124
|
))}
|
|
256
125
|
</div>
|
|
257
126
|
</div>
|
|
258
127
|
</div>
|
|
128
|
+
);
|
|
129
|
+
}, [config, onChangeHeight]);
|
|
130
|
+
|
|
131
|
+
// <div className="daf-analysis">
|
|
132
|
+
// <Header title={t('Dashboard Title')} />
|
|
133
|
+
|
|
134
|
+
// <div className="content">
|
|
135
|
+
// <div className="view-content">
|
|
136
|
+
// <div className="daf-analysis-layout">
|
|
137
|
+
// <div className='sections-cont w-pt'>
|
|
138
|
+
// <section>
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div className={contClassName} style={{ position: 'relative' }}>
|
|
142
|
+
{renderDashboard()}
|
|
259
143
|
{pages.map((page) => (
|
|
260
|
-
|
|
144
|
+
<>
|
|
261
145
|
<div
|
|
262
|
-
style={{
|
|
263
|
-
|
|
264
|
-
width: '100%',
|
|
265
|
-
height: HEADER_HEIGHT,
|
|
266
|
-
position: 'absolute',
|
|
267
|
-
left: 0,
|
|
268
|
-
zIndex: 1000000,
|
|
269
|
-
pointerEvents: 'none'
|
|
270
|
-
}}
|
|
146
|
+
style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT - 24, position: 'absolute', left: 0, zIndex: 1000000 }}
|
|
147
|
+
key={`headers-${page}`}
|
|
271
148
|
className="flex-row dashboard-header"
|
|
272
149
|
>
|
|
273
150
|
<div className="flex flex-column justify-center flex-1">
|
|
@@ -278,15 +155,8 @@ export default function PdfView({
|
|
|
278
155
|
</div>
|
|
279
156
|
</div>
|
|
280
157
|
<div
|
|
281
|
-
style={{
|
|
282
|
-
|
|
283
|
-
width: '100%',
|
|
284
|
-
height: FOOTER_HEIGHT,
|
|
285
|
-
position: 'absolute',
|
|
286
|
-
left: 0,
|
|
287
|
-
zIndex: 1000000,
|
|
288
|
-
pointerEvents: 'none'
|
|
289
|
-
}}
|
|
158
|
+
style={{ top: (page * PAGE_HEIGHT) - FOOTER_HEIGHT, width: '100%', height: FOOTER_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }}
|
|
159
|
+
key={`footers-${page}`}
|
|
290
160
|
className="dashboard-footer flex-row"
|
|
291
161
|
>
|
|
292
162
|
<div className="flex flex-column justify-center">
|
|
@@ -320,7 +190,7 @@ export default function PdfView({
|
|
|
320
190
|
<h5>{page}</h5>
|
|
321
191
|
</div>
|
|
322
192
|
</div>
|
|
323
|
-
|
|
193
|
+
</>
|
|
324
194
|
))}
|
|
325
195
|
</div>
|
|
326
196
|
);
|