datastake-daf 0.6.132 → 0.6.133

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.
@@ -12956,13 +12956,9 @@ DAFFooter.propTypes = {
12956
12956
  };
12957
12957
 
12958
12958
  const PAGE_HEIGHT = 1587;
12959
+ // margin-top: 20, bottom: 20;
12959
12960
  const FOOTER_HEIGHT = 70;
12960
- const HEADER_HEIGHT = 100; // Total area reserved for header (could be slightly more than actual div height)
12961
- const HEADER_DIV_HEIGHT = HEADER_HEIGHT - 24; // Actual height of the absolute header div
12962
-
12963
- const FIRST_CONTENT_TOP_MARGIN = 30; // Desired margin-top for the very first content section on any given page.
12964
- const SECTION_NORMAL_MARGIN = 24; // Default margin-top for subsequent sections on the same page.
12965
-
12961
+ const HEADER_HEIGHT = 100;
12966
12962
  const Row = _ref => {
12967
12963
  let {
12968
12964
  widgets,
@@ -13012,89 +13008,48 @@ function PdfView(_ref2) {
13012
13008
  let _pages = [1];
13013
13009
  let _page = 1;
13014
13010
  if (keys.length === config.length) {
13015
- // `currentContentHeightAccumulated` tracks the height used by content sections *plus their top margins*,
13016
- // relative to the top of the *usable content area* on the current page.
13017
- let currentContentHeightAccumulated = 0;
13018
-
13019
- // The total vertical space available for content sections *between* the absolute header and footer.
13020
- const USABLE_PAGE_CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_DIV_HEIGHT - FOOTER_HEIGHT;
13021
-
13022
- // Reset margins/padding for all sections before recalculating
13011
+ let incrHeight = 0;
13023
13012
  keys.forEach(k => {
13024
13013
  const {
13025
13014
  ref
13026
13015
  } = sectionsConfig[k];
13027
- if (ref.current) {
13028
- ref.current.style.marginBottom = '0px';
13029
- ref.current.style.marginTop = '0px';
13030
- ref.current.style.paddingBottom = '0px';
13031
- }
13016
+ ref.current.style.marginBottom = '0px';
13017
+ // ref.current.style.marginTop = '15px';
13032
13018
  });
13033
13019
  keys.forEach((k, i) => {
13034
13020
  const {
13035
13021
  height,
13036
13022
  ref
13037
13023
  } = sectionsConfig[k];
13038
- if (!ref.current) return; // Skip if ref.current is null (e.g., component unmounted or not yet rendered)
13039
-
13040
- let sectionTopMargin = 0;
13041
-
13042
- // Determine the top margin for the current section
13043
- if (currentContentHeightAccumulated === 0) {
13044
- // This is the very first content section on the current virtual page
13045
- sectionTopMargin = FIRST_CONTENT_TOP_MARGIN;
13046
- } else {
13047
- // Subsequent content sections on the same virtual page
13048
- sectionTopMargin = SECTION_NORMAL_MARGIN;
13024
+ if (i === 0) {
13025
+ ref.current.style.marginTop = "".concat(HEADER_HEIGHT, "px");
13026
+ incrHeight += HEADER_HEIGHT;
13049
13027
  }
13050
-
13051
- // Calculate the total space this section *would take* on the current page, including its own top margin.
13052
- const spaceNeededByThisSection = sectionTopMargin + height;
13053
-
13054
- // Check if adding this section (with its top margin) would exceed the usable content area.
13055
- if (currentContentHeightAccumulated + spaceNeededByThisSection > USABLE_PAGE_CONTENT_HEIGHT) {
13056
- // This section overflows, so it must start on a new page.
13028
+ const newHeight = incrHeight + height;
13029
+ if (i === keys.length - 1) {
13030
+ ref.current.style.paddingBottom = '30px';
13031
+ }
13032
+ if (newHeight > PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT) {
13033
+ const dif = Math.abs(PAGE_HEIGHT - incrHeight);
13034
+ ref.current.style.marginTop = '30px';
13057
13035
  _page += 1;
13058
13036
  _pages.push(_page);
13059
-
13060
- // If there was a previous section on the *old* page, we need to fill the remaining space
13061
- // on that page by adding a bottom margin to the last section that fit.
13062
- if (i > 0) {
13063
- var _sectionsConfig$keys;
13064
- const prevSectionRef = (_sectionsConfig$keys = sectionsConfig[keys[i - 1]]) === null || _sectionsConfig$keys === void 0 ? void 0 : _sectionsConfig$keys.ref;
13065
- if (prevSectionRef !== null && prevSectionRef !== void 0 && prevSectionRef.current) {
13066
- // Calculate remaining space on the previous page
13067
- const spaceLeftOnPrevPage = USABLE_PAGE_CONTENT_HEIGHT - currentContentHeightAccumulated;
13068
- if (spaceLeftOnPrevPage > 0) {
13069
- prevSectionRef.current.style.marginBottom = "".concat(spaceLeftOnPrevPage, "px");
13070
- }
13071
- }
13037
+ if (sectionsConfig[keys[i - 1]]) {
13038
+ const {
13039
+ ref: topRef
13040
+ } = sectionsConfig[keys[i - 1]];
13041
+ topRef.current.style.marginBottom = "".concat(dif + HEADER_HEIGHT - 24, "px");
13042
+ incrHeight = height + 24 + HEADER_HEIGHT;
13043
+ // console.log('margin', dif);
13072
13044
  }
13073
-
13074
- // For the current section (which is now the first on a new page), apply the `FIRST_CONTENT_TOP_MARGIN`.
13075
- ref.current.style.marginTop = "".concat(FIRST_CONTENT_TOP_MARGIN, "px");
13076
- currentContentHeightAccumulated = FIRST_CONTENT_TOP_MARGIN + height; // Reset and update accumulated height for the *new* page
13077
13045
  } else {
13078
- // This section fits on the current page. Apply its calculated top margin.
13079
- ref.current.style.marginTop = "".concat(sectionTopMargin, "px");
13080
- currentContentHeightAccumulated += spaceNeededByThisSection; // Add its height and its own top margin to accumulated height
13081
- }
13082
-
13083
- // Add the standard margin between sections (for the *next* section, if there is one).
13084
- // This is important because `currentContentHeightAccumulated` needs to reflect the space used *up to the bottom of this section*,
13085
- // plus any necessary space for the next section's margin *before* it gets evaluated.
13086
- if (i < keys.length - 1) {
13087
- currentContentHeightAccumulated += SECTION_NORMAL_MARGIN;
13088
- }
13089
-
13090
- // For the very last section of the entire document, add extra padding to the bottom.
13091
- if (i === keys.length - 1) {
13092
- ref.current.style.paddingBottom = '30px';
13046
+ incrHeight = newHeight + 24;
13093
13047
  }
13048
+ // console.groupEnd();
13094
13049
  });
13095
13050
  setPages(_pages);
13096
13051
  }
13097
- }, [sectionsConfig, config.length]);
13052
+ }, [sectionsConfig]);
13098
13053
  React.useEffect(() => {
13099
13054
  doSizing();
13100
13055
  }, [doSizing]);
@@ -13120,6 +13075,16 @@ function PdfView(_ref2) {
13120
13075
  })
13121
13076
  });
13122
13077
  }, [config, onChangeHeight]);
13078
+
13079
+ // <div className="daf-analysis">
13080
+ // <Header title={t('Dashboard Title')} />
13081
+
13082
+ // <div className="content">
13083
+ // <div className="view-content">
13084
+ // <div className="daf-analysis-layout">
13085
+ // <div className='sections-cont w-pt'>
13086
+ // <section>
13087
+
13123
13088
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
13124
13089
  className: contClassName,
13125
13090
  style: {
@@ -13130,7 +13095,7 @@ function PdfView(_ref2) {
13130
13095
  style: {
13131
13096
  top: (page - 1) * PAGE_HEIGHT,
13132
13097
  width: '100%',
13133
- height: HEADER_DIV_HEIGHT,
13098
+ height: HEADER_HEIGHT - 24,
13134
13099
  position: 'absolute',
13135
13100
  left: 0,
13136
13101
  zIndex: 1000000
@@ -14982,9 +14947,31 @@ const PdfFormContent = _ref2 => {
14982
14947
  getAppHeader = () => {},
14983
14948
  app
14984
14949
  } = _ref2;
14985
- return /*#__PURE__*/jsxRuntime.jsx("div", {
14950
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
14986
14951
  className: "pdf-form-content",
14987
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
14952
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
14953
+ className: "document-header",
14954
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
14955
+ className: "header-left",
14956
+ children: /*#__PURE__*/jsxRuntime.jsx("h1", {
14957
+ className: "company-name",
14958
+ children: title
14959
+ })
14960
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
14961
+ className: "header-right",
14962
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
14963
+ className: "meta-info",
14964
+ children: [t('Source'), ": ", /*#__PURE__*/jsxRuntime.jsx("b", {
14965
+ children: source
14966
+ })]
14967
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
14968
+ className: "meta-info",
14969
+ children: [t('Version'), ": ", /*#__PURE__*/jsxRuntime.jsx("b", {
14970
+ children: version
14971
+ })]
14972
+ })]
14973
+ })]
14974
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
14988
14975
  className: "pdf-tree",
14989
14976
  children: Object.keys(form).filter(sectionKey => {
14990
14977
  const section = form[sectionKey];
@@ -15015,7 +15002,7 @@ const PdfFormContent = _ref2 => {
15015
15002
  getAppHeader: getAppHeader
15016
15003
  }, sectionKey);
15017
15004
  })
15018
- })
15005
+ })]
15019
15006
  });
15020
15007
  };
15021
15008
  const PdfForm = _ref3 => {
@@ -15038,6 +15025,7 @@ const PdfForm = _ref3 => {
15038
15025
  getAppHeader = () => {},
15039
15026
  app
15040
15027
  } = _ref3;
15028
+ // Group objects under headers based on position
15041
15029
  const organizeFormByHeaders = formData => {
15042
15030
  const organizedSections = {};
15043
15031
  Object.keys(formData).forEach(sectionKey => {
@@ -15045,6 +15033,8 @@ const PdfForm = _ref3 => {
15045
15033
  if (typeof section !== 'object' || !section.label) {
15046
15034
  return;
15047
15035
  }
15036
+
15037
+ // Get all objects from this section and sort by position
15048
15038
  const allObjects = Object.keys(section).filter(key => {
15049
15039
  return !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle');
15050
15040
  }).map(key => _objectSpread2({
@@ -15054,13 +15044,18 @@ const PdfForm = _ref3 => {
15054
15044
  const positionB = b.position || 0;
15055
15045
  return positionA - positionB;
15056
15046
  });
15047
+
15048
+ // Identify headers and regular objects
15057
15049
  const headers = allObjects.filter(obj => obj.type === 'header');
15058
15050
  const nonHeaders = allObjects.filter(obj => obj.type !== 'header');
15059
15051
  if (headers.length === 0) {
15052
+ // No headers found, keep original structure
15060
15053
  organizedSections[sectionKey] = section;
15061
15054
  return;
15062
15055
  }
15063
15056
  const organizedSection = _objectSpread2({}, section);
15057
+
15058
+ // Clear the section of its original objects
15064
15059
  Object.keys(section).forEach(key => {
15065
15060
  if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
15066
15061
  delete organizedSection[key];
@@ -15069,23 +15064,30 @@ const PdfForm = _ref3 => {
15069
15064
  headers.forEach((header, index) => {
15070
15065
  const headerPosition = header.position || 0;
15071
15066
  const nextHeaderPosition = index < headers.length - 1 ? headers[index + 1].position || 0 : Infinity;
15067
+
15068
+ // Find objects that belong under this header
15072
15069
  const childrenObjects = nonHeaders.filter(obj => {
15073
15070
  const objPosition = obj.position || 0;
15074
15071
  return objPosition > headerPosition && objPosition < nextHeaderPosition;
15075
15072
  });
15073
+
15074
+ // Create the header structure with children as inputs
15076
15075
  const headerWithChildren = _objectSpread2({}, header);
15077
- delete headerWithChildren.key;
15076
+ delete headerWithChildren.key; // Remove the key we added temporarily
15077
+
15078
15078
  if (childrenObjects.length > 0) {
15079
15079
  headerWithChildren.inputs = {};
15080
15080
  childrenObjects.forEach(child => {
15081
15081
  const childKey = child.key;
15082
15082
  const childData = _objectSpread2({}, child);
15083
- delete childData.key;
15083
+ delete childData.key; // Remove the temporary key
15084
15084
  headerWithChildren.inputs[childKey] = childData;
15085
15085
  });
15086
15086
  }
15087
15087
  organizedSection[header.key] = headerWithChildren;
15088
15088
  });
15089
+
15090
+ // Add any remaining objects that don't fall under any header
15089
15091
  const uncategorizedObjects = nonHeaders.filter(obj => {
15090
15092
  const objPosition = obj.position || 0;
15091
15093
  return !headers.some((header, index) => {
@@ -15107,243 +15109,39 @@ const PdfForm = _ref3 => {
15107
15109
  const organizedForm = React.useMemo(() => organizeFormByHeaders(form), [form]);
15108
15110
  const pdfConfig = React.useMemo(() => {
15109
15111
  const sections = [];
15110
-
15111
- // Calculate available page space (from PdfView component)
15112
- const PAGE_HEIGHT = 1587;
15113
- const HEADER_HEIGHT = 100;
15114
- const FOOTER_HEIGHT = 70;
15115
- const USABLE_PAGE_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT; // 1417
15116
- const TARGET_FILL_HEIGHT = USABLE_PAGE_HEIGHT * 0.8; // 80% = ~1133px
15117
- const MAX_INPUTS_PER_SECTION = 4; // 3-4 inputs max per section
15118
-
15119
- // Function to estimate the height of a form element
15120
- const estimateElementHeight = function (config) {
15121
- let level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
15122
- let height = 0;
15123
-
15124
- // Base height for each element (label + value + margins)
15125
- const baseElementHeight = 25; // Rough estimate for a simple field
15126
- const nestedElementHeight = 20; // Slightly less for nested elements
15127
- const headerHeight = 30; // Headers take more space
15128
-
15129
- // Add base height
15130
- if (config.type === 'header') {
15131
- height += headerHeight;
15132
- } else {
15133
- height += level === 0 ? baseElementHeight : nestedElementHeight;
15134
- }
15135
-
15136
- // If it has inputs, recursively calculate their height
15137
- if (config.inputs) {
15138
- Object.values(config.inputs).forEach(inputConfig => {
15139
- // Check showIf condition
15140
- if (inputConfig !== null && inputConfig !== void 0 && inputConfig.showIf && !evaluateShowIfCondition(inputConfig.showIf, data)) {
15141
- return;
15142
- }
15143
- height += estimateElementHeight(inputConfig, level + 1);
15144
- });
15145
- }
15146
- return height;
15147
- };
15148
-
15149
- // Function to flatten nested inputs into a flat array
15150
- const flattenInputs = function (parentKey, config) {
15151
- let parentLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
15152
- if (!config.inputs) {
15153
- // No nested inputs, return as single item
15154
- return [{
15155
- key: parentKey,
15156
- config: config,
15157
- parentLabel: parentLabel,
15158
- isNested: false
15159
- }];
15160
- }
15161
-
15162
- // Has nested inputs, flatten them
15163
- const flatItems = [];
15164
- const inputKeys = Object.keys(config.inputs).filter(key => {
15165
- const inputConfig = config.inputs[key];
15166
- if (inputConfig !== null && inputConfig !== void 0 && inputConfig.showIf && !evaluateShowIfCondition(inputConfig.showIf, data)) {
15167
- return false;
15168
- }
15169
- return true;
15170
- }).sort((a, b) => {
15171
- var _config$inputs$a3, _config$inputs$b3;
15172
- const positionA = ((_config$inputs$a3 = config.inputs[a]) === null || _config$inputs$a3 === void 0 ? void 0 : _config$inputs$a3.position) || 0;
15173
- const positionB = ((_config$inputs$b3 = config.inputs[b]) === null || _config$inputs$b3 === void 0 ? void 0 : _config$inputs$b3.position) || 0;
15174
- return positionA - positionB;
15175
- });
15176
- inputKeys.forEach(inputKey => {
15177
- const inputConfig = config.inputs[inputKey];
15178
- const fullLabel = parentLabel ? "".concat(parentLabel, " - ").concat(config.label) : config.label;
15179
-
15180
- // Recursively flatten if this input also has nested inputs
15181
- if (inputConfig.inputs) {
15182
- const nestedItems = flattenInputs(inputKey, inputConfig, fullLabel);
15183
- flatItems.push(...nestedItems);
15184
- } else {
15185
- flatItems.push({
15186
- key: inputKey,
15187
- config: inputConfig,
15188
- parentKey: parentKey,
15189
- parentConfig: config,
15190
- parentLabel: fullLabel,
15191
- isNested: true
15192
- });
15193
- }
15194
- });
15195
- return flatItems;
15196
- };
15197
-
15198
- // Function to group flattened items into chunks
15199
- const groupItemsIntoChunks = (flatItems, sectionLabel) => {
15200
- const chunks = [];
15201
- let currentChunk = [];
15202
- let currentChunkHeight = 40; // Base height for section header
15203
-
15204
- flatItems.forEach((item, index) => {
15205
- const itemHeight = estimateElementHeight(item.config);
15206
-
15207
- // Check if we should start a new chunk
15208
- const shouldStartNewChunk = currentChunk.length >= MAX_INPUTS_PER_SECTION || currentChunkHeight + itemHeight > TARGET_FILL_HEIGHT && currentChunk.length > 0;
15209
- if (shouldStartNewChunk) {
15210
- chunks.push([...currentChunk]);
15211
- currentChunk = [];
15212
- currentChunkHeight = 40; // Reset for new chunk
15213
- }
15214
- currentChunk.push(item);
15215
- currentChunkHeight += itemHeight;
15216
-
15217
- // If this is the last item, add the current chunk
15218
- if (index === flatItems.length - 1 && currentChunk.length > 0) {
15219
- chunks.push([...currentChunk]);
15220
- }
15221
- });
15222
- return chunks;
15223
- };
15224
-
15225
- // Function to create a section from a chunk of items
15226
- const createSectionFromChunk = (chunk, sectionKey, sectionLabel, chunkIndex) => {
15227
- const chunkSection = {
15228
- id: sectionKey,
15229
- label: sectionLabel,
15230
- position: 0
15231
- };
15232
-
15233
- // Group items by their parent if they're nested
15234
- const itemsByParent = {};
15235
- chunk.forEach(item => {
15236
- if (item.isNested && item.parentKey) {
15237
- if (!itemsByParent[item.parentKey]) {
15238
- itemsByParent[item.parentKey] = {
15239
- config: _objectSpread2({}, item.parentConfig),
15240
- inputs: {}
15241
- };
15242
- }
15243
- itemsByParent[item.parentKey].inputs[item.key] = item.config;
15244
- } else {
15245
- // Direct child of section
15246
- chunkSection[item.key] = item.config;
15247
- }
15248
- });
15249
-
15250
- // Add grouped parent items to section
15251
- Object.keys(itemsByParent).forEach(parentKey => {
15252
- chunkSection[parentKey] = itemsByParent[parentKey].config;
15253
- chunkSection[parentKey].inputs = itemsByParent[parentKey].inputs;
15254
- });
15255
- return chunkSection;
15256
- };
15257
- let isFirstSection = true;
15258
- let globalChunkIndex = 0;
15259
15112
  Object.keys(organizedForm).forEach(sectionKey => {
15260
15113
  const section = organizedForm[sectionKey];
15261
15114
  if (typeof section !== 'object' || !section.label) {
15262
15115
  return;
15263
15116
  }
15264
-
15265
- // Get all inputs from this section
15266
- const sectionInputKeys = Object.keys(section).filter(key => !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')).sort((a, b) => {
15267
- var _section$a, _section$b;
15268
- const positionA = ((_section$a = section[a]) === null || _section$a === void 0 ? void 0 : _section$a.position) || 0;
15269
- const positionB = ((_section$b = section[b]) === null || _section$b === void 0 ? void 0 : _section$b.position) || 0;
15270
- return positionA - positionB;
15271
- });
15272
-
15273
- // Flatten all nested inputs in this section
15274
- let allFlatItems = [];
15275
- sectionInputKeys.forEach(inputKey => {
15276
- const inputConfig = section[inputKey];
15277
- const flatItems = flattenInputs(inputKey, inputConfig);
15278
- allFlatItems.push(...flatItems);
15279
- });
15280
-
15281
- // Group flat items into chunks
15282
- const chunks = groupItemsIntoChunks(allFlatItems, section.label);
15283
-
15284
- // Create sections from chunks
15285
- chunks.forEach((chunk, chunkIndex) => {
15286
- const chunkSection = createSectionFromChunk(chunk, sectionKey, section.label);
15287
- const chunkKey = "".concat(sectionKey, "_chunk_").concat(globalChunkIndex);
15288
- sections.push({
15289
- render: () => /*#__PURE__*/jsxRuntime.jsx("div", {
15290
- className: "pdf-form-section",
15291
- children: /*#__PURE__*/jsxRuntime.jsx(PdfFormContent, {
15292
- form: {
15293
- [chunkKey]: chunkSection
15294
- },
15295
- data: data,
15296
- t: t,
15297
- user: user,
15298
- title: isFirstSection && chunkIndex === 0 ? formName : '',
15299
- source: isFirstSection && chunkIndex === 0 ? source : '',
15300
- version: isFirstSection && chunkIndex === 0 ? version : '',
15301
- getApiBaseUrl: getApiBaseUrl,
15302
- getAppHeader: getAppHeader,
15303
- app: app
15304
- })
15305
- }, chunkKey),
15306
- style: {
15307
- marginBottom: '10px',
15308
- padding: '0 20px'
15309
- }
15310
- });
15311
- globalChunkIndex++;
15312
- if (chunkIndex === 0) isFirstSection = false;
15117
+ sections.push({
15118
+ render: () => /*#__PURE__*/jsxRuntime.jsx("div", {
15119
+ className: "pdf-form-section",
15120
+ children: /*#__PURE__*/jsxRuntime.jsx(PdfFormContent, {
15121
+ form: {
15122
+ [sectionKey]: section
15123
+ },
15124
+ data: data,
15125
+ t: t,
15126
+ user: user,
15127
+ title: formName,
15128
+ source: source,
15129
+ version: version,
15130
+ getApiBaseUrl: getApiBaseUrl,
15131
+ getAppHeader: getAppHeader,
15132
+ app: app
15133
+ })
15134
+ }, sectionKey),
15135
+ style: {
15136
+ marginBottom: '20px',
15137
+ padding: '0 20px'
15138
+ }
15313
15139
  });
15314
15140
  });
15315
15141
  return sections;
15316
15142
  }, [organizedForm, data, t, getApiBaseUrl, getAppHeader, app, formName, source, version]);
15317
- console.log({
15318
- pdfConfig
15319
- });
15320
- const _pdfConfig = [{
15321
- render: () => /*#__PURE__*/jsxRuntime.jsxs("div", {
15322
- className: "document-header",
15323
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
15324
- className: "header-left",
15325
- children: /*#__PURE__*/jsxRuntime.jsx("h1", {
15326
- className: "company-name",
15327
- children: title
15328
- })
15329
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
15330
- className: "header-right",
15331
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
15332
- className: "meta-info",
15333
- children: [t('Source'), ": ", /*#__PURE__*/jsxRuntime.jsx("b", {
15334
- children: source
15335
- })]
15336
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
15337
- className: "meta-info",
15338
- children: [t('Version'), ": ", /*#__PURE__*/jsxRuntime.jsx("b", {
15339
- children: version
15340
- })]
15341
- })]
15342
- })]
15343
- })
15344
- }, ...pdfConfig];
15345
15143
  return /*#__PURE__*/jsxRuntime.jsx(PdfView, {
15346
- config: _pdfConfig,
15144
+ config: pdfConfig,
15347
15145
  customClassName: "pdf-form ".concat(customClassName),
15348
15146
  title: title,
15349
15147
  imgSrc: imgSrc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.132",
3
+ "version": "0.6.133",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -1,16 +1,12 @@
1
- // Dashboard/PdfView/index.jsx
2
1
  import moment from "moment";
3
2
  import PropTypes from 'prop-types';
4
3
  import { useCallback, useEffect, useRef, useState } from "react";
5
4
  import { formatClassname } from "../../../../../helpers/ClassesHelper";
6
5
 
7
6
  const PAGE_HEIGHT = 1587;
7
+ // margin-top: 20, bottom: 20;
8
8
  const FOOTER_HEIGHT = 70;
9
- const HEADER_HEIGHT = 100; // Total area reserved for header (could be slightly more than actual div height)
10
- const HEADER_DIV_HEIGHT = HEADER_HEIGHT - 24; // Actual height of the absolute header div
11
-
12
- const FIRST_CONTENT_TOP_MARGIN = 30; // Desired margin-top for the very first content section on any given page.
13
- const SECTION_NORMAL_MARGIN = 24; // Default margin-top for subsequent sections on the same page.
9
+ const HEADER_HEIGHT = 100;
14
10
 
15
11
  const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
16
12
  const ref = useRef();
@@ -60,84 +56,48 @@ export default function PdfView({
60
56
  let _page = 1;
61
57
 
62
58
  if (keys.length === config.length) {
63
- // `currentContentHeightAccumulated` tracks the height used by content sections *plus their top margins*,
64
- // relative to the top of the *usable content area* on the current page.
65
- let currentContentHeightAccumulated = 0;
66
-
67
- // The total vertical space available for content sections *between* the absolute header and footer.
68
- const USABLE_PAGE_CONTENT_HEIGHT = PAGE_HEIGHT - HEADER_DIV_HEIGHT - FOOTER_HEIGHT;
69
-
70
- // Reset margins/padding for all sections before recalculating
59
+ let incrHeight = 0;
60
+
71
61
  keys.forEach(k => {
72
62
  const { ref } = sectionsConfig[k];
73
- if (ref.current) {
74
- ref.current.style.marginBottom = '0px';
75
- ref.current.style.marginTop = '0px';
76
- ref.current.style.paddingBottom = '0px';
77
- }
78
- });
63
+ ref.current.style.marginBottom = '0px';
64
+ // ref.current.style.marginTop = '15px';
65
+ })
79
66
 
80
67
  keys.forEach((k, i) => {
81
68
  const { height, ref } = sectionsConfig[k];
82
- if (!ref.current) return; // Skip if ref.current is null (e.g., component unmounted or not yet rendered)
83
69
 
84
- let sectionTopMargin = 0;
70
+ if (i === 0) {
71
+ ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
72
+ incrHeight += HEADER_HEIGHT;
73
+ }
74
+
75
+ const newHeight = incrHeight + height;
85
76
 
86
- // Determine the top margin for the current section
87
- if (currentContentHeightAccumulated === 0) {
88
- // This is the very first content section on the current virtual page
89
- sectionTopMargin = FIRST_CONTENT_TOP_MARGIN;
90
- } else {
91
- // Subsequent content sections on the same virtual page
92
- sectionTopMargin = SECTION_NORMAL_MARGIN;
77
+ if (i === keys.length - 1) {
78
+ ref.current.style.paddingBottom = '30px';
93
79
  }
94
-
95
- // Calculate the total space this section *would take* on the current page, including its own top margin.
96
- const spaceNeededByThisSection = sectionTopMargin + height;
97
80
 
98
- // Check if adding this section (with its top margin) would exceed the usable content area.
99
- if (currentContentHeightAccumulated + spaceNeededByThisSection > USABLE_PAGE_CONTENT_HEIGHT) {
100
- // This section overflows, so it must start on a new page.
81
+ if (newHeight > PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT) {
82
+ const dif = Math.abs(PAGE_HEIGHT - incrHeight);
83
+ ref.current.style.marginTop = '30px';
101
84
  _page += 1;
102
85
  _pages.push(_page);
103
86
 
104
- // If there was a previous section on the *old* page, we need to fill the remaining space
105
- // on that page by adding a bottom margin to the last section that fit.
106
- if (i > 0) {
107
- const prevSectionRef = sectionsConfig[keys[i - 1]]?.ref;
108
- if (prevSectionRef?.current) {
109
- // Calculate remaining space on the previous page
110
- const spaceLeftOnPrevPage = USABLE_PAGE_CONTENT_HEIGHT - currentContentHeightAccumulated;
111
- if (spaceLeftOnPrevPage > 0) {
112
- prevSectionRef.current.style.marginBottom = `${spaceLeftOnPrevPage}px`;
113
- }
114
- }
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
-
117
- // For the current section (which is now the first on a new page), apply the `FIRST_CONTENT_TOP_MARGIN`.
118
- ref.current.style.marginTop = `${FIRST_CONTENT_TOP_MARGIN}px`;
119
- currentContentHeightAccumulated = FIRST_CONTENT_TOP_MARGIN + height; // Reset and update accumulated height for the *new* page
120
93
  } else {
121
- // This section fits on the current page. Apply its calculated top margin.
122
- ref.current.style.marginTop = `${sectionTopMargin}px`;
123
- currentContentHeightAccumulated += spaceNeededByThisSection; // Add its height and its own top margin to accumulated height
94
+ incrHeight = newHeight + 24;
124
95
  }
125
-
126
- // Add the standard margin between sections (for the *next* section, if there is one).
127
- // This is important because `currentContentHeightAccumulated` needs to reflect the space used *up to the bottom of this section*,
128
- // plus any necessary space for the next section's margin *before* it gets evaluated.
129
- if (i < keys.length - 1) {
130
- currentContentHeightAccumulated += SECTION_NORMAL_MARGIN;
131
- }
132
-
133
- // For the very last section of the entire document, add extra padding to the bottom.
134
- if (i === keys.length - 1) {
135
- ref.current.style.paddingBottom = '30px';
136
- }
137
- });
96
+ // console.groupEnd();
97
+ })
138
98
  setPages(_pages);
139
99
  }
140
- }, [sectionsConfig, config.length]);
100
+ }, [sectionsConfig]);
141
101
 
142
102
  useEffect(() => {
143
103
  doSizing();
@@ -168,13 +128,22 @@ export default function PdfView({
168
128
  );
169
129
  }, [config, onChangeHeight]);
170
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
+
171
140
  return (
172
141
  <div className={contClassName} style={{ position: 'relative' }}>
173
142
  {renderDashboard()}
174
143
  {pages.map((page) => (
175
144
  <>
176
145
  <div
177
- style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_DIV_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }}
146
+ style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT - 24, position: 'absolute', left: 0, zIndex: 1000000 }}
178
147
  key={`headers-${page}`}
179
148
  className="flex-row dashboard-header"
180
149
  >
@@ -235,4 +204,4 @@ PdfView.propTypes = {
235
204
  userId: PropTypes.string,
236
205
  accountId: PropTypes.string,
237
206
  documentId: PropTypes.string,
238
- }
207
+ }
@@ -340,6 +340,15 @@ const PdfFormContent = ({
340
340
  }) => {
341
341
  return (
342
342
  <div className="pdf-form-content">
343
+ <div className="document-header">
344
+ <div className="header-left">
345
+ <h1 className="company-name">{title}</h1>
346
+ </div>
347
+ <div className="header-right">
348
+ <div className="meta-info">{t('Source')}: <b>{source}</b></div>
349
+ <div className="meta-info">{t('Version')}: <b>{version}</b></div>
350
+ </div>
351
+ </div>
343
352
  <div className="pdf-tree">
344
353
  {Object.keys(form)
345
354
  .filter(sectionKey => {
@@ -400,6 +409,7 @@ const PdfForm = ({
400
409
  getAppHeader = () => {},
401
410
  app
402
411
  }) => {
412
+ // Group objects under headers based on position
403
413
  const organizeFormByHeaders = (formData) => {
404
414
  const organizedSections = {};
405
415
 
@@ -410,6 +420,7 @@ const PdfForm = ({
410
420
  return;
411
421
  }
412
422
 
423
+ // Get all objects from this section and sort by position
413
424
  const allObjects = Object.keys(section)
414
425
  .filter(key => {
415
426
  return !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle');
@@ -424,18 +435,22 @@ const PdfForm = ({
424
435
  return positionA - positionB;
425
436
  });
426
437
 
438
+ // Identify headers and regular objects
427
439
  const headers = allObjects.filter(obj => obj.type === 'header');
428
440
  const nonHeaders = allObjects.filter(obj => obj.type !== 'header');
429
441
 
430
442
  if (headers.length === 0) {
443
+ // No headers found, keep original structure
431
444
  organizedSections[sectionKey] = section;
432
445
  return;
433
446
  }
434
447
 
435
448
  const organizedSection = {
436
449
  ...section,
450
+ // Keep the section-level properties
437
451
  };
438
452
 
453
+ // Clear the section of its original objects
439
454
  Object.keys(section).forEach(key => {
440
455
  if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
441
456
  delete organizedSection[key];
@@ -448,20 +463,22 @@ const PdfForm = ({
448
463
  ? (headers[index + 1].position || 0)
449
464
  : Infinity;
450
465
 
466
+ // Find objects that belong under this header
451
467
  const childrenObjects = nonHeaders.filter(obj => {
452
468
  const objPosition = obj.position || 0;
453
469
  return objPosition > headerPosition && objPosition < nextHeaderPosition;
454
470
  });
455
471
 
472
+ // Create the header structure with children as inputs
456
473
  const headerWithChildren = { ...header };
457
- delete headerWithChildren.key;
474
+ delete headerWithChildren.key; // Remove the key we added temporarily
458
475
 
459
476
  if (childrenObjects.length > 0) {
460
477
  headerWithChildren.inputs = {};
461
478
  childrenObjects.forEach(child => {
462
479
  const childKey = child.key;
463
480
  const childData = { ...child };
464
- delete childData.key;
481
+ delete childData.key; // Remove the temporary key
465
482
  headerWithChildren.inputs[childKey] = childData;
466
483
  });
467
484
  }
@@ -469,6 +486,7 @@ const PdfForm = ({
469
486
  organizedSection[header.key] = headerWithChildren;
470
487
  });
471
488
 
489
+ // Add any remaining objects that don't fall under any header
472
490
  const uncategorizedObjects = nonHeaders.filter(obj => {
473
491
  const objPosition = obj.position || 0;
474
492
  return !headers.some((header, index) => {
@@ -498,166 +516,6 @@ const PdfForm = ({
498
516
  const pdfConfig = useMemo(() => {
499
517
  const sections = [];
500
518
 
501
- // Calculate available page space (from PdfView component)
502
- const PAGE_HEIGHT = 1587;
503
- const HEADER_HEIGHT = 100;
504
- const FOOTER_HEIGHT = 70;
505
- const USABLE_PAGE_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT; // 1417
506
- const TARGET_FILL_HEIGHT = USABLE_PAGE_HEIGHT * 0.8; // 80% = ~1133px
507
- const MAX_INPUTS_PER_SECTION = 4; // 3-4 inputs max per section
508
-
509
- // Function to estimate the height of a form element
510
- const estimateElementHeight = (config, level = 0) => {
511
- let height = 0;
512
-
513
- // Base height for each element (label + value + margins)
514
- const baseElementHeight = 25; // Rough estimate for a simple field
515
- const nestedElementHeight = 20; // Slightly less for nested elements
516
- const headerHeight = 30; // Headers take more space
517
-
518
- // Add base height
519
- if (config.type === 'header') {
520
- height += headerHeight;
521
- } else {
522
- height += level === 0 ? baseElementHeight : nestedElementHeight;
523
- }
524
-
525
- // If it has inputs, recursively calculate their height
526
- if (config.inputs) {
527
- Object.values(config.inputs).forEach(inputConfig => {
528
- // Check showIf condition
529
- if (inputConfig?.showIf && !evaluateShowIfCondition(inputConfig.showIf, data)) {
530
- return;
531
- }
532
- height += estimateElementHeight(inputConfig, level + 1);
533
- });
534
- }
535
-
536
- return height;
537
- };
538
-
539
- // Function to flatten nested inputs into a flat array
540
- const flattenInputs = (parentKey, config, parentLabel = '') => {
541
- if (!config.inputs) {
542
- // No nested inputs, return as single item
543
- return [{
544
- key: parentKey,
545
- config: config,
546
- parentLabel: parentLabel,
547
- isNested: false
548
- }];
549
- }
550
-
551
- // Has nested inputs, flatten them
552
- const flatItems = [];
553
- const inputKeys = Object.keys(config.inputs)
554
- .filter(key => {
555
- const inputConfig = config.inputs[key];
556
- if (inputConfig?.showIf && !evaluateShowIfCondition(inputConfig.showIf, data)) {
557
- return false;
558
- }
559
- return true;
560
- })
561
- .sort((a, b) => {
562
- const positionA = config.inputs[a]?.position || 0;
563
- const positionB = config.inputs[b]?.position || 0;
564
- return positionA - positionB;
565
- });
566
-
567
- inputKeys.forEach(inputKey => {
568
- const inputConfig = config.inputs[inputKey];
569
- const fullLabel = parentLabel ? `${parentLabel} - ${config.label}` : config.label;
570
-
571
- // Recursively flatten if this input also has nested inputs
572
- if (inputConfig.inputs) {
573
- const nestedItems = flattenInputs(inputKey, inputConfig, fullLabel);
574
- flatItems.push(...nestedItems);
575
- } else {
576
- flatItems.push({
577
- key: inputKey,
578
- config: inputConfig,
579
- parentKey: parentKey,
580
- parentConfig: config,
581
- parentLabel: fullLabel,
582
- isNested: true
583
- });
584
- }
585
- });
586
-
587
- return flatItems;
588
- };
589
-
590
- // Function to group flattened items into chunks
591
- const groupItemsIntoChunks = (flatItems, sectionLabel) => {
592
- const chunks = [];
593
- let currentChunk = [];
594
- let currentChunkHeight = 40; // Base height for section header
595
-
596
- flatItems.forEach((item, index) => {
597
- const itemHeight = estimateElementHeight(item.config);
598
-
599
- // Check if we should start a new chunk
600
- const shouldStartNewChunk = (
601
- currentChunk.length >= MAX_INPUTS_PER_SECTION ||
602
- (currentChunkHeight + itemHeight > TARGET_FILL_HEIGHT && currentChunk.length > 0)
603
- );
604
-
605
- if (shouldStartNewChunk) {
606
- chunks.push([...currentChunk]);
607
- currentChunk = [];
608
- currentChunkHeight = 40; // Reset for new chunk
609
- }
610
-
611
- currentChunk.push(item);
612
- currentChunkHeight += itemHeight;
613
-
614
- // If this is the last item, add the current chunk
615
- if (index === flatItems.length - 1 && currentChunk.length > 0) {
616
- chunks.push([...currentChunk]);
617
- }
618
- });
619
-
620
- return chunks;
621
- };
622
-
623
- // Function to create a section from a chunk of items
624
- const createSectionFromChunk = (chunk, sectionKey, sectionLabel, chunkIndex) => {
625
- const chunkSection = {
626
- id: sectionKey,
627
- label: sectionLabel,
628
- position: 0
629
- };
630
-
631
- // Group items by their parent if they're nested
632
- const itemsByParent = {};
633
-
634
- chunk.forEach(item => {
635
- if (item.isNested && item.parentKey) {
636
- if (!itemsByParent[item.parentKey]) {
637
- itemsByParent[item.parentKey] = {
638
- config: { ...item.parentConfig },
639
- inputs: {}
640
- };
641
- }
642
- itemsByParent[item.parentKey].inputs[item.key] = item.config;
643
- } else {
644
- // Direct child of section
645
- chunkSection[item.key] = item.config;
646
- }
647
- });
648
-
649
- // Add grouped parent items to section
650
- Object.keys(itemsByParent).forEach(parentKey => {
651
- chunkSection[parentKey] = itemsByParent[parentKey].config;
652
- chunkSection[parentKey].inputs = itemsByParent[parentKey].inputs;
653
- });
654
-
655
- return chunkSection;
656
- };
657
-
658
- let isFirstSection = true;
659
- let globalChunkIndex = 0;
660
-
661
519
  Object.keys(organizedForm).forEach((sectionKey) => {
662
520
  const section = organizedForm[sectionKey];
663
521
 
@@ -665,85 +523,36 @@ const PdfForm = ({
665
523
  return;
666
524
  }
667
525
 
668
- // Get all inputs from this section
669
- const sectionInputKeys = Object.keys(section)
670
- .filter(key => !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle'))
671
- .sort((a, b) => {
672
- const positionA = section[a]?.position || 0;
673
- const positionB = section[b]?.position || 0;
674
- return positionA - positionB;
675
- });
676
-
677
- // Flatten all nested inputs in this section
678
- let allFlatItems = [];
679
- sectionInputKeys.forEach(inputKey => {
680
- const inputConfig = section[inputKey];
681
- const flatItems = flattenInputs(inputKey, inputConfig);
682
- allFlatItems.push(...flatItems);
683
- });
684
-
685
- // Group flat items into chunks
686
- const chunks = groupItemsIntoChunks(allFlatItems, section.label);
687
-
688
- // Create sections from chunks
689
- chunks.forEach((chunk, chunkIndex) => {
690
- const chunkSection = createSectionFromChunk(chunk, sectionKey, section.label, chunkIndex);
691
- const chunkKey = `${sectionKey}_chunk_${globalChunkIndex}`;
692
-
693
- sections.push({
694
- render: () => (
695
- <div key={chunkKey} className="pdf-form-section">
696
- <PdfFormContent
697
- form={{ [chunkKey]: chunkSection }}
698
- data={data}
699
- t={t}
700
- user={user}
701
- title={isFirstSection && chunkIndex === 0 ? formName : ''}
702
- source={isFirstSection && chunkIndex === 0 ? source : ''}
703
- version={isFirstSection && chunkIndex === 0 ? version : ''}
704
- getApiBaseUrl={getApiBaseUrl}
705
- getAppHeader={getAppHeader}
706
- app={app}
707
- />
708
- </div>
709
- ),
710
- style: {
711
- marginBottom: '10px',
712
- padding: '0 20px'
713
- }
714
- });
715
-
716
- globalChunkIndex++;
717
- if (chunkIndex === 0) isFirstSection = false;
526
+ sections.push({
527
+ render: () => (
528
+ <div key={sectionKey} className="pdf-form-section">
529
+ <PdfFormContent
530
+ form={{ [sectionKey]: section }}
531
+ data={data}
532
+ t={t}
533
+ user={user}
534
+ title={formName}
535
+ source={source}
536
+ version={version}
537
+ getApiBaseUrl={getApiBaseUrl}
538
+ getAppHeader={getAppHeader}
539
+ app={app}
540
+ />
541
+ </div>
542
+ ),
543
+ style: {
544
+ marginBottom: '20px',
545
+ padding: '0 20px'
546
+ }
718
547
  });
719
548
  });
720
-
549
+
721
550
  return sections;
722
551
  }, [organizedForm, data, t, getApiBaseUrl, getAppHeader, app, formName, source, version]);
723
552
 
724
- console.log({pdfConfig});
725
-
726
-
727
- const _pdfConfig = [
728
- {
729
- render: () => (
730
- <div className="document-header">
731
- <div className="header-left">
732
- <h1 className="company-name">{title}</h1>
733
- </div>
734
- <div className="header-right">
735
- <div className="meta-info">{t('Source')}: <b>{source}</b></div>
736
- <div className="meta-info">{t('Version')}: <b>{version}</b></div>
737
- </div>
738
- </div>
739
- ),
740
- },
741
- ...pdfConfig
742
- ]
743
-
744
553
  return (
745
554
  <PdfView
746
- config={_pdfConfig}
555
+ config={pdfConfig}
747
556
  customClassName={`pdf-form ${customClassName}`}
748
557
  title={title}
749
558
  imgSrc={imgSrc}