@visns-studio/visns-components 5.15.1 → 5.15.2

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
@@ -90,7 +90,7 @@
90
90
  "react-dom": "^17.0.0 || ^18.0.0"
91
91
  },
92
92
  "name": "@visns-studio/visns-components",
93
- "version": "5.15.1",
93
+ "version": "5.15.2",
94
94
  "description": "Various packages to assist in the development of our Custom Applications.",
95
95
  "main": "src/index.js",
96
96
  "files": [
@@ -592,14 +592,9 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
592
592
  console.log('Saved template ID not found in available templates:', data.proposal_template_id);
593
593
  }
594
594
  } else {
595
- // Set default template if no saved template and available
596
- const defaultTemplate = templates.find(
597
- t => t.label?.includes('Standard') || t.label?.includes('Default')
598
- );
599
- if (defaultTemplate) {
600
- console.log('Setting default template:', defaultTemplate);
601
- setSelectedTemplate(defaultTemplate.id);
602
- }
595
+ // Leave template unselected if no saved template
596
+ console.log('No saved template found, leaving unselected');
597
+ setSelectedTemplate(null);
603
598
  }
604
599
 
605
600
  console.log('Templates successfully loaded:', templates.length, 'templates');
@@ -833,13 +828,22 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
833
828
  };
834
829
 
835
830
  const generateProposalPDF = async () => {
831
+ console.log('generateProposalPDF - Starting', {
832
+ selectedTemplate,
833
+ hasSelectedTemplate: !!selectedTemplate,
834
+ dataId: data.id,
835
+ proposalTemplateId: data.proposal_template_id,
836
+ });
837
+
836
838
  if (!selectedTemplate) {
839
+ console.error('generateProposalPDF - No template selected');
837
840
  toast.error('Please select a template first');
838
841
  return;
839
842
  }
840
843
 
841
844
  setIsGeneratingProposal(true);
842
845
  const toastId = toast.loading('Generating proposal PDF...');
846
+ console.log('generateProposalPDF - Toast created', { toastId });
843
847
 
844
848
  try {
845
849
  const proposalData = {
@@ -889,45 +893,79 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
889
893
  orientation: 'portrait'
890
894
  };
891
895
 
892
- // Create a form for file download
893
- const form = document.createElement('form');
894
- form.method = 'POST';
895
- form.action = `/ajax/quotes/${data.id}/generate-proposal`;
896
- form.style.display = 'none';
896
+ console.log('generateProposalPDF - Proposal data prepared', {
897
+ proposalDataKeys: Object.keys(proposalData.proposal_data),
898
+ templateId: proposalData.template_id,
899
+ filename: proposalData.filename,
900
+ dataLength: JSON.stringify(proposalData.proposal_data).length,
901
+ });
897
902
 
898
- // Add CSRF token
903
+ // Use fetch + file-saver for clean PDF download
899
904
  const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
900
- if (csrfToken) {
901
- const csrfInput = document.createElement('input');
902
- csrfInput.type = 'hidden';
903
- csrfInput.name = '_token';
904
- csrfInput.value = csrfToken;
905
- form.appendChild(csrfInput);
905
+ console.log('generateProposalPDF - CSRF token', {
906
+ hasToken: !!csrfToken,
907
+ tokenLength: csrfToken?.length || 0
908
+ });
909
+
910
+ if (!csrfToken) {
911
+ console.error('generateProposalPDF - No CSRF token found!');
912
+ throw new Error('CSRF token not found');
906
913
  }
907
914
 
908
- // Add proposal data as hidden input
909
- const dataInput = document.createElement('input');
910
- dataInput.type = 'hidden';
911
- dataInput.name = 'proposal_data';
912
- dataInput.value = JSON.stringify(proposalData.proposal_data);
913
- form.appendChild(dataInput);
914
-
915
- const templateInput = document.createElement('input');
916
- templateInput.type = 'hidden';
917
- templateInput.name = 'template_id';
918
- templateInput.value = selectedTemplate;
919
- form.appendChild(templateInput);
920
-
921
- const filenameInput = document.createElement('input');
922
- filenameInput.type = 'hidden';
923
- filenameInput.name = 'filename';
924
- filenameInput.value = proposalData.filename;
925
- form.appendChild(filenameInput);
926
-
927
- // Submit form to trigger download
928
- document.body.appendChild(form);
929
- form.submit();
930
- document.body.removeChild(form);
915
+ console.log('generateProposalPDF - Making fetch request with FormData...');
916
+
917
+ // Create FormData for the request
918
+ const formData = new FormData();
919
+ formData.append('_token', csrfToken);
920
+ formData.append('proposal_data', JSON.stringify(proposalData.proposal_data));
921
+ formData.append('template_id', selectedTemplate);
922
+ formData.append('filename', proposalData.filename);
923
+ formData.append('download', 'false'); // Use stream instead of download for AJAX
924
+
925
+ console.log('generateProposalPDF - FormData prepared');
926
+
927
+ const response = await fetch(`/ajax/quotes/${data.id}/generate-proposal`, {
928
+ method: 'POST',
929
+ headers: {
930
+ 'X-Requested-With': 'XMLHttpRequest',
931
+ // Don't set Content-Type for FormData - browser sets it automatically
932
+ },
933
+ body: formData,
934
+ });
935
+
936
+ console.log('generateProposalPDF - Fetch response received', {
937
+ status: response.status,
938
+ statusText: response.statusText,
939
+ contentType: response.headers.get('content-type'),
940
+ ok: response.ok,
941
+ });
942
+
943
+ if (!response.ok) {
944
+ let errorText = 'Unknown error';
945
+ try {
946
+ errorText = await response.text();
947
+ } catch (e) {
948
+ console.error('Failed to read error response', e);
949
+ }
950
+ console.error('generateProposalPDF - Server error response', {
951
+ status: response.status,
952
+ statusText: response.statusText,
953
+ errorText,
954
+ });
955
+ throw new Error(`Server error: ${response.status} - ${errorText}`);
956
+ }
957
+
958
+ console.log('generateProposalPDF - Converting response to blob...');
959
+ const blob = await response.blob();
960
+
961
+ console.log('generateProposalPDF - Blob created', {
962
+ size: blob.size,
963
+ type: blob.type,
964
+ });
965
+
966
+ // Use file-saver to download the PDF
967
+ saveAs(blob, proposalData.filename);
968
+ console.log('generateProposalPDF - File saved using saveAs');
931
969
 
932
970
  toast.update(toastId, {
933
971
  render: 'Proposal PDF download started',
@@ -937,7 +975,13 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
937
975
  closeButton: true,
938
976
  });
939
977
  } catch (error) {
940
- console.error('Error generating proposal PDF:', error);
978
+ console.error('generateProposalPDF - Exception caught', {
979
+ error: error,
980
+ errorMessage: error.message,
981
+ errorStack: error.stack,
982
+ selectedTemplate,
983
+ dataId: data.id,
984
+ });
941
985
  toast.update(toastId, {
942
986
  render: 'Failed to generate proposal PDF: ' + error.message,
943
987
  type: 'error',
@@ -946,6 +990,7 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
946
990
  closeButton: true,
947
991
  });
948
992
  } finally {
993
+ console.log('generateProposalPDF - Finally block, setting isGeneratingProposal to false');
949
994
  setIsGeneratingProposal(false);
950
995
  }
951
996
  };