@visns-studio/visns-components 5.13.12 → 5.13.13

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
@@ -88,7 +88,7 @@
88
88
  "react-dom": "^17.0.0 || ^18.0.0"
89
89
  },
90
90
  "name": "@visns-studio/visns-components",
91
- "version": "5.13.12",
91
+ "version": "5.13.13",
92
92
  "description": "Various packages to assist in the development of our Custom Applications.",
93
93
  "main": "src/index.js",
94
94
  "files": [
@@ -87,6 +87,13 @@
87
87
  margin-bottom: 1rem;
88
88
  }
89
89
 
90
+ .signature-editor-label-with-button {
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ margin-bottom: 0.5rem;
95
+ }
96
+
90
97
  .signature-btn {
91
98
  display: inline-flex;
92
99
  align-items: center;
@@ -1,9 +1,10 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Plus, Trash2, Move, Type, Edit3, Save, X } from 'lucide-react';
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { Plus, Trash2, Move, Type, Edit3, Save, X, Tag } from 'lucide-react';
3
3
  import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
4
4
  import { arrayMoveImmutable } from 'array-move';
5
5
  import { toast } from 'react-toastify';
6
6
  import { buildUrl, defaultProposalApiEndpoints } from '../../utils/urlBuilder';
7
+ import VariableInserter from './VariableInserter';
7
8
  import './AgreementSignatureEditor.css';
8
9
 
9
10
  const DragHandle = SortableHandle(() => (
@@ -195,6 +196,8 @@ const AgreementSignatureEditor = ({
195
196
  const [editingField, setEditingField] = useState(null);
196
197
  const [showFieldEditor, setShowFieldEditor] = useState(false);
197
198
  const [isLoading, setIsLoading] = useState(false);
199
+ const [showVariableInserter, setShowVariableInserter] = useState(false);
200
+ const bodyTextRef = useRef(null);
198
201
 
199
202
  // Helper function to replace template variables in URLs
200
203
  const buildUrlWithTemplate = (urlTemplate, params = {}) => {
@@ -399,6 +402,33 @@ const AgreementSignatureEditor = ({
399
402
  });
400
403
  };
401
404
 
405
+ const handleVariableInsert = (variableName) => {
406
+ const textarea = bodyTextRef.current;
407
+ if (!textarea) return;
408
+
409
+ const start = textarea.selectionStart;
410
+ const end = textarea.selectionEnd;
411
+ const text = textarea.value;
412
+ const before = text.substring(0, start);
413
+ const after = text.substring(end, text.length);
414
+ const variableText = `{{${variableName}}}`;
415
+
416
+ const newText = before + variableText + after;
417
+
418
+ setTemplate({
419
+ ...template,
420
+ bodyText: newText
421
+ });
422
+
423
+ // Reset cursor position after the inserted variable
424
+ setTimeout(() => {
425
+ textarea.focus();
426
+ textarea.setSelectionRange(start + variableText.length, start + variableText.length);
427
+ }, 0);
428
+
429
+ setShowVariableInserter(false);
430
+ };
431
+
402
432
  const handleSaveTemplate = async () => {
403
433
  try {
404
434
  setIsLoading(true);
@@ -508,7 +538,7 @@ const AgreementSignatureEditor = ({
508
538
  .join('');
509
539
 
510
540
  return `
511
- <div style="padding: 2rem; border: 1px solid #ddd; border-radius: 8px; background: #fff;">
541
+ <div style="padding: 2rem;">
512
542
  ${templateData.headerText ? `<h3 style="margin-bottom: 1rem; color: #333;">${templateData.headerText}</h3>` : ''}
513
543
  <p style="margin-bottom: 2rem; line-height: 1.6;">${templateData.bodyText}</p>
514
544
  <div style="clear: both;">${fieldsHtml}</div>
@@ -548,8 +578,20 @@ const AgreementSignatureEditor = ({
548
578
  </div>
549
579
 
550
580
  <div className="signature-editor-section">
551
- <label className="signature-editor-label">Body Text</label>
581
+ <div className="signature-editor-label-with-button">
582
+ <label className="signature-editor-label">Body Text</label>
583
+ <button
584
+ type="button"
585
+ onClick={() => setShowVariableInserter(true)}
586
+ className="signature-btn secondary small"
587
+ title="Insert Variable"
588
+ >
589
+ <Tag size={16} />
590
+ Insert Variable
591
+ </button>
592
+ </div>
552
593
  <textarea
594
+ ref={bodyTextRef}
553
595
  value={template.bodyText}
554
596
  onChange={(e) => setTemplate({...template, bodyText: e.target.value})}
555
597
  placeholder="Enter the agreement text. Use {{variable_name}} for dynamic content."
@@ -557,7 +599,7 @@ const AgreementSignatureEditor = ({
557
599
  rows="3"
558
600
  />
559
601
  <small className="signature-editor-help">
560
- Use variables like {'{{company_name}}'} for dynamic content
602
+ Use variables like {'{{company_name}}'} for dynamic content. Click "Insert Variable" to browse available variables.
561
603
  </small>
562
604
  </div>
563
605
 
@@ -637,6 +679,14 @@ const AgreementSignatureEditor = ({
637
679
  </div>
638
680
  </div>
639
681
  )}
682
+
683
+ {showVariableInserter && (
684
+ <VariableInserter
685
+ onInsert={handleVariableInsert}
686
+ onCancel={() => setShowVariableInserter(false)}
687
+ apiEndpoints={apiEndpoints}
688
+ />
689
+ )}
640
690
  </div>
641
691
  );
642
692
  };