datastake-daf 0.6.121 → 0.6.123

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.121",
3
+ "version": "0.6.123",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -3,9 +3,9 @@ import PropTypes from 'prop-types';
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { formatClassname } from "../../../../../helpers/ClassesHelper";
5
5
 
6
- const PAGE_HEIGHT = 3508;
6
+ const PAGE_HEIGHT = 1587;
7
7
  // margin-top: 20, bottom: 20;
8
- const FOOTER_HEIGHT = 40;
8
+ const FOOTER_HEIGHT = 70;
9
9
  const HEADER_HEIGHT = 100;
10
10
 
11
11
  const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
@@ -66,18 +66,12 @@ export default function PdfView({
66
66
 
67
67
  keys.forEach((k, i) => {
68
68
  const { height, ref } = sectionsConfig[k];
69
-
69
+
70
70
  if (i === 0) {
71
- const availableSpace = PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT;
72
- if (height > availableSpace) {
73
- ref.current.style.marginTop = '30px';
74
- incrHeight = 30;
75
- } else {
76
- ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
77
- incrHeight = HEADER_HEIGHT;
78
- }
71
+ ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
72
+ incrHeight += HEADER_HEIGHT;
79
73
  }
80
-
74
+
81
75
  const newHeight = incrHeight + height;
82
76
 
83
77
  if (i === keys.length - 1) {
@@ -6,42 +6,6 @@
6
6
  position: relative;
7
7
  flex-direction: column;
8
8
 
9
- // Widget Catalogue specific styles
10
- &.widget-catalogue {
11
- padding: var(--size-lg);
12
-
13
- @media (max-width: 850px) {
14
- padding: var(--size);
15
- }
16
-
17
- .grid {
18
- display: grid;
19
- gap: 1.5rem;
20
-
21
- @media (min-width: 768px) {
22
- grid-template-columns: repeat(2, 1fr);
23
- }
24
-
25
- @media (min-width: 1024px) {
26
- grid-template-columns: repeat(3, 1fr);
27
- }
28
-
29
- @media (min-width: 1280px) {
30
- grid-template-columns: repeat(4, 1fr);
31
- }
32
- }
33
-
34
- .ant-card {
35
- transition: all 0.2s ease-in-out;
36
- border: 1px solid #e5e7eb;
37
-
38
- &:hover {
39
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
40
- transform: translateY(-2px);
41
- }
42
- }
43
- }
44
-
45
9
  .month-select {
46
10
  min-width: 165px;
47
11
  max-width: 165px;
@@ -142,7 +142,7 @@ export const handleDataLinkGroupWithTableKeys = ({
142
142
  label: uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : tableKey,
143
143
  type: inputConfig?.type
144
144
  };
145
- values[tableKey] = item?.linking?.SCL?.[item?.[tableKey]]?.name || item?.[tableKey];
145
+ values[tableKey] = item?.[tableKey];
146
146
  }
147
147
  });
148
148
 
@@ -90,7 +90,7 @@ export const handleDataLinkWithTableKeys = ({
90
90
  inputs[tableKey].label = resolvedLabel || Object.values(formInputConfig.label)[0] ||
91
91
  (uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : tableKey);
92
92
  }
93
- values[tableKey] = item?.linking?.SCL?.[item?.[tableKey]]?.name || item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[tableKey];
93
+ values[tableKey] = item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[tableKey];
94
94
  } else {
95
95
  inputs[tableKey] = {
96
96
  label: uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : tableKey,
@@ -139,7 +139,7 @@ export const handleDataLinkWithTableKeys = ({
139
139
  inputs[fieldKey].label = resolvedLabel || Object.values(formInputConfig.label)[0] ||
140
140
  (uploadTypeFields.includes(fieldKey) ? uploadTypeLabels[fieldKey] : fieldKey);
141
141
  }
142
- values[fieldKey] = item?.linking?.SCL?.[item?.[fieldKey]]?.name || item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[fieldKey];
142
+ values[fieldKey] = item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[fieldKey];
143
143
  });
144
144
  }
145
145
 
@@ -409,6 +409,7 @@ const PdfForm = ({
409
409
  getAppHeader = () => {},
410
410
  app
411
411
  }) => {
412
+ // Group objects under headers based on position
412
413
  const organizeFormByHeaders = (formData) => {
413
414
  const organizedSections = {};
414
415
 
@@ -419,6 +420,7 @@ const PdfForm = ({
419
420
  return;
420
421
  }
421
422
 
423
+ // Get all objects from this section and sort by position
422
424
  const allObjects = Object.keys(section)
423
425
  .filter(key => {
424
426
  return !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle');
@@ -433,18 +435,22 @@ const PdfForm = ({
433
435
  return positionA - positionB;
434
436
  });
435
437
 
438
+ // Identify headers and regular objects
436
439
  const headers = allObjects.filter(obj => obj.type === 'header');
437
440
  const nonHeaders = allObjects.filter(obj => obj.type !== 'header');
438
441
 
439
442
  if (headers.length === 0) {
443
+ // No headers found, keep original structure
440
444
  organizedSections[sectionKey] = section;
441
445
  return;
442
446
  }
443
447
 
444
448
  const organizedSection = {
445
449
  ...section,
450
+ // Keep the section-level properties
446
451
  };
447
452
 
453
+ // Clear the section of its original objects
448
454
  Object.keys(section).forEach(key => {
449
455
  if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
450
456
  delete organizedSection[key];
@@ -457,20 +463,22 @@ const PdfForm = ({
457
463
  ? (headers[index + 1].position || 0)
458
464
  : Infinity;
459
465
 
466
+ // Find objects that belong under this header
460
467
  const childrenObjects = nonHeaders.filter(obj => {
461
468
  const objPosition = obj.position || 0;
462
469
  return objPosition > headerPosition && objPosition < nextHeaderPosition;
463
470
  });
464
471
 
472
+ // Create the header structure with children as inputs
465
473
  const headerWithChildren = { ...header };
466
- delete headerWithChildren.key;
474
+ delete headerWithChildren.key; // Remove the key we added temporarily
467
475
 
468
476
  if (childrenObjects.length > 0) {
469
477
  headerWithChildren.inputs = {};
470
478
  childrenObjects.forEach(child => {
471
479
  const childKey = child.key;
472
480
  const childData = { ...child };
473
- delete childData.key;
481
+ delete childData.key; // Remove the temporary key
474
482
  headerWithChildren.inputs[childKey] = childData;
475
483
  });
476
484
  }
@@ -478,6 +486,7 @@ const PdfForm = ({
478
486
  organizedSection[header.key] = headerWithChildren;
479
487
  });
480
488
 
489
+ // Add any remaining objects that don't fall under any header
481
490
  const uncategorizedObjects = nonHeaders.filter(obj => {
482
491
  const objPosition = obj.position || 0;
483
492
  return !headers.some((header, index) => {
@@ -507,124 +516,37 @@ const PdfForm = ({
507
516
  const pdfConfig = useMemo(() => {
508
517
  const sections = [];
509
518
 
510
- // Function to count the complexity/size of a section
511
- const getSectionComplexity = (section) => {
512
- let complexity = 0;
513
- const countInputs = (obj) => {
514
- if (!obj || typeof obj !== 'object') return 0;
515
-
516
- let count = 0;
517
- Object.keys(obj).forEach(key => {
518
- if (key === 'inputs' && obj[key]) {
519
- count += Object.keys(obj[key]).length;
520
- // Recursively count nested inputs
521
- Object.values(obj[key]).forEach(input => {
522
- count += countInputs(input);
523
- });
524
- } else if (typeof obj[key] === 'object' && obj[key] !== null) {
525
- count += countInputs(obj[key]);
526
- }
527
- });
528
- return count;
529
- };
530
-
531
- complexity += countInputs(section);
532
- return complexity;
533
- };
534
-
535
- // Function to split a section into smaller chunks
536
- const splitSection = (sectionKey, section, maxComplexity = 15) => {
537
- const complexity = getSectionComplexity(section);
538
-
539
- if (complexity <= maxComplexity) {
540
- // Section is small enough, return as-is
541
- return [{
542
- key: sectionKey,
543
- section: section,
544
- title: formName,
545
- isFirstPart: true,
546
- isLastPart: true
547
- }];
548
- }
549
-
550
- // Section is too large, split it
551
- const chunks = [];
552
- const sectionInputs = Object.keys(section)
553
- .filter(key => !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle'))
554
- .sort((a, b) => {
555
- const positionA = section[a]?.position || 0;
556
- const positionB = section[b]?.position || 0;
557
- return positionA - positionB;
558
- });
559
-
560
- const chunkSize = Math.ceil(sectionInputs.length / Math.ceil(complexity / maxComplexity));
561
-
562
- for (let i = 0; i < sectionInputs.length; i += chunkSize) {
563
- const chunkInputs = sectionInputs.slice(i, i + chunkSize);
564
- const chunkSection = {
565
- ...section,
566
- label: `${section.label} ${chunks.length > 0 ? `(Part ${chunks.length + 1})` : ''}`
567
- };
568
-
569
- // Remove all inputs first
570
- Object.keys(chunkSection).forEach(key => {
571
- if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
572
- delete chunkSection[key];
573
- }
574
- });
575
-
576
- // Add only the inputs for this chunk
577
- chunkInputs.forEach(inputKey => {
578
- chunkSection[inputKey] = section[inputKey];
579
- });
580
-
581
- chunks.push({
582
- key: `${sectionKey}_chunk_${chunks.length}`,
583
- section: chunkSection,
584
- title: chunks.length === 0 ? formName : '', // Only show title on first chunk
585
- isFirstPart: chunks.length === 0,
586
- isLastPart: i + chunkSize >= sectionInputs.length
587
- });
588
- }
589
-
590
- return chunks;
591
- };
592
-
593
519
  Object.keys(organizedForm).forEach((sectionKey) => {
594
520
  const section = organizedForm[sectionKey];
595
521
 
596
522
  if (typeof section !== 'object' || !section.label) {
597
523
  return;
598
524
  }
599
-
600
- const sectionChunks = splitSection(sectionKey, section);
601
-
602
- sectionChunks.forEach((chunk) => {
603
- sections.push({
604
- render: () => (
605
- <div key={chunk.key} className="pdf-form-section">
606
- <PdfFormContent
607
- form={{ [chunk.key]: chunk.section }}
608
- data={data}
609
- t={t}
610
- user={user}
611
- title={chunk.title}
612
- source={chunk.isFirstPart ? source : ''}
613
- version={chunk.isFirstPart ? version : ''}
614
- getApiBaseUrl={getApiBaseUrl}
615
- getAppHeader={getAppHeader}
616
- app={app}
617
- />
618
- </div>
619
- ),
620
- style: {
621
- marginBottom: chunk.isLastPart ? '20px' : '10px',
622
- padding: '0 20px'
623
- }
624
- });
525
+
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
+ }
625
547
  });
626
548
  });
627
-
549
+
628
550
  return sections;
629
551
  }, [organizedForm, data, t, getApiBaseUrl, getAppHeader, app, formName, source, version]);
630
552
 
@@ -1343,7 +1343,7 @@ export const storyData = {
1343
1343
  }
1344
1344
  },
1345
1345
  data: {
1346
- "_id": "68c1930d459dca833f27c72b",
1346
+ "_id": "68bea82c811b1cf197c94a70",
1347
1347
  "createdAt": "2025-09-08T09:55:56.733Z",
1348
1348
  "updatedAt": "2025-09-08T10:05:59.817Z",
1349
1349
  "form": "stakeholder",
@@ -1672,7 +1672,7 @@ export const storyData = {
1672
1672
  "maleMembers": 3,
1673
1673
  "namespace": "registration",
1674
1674
  "phoneNumber": "+57 12 359 4378 3",
1675
- "stakeholderId": "68c1930d459dca833f27c72b",
1675
+ "stakeholderId": "68bea82c811b1cf197c94a70",
1676
1676
  "taxNr": "TTTTT123456789",
1677
1677
  "website": null
1678
1678
  },
@@ -10,11 +10,6 @@
10
10
  align-items: center;
11
11
  margin-bottom: 10px;
12
12
  padding: 20px 0 0 0;
13
- page-break-inside: avoid;
14
- page-break-after: avoid;
15
- break-inside: avoid;
16
- top: 0;
17
- z-index: 100;
18
13
 
19
14
  .company-name {
20
15
  font-size: 20px;
@@ -87,10 +82,6 @@
87
82
 
88
83
  .pdf-form-content {
89
84
  margin-top: 30px;
90
- page-break-inside: auto;
91
- page-break-after: auto;
92
- break-inside: auto;
93
- break-after: auto;
94
85
 
95
86
  .pdf-tree {
96
87
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
@@ -0,0 +1,118 @@
1
+ import React, { useState } from 'react';
2
+ import { CheckOutlined, ScanOutlined, FileTextOutlined, CheckCircleOutlined } from '@ant-design/icons';
3
+ import ProgressTabs from './index';
4
+
5
+ export default {
6
+ title: 'Components/ProgressTabs',
7
+ component: ProgressTabs,
8
+ parameters: {
9
+ layout: 'centered',
10
+ },
11
+ argTypes: {
12
+ value: {
13
+ control: { type: 'select', options: ['setup', 'scan', 'review', 'status'] },
14
+ description: 'Current selected value',
15
+ },
16
+ onChange: {
17
+ action: 'changed',
18
+ description: 'Callback when selection changes',
19
+ },
20
+ },
21
+ };
22
+
23
+ const Template = (args) => {
24
+ const [value, setValue] = useState(args.value || 'setup');
25
+
26
+ const handleChange = (newValue) => {
27
+ setValue(newValue);
28
+ args.onChange?.(newValue);
29
+ };
30
+
31
+ return (
32
+ <div style={{ width: '600px', padding: '20px' }}>
33
+ <ProgressTabs
34
+ {...args}
35
+ value={value}
36
+ onChange={handleChange}
37
+ />
38
+ </div>
39
+ );
40
+ };
41
+
42
+ export const Default = Template.bind({});
43
+ Default.args = {
44
+ value: 'setup',
45
+ };
46
+
47
+ export const SecondStep = Template.bind({});
48
+ SecondStep.args = {
49
+ value: 'scan',
50
+ };
51
+
52
+ export const ThirdStep = Template.bind({});
53
+ ThirdStep.args = {
54
+ value: 'review',
55
+ };
56
+
57
+ export const LastStep = Template.bind({});
58
+ LastStep.args = {
59
+ value: 'status',
60
+ };
61
+
62
+ export const CustomOptions = Template.bind({});
63
+ CustomOptions.args = {
64
+ value: 'data',
65
+ options: [
66
+ { label: 'Initial Setup', value: 'init' },
67
+ { label: 'Data Collection', value: 'data' },
68
+ { label: 'Analysis', value: 'analysis' },
69
+ { label: 'Final Report', value: 'report' }
70
+ ],
71
+ };
72
+
73
+ export const WithIcons = Template.bind({});
74
+ WithIcons.args = {
75
+ value: 'setup',
76
+ options: [
77
+ { label: 'Set Up', value: 'setup', icon: <CheckOutlined /> },
78
+ { label: 'Project Scan', value: 'scan', icon: <ScanOutlined /> },
79
+ { label: 'Review & Submission', value: 'review', icon: <FileTextOutlined /> },
80
+ { label: 'Submission Status', value: 'status', icon: <CheckCircleOutlined /> }
81
+ ],
82
+ };
83
+
84
+ export const WithDisabled = Template.bind({});
85
+ WithDisabled.args = {
86
+ value: 'setup',
87
+ options: [
88
+ { label: 'Set Up', value: 'setup' },
89
+ { label: 'Project Scan', value: 'scan', isDisabled: true },
90
+ { label: 'Review & Submission', value: 'review', isDisabled: true },
91
+ { label: 'Submission Status', value: 'status', isDisabled: true }
92
+ ],
93
+ };
94
+
95
+ export const WithIconsAndDisabled = Template.bind({});
96
+ WithIconsAndDisabled.args = {
97
+ value: 'setup',
98
+ options: [
99
+ { label: 'Set Up', value: 'setup', icon: <CheckOutlined /> },
100
+ { label: 'Project Scan', value: 'scan', icon: <ScanOutlined />, isDisabled: true },
101
+ { label: 'Review & Submission', value: 'review', icon: <FileTextOutlined />, isDisabled: true },
102
+ { label: 'Submission Status', value: 'status', icon: <CheckCircleOutlined />, isDisabled: true }
103
+ ],
104
+ };
105
+
106
+ export const CustomWidth = Template.bind({});
107
+ CustomWidth.args = {
108
+ value: 'scan',
109
+ width: '400px',
110
+ };
111
+
112
+ export const SmallWidth = Template.bind({});
113
+ SmallWidth.args = {
114
+ value: 'review',
115
+ width: '300px',
116
+ };
117
+
118
+
@@ -0,0 +1,100 @@
1
+ .progress-tabs {
2
+ width: 100%;
3
+ padding: 16px 0;
4
+
5
+ &__segmented {
6
+ .ant-segmented {
7
+ background: #f8f9fa;
8
+ border-radius: 8px;
9
+ padding: 4px;
10
+ border: 1px solid #e6e7eb;
11
+ width: 100%;
12
+ height: 36px;
13
+ }
14
+
15
+ .ant-segmented-group {
16
+ display: flex;
17
+ width: 100%;
18
+ }
19
+
20
+ .ant-segmented-item {
21
+ flex: 1;
22
+ text-align: center;
23
+ border: none;
24
+ background: transparent;
25
+ margin: 0;
26
+ padding: 8px 16px;
27
+ border-radius: 6px;
28
+ transition: all 0.3s ease;
29
+ font-size: 14px;
30
+ font-weight: 500;
31
+ color: #6b7280;
32
+ position: relative;
33
+
34
+ &:hover:not(.ant-segmented-item-disabled) {
35
+ color: #6b7280;
36
+ background: rgba(255, 255, 255, 0.5);
37
+ }
38
+
39
+ &.ant-segmented-item-selected {
40
+ background: #ffffff;
41
+ color: #374151;
42
+ font-weight: 600;
43
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
44
+ }
45
+
46
+ &.ant-segmented-item-disabled {
47
+ color: #d1d5db;
48
+ cursor: not-allowed;
49
+ opacity: 0.5;
50
+
51
+ &:hover {
52
+ background: transparent;
53
+ color: #d1d5db;
54
+ }
55
+ }
56
+ }
57
+
58
+ // Custom option content styling
59
+ .progress-tabs__option-content {
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ gap: 6px;
64
+ }
65
+
66
+ .progress-tabs__icon {
67
+ display: flex;
68
+ align-items: center;
69
+ font-size: 14px;
70
+ }
71
+
72
+ .progress-tabs__label {
73
+ display: flex;
74
+ align-items: center;
75
+ }
76
+
77
+ .ant-segmented-thumb {
78
+ display: none;
79
+ }
80
+ }
81
+
82
+ // Responsive design
83
+ @media (max-width: 768px) {
84
+ &__segmented {
85
+ .ant-segmented-item {
86
+ font-size: 12px;
87
+ padding: 6px 12px;
88
+ }
89
+ }
90
+ }
91
+
92
+ @media (max-width: 480px) {
93
+ &__segmented {
94
+ .ant-segmented-item {
95
+ font-size: 11px;
96
+ padding: 4px 8px;
97
+ }
98
+ }
99
+ }
100
+ }