datastake-daf 0.6.254 → 0.6.255
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.css +1 -1
- package/dist/components/index.js +340 -29
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Steps/Steps.stories.js +5 -0
- package/src/@daf/core/components/Dashboard/Steps/index.jsx +29 -8
- package/src/@daf/core/components/EditForm/storyConfig.js +1 -1
- package/src/@daf/core/components/EditForm/storyConfig1.js +249 -244
- package/src/@daf/core/components/PdfForm/index.js +311 -21
- package/src/@daf/core/components/PdfForm/style.scss +50 -6
- package/.env +0 -8
- package/.vscode/settings.json +0 -13
|
@@ -525,8 +525,293 @@ const PdfForm = ({
|
|
|
525
525
|
|
|
526
526
|
const organizedForm = useMemo(() => organizeFormByHeaders(form), [form]);
|
|
527
527
|
|
|
528
|
+
// Constants for height calculations (same as PdfView)
|
|
529
|
+
const PAGE_HEIGHT = 1587;
|
|
530
|
+
const FOOTER_HEIGHT = 70;
|
|
531
|
+
const HEADER_HEIGHT = 100;
|
|
532
|
+
|
|
533
|
+
// Detect if running in headless/Puppeteer environment (more conservative detection)
|
|
534
|
+
const isPuppeteerEnvironment = () => {
|
|
535
|
+
if (typeof window === 'undefined') return false;
|
|
536
|
+
|
|
537
|
+
// Only trigger on explicit URL parameters (most reliable)
|
|
538
|
+
return (
|
|
539
|
+
window.location.search.includes('puppeteer=true') ||
|
|
540
|
+
window.location.search.includes('headless=true') ||
|
|
541
|
+
window.location.search.includes('pdf=true') ||
|
|
542
|
+
// Only very specific headless browser indicators
|
|
543
|
+
(window.navigator.webdriver === true && window.navigator.userAgent.includes('HeadlessChrome'))
|
|
544
|
+
);
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// Debug function to log detection results (can be removed later)
|
|
548
|
+
const debugEnvironment = () => {
|
|
549
|
+
if (typeof window !== 'undefined' && window.console) {
|
|
550
|
+
console.log('Environment Detection:', {
|
|
551
|
+
isPuppeteer: isPuppeteerEnvironment(),
|
|
552
|
+
userAgent: window.navigator.userAgent,
|
|
553
|
+
webdriver: window.navigator.webdriver,
|
|
554
|
+
resizeObserver: !!window.ResizeObserver,
|
|
555
|
+
urlParams: window.location.search
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
// Conservative height estimation for Puppeteer compatibility
|
|
561
|
+
const estimateTreeNodeHeight = (key, config, value, level = 0) => {
|
|
562
|
+
const isPuppeteer = isPuppeteerEnvironment();
|
|
563
|
+
// Call debug only once to avoid spam
|
|
564
|
+
if (level === 0 && key === Object.keys(form)[0]) {
|
|
565
|
+
debugEnvironment();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Appropriate base heights for each environment
|
|
569
|
+
const baseHeight = isPuppeteer ? 35 : 25; // Less aggressive for normal browsers
|
|
570
|
+
const indentHeight = level * (isPuppeteer ? 3 : 2); // Normal indent for browsers
|
|
571
|
+
let totalHeight = baseHeight + indentHeight;
|
|
572
|
+
|
|
573
|
+
// Type-based adjustments - less aggressive for normal browsers
|
|
574
|
+
if (config?.type === 'header') {
|
|
575
|
+
totalHeight += isPuppeteer ? 25 : 12;
|
|
576
|
+
} else if (config?.type === 'textarea') {
|
|
577
|
+
totalHeight += isPuppeteer ? 60 : 30;
|
|
578
|
+
} else if (config?.type === 'dataLink' || config?.type === 'dataLinkGroup') {
|
|
579
|
+
totalHeight += isPuppeteer ? 35 : 15;
|
|
580
|
+
} else if (config?.type === 'groupInputs') {
|
|
581
|
+
totalHeight += isPuppeteer ? 40 : 20;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Content height estimation - appropriate for each environment
|
|
585
|
+
if (value && typeof value === 'string') {
|
|
586
|
+
if (value.length > 100) {
|
|
587
|
+
const multiplier = isPuppeteer ? 20 : 12; // Less aggressive for browsers
|
|
588
|
+
totalHeight += Math.ceil(value.length / 50) * multiplier;
|
|
589
|
+
} else if (value.length > 30) {
|
|
590
|
+
totalHeight += isPuppeteer ? 25 : 10; // Much less for normal browsers
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Add height for children recursively with appropriate multiplier
|
|
595
|
+
if (config?.inputs) {
|
|
596
|
+
const childKeys = Object.keys(config.inputs)
|
|
597
|
+
.filter(childKey => {
|
|
598
|
+
const childConfig = config.inputs[childKey];
|
|
599
|
+
// Check showIf condition
|
|
600
|
+
if (childConfig?.showIf && !evaluateShowIfCondition(childConfig.showIf, data)) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
return true;
|
|
604
|
+
})
|
|
605
|
+
.sort((a, b) => {
|
|
606
|
+
const positionA = config.inputs[a]?.position || 0;
|
|
607
|
+
const positionB = config.inputs[b]?.position || 0;
|
|
608
|
+
return positionA - positionB;
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
let childrenHeight = 0;
|
|
612
|
+
childKeys.forEach(childKey => {
|
|
613
|
+
const childConfig = config.inputs[childKey];
|
|
614
|
+
const childValue = value?.[childKey] || data?.[childKey];
|
|
615
|
+
childrenHeight += estimateTreeNodeHeight(childKey, childConfig, childValue, level + 1);
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// Only add safety multiplier for Puppeteer
|
|
619
|
+
totalHeight += childrenHeight * (isPuppeteer ? 1.3 : 1.0);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Handle array/repeated content
|
|
623
|
+
if (Array.isArray(value)) {
|
|
624
|
+
value.forEach(itemValue => {
|
|
625
|
+
const multiplier = isPuppeteer ? 1.1 : 1.0; // No buffer for normal browsers
|
|
626
|
+
totalHeight += estimateTreeNodeHeight(key, config, itemValue, level) * multiplier;
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
return Math.ceil(totalHeight);
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// Helper function to split section based on height constraints (goes deep if needed)
|
|
634
|
+
const createHeightConstrainedSections = (sectionKey, section) => {
|
|
635
|
+
const isPuppeteer = isPuppeteerEnvironment();
|
|
636
|
+
|
|
637
|
+
// Environment-appropriate height limits
|
|
638
|
+
const BASE_BUFFER = isPuppeteer ? 300 : 100; // Much smaller buffer for normal browsers
|
|
639
|
+
const MAX_SECTION_HEIGHT = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT - BASE_BUFFER;
|
|
640
|
+
const subSections = [];
|
|
641
|
+
|
|
642
|
+
// Get all top-level items in the section with detailed analysis
|
|
643
|
+
const topLevelItems = Object.keys(section)
|
|
644
|
+
.filter(key => !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle'))
|
|
645
|
+
.map(key => ({
|
|
646
|
+
key,
|
|
647
|
+
config: section[key],
|
|
648
|
+
estimatedHeight: estimateTreeNodeHeight(key, section[key], data?.[key]),
|
|
649
|
+
canSplit: section[key]?.inputs && Object.keys(section[key].inputs).length > 1 // Can this item be further split?
|
|
650
|
+
}))
|
|
651
|
+
.sort((a, b) => (a.config?.position || 0) - (b.config?.position || 0));
|
|
652
|
+
|
|
653
|
+
let currentSubSection = {
|
|
654
|
+
...section,
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
// Remove all items from the base section structure
|
|
658
|
+
Object.keys(section).forEach(key => {
|
|
659
|
+
if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
|
|
660
|
+
delete currentSubSection[key];
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
let currentHeight = 80; // Base height for section header
|
|
665
|
+
let subSectionIndex = 0;
|
|
666
|
+
|
|
667
|
+
topLevelItems.forEach((item, index) => {
|
|
668
|
+
const { key, config, estimatedHeight, canSplit } = item;
|
|
669
|
+
|
|
670
|
+
// Environment-appropriate splitting thresholds
|
|
671
|
+
const SPLIT_THRESHOLD = isPuppeteer ? 0.6 : 0.85; // Less aggressive for browsers
|
|
672
|
+
const CHILD_MAX_HEIGHT = isPuppeteer ? 0.4 : 0.7;
|
|
673
|
+
|
|
674
|
+
// If a single item is too large and can be split, split it at the child level
|
|
675
|
+
if (estimatedHeight > MAX_SECTION_HEIGHT * SPLIT_THRESHOLD && canSplit) {
|
|
676
|
+
// Split this large item into smaller parts
|
|
677
|
+
const childSplits = splitLargeItem(key, config, data?.[key], MAX_SECTION_HEIGHT * CHILD_MAX_HEIGHT);
|
|
678
|
+
|
|
679
|
+
childSplits.forEach((splitItem, splitIndex) => {
|
|
680
|
+
// Check if current subsection has room
|
|
681
|
+
if (currentHeight + splitItem.estimatedHeight > MAX_SECTION_HEIGHT && Object.keys(currentSubSection).length > 4) {
|
|
682
|
+
// Save current sub-section
|
|
683
|
+
subSections.push({
|
|
684
|
+
key: `${sectionKey}_part_${subSectionIndex}`,
|
|
685
|
+
section: { ...currentSubSection },
|
|
686
|
+
title: section.label
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// Start new sub-section
|
|
690
|
+
currentSubSection = {
|
|
691
|
+
id: section.id,
|
|
692
|
+
label: section.label,
|
|
693
|
+
position: section.position + subSectionIndex + 1,
|
|
694
|
+
subTitle: section.subTitle
|
|
695
|
+
};
|
|
696
|
+
currentHeight = 80;
|
|
697
|
+
subSectionIndex++;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Add split item to current sub-section
|
|
701
|
+
currentSubSection[splitItem.key] = splitItem.config;
|
|
702
|
+
currentHeight += splitItem.estimatedHeight;
|
|
703
|
+
});
|
|
704
|
+
} else {
|
|
705
|
+
// Regular processing for items that fit or can't be split
|
|
706
|
+
// Check if adding this item would exceed height limit
|
|
707
|
+
if (currentHeight + estimatedHeight > MAX_SECTION_HEIGHT && Object.keys(currentSubSection).length > 4) {
|
|
708
|
+
// Save current sub-section
|
|
709
|
+
subSections.push({
|
|
710
|
+
key: `${sectionKey}_part_${subSectionIndex}`,
|
|
711
|
+
section: { ...currentSubSection },
|
|
712
|
+
title: section.label
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
// Start new sub-section
|
|
716
|
+
currentSubSection = {
|
|
717
|
+
id: section.id,
|
|
718
|
+
label: section.label,
|
|
719
|
+
position: section.position + subSectionIndex + 1,
|
|
720
|
+
subTitle: section.subTitle
|
|
721
|
+
};
|
|
722
|
+
currentHeight = 80;
|
|
723
|
+
subSectionIndex++;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Add item to current sub-section
|
|
727
|
+
currentSubSection[key] = config;
|
|
728
|
+
currentHeight += estimatedHeight;
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
// Add the final sub-section if it has content
|
|
733
|
+
if (Object.keys(currentSubSection).length > 4) {
|
|
734
|
+
subSections.push({
|
|
735
|
+
key: subSectionIndex === 0 ? sectionKey : `${sectionKey}_part_${subSectionIndex}`,
|
|
736
|
+
section: currentSubSection,
|
|
737
|
+
title: section.label
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return subSections.length > 0 ? subSections : [{
|
|
742
|
+
key: sectionKey,
|
|
743
|
+
section: section,
|
|
744
|
+
title: section.label
|
|
745
|
+
}];
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// Helper function to split large items at the child level
|
|
749
|
+
const splitLargeItem = (parentKey, parentConfig, parentValue, maxHeight) => {
|
|
750
|
+
if (!parentConfig?.inputs) {
|
|
751
|
+
return [{ key: parentKey, config: parentConfig, estimatedHeight: estimateTreeNodeHeight(parentKey, parentConfig, parentValue) }];
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
const childItems = Object.keys(parentConfig.inputs)
|
|
755
|
+
.filter(childKey => {
|
|
756
|
+
const childConfig = parentConfig.inputs[childKey];
|
|
757
|
+
return !childConfig?.showIf || evaluateShowIfCondition(childConfig.showIf, data);
|
|
758
|
+
})
|
|
759
|
+
.map(childKey => ({
|
|
760
|
+
key: childKey,
|
|
761
|
+
config: parentConfig.inputs[childKey],
|
|
762
|
+
estimatedHeight: estimateTreeNodeHeight(childKey, parentConfig.inputs[childKey], parentValue?.[childKey])
|
|
763
|
+
}))
|
|
764
|
+
.sort((a, b) => (a.config?.position || 0) - (b.config?.position || 0));
|
|
765
|
+
|
|
766
|
+
const splits = [];
|
|
767
|
+
let currentSplit = {
|
|
768
|
+
key: `${parentKey}_part_0`,
|
|
769
|
+
config: {
|
|
770
|
+
...parentConfig,
|
|
771
|
+
inputs: {}
|
|
772
|
+
},
|
|
773
|
+
estimatedHeight: 40 // Base height for parent structure
|
|
774
|
+
};
|
|
775
|
+
let splitIndex = 0;
|
|
776
|
+
|
|
777
|
+
childItems.forEach(child => {
|
|
778
|
+
if (currentSplit.estimatedHeight + child.estimatedHeight > maxHeight && Object.keys(currentSplit.config.inputs).length > 0) {
|
|
779
|
+
splits.push(currentSplit);
|
|
780
|
+
splitIndex++;
|
|
781
|
+
currentSplit = {
|
|
782
|
+
key: `${parentKey}_part_${splitIndex}`,
|
|
783
|
+
config: {
|
|
784
|
+
...parentConfig,
|
|
785
|
+
label: parentConfig.label,
|
|
786
|
+
inputs: {}
|
|
787
|
+
},
|
|
788
|
+
estimatedHeight: 40
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
currentSplit.config.inputs[child.key] = child.config;
|
|
793
|
+
currentSplit.estimatedHeight += child.estimatedHeight;
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
if (Object.keys(currentSplit.config.inputs).length > 0) {
|
|
797
|
+
splits.push(currentSplit);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
return splits.length > 0 ? splits : [{ key: parentKey, config: parentConfig, estimatedHeight: estimateTreeNodeHeight(parentKey, parentConfig, parentValue) }];
|
|
801
|
+
};
|
|
802
|
+
|
|
528
803
|
const pdfConfig = useMemo(() => {
|
|
529
804
|
const sections = [];
|
|
805
|
+
const isPuppeteer = isPuppeteerEnvironment();
|
|
806
|
+
|
|
807
|
+
// Apply Puppeteer-specific class to document body if needed
|
|
808
|
+
if (typeof document !== 'undefined') {
|
|
809
|
+
if (isPuppeteer) {
|
|
810
|
+
document.body.setAttribute('data-puppeteer', 'true');
|
|
811
|
+
} else {
|
|
812
|
+
document.body.removeAttribute('data-puppeteer');
|
|
813
|
+
}
|
|
814
|
+
}
|
|
530
815
|
|
|
531
816
|
Object.keys(organizedForm).forEach((sectionKey) => {
|
|
532
817
|
const section = organizedForm[sectionKey];
|
|
@@ -535,27 +820,32 @@ const PdfForm = ({
|
|
|
535
820
|
return;
|
|
536
821
|
}
|
|
537
822
|
|
|
538
|
-
sections
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
823
|
+
// Create height-constrained sub-sections
|
|
824
|
+
const subSections = createHeightConstrainedSections(sectionKey, section);
|
|
825
|
+
|
|
826
|
+
subSections.forEach(({ key, section: subSection, title }) => {
|
|
827
|
+
sections.push({
|
|
828
|
+
render: () => (
|
|
829
|
+
<div key={key} className={`pdf-form-section ${isPuppeteer ? 'puppeteer-mode' : ''}`}>
|
|
830
|
+
<PdfFormContent
|
|
831
|
+
form={{ [key]: { ...subSection, label: title } }}
|
|
832
|
+
data={data}
|
|
833
|
+
t={t}
|
|
834
|
+
user={user}
|
|
835
|
+
title={formName}
|
|
836
|
+
source={source}
|
|
837
|
+
version={version}
|
|
838
|
+
getApiBaseUrl={getApiBaseUrl}
|
|
839
|
+
getAppHeader={getAppHeader}
|
|
840
|
+
app={app}
|
|
841
|
+
/>
|
|
842
|
+
</div>
|
|
843
|
+
),
|
|
844
|
+
style: {
|
|
845
|
+
marginBottom: '20px',
|
|
846
|
+
padding: '0 20px'
|
|
847
|
+
}
|
|
848
|
+
});
|
|
559
849
|
});
|
|
560
850
|
});
|
|
561
851
|
|
|
@@ -482,12 +482,13 @@
|
|
|
482
482
|
|
|
483
483
|
@media print {
|
|
484
484
|
.pdf-form-section {
|
|
485
|
-
|
|
486
|
-
margin-bottom:
|
|
485
|
+
page-break-inside: avoid;
|
|
486
|
+
margin-bottom: 30px;
|
|
487
|
+
padding-bottom: 20px; // Extra space before potential breaks
|
|
487
488
|
}
|
|
488
489
|
|
|
489
490
|
.pdf-tree .tree-node {
|
|
490
|
-
|
|
491
|
+
page-break-inside: avoid;
|
|
491
492
|
|
|
492
493
|
&::after,
|
|
493
494
|
.tree-indent .indent-line::before,
|
|
@@ -497,9 +498,52 @@
|
|
|
497
498
|
-webkit-print-color-adjust: exact;
|
|
498
499
|
}
|
|
499
500
|
|
|
500
|
-
//
|
|
501
|
-
|
|
502
|
-
|
|
501
|
+
// Force page breaks for deeply nested content in print
|
|
502
|
+
&.level-0,
|
|
503
|
+
&.level-1 {
|
|
504
|
+
&.parent {
|
|
505
|
+
page-break-after: avoid;
|
|
506
|
+
margin-bottom: 15px;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// More conservative spacing for print
|
|
511
|
+
.tree-node-content {
|
|
512
|
+
padding: 6px 0; // Slightly more padding
|
|
513
|
+
|
|
514
|
+
.tree-node-title {
|
|
515
|
+
min-height: 28px; // Ensure minimum height
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Only add extra spacing when explicitly running in headless/PDF mode
|
|
522
|
+
&.puppeteer-mode,
|
|
523
|
+
body[data-puppeteer="true"] & {
|
|
524
|
+
.pdf-form-section {
|
|
525
|
+
margin-bottom: 40px;
|
|
526
|
+
padding: 10px 0;
|
|
527
|
+
|
|
528
|
+
&:last-child {
|
|
529
|
+
margin-bottom: 60px;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.pdf-tree .tree-node {
|
|
534
|
+
margin-bottom: 12px;
|
|
535
|
+
|
|
536
|
+
.tree-node-content {
|
|
537
|
+
padding: 8px 0;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
&.level-0 {
|
|
541
|
+
margin-bottom: 25px;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
&.level-1 {
|
|
545
|
+
margin-bottom: 18px;
|
|
546
|
+
}
|
|
503
547
|
}
|
|
504
548
|
}
|
|
505
549
|
}
|
package/.env
DELETED
package/.vscode/settings.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"cSpell.words": ["cukura"],
|
|
3
|
-
"files.autoSave": "afterDelay",
|
|
4
|
-
"editor.wordWrap": "on",
|
|
5
|
-
"editor.autoClosingBrackets": "always",
|
|
6
|
-
"editor.autoClosingComments": "always",
|
|
7
|
-
"editor.autoClosingQuotes": "always",
|
|
8
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
9
|
-
"editor.formatOnPaste": true,
|
|
10
|
-
"editor.formatOnSave": true,
|
|
11
|
-
"notebook.defaultFormatter": "esbenp.prettier-vscode",
|
|
12
|
-
"javascript.format.semicolons": "insert"
|
|
13
|
-
}
|