datastake-daf 0.6.302 → 0.6.304
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.
|
@@ -525,404 +525,8 @@ 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
|
-
// Balanced height estimation that prevents over-splitting while ensuring content fits
|
|
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
|
-
// More accurate base heights that align better with PdfView's ResizeObserver measurements
|
|
569
|
-
const baseHeight = isPuppeteer ? 48 : 38; // More accurate base heights to match actual rendering
|
|
570
|
-
const indentHeight = level * (isPuppeteer ? 4 : 3.5); // More accurate indent space
|
|
571
|
-
let totalHeight = baseHeight + indentHeight;
|
|
572
|
-
|
|
573
|
-
// Reasonable type-based adjustments based on actual rendered heights
|
|
574
|
-
if (config?.type === 'header') {
|
|
575
|
-
totalHeight += isPuppeteer ? 25 : 18; // Headers with reasonable padding
|
|
576
|
-
} else if (config?.type === 'textarea') {
|
|
577
|
-
totalHeight += isPuppeteer ? 60 : 45; // Textareas with multiline content
|
|
578
|
-
} else if (config?.type === 'dataLink' || config?.type === 'dataLinkGroup') {
|
|
579
|
-
totalHeight += isPuppeteer ? 35 : 25; // Data links with formatted content
|
|
580
|
-
} else if (config?.type === 'groupInputs') {
|
|
581
|
-
totalHeight += isPuppeteer ? 45 : 35; // Group inputs with structured layout
|
|
582
|
-
} else if (config?.type === 'ajaxSubGroup') {
|
|
583
|
-
totalHeight += isPuppeteer ? 50 : 40; // Ajax content with loading states
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
// More accurate content height estimation that better matches actual DOM measurements
|
|
587
|
-
if (value && typeof value === 'string') {
|
|
588
|
-
const cleanValue = value.trim();
|
|
589
|
-
if (cleanValue.length > 150) {
|
|
590
|
-
// Long text: be more generous with line estimates
|
|
591
|
-
const estimatedLines = Math.ceil(cleanValue.length / 45); // Shorter assumed line length
|
|
592
|
-
const lineHeight = isPuppeteer ? 20 : 18; // Slightly taller line height
|
|
593
|
-
totalHeight += estimatedLines * lineHeight;
|
|
594
|
-
} else if (cleanValue.length > 60) {
|
|
595
|
-
// Medium text: likely spans 2-3 lines
|
|
596
|
-
totalHeight += isPuppeteer ? 35 : 28;
|
|
597
|
-
} else if (cleanValue.length > 15) {
|
|
598
|
-
// Short-medium text: single to double line
|
|
599
|
-
totalHeight += isPuppeteer ? 18 : 14;
|
|
600
|
-
} else if (cleanValue.length > 0) {
|
|
601
|
-
// Very short text: single line with padding
|
|
602
|
-
totalHeight += isPuppeteer ? 12 : 10;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
// Add height for children recursively with balanced multiplier
|
|
607
|
-
if (config?.inputs) {
|
|
608
|
-
const childKeys = Object.keys(config.inputs)
|
|
609
|
-
.filter(childKey => {
|
|
610
|
-
const childConfig = config.inputs[childKey];
|
|
611
|
-
// Check showIf condition
|
|
612
|
-
if (childConfig?.showIf && !evaluateShowIfCondition(childConfig.showIf, data)) {
|
|
613
|
-
return false;
|
|
614
|
-
}
|
|
615
|
-
return true;
|
|
616
|
-
})
|
|
617
|
-
.sort((a, b) => {
|
|
618
|
-
const positionA = config.inputs[a]?.position || 0;
|
|
619
|
-
const positionB = config.inputs[b]?.position || 0;
|
|
620
|
-
return positionA - positionB;
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
let childrenHeight = 0;
|
|
624
|
-
childKeys.forEach(childKey => {
|
|
625
|
-
const childConfig = config.inputs[childKey];
|
|
626
|
-
const childValue = value?.[childKey] || data?.[childKey];
|
|
627
|
-
childrenHeight += estimateTreeNodeHeight(childKey, childConfig, childValue, level + 1);
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
// More accurate multiplier that accounts for spacing and margins in actual DOM
|
|
631
|
-
totalHeight += childrenHeight * (isPuppeteer ? 1.25 : 1.15);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
// Handle array/repeated content with accurate estimates
|
|
635
|
-
if (Array.isArray(value) && value.length > 0) {
|
|
636
|
-
value.forEach(itemValue => {
|
|
637
|
-
const itemHeight = estimateTreeNodeHeight(key, config, itemValue, level);
|
|
638
|
-
totalHeight += itemHeight * (isPuppeteer ? 1.1 : 1.05); // Minimal buffer
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// Minimal buffer for deep nesting
|
|
643
|
-
if (level > 3) {
|
|
644
|
-
totalHeight *= (isPuppeteer ? 1.08 : 1.05);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
return Math.ceil(totalHeight);
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
// Helper function to split section based on height constraints (aligned with PdfView calculations)
|
|
651
|
-
const createHeightConstrainedSections = (sectionKey, section) => {
|
|
652
|
-
const isPuppeteer = isPuppeteerEnvironment();
|
|
653
|
-
|
|
654
|
-
// Align with PdfView but use a more conservative limit to prevent large margin calculations
|
|
655
|
-
// PdfView uses PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT = 1387px
|
|
656
|
-
// We'll use 85% of that to ensure sections fit comfortably and don't trigger large margins
|
|
657
|
-
const PDFVIEW_MAX_HEIGHT = PAGE_HEIGHT - 30 - FOOTER_HEIGHT - HEADER_HEIGHT; // 1387px
|
|
658
|
-
const MAX_SECTION_HEIGHT = Math.floor(PDFVIEW_MAX_HEIGHT * 0.85); // ~1179px - more conservative
|
|
659
|
-
const MIN_SECTION_HEIGHT = 300; // Slightly larger minimum to ensure meaningful content
|
|
660
|
-
const subSections = [];
|
|
661
|
-
|
|
662
|
-
// Get all top-level items in the section with detailed analysis
|
|
663
|
-
const topLevelItems = Object.keys(section)
|
|
664
|
-
.filter(key => !(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle'))
|
|
665
|
-
.map(key => ({
|
|
666
|
-
key,
|
|
667
|
-
config: section[key],
|
|
668
|
-
estimatedHeight: estimateTreeNodeHeight(key, section[key], data?.[key]),
|
|
669
|
-
canSplit: section[key]?.inputs && Object.keys(section[key].inputs).length > 3 // Only split if sufficient children
|
|
670
|
-
}))
|
|
671
|
-
.sort((a, b) => (a.config?.position || 0) - (b.config?.position || 0));
|
|
672
|
-
|
|
673
|
-
// If the entire section fits, don't split it
|
|
674
|
-
const totalSectionHeight = topLevelItems.reduce((sum, item) => sum + item.estimatedHeight, 0);
|
|
675
|
-
|
|
676
|
-
// Add detailed debugging for height calculations
|
|
677
|
-
if (typeof window !== 'undefined' && window.console) {
|
|
678
|
-
console.log(`Section ${sectionKey}:`, {
|
|
679
|
-
totalEstimatedHeight: totalSectionHeight,
|
|
680
|
-
maxAllowedHeight: MAX_SECTION_HEIGHT,
|
|
681
|
-
pdfViewMaxHeight: PDFVIEW_MAX_HEIGHT,
|
|
682
|
-
utilizationPercentage: Math.round((totalSectionHeight / MAX_SECTION_HEIGHT) * 100) + '%',
|
|
683
|
-
shouldSplit: totalSectionHeight > MAX_SECTION_HEIGHT,
|
|
684
|
-
itemCount: topLevelItems.length,
|
|
685
|
-
itemSummary: topLevelItems.map(item => ({
|
|
686
|
-
key: item.key,
|
|
687
|
-
height: item.estimatedHeight,
|
|
688
|
-
type: item.config?.type
|
|
689
|
-
}))
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
if (totalSectionHeight <= MAX_SECTION_HEIGHT) {
|
|
694
|
-
return [{
|
|
695
|
-
key: sectionKey,
|
|
696
|
-
section: section,
|
|
697
|
-
title: section.label
|
|
698
|
-
}];
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
let currentSubSection = {
|
|
702
|
-
...section,
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
// Remove all items from the base section structure
|
|
706
|
-
Object.keys(section).forEach(key => {
|
|
707
|
-
if (!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')) {
|
|
708
|
-
delete currentSubSection[key];
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
|
|
712
|
-
let currentHeight = isPuppeteer ? 120 : 100; // More accurate base height including section headers and margins
|
|
713
|
-
let subSectionIndex = 0;
|
|
714
|
-
|
|
715
|
-
topLevelItems.forEach((item, index) => {
|
|
716
|
-
const { key, config, estimatedHeight, canSplit } = item;
|
|
717
|
-
|
|
718
|
-
// More conservative splitting thresholds to work better with PdfView
|
|
719
|
-
const SPLIT_THRESHOLD = 0.65; // Split if item takes up more than 65% of available space
|
|
720
|
-
|
|
721
|
-
// If a single item is large and can be split, consider splitting it
|
|
722
|
-
if (estimatedHeight > MAX_SECTION_HEIGHT * SPLIT_THRESHOLD && canSplit && estimatedHeight > MIN_SECTION_HEIGHT * 1.5) {
|
|
723
|
-
// Split this large item into smaller parts
|
|
724
|
-
const childSplits = splitLargeItem(key, config, data?.[key], MAX_SECTION_HEIGHT * 0.6);
|
|
725
|
-
|
|
726
|
-
childSplits.forEach((splitItem, splitIndex) => {
|
|
727
|
-
// Check if current subsection has room - be more lenient about splitting
|
|
728
|
-
if (currentHeight + splitItem.estimatedHeight > MAX_SECTION_HEIGHT &&
|
|
729
|
-
currentHeight > MIN_SECTION_HEIGHT &&
|
|
730
|
-
Object.keys(currentSubSection).length > 4) {
|
|
731
|
-
|
|
732
|
-
// Save current sub-section if it has meaningful content
|
|
733
|
-
subSections.push({
|
|
734
|
-
key: `${sectionKey}_part_${subSectionIndex}`,
|
|
735
|
-
section: { ...currentSubSection },
|
|
736
|
-
title: section.label
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
// Start new sub-section
|
|
740
|
-
currentSubSection = {
|
|
741
|
-
id: section.id,
|
|
742
|
-
label: section.label,
|
|
743
|
-
position: section.position + subSectionIndex + 1,
|
|
744
|
-
subTitle: section.subTitle
|
|
745
|
-
};
|
|
746
|
-
currentHeight = isPuppeteer ? 120 : 100;
|
|
747
|
-
subSectionIndex++;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// Add split item to current sub-section
|
|
751
|
-
currentSubSection[splitItem.key] = splitItem.config;
|
|
752
|
-
currentHeight += splitItem.estimatedHeight;
|
|
753
|
-
});
|
|
754
|
-
} else {
|
|
755
|
-
// Regular processing for items that fit or shouldn't be split
|
|
756
|
-
// More lenient threshold - only split if really necessary and ensures meaningful sections
|
|
757
|
-
const remainingItems = topLevelItems.length - index - 1;
|
|
758
|
-
const shouldSplitSection = (currentHeight + estimatedHeight > MAX_SECTION_HEIGHT) &&
|
|
759
|
-
(currentHeight > MIN_SECTION_HEIGHT * 0.8) && // More lenient minimum
|
|
760
|
-
(Object.keys(currentSubSection).length > 3) && // Fewer items required
|
|
761
|
-
(remainingItems > 0); // Ensure there are items left for next section
|
|
762
|
-
|
|
763
|
-
if (shouldSplitSection) {
|
|
764
|
-
|
|
765
|
-
// Save current sub-section
|
|
766
|
-
subSections.push({
|
|
767
|
-
key: `${sectionKey}_part_${subSectionIndex}`,
|
|
768
|
-
section: { ...currentSubSection },
|
|
769
|
-
title: section.label
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
// Start new sub-section
|
|
773
|
-
currentSubSection = {
|
|
774
|
-
id: section.id,
|
|
775
|
-
label: section.label,
|
|
776
|
-
position: section.position + subSectionIndex + 1,
|
|
777
|
-
subTitle: section.subTitle
|
|
778
|
-
};
|
|
779
|
-
currentHeight = isPuppeteer ? 120 : 100;
|
|
780
|
-
subSectionIndex++;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// Add item to current sub-section
|
|
784
|
-
currentSubSection[key] = config;
|
|
785
|
-
currentHeight += estimatedHeight;
|
|
786
|
-
}
|
|
787
|
-
});
|
|
788
|
-
|
|
789
|
-
// Add the final sub-section if it has meaningful content
|
|
790
|
-
const finalSectionKeys = Object.keys(currentSubSection).filter(key =>
|
|
791
|
-
!(key === 'id' || key === 'label' || key === 'position' || key === 'subTitle')
|
|
792
|
-
);
|
|
793
|
-
|
|
794
|
-
if (finalSectionKeys.length > 0) {
|
|
795
|
-
const finalSubSection = {
|
|
796
|
-
key: subSectionIndex === 0 ? sectionKey : `${sectionKey}_part_${subSectionIndex}`,
|
|
797
|
-
section: currentSubSection,
|
|
798
|
-
title: section.label
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
subSections.push(finalSubSection);
|
|
802
|
-
|
|
803
|
-
// Debug final section creation
|
|
804
|
-
if (typeof window !== 'undefined' && window.console) {
|
|
805
|
-
console.log(`Final section ${finalSubSection.key}:`, {
|
|
806
|
-
itemCount: finalSectionKeys.length,
|
|
807
|
-
estimatedHeight: currentHeight,
|
|
808
|
-
utilizationPercentage: Math.round((currentHeight / MAX_SECTION_HEIGHT) * 100) + '%',
|
|
809
|
-
isWithinLimits: currentHeight <= MAX_SECTION_HEIGHT
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
// If we only have one section and it's not too large, return the original
|
|
815
|
-
if (subSections.length === 1 && subSections[0].key === sectionKey) {
|
|
816
|
-
return [{
|
|
817
|
-
key: sectionKey,
|
|
818
|
-
section: section,
|
|
819
|
-
title: section.label
|
|
820
|
-
}];
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
return subSections.length > 0 ? subSections : [{
|
|
824
|
-
key: sectionKey,
|
|
825
|
-
section: section,
|
|
826
|
-
title: section.label
|
|
827
|
-
}];
|
|
828
|
-
};
|
|
829
|
-
|
|
830
|
-
// Helper function to split large items at the child level (more intelligent splitting)
|
|
831
|
-
const splitLargeItem = (parentKey, parentConfig, parentValue, maxHeight) => {
|
|
832
|
-
if (!parentConfig?.inputs) {
|
|
833
|
-
return [{ key: parentKey, config: parentConfig, estimatedHeight: estimateTreeNodeHeight(parentKey, parentConfig, parentValue) }];
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
const childItems = Object.keys(parentConfig.inputs)
|
|
837
|
-
.filter(childKey => {
|
|
838
|
-
const childConfig = parentConfig.inputs[childKey];
|
|
839
|
-
return !childConfig?.showIf || evaluateShowIfCondition(childConfig.showIf, data);
|
|
840
|
-
})
|
|
841
|
-
.map(childKey => ({
|
|
842
|
-
key: childKey,
|
|
843
|
-
config: parentConfig.inputs[childKey],
|
|
844
|
-
estimatedHeight: estimateTreeNodeHeight(childKey, parentConfig.inputs[childKey], parentValue?.[childKey])
|
|
845
|
-
}))
|
|
846
|
-
.sort((a, b) => (a.config?.position || 0) - (b.config?.position || 0));
|
|
847
|
-
|
|
848
|
-
// If total children height is not that large, don't split
|
|
849
|
-
const totalChildrenHeight = childItems.reduce((sum, child) => sum + child.estimatedHeight, 0);
|
|
850
|
-
if (totalChildrenHeight <= maxHeight * 1.1) { // More conservative threshold
|
|
851
|
-
return [{ key: parentKey, config: parentConfig, estimatedHeight: estimateTreeNodeHeight(parentKey, parentConfig, parentValue) }];
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
const splits = [];
|
|
855
|
-
let currentSplit = {
|
|
856
|
-
key: `${parentKey}_part_0`,
|
|
857
|
-
config: {
|
|
858
|
-
...parentConfig,
|
|
859
|
-
inputs: {}
|
|
860
|
-
},
|
|
861
|
-
estimatedHeight: 60 // More accurate base height for parent structure with styling
|
|
862
|
-
};
|
|
863
|
-
let splitIndex = 0;
|
|
864
|
-
const minItemsPerSplit = 2; // Ensure at least 2 items per split to avoid tiny sections
|
|
865
|
-
|
|
866
|
-
childItems.forEach((child, index) => {
|
|
867
|
-
const isLastChild = index === childItems.length - 1;
|
|
868
|
-
const currentSplitItemCount = Object.keys(currentSplit.config.inputs).length;
|
|
869
|
-
|
|
870
|
-
// Only split if:
|
|
871
|
-
// 1. Adding this child would exceed max height
|
|
872
|
-
// 2. Current split has at least minimum items
|
|
873
|
-
// 3. There are enough remaining items to make another meaningful split
|
|
874
|
-
const remainingItems = childItems.length - index;
|
|
875
|
-
const shouldSplit = (currentSplit.estimatedHeight + child.estimatedHeight > maxHeight) &&
|
|
876
|
-
(currentSplitItemCount >= minItemsPerSplit) &&
|
|
877
|
-
(remainingItems > minItemsPerSplit || isLastChild);
|
|
878
|
-
|
|
879
|
-
if (shouldSplit) {
|
|
880
|
-
// Save current split if it has content
|
|
881
|
-
splits.push(currentSplit);
|
|
882
|
-
splitIndex++;
|
|
883
|
-
|
|
884
|
-
// Start new split
|
|
885
|
-
currentSplit = {
|
|
886
|
-
key: `${parentKey}_part_${splitIndex}`,
|
|
887
|
-
config: {
|
|
888
|
-
...parentConfig,
|
|
889
|
-
label: parentConfig.label, // Keep original label without part indicator
|
|
890
|
-
inputs: {}
|
|
891
|
-
},
|
|
892
|
-
estimatedHeight: 60
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
// Add child to current split
|
|
897
|
-
currentSplit.config.inputs[child.key] = child.config;
|
|
898
|
-
currentSplit.estimatedHeight += child.estimatedHeight;
|
|
899
|
-
});
|
|
900
|
-
|
|
901
|
-
// Add the final split if it has content
|
|
902
|
-
if (Object.keys(currentSplit.config.inputs).length > 0) {
|
|
903
|
-
splits.push(currentSplit);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// If we ended up with only one split, return original
|
|
907
|
-
if (splits.length <= 1) {
|
|
908
|
-
return [{ key: parentKey, config: parentConfig, estimatedHeight: estimateTreeNodeHeight(parentKey, parentConfig, parentValue) }];
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
return splits;
|
|
912
|
-
};
|
|
913
|
-
|
|
914
528
|
const pdfConfig = useMemo(() => {
|
|
915
529
|
const sections = [];
|
|
916
|
-
const isPuppeteer = isPuppeteerEnvironment();
|
|
917
|
-
|
|
918
|
-
// Apply Puppeteer-specific class to document body if needed
|
|
919
|
-
if (typeof document !== 'undefined') {
|
|
920
|
-
if (isPuppeteer) {
|
|
921
|
-
document.body.setAttribute('data-puppeteer', 'true');
|
|
922
|
-
} else {
|
|
923
|
-
document.body.removeAttribute('data-puppeteer');
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
530
|
|
|
927
531
|
Object.keys(organizedForm).forEach((sectionKey) => {
|
|
928
532
|
const section = organizedForm[sectionKey];
|
|
@@ -931,32 +535,27 @@ const PdfForm = ({
|
|
|
931
535
|
return;
|
|
932
536
|
}
|
|
933
537
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
style: {
|
|
956
|
-
marginBottom: '20px',
|
|
957
|
-
padding: '0 20px'
|
|
958
|
-
}
|
|
959
|
-
});
|
|
538
|
+
sections.push({
|
|
539
|
+
render: () => (
|
|
540
|
+
<div key={sectionKey} className="pdf-form-section">
|
|
541
|
+
<PdfFormContent
|
|
542
|
+
form={{ [sectionKey]: section }}
|
|
543
|
+
data={data}
|
|
544
|
+
t={t}
|
|
545
|
+
user={user}
|
|
546
|
+
title={formName}
|
|
547
|
+
source={source}
|
|
548
|
+
version={version}
|
|
549
|
+
getApiBaseUrl={getApiBaseUrl}
|
|
550
|
+
getAppHeader={getAppHeader}
|
|
551
|
+
app={app}
|
|
552
|
+
/>
|
|
553
|
+
</div>
|
|
554
|
+
),
|
|
555
|
+
style: {
|
|
556
|
+
marginBottom: '20px',
|
|
557
|
+
padding: '0 20px'
|
|
558
|
+
}
|
|
960
559
|
});
|
|
961
560
|
});
|
|
962
561
|
|
|
@@ -991,4 +590,4 @@ PdfForm.propTypes = {
|
|
|
991
590
|
user: PropTypes.object,
|
|
992
591
|
};
|
|
993
592
|
|
|
994
|
-
export default PdfForm;
|
|
593
|
+
export default PdfForm;
|
|
@@ -59,24 +59,17 @@
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
.pdf-form-section {
|
|
62
|
-
margin-bottom:
|
|
63
|
-
padding-bottom: 10px; // Balanced padding to avoid footers
|
|
62
|
+
margin-bottom: 40px;
|
|
64
63
|
position: relative;
|
|
65
64
|
width: 100%;
|
|
66
|
-
min-height: 50px; // Ensure minimum content height
|
|
67
|
-
|
|
68
|
-
// Prevent completely empty sections
|
|
69
|
-
&:empty {
|
|
70
|
-
display: none;
|
|
71
|
-
}
|
|
72
65
|
|
|
73
66
|
.section-header {
|
|
74
|
-
margin-bottom:
|
|
75
|
-
padding-bottom:
|
|
67
|
+
margin-bottom: 25px;
|
|
68
|
+
padding-bottom: 8px;
|
|
76
69
|
border-bottom: 1px solid #ddd;
|
|
77
70
|
|
|
78
71
|
h2 {
|
|
79
|
-
margin: 0 0
|
|
72
|
+
margin: 0 0 5px 0;
|
|
80
73
|
font-size: 16px;
|
|
81
74
|
font-weight: 700;
|
|
82
75
|
color: #333;
|
|
@@ -105,8 +98,7 @@
|
|
|
105
98
|
|
|
106
99
|
.tree-node {
|
|
107
100
|
position: relative;
|
|
108
|
-
margin-bottom: 8px;
|
|
109
|
-
padding: 1px 0; // Minimal padding
|
|
101
|
+
margin-bottom: 8px;
|
|
110
102
|
|
|
111
103
|
&.parent {
|
|
112
104
|
&::after {
|
|
@@ -489,27 +481,13 @@
|
|
|
489
481
|
}
|
|
490
482
|
|
|
491
483
|
@media print {
|
|
492
|
-
// Spacer to ensure content clears the floating header in print/PDF mode
|
|
493
|
-
.pdf-form-section:first-of-type::before {
|
|
494
|
-
content: "";
|
|
495
|
-
display: block;
|
|
496
|
-
height: 120px;
|
|
497
|
-
margin-bottom: 12px;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
484
|
.pdf-form-section {
|
|
501
|
-
page-break-inside: avoid;
|
|
485
|
+
// page-break-inside: avoid;
|
|
502
486
|
margin-bottom: 20px;
|
|
503
|
-
padding-bottom: 10px; // Reasonable space before potential breaks
|
|
504
|
-
|
|
505
|
-
// Prevent orphaned sections
|
|
506
|
-
&:empty {
|
|
507
|
-
display: none;
|
|
508
|
-
}
|
|
509
487
|
}
|
|
510
488
|
|
|
511
489
|
.pdf-tree .tree-node {
|
|
512
|
-
page-break-inside: avoid;
|
|
490
|
+
// page-break-inside: avoid;
|
|
513
491
|
|
|
514
492
|
&::after,
|
|
515
493
|
.tree-indent .indent-line::before,
|
|
@@ -519,52 +497,9 @@
|
|
|
519
497
|
-webkit-print-color-adjust: exact;
|
|
520
498
|
}
|
|
521
499
|
|
|
522
|
-
//
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
&.parent {
|
|
526
|
-
page-break-after: avoid;
|
|
527
|
-
margin-bottom: 15px;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// More conservative spacing for print
|
|
532
|
-
.tree-node-content {
|
|
533
|
-
padding: 6px 0; // Slightly more padding
|
|
534
|
-
|
|
535
|
-
.tree-node-title {
|
|
536
|
-
min-height: 28px; // Ensure minimum height
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Balanced spacing for headless/PDF mode
|
|
543
|
-
&.puppeteer-mode,
|
|
544
|
-
body[data-puppeteer="true"] & {
|
|
545
|
-
.pdf-form-section {
|
|
546
|
-
margin-bottom: 30px;
|
|
547
|
-
padding: 8px 0;
|
|
548
|
-
|
|
549
|
-
&:last-child {
|
|
550
|
-
margin-bottom: 40px;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
.pdf-tree .tree-node {
|
|
555
|
-
margin-bottom: 10px;
|
|
556
|
-
|
|
557
|
-
.tree-node-content {
|
|
558
|
-
padding: 6px 0;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
&.level-0 {
|
|
562
|
-
margin-bottom: 18px;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
&.level-1 {
|
|
566
|
-
margin-bottom: 12px;
|
|
567
|
-
}
|
|
500
|
+
// &.parent {
|
|
501
|
+
// page-break-after: avoid;
|
|
502
|
+
// }
|
|
568
503
|
}
|
|
569
504
|
}
|
|
570
505
|
}
|
|
@@ -685,4 +620,4 @@
|
|
|
685
620
|
.tree-node-content {
|
|
686
621
|
padding-left: 10px;
|
|
687
622
|
}
|
|
688
|
-
}
|
|
623
|
+
}
|