@visns-studio/visns-components 5.11.8 → 5.11.9

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
@@ -87,7 +87,7 @@
87
87
  "react-dom": "^17.0.0 || ^18.0.0"
88
88
  },
89
89
  "name": "@visns-studio/visns-components",
90
- "version": "5.11.8",
90
+ "version": "5.11.9",
91
91
  "description": "Various packages to assist in the development of our Custom Applications.",
92
92
  "main": "src/index.js",
93
93
  "files": [
@@ -20,6 +20,54 @@ import SortableTableBody from './SortableQuoteItems';
20
20
 
21
21
  import styles from './styles/GenericQuote.module.scss';
22
22
 
23
+ // Isolated Proposal Preview Component
24
+ function ProposalPreviewFrame({ content }) {
25
+ const iframeRef = React.useRef(null);
26
+
27
+ React.useEffect(() => {
28
+ if (iframeRef.current && content) {
29
+ const iframe = iframeRef.current;
30
+ const doc = iframe.contentDocument || iframe.contentWindow.document;
31
+
32
+ // Write the complete HTML document to iframe
33
+ doc.open();
34
+ doc.write(content);
35
+ doc.close();
36
+
37
+ // Optional: Add responsive styling to iframe body
38
+ const style = doc.createElement('style');
39
+ style.textContent = `
40
+ body {
41
+ margin: 0;
42
+ padding: 20px;
43
+ font-family: Arial, sans-serif;
44
+ background: white;
45
+ overflow-x: auto;
46
+ }
47
+ * {
48
+ box-sizing: border-box;
49
+ }
50
+ `;
51
+ doc.head.appendChild(style);
52
+ }
53
+ }, [content]);
54
+
55
+ return (
56
+ <iframe
57
+ ref={iframeRef}
58
+ className={styles.proposalPreview}
59
+ title="Proposal Preview"
60
+ sandbox="allow-same-origin"
61
+ style={{
62
+ width: '100%',
63
+ height: '100%',
64
+ border: 'none',
65
+ background: 'white'
66
+ }}
67
+ />
68
+ );
69
+ }
70
+
23
71
  function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
24
72
  const routeParams = useParams();
25
73
  const navigate = useNavigate();
@@ -835,7 +883,7 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
835
883
  proposal_section_type: data.proposal_section_type || 'content',
836
884
  },
837
885
  template_id: parseInt(selectedTemplate),
838
- filename: `proposal-${data.id || 'draft'}-${new Date().toISOString().split('T')[0]}.pdf`,
886
+ filename: `${(data.customer?.name || 'Customer').replace(/[/\\?%*:|"<>]/g, '-')} - Proposal #${data.id || 'draft'} - ${(data.label || 'Quote').replace(/[/\\?%*:|"<>]/g, '-')}.pdf`,
839
887
  download: true,
840
888
  paper: 'a4',
841
889
  orientation: 'portrait'
@@ -844,7 +892,7 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
844
892
  // Create a form for file download
845
893
  const form = document.createElement('form');
846
894
  form.method = 'POST';
847
- form.action = '/ajax/pdf/generate-proposal';
895
+ form.action = `/ajax/quotes/${data.id}/generate-proposal`;
848
896
  form.style.display = 'none';
849
897
 
850
898
  // Add CSRF token
@@ -1454,10 +1502,7 @@ function GenericQuote({ logo, setting, urlParam, proposalConfig = null }) {
1454
1502
  <X size={16} aria-hidden="true" />
1455
1503
  </button>
1456
1504
  </div>
1457
- <div
1458
- className={styles.proposalPreview}
1459
- dangerouslySetInnerHTML={{ __html: proposalPreview }}
1460
- />
1505
+ <ProposalPreviewFrame content={proposalPreview} />
1461
1506
  </div>
1462
1507
  )}
1463
1508
 
@@ -179,8 +179,10 @@
179
179
  border: 1px solid #e9ecef;
180
180
  border-radius: 8px;
181
181
  background: white;
182
- max-height: 1200px; /* Double the previous height */
183
- overflow: hidden;
182
+ height: auto;
183
+ min-height: 1100px;
184
+ max-height: none; /* Remove height restriction */
185
+ overflow: visible; /* Allow content to be visible */
184
186
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
185
187
  }
186
188
 
@@ -213,225 +215,16 @@
213
215
  }
214
216
 
215
217
  .proposalPreview {
216
- /* Container styles - only affect this container */
217
- padding: 20px;
218
- overflow-y: auto;
219
- overflow-x: hidden;
220
- max-height: 1000px;
218
+ /* Iframe container styles - content is completely isolated */
219
+ width: 100% !important;
220
+ height: 1000px !important;
221
+ min-height: 1000px !important;
222
+ max-height: none !important;
221
223
  background: white;
222
224
  box-sizing: border-box;
223
- position: relative;
224
-
225
- /* Isolate content styles using descendant selectors */
226
-
227
- /* Reset and apply clean typography for proposal content */
228
- & * {
229
- font-family: inherit;
230
- color: inherit;
231
- }
232
-
233
- /* Base content styling */
234
- font-family: 'Times', 'Times New Roman', serif;
235
- font-size: 14px;
236
- line-height: 1.6;
237
- color: #333;
238
-
239
- /* Headings */
240
- & h1, & h2, & h3, & h4, & h5, & h6 {
241
- font-family: 'Arial', 'Helvetica', sans-serif;
242
- font-weight: bold;
243
- color: #333;
244
- margin-top: 0;
245
- margin-bottom: 15px;
246
- line-height: 1.2;
247
- }
248
-
249
- & h1 {
250
- font-size: 28px;
251
- margin-bottom: 20px;
252
- margin-top: 0;
253
- }
254
- & h2 {
255
- font-size: 24px;
256
- margin-top: 30px;
257
- margin-bottom: 15px;
258
- }
259
- & h3 {
260
- font-size: 20px;
261
- margin-top: 25px;
262
- margin-bottom: 12px;
263
- }
264
- & h4 { font-size: 18px; margin-bottom: 12px; }
265
- & h5 { font-size: 16px; margin-bottom: 10px; }
266
- & h6 { font-size: 14px; margin-bottom: 10px; }
267
-
268
- /* Paragraphs and text */
269
- & p {
270
- font-family: 'Times', 'Times New Roman', serif;
271
- font-size: 14px;
272
- line-height: 1.6;
273
- margin: 0 0 12px 0;
274
- color: #333;
275
- }
276
-
277
- /* Page breaks */
278
- & .page-break, & [style*="page-break"] {
279
- margin-top: 40px;
280
- padding-top: 40px;
281
- border-top: 2px dashed #ccc;
282
- }
283
-
284
- /* Tables */
285
- & table {
286
- width: 100%;
287
- border-collapse: collapse;
288
- margin: 15px 0;
289
- font-family: 'Arial', 'Helvetica', sans-serif;
290
- border: 2px solid #333333;
291
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
292
-
293
- & th, & td {
294
- padding: 14px;
295
- border: 1px solid #333333;
296
- text-align: left;
297
- font-size: 14px;
298
- line-height: 1.4;
299
- color: #333;
300
- vertical-align: middle;
301
- }
302
-
303
- & th {
304
- background: #4fbfa5 !important;
305
- color: white !important;
306
- font-weight: bold;
307
- }
308
-
309
- & td {
310
- background: white;
311
- font-weight: 500;
312
- }
313
-
314
- & tr:nth-child(even) td {
315
- background: #f9f9f9;
316
- }
317
-
318
- & tfoot tr {
319
- background: #f3f4f6;
320
-
321
- & td {
322
- font-weight: bold;
323
- border-top: 2px solid #333333;
324
- }
325
-
326
- &:last-child {
327
- background: #333333 !important;
328
-
329
- & td {
330
- color: white !important;
331
- font-weight: bold;
332
- }
333
- }
334
- }
335
- }
336
-
337
- /* Lists */
338
- & ul, & ol {
339
- font-family: 'Times', 'Times New Roman', serif;
340
- font-size: 14px;
341
- line-height: 1.6;
342
- margin: 12px 0;
343
- padding-left: 25px;
344
- color: #333;
345
-
346
- & li {
347
- margin: 8px 0;
348
- color: #333;
349
- }
350
- }
351
-
352
- /* Text formatting */
353
- & strong, & b {
354
- font-weight: bold;
355
- }
356
-
357
- & em, & i {
358
- font-style: italic;
359
- }
360
-
361
- /* Images */
362
- & img {
363
- max-width: 100%;
364
- height: auto;
365
- margin: 10px 0;
366
- }
367
-
368
- /* Divs and sections */
369
- & div {
370
- margin-bottom: 0;
371
- }
372
-
373
- /* Override any branding classes that might interfere */
374
- & .primary-bg, & .secondary-bg, & .accent-bg,
375
- & .primary-text, & .secondary-text, & .accent-text {
376
- color: #333 !important;
377
- background: transparent !important;
378
- }
379
-
380
- /* Terms and conditions specific styling */
381
- & .terms-section, & .terms-conditions-section, & [class*="terms"] {
382
- margin: 20px 0;
383
- padding: 15px;
384
- border: 1px solid #ddd;
385
- background: #f9f9f9;
386
-
387
- & h1, & h2, & h3, & h4 {
388
- margin-top: 15px;
389
- margin-bottom: 10px;
390
- color: #333;
391
-
392
- &:first-child {
393
- margin-top: 0;
394
- }
395
- }
396
-
397
- & h1 {
398
- font-size: 24px;
399
- border-bottom: 2px solid #333;
400
- padding-bottom: 10px;
401
- }
402
-
403
- & h3 {
404
- font-size: 16px;
405
- margin-top: 20px;
406
- }
407
-
408
- & p {
409
- white-space: pre-wrap;
410
- word-wrap: break-word;
411
- margin-bottom: 12px;
412
- text-align: justify;
413
- hyphens: auto;
414
- }
415
-
416
- & .terms-content {
417
- max-width: none;
418
- overflow: visible;
419
- }
420
- }
421
-
422
- /* Ensure all content is visible and not truncated */
423
- & * {
424
- max-height: none !important;
425
- overflow: visible !important;
426
- text-overflow: clip !important;
427
- }
428
-
429
- /* Special handling for long content */
430
- & div, & section {
431
- overflow: visible;
432
- height: auto;
433
- max-height: none;
434
- }
225
+ border: none;
226
+ border-radius: 4px;
227
+ display: block !important;
435
228
  }
436
229
 
437
230
  /* Content Editor Styles */
@@ -1419,12 +1212,18 @@
1419
1212
  background-color: #f3f4f6;
1420
1213
  }
1421
1214
 
1215
+ .subtotalLabel,
1216
+ .subtotalValue {
1217
+ color: #333 !important;
1218
+ }
1219
+
1422
1220
  &:last-child {
1423
1221
  background-color: #333333 !important;
1424
1222
 
1425
1223
  .subtotalLabel,
1426
1224
  .subtotalValue {
1427
1225
  color: white !important;
1226
+ background-color: #333333 !important;
1428
1227
  }
1429
1228
  }
1430
1229
  }
@@ -1436,6 +1235,7 @@
1436
1235
  color: #374151;
1437
1236
  font-size: 14px;
1438
1237
  border: 1px solid #333333;
1238
+ background: inherit;
1439
1239
  }
1440
1240
 
1441
1241
  .subtotalValue {
@@ -1446,6 +1246,7 @@
1446
1246
  font-size: 14px;
1447
1247
  white-space: nowrap;
1448
1248
  border: 1px solid #333333;
1249
+ background: inherit;
1449
1250
  }
1450
1251
 
1451
1252
  /* Responsive styles */