datastake-daf 0.6.150 → 0.6.151

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.
@@ -12955,12 +12955,15 @@ DAFFooter.propTypes = {
12955
12955
  isViewMode: PropTypes__default["default"].bool
12956
12956
  };
12957
12957
 
12958
- const PAGE_HEIGHT = 1587;
12958
+ const PAGE_HEIGHT = 1587; // Total height of a virtual PDF page
12959
12959
  const FOOTER_HEIGHT = 70;
12960
12960
  const HEADER_HEIGHT = 100;
12961
12961
  const ROW_SPACING = 24; // Spacing between content rows
12962
12962
  const CONTENT_BOTTOM_PADDING = 30; // Extra padding at the very bottom of the last section of the document
12963
12963
 
12964
+ // This is the actual height available for the *flowing content* after Puppeteer
12965
+ // applies its margins for the header and footer.
12966
+ const USABLE_FLOW_HEIGHT_PER_PAGE = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
12964
12967
  const Row = _ref => {
12965
12968
  let {
12966
12969
  widgets,
@@ -12975,8 +12978,14 @@ const Row = _ref => {
12975
12978
  setHeight(entry.contentRect.height);
12976
12979
  }
12977
12980
  });
12978
- observer.observe(ref.current);
12979
- return () => observer.disconnect();
12981
+ if (ref.current) {
12982
+ observer.observe(ref.current);
12983
+ }
12984
+ return () => {
12985
+ if (ref.current) {
12986
+ observer.disconnect();
12987
+ }
12988
+ };
12980
12989
  }, []);
12981
12990
  React.useEffect(() => {
12982
12991
  if (height) {
@@ -12985,7 +12994,7 @@ const Row = _ref => {
12985
12994
  ref
12986
12995
  });
12987
12996
  }
12988
- }, [height]);
12997
+ }, [height, i, onChangeHeight]);
12989
12998
  return /*#__PURE__*/jsxRuntime.jsx("section", {
12990
12999
  ref: ref,
12991
13000
  style: widgets.style,
@@ -12996,6 +13005,8 @@ function PdfView(_ref2) {
12996
13005
  let {
12997
13006
  config = [],
12998
13007
  customClassName,
13008
+ // No longer needed to directly render title/imgSrc/etc within PdfView as Puppeteer handles it
13009
+ // but kept in props for completeness if other parts of the app use them.
12999
13010
  title = 'Title',
13000
13011
  imgSrc = '',
13001
13012
  userId = 'IDD-0000000',
@@ -13004,28 +13015,24 @@ function PdfView(_ref2) {
13004
13015
  downloadId = 'DWL-00000123'
13005
13016
  } = _ref2;
13006
13017
  const [sectionsConfig, setSectionsConfig] = React.useState({});
13007
- const [pages, setPages] = React.useState([1]);
13018
+ const [pagesCount, setPagesCount] = React.useState(1); // Track total pages for Puppeteer footer
13019
+
13008
13020
  const doSizing = React.useCallback(() => {
13009
- const keys = Object.keys(sectionsConfig);
13010
- let _pages = [1];
13011
- let _page = 1;
13012
-
13013
- // The total vertical space available for flowing content on each page,
13014
- // considering that HEADER_HEIGHT and FOOTER_HEIGHT are for absolutely positioned elements
13015
- // and content should flow between them.
13016
- const usableContentHeightPerPage = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
13021
+ // Ensure keys are processed in order
13022
+ const keys = Object.keys(sectionsConfig).sort((a, b) => parseInt(a) - parseInt(b));
13017
13023
  if (keys.length === config.length) {
13018
- let currentFlowHeight = 0; // Tracks height accumulated within the `usableContentHeightPerPage` for the current page
13024
+ let currentPageContentHeight = 0;
13025
+ let currentPage = 1;
13019
13026
 
13020
- // Reset all margins/paddings first for a clean slate
13027
+ // Reset all page-break styles before recalculating
13021
13028
  keys.forEach(k => {
13022
13029
  const {
13023
13030
  ref
13024
13031
  } = sectionsConfig[k];
13025
13032
  if (ref.current) {
13026
- ref.current.style.marginBottom = '0px';
13027
- ref.current.style.marginTop = '0px';
13028
- ref.current.style.paddingBottom = '0px';
13033
+ ref.current.style.pageBreakBefore = 'auto'; // Reset to default
13034
+ ref.current.style.marginTop = '0px'; // Clear any previous dynamic margins
13035
+ ref.current.style.paddingBottom = '0px'; // Clear any previous dynamic paddings
13029
13036
  }
13030
13037
  });
13031
13038
  keys.forEach((k, i) => {
@@ -13033,58 +13040,30 @@ function PdfView(_ref2) {
13033
13040
  height,
13034
13041
  ref
13035
13042
  } = sectionsConfig[k];
13036
- if (!ref.current) return; // Skip if ref is not available yet
13043
+ if (!ref.current) return;
13044
+ let spaceNeededForThisSection = height;
13037
13045
 
13038
- let sectionTopMargin = ROW_SPACING; // Default margin for sections that follow another on the same page
13039
-
13040
- // The first section on *any* page (either global first or first on a new page)
13041
- // needs to be offset by HEADER_HEIGHT from the top of the page.
13042
- if (i === 0 || currentFlowHeight === 0) {
13043
- sectionTopMargin = HEADER_HEIGHT;
13044
- }
13045
-
13046
- // Calculate the total height this section would occupy *including its immediate top margin and its own height*.
13047
- let totalHeightForThisSection = sectionTopMargin + height;
13048
-
13049
- // If it's not the very last section of the document, add the standard row spacing.
13046
+ // Add ROW_SPACING *after* each section, except the very last one.
13050
13047
  if (i < keys.length - 1) {
13051
- totalHeightForThisSection += ROW_SPACING;
13048
+ spaceNeededForThisSection += ROW_SPACING;
13052
13049
  } else {
13053
- // For the very last section, add the document-level bottom padding.
13054
- totalHeightForThisSection += CONTENT_BOTTOM_PADDING;
13050
+ // Add CONTENT_BOTTOM_PADDING after the very last section of the document.
13051
+ spaceNeededForThisSection += CONTENT_BOTTOM_PADDING;
13055
13052
  }
13056
13053
 
13057
- // Check if placing this section (with its calculated space) on the current page
13058
- // would exceed the usable content area for a theoretical page.
13059
- if (currentFlowHeight + totalHeightForThisSection > usableContentHeightPerPage) {
13060
- // This section overflows, so it starts on a new page.
13061
- _page += 1;
13062
- _pages.push(_page);
13063
-
13064
- // Reset flow height for the new page.
13065
- // This section is now the first on a new page, so its top margin is HEADER_HEIGHT.
13066
- ref.current.style.marginTop = "".concat(HEADER_HEIGHT, "px");
13067
- currentFlowHeight = HEADER_HEIGHT + height; // Start accumulated height for new page
13068
-
13069
- // Add row spacing or bottom padding for this section on its new page
13070
- if (i < keys.length - 1) {
13071
- currentFlowHeight += ROW_SPACING;
13072
- } else {
13073
- ref.current.style.paddingBottom = "".concat(CONTENT_BOTTOM_PADDING, "px");
13074
- currentFlowHeight += CONTENT_BOTTOM_PADDING;
13075
- }
13054
+ // If placing this section on the current page would exceed the usable content area,
13055
+ // mark it to start on a new page.
13056
+ if (currentPageContentHeight + spaceNeededForThisSection > USABLE_FLOW_HEIGHT_PER_PAGE) {
13057
+ ref.current.style.pageBreakBefore = 'always';
13058
+ currentPage++;
13059
+ // Reset current page content height to just what this new section takes.
13060
+ currentPageContentHeight = spaceNeededForThisSection;
13076
13061
  } else {
13077
13062
  // This section fits on the current page.
13078
- ref.current.style.marginTop = "".concat(sectionTopMargin, "px");
13079
- currentFlowHeight += totalHeightForThisSection; // Accumulate the height this section takes
13080
-
13081
- // Apply special padding for the very last section of the document if it fits on current page
13082
- if (i === keys.length - 1) {
13083
- ref.current.style.paddingBottom = "".concat(CONTENT_BOTTOM_PADDING, "px");
13084
- }
13063
+ currentPageContentHeight += spaceNeededForThisSection;
13085
13064
  }
13086
13065
  });
13087
- setPages(_pages);
13066
+ setPagesCount(currentPage);
13088
13067
  }
13089
13068
  }, [sectionsConfig, config.length]);
13090
13069
  React.useEffect(() => {
@@ -13112,83 +13091,28 @@ function PdfView(_ref2) {
13112
13091
  })
13113
13092
  });
13114
13093
  }, [config, onChangeHeight]);
13115
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
13094
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
13116
13095
  className: contClassName,
13117
13096
  style: {
13118
13097
  position: 'relative'
13119
13098
  },
13120
- children: [renderDashboard(), pages.map(page => /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
13121
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
13122
- style: {
13123
- top: (page - 1) * PAGE_HEIGHT,
13124
- width: '100%',
13125
- height: HEADER_HEIGHT,
13126
- position: 'absolute',
13127
- left: 0,
13128
- zIndex: 1000000
13129
- } // Changed height from HEADER_HEIGHT - 24 to HEADER_HEIGHT for consistency
13130
- ,
13131
-
13132
- className: "flex-row dashboard-header",
13133
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
13134
- className: "flex flex-column justify-center flex-1",
13135
- children: /*#__PURE__*/jsxRuntime.jsx("h2", {
13136
- children: title
13137
- })
13138
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
13139
- className: "flex flex-column justify-center",
13140
- children: /*#__PURE__*/jsxRuntime.jsx("img", {
13141
- src: imgSrc,
13142
- alt: "logo"
13143
- })
13144
- })]
13145
- }, "headers-".concat(page)), /*#__PURE__*/jsxRuntime.jsxs("div", {
13146
- style: {
13147
- top: page * PAGE_HEIGHT - FOOTER_HEIGHT,
13148
- width: '100%',
13149
- height: FOOTER_HEIGHT,
13150
- position: 'absolute',
13151
- left: 0,
13152
- zIndex: 1000000
13153
- },
13154
- className: "dashboard-footer flex-row",
13155
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
13156
- className: "flex flex-column justify-center",
13157
- children: /*#__PURE__*/jsxRuntime.jsx("h5", {
13158
- children: moment__default["default"]().format('DD MMM YYYY')
13159
- })
13160
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
13161
- className: "flex flex-column justify-center",
13162
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
13163
- className: "flex gap-2",
13164
- children: [/*#__PURE__*/jsxRuntime.jsxs("h5", {
13165
- children: ["User ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
13166
- children: userId
13167
- })]
13168
- }), /*#__PURE__*/jsxRuntime.jsxs("h5", {
13169
- children: ["Account ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
13170
- children: accountId
13171
- })]
13172
- }), /*#__PURE__*/jsxRuntime.jsxs("h5", {
13173
- children: ["Document ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
13174
- children: documentId
13175
- })]
13176
- }), /*#__PURE__*/jsxRuntime.jsxs("h5", {
13177
- children: ["Download ID:", ' ', /*#__PURE__*/jsxRuntime.jsx("strong", {
13178
- children: downloadId
13179
- })]
13180
- })]
13181
- })
13182
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
13183
- className: "flex flex-column justify-center",
13184
- children: /*#__PURE__*/jsxRuntime.jsx("h5", {
13185
- children: page
13186
- })
13187
- })]
13188
- }, "footers-".concat(page))]
13189
- }))]
13099
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
13100
+ id: "pdf-content-root",
13101
+ "data-page-count": pagesCount,
13102
+ children: renderDashboard()
13103
+ })
13190
13104
  });
13191
13105
  }
13106
+ PdfView.propTypes = {
13107
+ config: PropTypes__default["default"].array,
13108
+ customClassName: PropTypes__default["default"].any,
13109
+ title: PropTypes__default["default"].string,
13110
+ imgSrc: PropTypes__default["default"].string,
13111
+ userId: PropTypes__default["default"].string,
13112
+ accountId: PropTypes__default["default"].string,
13113
+ documentId: PropTypes__default["default"].string,
13114
+ downloadId: PropTypes__default["default"].string
13115
+ };
13192
13116
 
13193
13117
  const ajaxSelectFieldData = async (value, config, getApiBaseUrl = () => {}, getAppHeader = () => {}, app, formValues = {}) => {
13194
13118
  const url = getApiBaseUrl();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.150",
3
+ "version": "0.6.151",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -4,12 +4,16 @@ import PropTypes from 'prop-types';
4
4
  import { useCallback, useEffect, useRef, useState } from "react";
5
5
  import { formatClassname } from "../../../../../helpers/ClassesHelper";
6
6
 
7
- const PAGE_HEIGHT = 1587;
7
+ const PAGE_HEIGHT = 1587; // Total height of a virtual PDF page
8
8
  const FOOTER_HEIGHT = 70;
9
9
  const HEADER_HEIGHT = 100;
10
10
  const ROW_SPACING = 24; // Spacing between content rows
11
11
  const CONTENT_BOTTOM_PADDING = 30; // Extra padding at the very bottom of the last section of the document
12
12
 
13
+ // This is the actual height available for the *flowing content* after Puppeteer
14
+ // applies its margins for the header and footer.
15
+ const USABLE_FLOW_HEIGHT_PER_PAGE = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
16
+
13
17
  const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
14
18
  const ref = useRef();
15
19
  const [height, setHeight] = useState(0);
@@ -21,16 +25,22 @@ const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
21
25
  }
22
26
  });
23
27
 
24
- observer.observe(ref.current);
28
+ if (ref.current) {
29
+ observer.observe(ref.current);
30
+ }
25
31
 
26
- return () => observer.disconnect();
32
+ return () => {
33
+ if (ref.current) {
34
+ observer.disconnect();
35
+ }
36
+ };
27
37
  }, []);
28
38
 
29
39
  useEffect(() => {
30
40
  if (height) {
31
41
  onChangeHeight(i, { height, ref });
32
42
  }
33
- }, [height])
43
+ }, [height, i, onChangeHeight]);
34
44
 
35
45
  return (
36
46
  <section ref={ref} style={widgets.style}>
@@ -42,6 +52,8 @@ const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
42
52
  export default function PdfView({
43
53
  config = [],
44
54
  customClassName,
55
+ // No longer needed to directly render title/imgSrc/etc within PdfView as Puppeteer handles it
56
+ // but kept in props for completeness if other parts of the app use them.
45
57
  title = 'Title',
46
58
  imgSrc = '',
47
59
  userId = 'IDD-0000000',
@@ -50,86 +62,52 @@ export default function PdfView({
50
62
  downloadId = 'DWL-00000123',
51
63
  }) {
52
64
  const [sectionsConfig, setSectionsConfig] = useState({});
53
- const [pages, setPages] = useState([1]);
65
+ const [pagesCount, setPagesCount] = useState(1); // Track total pages for Puppeteer footer
54
66
 
55
67
  const doSizing = useCallback(() => {
56
- const keys = Object.keys(sectionsConfig);
57
- let _pages = [1];
58
- let _page = 1;
59
-
60
- // The total vertical space available for flowing content on each page,
61
- // considering that HEADER_HEIGHT and FOOTER_HEIGHT are for absolutely positioned elements
62
- // and content should flow between them.
63
- const usableContentHeightPerPage = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
64
-
68
+ // Ensure keys are processed in order
69
+ const keys = Object.keys(sectionsConfig).sort((a,b) => parseInt(a) - parseInt(b));
65
70
  if (keys.length === config.length) {
66
- let currentFlowHeight = 0; // Tracks height accumulated within the `usableContentHeightPerPage` for the current page
71
+ let currentPageContentHeight = 0;
72
+ let currentPage = 1;
67
73
 
68
- // Reset all margins/paddings first for a clean slate
74
+ // Reset all page-break styles before recalculating
69
75
  keys.forEach(k => {
70
76
  const { ref } = sectionsConfig[k];
71
77
  if (ref.current) {
72
- ref.current.style.marginBottom = '0px';
73
- ref.current.style.marginTop = '0px';
74
- ref.current.style.paddingBottom = '0px';
78
+ ref.current.style.pageBreakBefore = 'auto'; // Reset to default
79
+ ref.current.style.marginTop = '0px'; // Clear any previous dynamic margins
80
+ ref.current.style.paddingBottom = '0px'; // Clear any previous dynamic paddings
75
81
  }
76
82
  });
77
83
 
78
84
  keys.forEach((k, i) => {
79
85
  const { height, ref } = sectionsConfig[k];
80
- if (!ref.current) return; // Skip if ref is not available yet
81
-
82
- let sectionTopMargin = ROW_SPACING; // Default margin for sections that follow another on the same page
86
+ if (!ref.current) return;
83
87
 
84
- // The first section on *any* page (either global first or first on a new page)
85
- // needs to be offset by HEADER_HEIGHT from the top of the page.
86
- if (i === 0 || currentFlowHeight === 0) {
87
- sectionTopMargin = HEADER_HEIGHT;
88
- }
88
+ let spaceNeededForThisSection = height;
89
89
 
90
- // Calculate the total height this section would occupy *including its immediate top margin and its own height*.
91
- let totalHeightForThisSection = sectionTopMargin + height;
92
-
93
- // If it's not the very last section of the document, add the standard row spacing.
90
+ // Add ROW_SPACING *after* each section, except the very last one.
94
91
  if (i < keys.length - 1) {
95
- totalHeightForThisSection += ROW_SPACING;
92
+ spaceNeededForThisSection += ROW_SPACING;
96
93
  } else {
97
- // For the very last section, add the document-level bottom padding.
98
- totalHeightForThisSection += CONTENT_BOTTOM_PADDING;
94
+ // Add CONTENT_BOTTOM_PADDING after the very last section of the document.
95
+ spaceNeededForThisSection += CONTENT_BOTTOM_PADDING;
99
96
  }
100
97
 
101
- // Check if placing this section (with its calculated space) on the current page
102
- // would exceed the usable content area for a theoretical page.
103
- if (currentFlowHeight + totalHeightForThisSection > usableContentHeightPerPage) {
104
- // This section overflows, so it starts on a new page.
105
- _page += 1;
106
- _pages.push(_page);
107
-
108
- // Reset flow height for the new page.
109
- // This section is now the first on a new page, so its top margin is HEADER_HEIGHT.
110
- ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
111
- currentFlowHeight = HEADER_HEIGHT + height; // Start accumulated height for new page
112
-
113
- // Add row spacing or bottom padding for this section on its new page
114
- if (i < keys.length - 1) {
115
- currentFlowHeight += ROW_SPACING;
116
- } else {
117
- ref.current.style.paddingBottom = `${CONTENT_BOTTOM_PADDING}px`;
118
- currentFlowHeight += CONTENT_BOTTOM_PADDING;
119
- }
120
-
98
+ // If placing this section on the current page would exceed the usable content area,
99
+ // mark it to start on a new page.
100
+ if (currentPageContentHeight + spaceNeededForThisSection > USABLE_FLOW_HEIGHT_PER_PAGE) {
101
+ ref.current.style.pageBreakBefore = 'always';
102
+ currentPage++;
103
+ // Reset current page content height to just what this new section takes.
104
+ currentPageContentHeight = spaceNeededForThisSection;
121
105
  } else {
122
106
  // This section fits on the current page.
123
- ref.current.style.marginTop = `${sectionTopMargin}px`;
124
- currentFlowHeight += totalHeightForThisSection; // Accumulate the height this section takes
125
-
126
- // Apply special padding for the very last section of the document if it fits on current page
127
- if (i === keys.length - 1) {
128
- ref.current.style.paddingBottom = `${CONTENT_BOTTOM_PADDING}px`;
129
- }
107
+ currentPageContentHeight += spaceNeededForThisSection;
130
108
  }
131
109
  });
132
- setPages(_pages);
110
+ setPagesCount(currentPage);
133
111
  }
134
112
  }, [sectionsConfig, config.length]);
135
113
 
@@ -164,59 +142,23 @@ export default function PdfView({
164
142
 
165
143
  return (
166
144
  <div className={contClassName} style={{ position: 'relative' }}>
167
- {renderDashboard()}
168
- {pages.map((page) => (
169
- <>
170
- <div
171
- style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }} // Changed height from HEADER_HEIGHT - 24 to HEADER_HEIGHT for consistency
172
- key={`headers-${page}`}
173
- className="flex-row dashboard-header"
174
- >
175
- <div className="flex flex-column justify-center flex-1">
176
- <h2>{title}</h2>
177
- </div>
178
- <div className="flex flex-column justify-center">
179
- <img src={imgSrc} alt="logo" />
180
- </div>
181
- </div>
182
- <div
183
- style={{ top: (page * PAGE_HEIGHT) - FOOTER_HEIGHT, width: '100%', height: FOOTER_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }}
184
- key={`footers-${page}`}
185
- className="dashboard-footer flex-row"
186
- >
187
- <div className="flex flex-column justify-center">
188
- <h5>{moment().format('DD MMM YYYY')}</h5>
189
- </div>
190
- <div className="flex flex-column justify-center">
191
- <div className="flex gap-2">
192
- <h5>
193
- User ID:
194
- {' '}
195
- <strong>{userId}</strong>
196
- </h5>
197
- <h5>
198
- Account ID:
199
- {' '}
200
- <strong>{accountId}</strong>
201
- </h5>
202
- <h5>
203
- Document ID:
204
- {' '}
205
- <strong>{documentId}</strong>
206
- </h5>
207
- <h5>
208
- Download ID:
209
- {' '}
210
- <strong>{downloadId}</strong>
211
- </h5>
212
- </div>
213
- </div>
214
- <div className="flex flex-column justify-center">
215
- <h5>{page}</h5>
216
- </div>
217
- </div>
218
- </>
219
- ))}
145
+ {/* Container for content, Puppeteer reads data-page-count from this */}
146
+ <div id="pdf-content-root" data-page-count={pagesCount}>
147
+ {renderDashboard()}
148
+ </div>
149
+ {/* The absolute positioned headers and footers are removed from here.
150
+ Puppeteer's headerTemplate and footerTemplate will now handle them. */}
220
151
  </div>
221
152
  );
153
+ }
154
+
155
+ PdfView.propTypes = {
156
+ config: PropTypes.array,
157
+ customClassName: PropTypes.any,
158
+ title: PropTypes.string,
159
+ imgSrc: PropTypes.string,
160
+ userId: PropTypes.string,
161
+ accountId: PropTypes.string,
162
+ documentId: PropTypes.string,
163
+ downloadId: PropTypes.string,
222
164
  }