@visns-studio/visns-components 4.5.12 → 4.6.0

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.
@@ -2561,6 +2561,7 @@ const DataGrid = forwardRef(
2561
2561
  open={modalShow}
2562
2562
  onClose={modalClose}
2563
2563
  closeOnDocumentClick={false}
2564
+ nested
2564
2565
  >
2565
2566
  <Form
2566
2567
  ajaxSetting={ajaxSetting}
@@ -6,6 +6,7 @@ import _ from 'lodash';
6
6
  import Toggle from 'react-toggle';
7
7
  import moment from 'moment';
8
8
  import parse from 'html-react-parser';
9
+ import Popup from 'reactjs-popup';
9
10
  import { BlockPicker } from 'react-color';
10
11
  import { CopyToClipboard } from 'react-copy-to-clipboard';
11
12
  import { NumericFormat, PatternFormat } from 'react-number-format';
@@ -15,6 +16,7 @@ import { toast } from 'react-toastify';
15
16
  import styles from './styles/Field.module.css';
16
17
 
17
18
  import CustomFetch from './Fetch';
19
+ import Form from './Form';
18
20
  import MultiSelect from './MultiSelect';
19
21
  import Select from './Select';
20
22
  import VisnsAsyncSelect from './AsyncSelect';
@@ -54,6 +56,7 @@ function Field({
54
56
  const editorRef = useRef(null);
55
57
  const fileImageInputRef = useRef(null);
56
58
  const [colorPickerShow, setColorPickerShow] = useState(false);
59
+ const [counter, setCounter] = useState(0);
57
60
  const [dataOptions, setDataOptions] = useState([]);
58
61
  const [formItemStyle, setFormItemStyle] = useState({});
59
62
  const [formItemClass, setFormItemClass] = useState('formItem');
@@ -142,7 +145,7 @@ function Field({
142
145
  } else if (settings.size === 'quarter') {
143
146
  setFormItemClass('formItem qtrItem');
144
147
  }
145
- }, [settings]);
148
+ }, [settings, counter]);
146
149
 
147
150
  useEffect(() => {
148
151
  const fetchChildDropdownData = () => {
@@ -220,7 +223,7 @@ function Field({
220
223
  };
221
224
 
222
225
  fetchChildDropdownData();
223
- }, [inputValue, settings]);
226
+ }, [inputValue, settings, counter]);
224
227
 
225
228
  useEffect(() => {
226
229
  const processOptions = () => {
@@ -262,6 +265,8 @@ function Field({
262
265
  'copytoclipboard',
263
266
  'date',
264
267
  'datetime',
268
+ 'dropdown',
269
+ 'dropdown-ajax',
265
270
  'dynamicdata',
266
271
  'file',
267
272
  'gallery',
@@ -532,18 +537,35 @@ function Field({
532
537
  case 'dropdown':
533
538
  case 'dropdown-ajax':
534
539
  return (
535
- <Select
536
- settings={settings}
537
- className={inputClass[settings.id]}
538
- onChange={onChange}
539
- inputValue={inputValue === null ? '' : inputValue}
540
- options={
541
- settings.type === 'dropdown'
542
- ? settings.options
543
- : options
544
- }
545
- dataOptions={dataOptions}
546
- />
540
+ <div className={styles.dropdownContainer}>
541
+ <Select
542
+ settings={settings}
543
+ className={
544
+ settings.create ? styles.selectFullWidth : ''
545
+ }
546
+ onChange={onChange}
547
+ inputValue={inputValue === null ? '' : inputValue}
548
+ options={
549
+ settings.type === 'dropdown'
550
+ ? settings.options
551
+ : options
552
+ }
553
+ dataOptions={dataOptions}
554
+ />
555
+
556
+ {settings.create && (
557
+ <button
558
+ className={styles.buttonRight}
559
+ onClick={(e) => {
560
+ e.preventDefault();
561
+
562
+ handleAddEntry(settings.create);
563
+ }}
564
+ >
565
+ <CirclePlus strokeWidth={2} size={16} />
566
+ </button>
567
+ )}
568
+ </div>
547
569
  );
548
570
  case 'dynamicdata':
549
571
  return (
@@ -849,28 +871,44 @@ function Field({
849
871
  case 'multi-dropdown':
850
872
  case 'multi-dropdown-ajax':
851
873
  return (
852
- <MultiSelect
853
- settings={settings}
854
- className={inputClass[settings.id]}
855
- multi={
856
- settings.hasOwnProperty('multi')
857
- ? settings.multi
858
- : false
859
- }
860
- onChange={onChangeSelect}
861
- inputValue={
862
- inputValue === null || inputValue === undefined
863
- ? ''
864
- : inputValue
865
- }
866
- options={
867
- settings.type === 'multi-dropdown'
868
- ? settings.options
869
- : options
870
- }
871
- dataOptions={dataOptions}
872
- style={style}
873
- />
874
+ <div className={styles.dropdownContainer}>
875
+ <MultiSelect
876
+ settings={settings}
877
+ className={
878
+ settings.create ? styles.selectFullWidth : ''
879
+ }
880
+ multi={
881
+ settings.hasOwnProperty('multi')
882
+ ? settings.multi
883
+ : false
884
+ }
885
+ onChange={onChangeSelect}
886
+ inputValue={
887
+ inputValue === null || inputValue === undefined
888
+ ? ''
889
+ : inputValue
890
+ }
891
+ options={
892
+ settings.type === 'multi-dropdown'
893
+ ? settings.options
894
+ : options
895
+ }
896
+ dataOptions={dataOptions}
897
+ style={style}
898
+ />
899
+ {settings.create && (
900
+ <button
901
+ className={styles.buttonRight}
902
+ onClick={(e) => {
903
+ e.preventDefault();
904
+
905
+ handleAddEntry(settings.create);
906
+ }}
907
+ >
908
+ <CirclePlus strokeWidth={2} size={16} />
909
+ </button>
910
+ )}
911
+ </div>
874
912
  );
875
913
  case 'percentage':
876
914
  return (
@@ -1329,6 +1367,8 @@ function Field({
1329
1367
  'copytoclipboard',
1330
1368
  'date',
1331
1369
  'datetime',
1370
+ 'dropdown',
1371
+ 'dropdown-ajax',
1332
1372
  'dynamicdata',
1333
1373
  'file',
1334
1374
  'gallery',
@@ -1441,6 +1481,40 @@ function Field({
1441
1481
  }
1442
1482
  };
1443
1483
 
1484
+ /** Child Form */
1485
+ const [childForm, setChildForm] = useState({});
1486
+ const [childFormShow, setChildFormShow] = useState(false);
1487
+
1488
+ const childFormClose = () => {
1489
+ setChildFormShow(false);
1490
+ setChildForm({});
1491
+ };
1492
+
1493
+ const childFormOpen = () => {
1494
+ setChildFormShow(true);
1495
+ };
1496
+
1497
+ const handleAddEntry = (form) => {
1498
+ if (form) {
1499
+ let f = form;
1500
+
1501
+ form.fields.forEach((item, itemKey) => {
1502
+ if (item.hasOwnProperty('dataId') && formData[item.dataId]) {
1503
+ f.fields[itemKey].value = formData[item.dataId].value
1504
+ ? formData[item.dataId].value
1505
+ : formData[item.dataId];
1506
+ }
1507
+ });
1508
+
1509
+ setChildForm(f);
1510
+ childFormOpen();
1511
+ }
1512
+ };
1513
+
1514
+ const handleReload = () => {
1515
+ setCounter(counter + 1);
1516
+ };
1517
+
1444
1518
  return (
1445
1519
  <div className={formItemClass} style={formItemStyle}>
1446
1520
  <label className={styles.fi__label}>
@@ -1449,6 +1523,27 @@ function Field({
1449
1523
  {renderFieldLabel()}
1450
1524
  </label>
1451
1525
  {renderAdditionalContainer()}
1526
+ <Popup
1527
+ open={childFormShow}
1528
+ onClose={childFormClose}
1529
+ closeOnDocumentClick={false}
1530
+ >
1531
+ <Form
1532
+ ajaxSetting={childForm.ajaxSetting}
1533
+ api={api}
1534
+ closeModal={childFormClose}
1535
+ columnId={0}
1536
+ fetchTable={handleReload}
1537
+ formSettings={childForm}
1538
+ formType={'create'}
1539
+ gridRef={null}
1540
+ mapbox={null}
1541
+ modalOpen={childFormOpen}
1542
+ paramValue={null}
1543
+ style={style}
1544
+ updateForm={setChildForm}
1545
+ />
1546
+ </Popup>
1452
1547
  </div>
1453
1548
  );
1454
1549
  }
@@ -1348,7 +1348,7 @@ function Form({
1348
1348
  <div className="modalwrap top--modal">
1349
1349
  <div className="modal">
1350
1350
  <div className="modal__header">
1351
- <h1>{formSettings[formType].title}</h1>
1351
+ <h1>{formSettings[formType]?.title}</h1>
1352
1352
  <button className="modal__close" onClick={closeModal}>
1353
1353
  <CircleX strokeWidth={1} size={24} />
1354
1354
  </button>
@@ -1356,7 +1356,7 @@ function Form({
1356
1356
  <div className="modal__content">
1357
1357
  <div className={styles.formcontainer}>
1358
1358
  <form className={styles.modalForm}>
1359
- {formSettings.fields.map((item, index) => {
1359
+ {formSettings?.fields?.map((item, index) => {
1360
1360
  if (
1361
1361
  item.hasOwnProperty('hide') &&
1362
1362
  item.hide === true
@@ -4,6 +4,7 @@ import Select, { createFilter } from 'react-select';
4
4
  import styles from './styles/AsyncSelect.module.css';
5
5
 
6
6
  function MultiSelect({
7
+ className,
7
8
  inputValue,
8
9
  multi,
9
10
  onChange,
@@ -52,7 +53,11 @@ function MultiSelect({
52
53
  onChange={(inputValue, action) => {
53
54
  onChange(inputValue, action, settings.id);
54
55
  }}
55
- className={styles.visns__ms}
56
+ className={
57
+ className
58
+ ? `${styles.visns__ms} ${className}`
59
+ : styles.visns__ms
60
+ }
56
61
  classNamePrefix="visns-select"
57
62
  styles={{
58
63
  menu: (provided) => ({ ...provided, zIndex: 9999 }),
@@ -655,7 +655,11 @@ function GenericDetail({
655
655
  <GenericDynamic
656
656
  data={data}
657
657
  fetchData={handleReload}
658
- label={data.task_template.label}
658
+ label={
659
+ data.task_template
660
+ ? data.task_template.label
661
+ : ''
662
+ }
659
663
  multiple={false}
660
664
  originalData={data}
661
665
  primaryKey={activeTabConfig.setting.key}
@@ -207,9 +207,9 @@
207
207
  .crmtitle {
208
208
  border: none;
209
209
  min-height: auto;
210
- padding: 5px 20px;
210
+ padding: 10px 20px;
211
211
  margin: 0;
212
- background: var(--primary-color);
212
+ background: var(--tertiary-color);
213
213
  border-radius: var(--br);
214
214
  border: 1px solid rgba(var(--item-color-rgb), 1.15);
215
215
  position: relative;
@@ -217,26 +217,22 @@
217
217
  align-items: center;
218
218
 
219
219
  h1 {
220
- color: var(--background-color);
221
220
  font-weight: 700;
222
- font-size: 1.15em;
221
+ font-size: 1.45em;
223
222
  margin: 0;
224
223
  padding: 0.65rem 0;
225
- display: flex;
226
- align-items: center;
227
- gap: 0.25rem;
228
224
 
229
225
  a {
230
226
  text-decoration: none;
231
227
  color: var(--secondary-color);
228
+ font-weight: 300;
232
229
  }
233
230
 
234
231
  svg {
235
- color: rgba(var(--tertiary-color-rgb), 0.5);
232
+ color: rgba(var(--primary-color-rgb), 0.5);
236
233
  position: relative;
237
- top: 0;
238
- margin: 0 0.5rem;
239
- max-width: 15px;
234
+ top: 2px;
235
+ margin: 0 0.25rem;
240
236
  }
241
237
  }
242
238
  }
@@ -7,6 +7,35 @@
7
7
  box-sizing: border-box;
8
8
  }
9
9
 
10
+ .dropdownContainer {
11
+ position: relative;
12
+ width: 100%;
13
+ }
14
+
15
+ .selectFullWidth {
16
+ width: 90%;
17
+ }
18
+
19
+ .buttonRight {
20
+ position: absolute;
21
+ right: 0;
22
+ top: 50%;
23
+ transform: translateY(-50%);
24
+ z-index: 1;
25
+ background: var(--primary-color);
26
+ color: var(--secondary-color);
27
+ padding: 1rem 0.5rem;
28
+ border: none;
29
+ border-radius: var(--br);
30
+ cursor: pointer;
31
+ transition: background 0.3s;
32
+ }
33
+
34
+ .buttonRight:hover {
35
+ background: var(--secondary-color);
36
+ color: var(--primary-color);
37
+ }
38
+
10
39
  .formItem .fi__label {
11
40
  position: relative;
12
41
  display: block;
@@ -51,6 +80,25 @@ select:not(:placeholder-shown) + .fi__span {
51
80
  top: 0;
52
81
  }
53
82
 
83
+ .fi__button--right {
84
+ position: absolute;
85
+ right: 50px;
86
+ top: 20px;
87
+ z-index: 500;
88
+ background: var(--primary-color);
89
+ color: var(--item-color);
90
+ padding: 0.2rem 0.4rem;
91
+ border: none;
92
+ border-radius: var(--br);
93
+ cursor: pointer;
94
+ transition: background 0.3s;
95
+ }
96
+
97
+ .fi__button--right:hover {
98
+ background: var(--secondary-color);
99
+ color: var(--primary-color);
100
+ }
101
+
54
102
  .formItem textarea,
55
103
  .formItem select,
56
104
  .formItem
package/package.json CHANGED
@@ -11,10 +11,10 @@
11
11
  "akar-icons": "^1.9.31",
12
12
  "array-move": "^4.0.0",
13
13
  "awesome-debounce-promise": "^2.1.0",
14
- "axios": "^1.7.2",
14
+ "axios": "^1.7.3",
15
15
  "dayjs": "^1.11.12",
16
16
  "file-saver": "^2.0.5",
17
- "framer-motion": "^11.3.19",
17
+ "framer-motion": "^11.3.21",
18
18
  "html-react-parser": "^5.1.12",
19
19
  "lodash": "^4.17.21",
20
20
  "lodash.debounce": "^4.0.8",
@@ -41,7 +41,7 @@
41
41
  "react-to-print": "^2.15.1",
42
42
  "react-toastify": "^10.0.5",
43
43
  "react-toggle": "^4.1.3",
44
- "react-tooltip": "^5.27.1",
44
+ "react-tooltip": "^5.28.0",
45
45
  "react-window": "^1.8.10",
46
46
  "reactjs-popup": "^2.0.6",
47
47
  "truncate": "^3.0.0",
@@ -58,7 +58,7 @@
58
58
  "react-dom": "^17.0.1"
59
59
  },
60
60
  "name": "@visns-studio/visns-components",
61
- "version": "4.5.12",
61
+ "version": "4.6.0",
62
62
  "description": "Various packages to assist in the development of our Custom Applications.",
63
63
  "main": "index.js",
64
64
  "scripts": {