@visns-studio/visns-components 4.10.47 → 5.0.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.
Files changed (41) hide show
  1. package/package.json +28 -30
  2. package/src/components/cms/Field.jsx +39 -63
  3. package/src/components/crm/Breadcrumb.jsx +2 -18
  4. package/src/components/crm/DataGrid.jsx +23 -379
  5. package/src/components/crm/Field.jsx +16 -215
  6. package/src/components/crm/Form.jsx +81 -79
  7. package/src/components/crm/MultiSelect.jsx +25 -71
  8. package/src/components/crm/Navigation.jsx +7 -11
  9. package/src/components/crm/QrCode.jsx +8 -12
  10. package/src/components/crm/QuickAction.jsx +1 -0
  11. package/src/components/crm/generic/GenericAuth.jsx +2 -6
  12. package/src/components/crm/generic/GenericDashboard.jsx +30 -340
  13. package/src/components/crm/generic/GenericDetail.jsx +37 -80
  14. package/src/components/crm/generic/GenericDynamic.jsx +76 -94
  15. package/src/components/crm/generic/GenericFormBuilder.jsx +19 -79
  16. package/src/components/crm/generic/GenericIndex.jsx +1 -2
  17. package/src/components/crm/generic/styles/GenericDetail.module.scss +0 -51
  18. package/src/components/crm/generic/styles/GenericFormBuilder.module.scss +0 -5
  19. package/src/components/crm/styles/DataGrid.module.scss +25 -0
  20. package/src/components/crm/styles/Field.module.scss +0 -210
  21. package/src/components/crm/styles/Form.module.scss +0 -78
  22. package/src/components/crm/styles/Navigation.module.scss +4 -10
  23. package/src/components/crm/styles/QrCode.module.scss +0 -18
  24. package/src/index.js +0 -8
  25. package/src/components/crm/generic/styles/GenericDashboard.module.scss +0 -325
  26. package/src/components/crm/sketch/SketchField.jsx +0 -395
  27. package/src/components/crm/sketch/arrow.jsx +0 -108
  28. package/src/components/crm/sketch/circle.jsx +0 -75
  29. package/src/components/crm/sketch/default-tool.jsx +0 -16
  30. package/src/components/crm/sketch/fabrictool.jsx +0 -22
  31. package/src/components/crm/sketch/history.jsx +0 -144
  32. package/src/components/crm/sketch/json/config.json +0 -14
  33. package/src/components/crm/sketch/line.jsx +0 -64
  34. package/src/components/crm/sketch/pan.jsx +0 -48
  35. package/src/components/crm/sketch/pencil.jsx +0 -36
  36. package/src/components/crm/sketch/rectangle-label-object.jsx +0 -69
  37. package/src/components/crm/sketch/rectangle-label.jsx +0 -93
  38. package/src/components/crm/sketch/rectangle.jsx +0 -76
  39. package/src/components/crm/sketch/select.jsx +0 -16
  40. package/src/components/crm/sketch/tools.jsx +0 -11
  41. package/src/components/crm/sketch/utils.jsx +0 -67
@@ -59,7 +59,7 @@ import 'react-confirm-alert/src/react-confirm-alert.css';
59
59
  import CustomFetch from './Fetch';
60
60
  import Download from './Download';
61
61
  import Form from './Form';
62
- import _, { set } from 'lodash';
62
+ import _ from 'lodash';
63
63
 
64
64
  const loadData = async (
65
65
  { skip, limit, sortInfo, filterValue },
@@ -94,7 +94,6 @@ const loadData = async (
94
94
  id: identifier,
95
95
  value: fv.value,
96
96
  operator: fv.operator,
97
- whereHas: fv.whereHas || [],
98
97
  });
99
98
  }
100
99
  } else {
@@ -150,19 +149,6 @@ const DataGrid = forwardRef(
150
149
  }
151
150
  }, [audioSource]);
152
151
 
153
- /** JSON Modal States */
154
- const [modalJsonShow, setModalJsonShow] = useState(false);
155
- const [jsonData, setJsonData] = useState({});
156
-
157
- /** JSON Modal Functions */
158
- const modalJsonOpen = () => {
159
- setModalJsonShow(true);
160
- };
161
-
162
- const modalJsonClose = () => {
163
- setModalJsonShow(false);
164
- };
165
-
166
152
  /** Gallery Modal States */
167
153
  const [modalGalleryShow, setModalGalleryShow] = useState(false);
168
154
  const [galleryData, setGalleryData] = useState([]);
@@ -182,32 +168,17 @@ const DataGrid = forwardRef(
182
168
  const [formId, setFormId] = useState(0);
183
169
  const [modalShow, setModalShow] = useState(false);
184
170
 
185
- const [formSettingData, setFormSettingData] = useState({});
186
- const [formSettingType, setFormSettingType] = useState('');
187
- const [formSettingId, setFormSettingId] = useState(0);
188
- const [modalSettingShow, setModalSettingShow] = useState(false);
189
-
190
171
  /** Modal Functions */
191
- const modalOpen = (type, id) => {
172
+ const modalOpen = (formType, formId) => {
192
173
  setModalShow(true);
193
- setFormType(type);
194
- setFormId(id);
174
+ setFormType(formType);
175
+ setFormId(formId);
195
176
  };
196
177
 
197
178
  const modalClose = () => {
198
179
  setModalShow(false);
199
180
  };
200
181
 
201
- const modalSettingOpen = (type, id) => {
202
- setModalSettingShow(true);
203
- setFormSettingType(type);
204
- setFormSettingId(id);
205
- };
206
-
207
- const modalSettingClose = () => {
208
- setModalSettingShow(false);
209
- };
210
-
211
182
  useEffect(() => {
212
183
  setFormData(form);
213
184
  }, [form]);
@@ -257,65 +228,23 @@ const DataGrid = forwardRef(
257
228
  const toastId = toast.loading('Starting download please wait...');
258
229
 
259
230
  try {
260
- if (d.id && d.id > 0) {
261
- const res = await Download(
262
- `/ajax/files/download/${d.id}/null`,
263
- 'GET',
264
- {}
265
- );
231
+ const res = await Download(
232
+ `/ajax/files/download/${d.id}/null`,
233
+ 'GET',
234
+ {}
235
+ );
266
236
 
267
- if (res.data.error) {
268
- toast.error(res.data.error);
269
- } else {
270
- // Assuming the response contains a Blob or similar data
271
- if (res.data && res.data instanceof Blob) {
272
- const fileName = `${d.file_name}`;
273
- saveAs(res.data, fileName);
274
- } else {
275
- // Handle the case where the response is not a Blob
276
- toast.error('Invalid file format received.');
277
- }
278
- }
237
+ if (res.data.error) {
238
+ toast.error(res.data.error);
279
239
  } else {
280
- toast.error(
281
- 'An issue with downloading the file has occurred.'
282
- );
283
- }
284
- } catch (error) {
285
- console.info(error);
286
- } finally {
287
- // Dismiss the loading toast in the finally block to ensure it's always dismissed
288
- toast.dismiss(toastId);
289
- }
290
- };
291
-
292
- const handleDownloadPath = async (file) => {
293
- const toastId = toast.loading('Starting download please wait...');
294
-
295
- try {
296
- if (file.file_path && file.file_name && file.file_extension) {
297
- const res = await Download(
298
- `/ajax/files/downloadByPath`,
299
- 'POST',
300
- { ...file }
301
- );
302
-
303
- if (res.data.error) {
304
- toast.error(res.data.error);
240
+ // Assuming the response contains a Blob or similar data
241
+ if (res.data && res.data instanceof Blob) {
242
+ const fileName = `${d.file_name}`;
243
+ saveAs(res.data, fileName);
305
244
  } else {
306
- // Assuming the response contains a Blob or similar data
307
- if (res.data && res.data instanceof Blob) {
308
- const fileName = `${file.file_name}`;
309
- saveAs(res.data, fileName);
310
- } else {
311
- // Handle the case where the response is not a Blob
312
- toast.error('Invalid file format received.');
313
- }
245
+ // Handle the case where the response is not a Blob
246
+ toast.error('Invalid file format received.');
314
247
  }
315
- } else {
316
- toast.error(
317
- 'An issue with downloading the file has occurred.'
318
- );
319
248
  }
320
249
  } catch (error) {
321
250
  console.info(error);
@@ -570,25 +499,6 @@ const DataGrid = forwardRef(
570
499
  ],
571
500
  });
572
501
  break;
573
- case 'form':
574
- if (s.key) {
575
- let fsd = s.form;
576
-
577
- if (fsd.fields && fsd.fields.length > 0) {
578
- fsd.fields.forEach((fItem, fKey) => {
579
- if (fItem.id === s.key) {
580
- fsd.fields[fKey].value = d.id;
581
- }
582
- });
583
-
584
- setFormSettingData((prevState) => ({
585
- ...prevState,
586
- ...fsd,
587
- }));
588
- }
589
- }
590
- modalSettingOpen('create', 0);
591
- break;
592
502
  case 'envelope':
593
503
  CustomFetch(s.url, 'POST', { id: d[s.key] }, (result) => {
594
504
  toast.success(result.message);
@@ -660,14 +570,6 @@ const DataGrid = forwardRef(
660
570
  );
661
571
  }
662
572
  break;
663
- case 'view':
664
- modalJsonOpen();
665
- setJsonData((prevState) => ({
666
- ...prevState,
667
- data: d[s.key],
668
- headers: s.headers,
669
- }));
670
- break;
671
573
  case 'update':
672
574
  modalOpen('update', d.id);
673
575
  break;
@@ -757,9 +659,7 @@ const DataGrid = forwardRef(
757
659
  } else {
758
660
  const column = rowProps.columns[columnIndex];
759
661
 
760
- const excludedColumnTypes = ['dropdown', 'text_input'];
761
-
762
- if (!excludedColumnTypes.includes(column.type)) {
662
+ if (column.type !== 'dropdown') {
763
663
  if (column.id !== '__checkbox-column') {
764
664
  if (column.link && column.link.hasOwnProperty('url')) {
765
665
  if (column.link.url) {
@@ -767,17 +667,7 @@ const DataGrid = forwardRef(
767
667
  const linkUrl = column.link.url;
768
668
  const linkKey =
769
669
  rowProps.columns[columnIndex].link.key;
770
- const rowData = linkKey.includes('.')
771
- ? linkKey
772
- .split('.')
773
- .reduce(
774
- (obj, key) =>
775
- obj && obj[key]
776
- ? obj[key]
777
- : null,
778
- rowProps.data
779
- )
780
- : rowProps.data[linkKey];
670
+ const rowData = rowProps.data[linkKey];
781
671
 
782
672
  if (column.link.hasOwnProperty('folder')) {
783
673
  const linkFolder =
@@ -794,13 +684,7 @@ const DataGrid = forwardRef(
794
684
  }
795
685
  }
796
686
  } else {
797
- if (rowData) {
798
- navigate(`${linkUrl}${rowData}`);
799
- } else {
800
- toast.warn(
801
- 'No data available for this link.'
802
- );
803
- }
687
+ navigate(`${linkUrl}${rowData}`);
804
688
  }
805
689
  } else {
806
690
  if (rowProps.data[column.id]) {
@@ -1231,7 +1115,6 @@ const DataGrid = forwardRef(
1231
1115
  return getIconComponent(Network);
1232
1116
  case 'gallery':
1233
1117
  return getIconComponent(Image);
1234
- case 'form':
1235
1118
  case 'link':
1236
1119
  return getIconComponent(LinkOut);
1237
1120
  case 'primary':
@@ -1244,8 +1127,6 @@ const DataGrid = forwardRef(
1244
1127
  return getIconComponent(Clock);
1245
1128
  case 'update':
1246
1129
  return getIconComponent(Edit);
1247
- case 'view':
1248
- return getIconComponent(Search);
1249
1130
  default:
1250
1131
  return null;
1251
1132
  }
@@ -1828,19 +1709,9 @@ const DataGrid = forwardRef(
1828
1709
  onClick={(e) => {
1829
1710
  e.stopPropagation();
1830
1711
  e.preventDefault();
1831
-
1832
- if (
1833
- file.id &&
1834
- file.id > 0
1835
- ) {
1836
- handleDownload(
1837
- file
1838
- );
1839
- } else {
1840
- handleDownloadPath(
1841
- file
1842
- );
1843
- }
1712
+ handleDownload(
1713
+ file
1714
+ );
1844
1715
  }}
1845
1716
  style={{
1846
1717
  marginRight:
@@ -2338,51 +2209,6 @@ const DataGrid = forwardRef(
2338
2209
  return <span>{stage}</span>;
2339
2210
  },
2340
2211
  };
2341
- case 'text_input':
2342
- columnId = Array.isArray(column.id)
2343
- ? column.id.join('-')
2344
- : column.id;
2345
-
2346
- return {
2347
- ...commonProps,
2348
- name: columnId,
2349
- render: ({ data }) => {
2350
- const debouncedOnChange = debounce(
2351
- (name, value) => {
2352
- if (
2353
- column.update?.key &&
2354
- column.update?.url &&
2355
- column.update?.method
2356
- ) {
2357
- handleDropdownUpdate(
2358
- column.update.key,
2359
- `${column.update.url}/${data.id}`,
2360
- column.update.method,
2361
- value
2362
- );
2363
- }
2364
- },
2365
- 1000
2366
- );
2367
-
2368
- const handleChange = (e) => {
2369
- const { name, value } = e.target;
2370
- debouncedOnChange(name, value);
2371
- };
2372
-
2373
- return (
2374
- <input
2375
- name={column.id}
2376
- defaultValue={
2377
- data[column.id] || ''
2378
- }
2379
- style={{ padding: '7px' }}
2380
- onChange={handleChange}
2381
- type="text"
2382
- />
2383
- );
2384
- },
2385
- };
2386
2212
  case 'time':
2387
2213
  return {
2388
2214
  ...commonProps,
@@ -2639,7 +2465,6 @@ const DataGrid = forwardRef(
2639
2465
  name: filterName,
2640
2466
  operator: column.filter.operator,
2641
2467
  type: column.filter.type,
2642
- whereHas: column.filter.whereHas || [],
2643
2468
  value: filterValue,
2644
2469
  reset: column.filter.reset
2645
2470
  ? column.filter.reset
@@ -2701,69 +2526,6 @@ const DataGrid = forwardRef(
2701
2526
  }
2702
2527
  };
2703
2528
 
2704
- const snakeCaseToTitle = (text) => {
2705
- return text
2706
- .replace(/_/g, ' ')
2707
- .replace(/\b\w/g, (char) => char.toUpperCase()); // Capitalize first letter of each word
2708
- };
2709
-
2710
- // Recursive function to handle nested objects
2711
- const renderField = (key, value) => {
2712
- // If the value is an object, recursively render its fields
2713
- if (typeof value === 'object' && value !== null) {
2714
- return (
2715
- <div key={key} style={{ marginBottom: '1rem' }}>
2716
- <h4
2717
- style={{
2718
- fontSize: '1.2rem',
2719
- marginBottom: '0.5rem',
2720
- color: '#333',
2721
- borderBottom: '1px solid #ccc',
2722
- }}
2723
- >
2724
- {snakeCaseToTitle(key)}
2725
- </h4>
2726
- <div style={{ paddingLeft: '1.5rem' }}>
2727
- {Object.keys(value).map((childKey) =>
2728
- renderField(childKey, value[childKey])
2729
- )}
2730
- </div>
2731
- </div>
2732
- );
2733
- }
2734
- // Otherwise, render the key and value as a label and paragraph
2735
- return (
2736
- <div key={key} style={{ marginBottom: '1rem' }}>
2737
- <span
2738
- style={{
2739
- fontWeight: 'bold',
2740
- marginBottom: '0.2rem',
2741
- display: 'block',
2742
- color: '#444',
2743
- }}
2744
- >
2745
- {snakeCaseToTitle(key)}
2746
- </span>
2747
- <p
2748
- style={{
2749
- margin: 0,
2750
- color: '#666',
2751
- backgroundColor: '#f9f9f9',
2752
- padding: '0.5rem',
2753
- borderRadius: '5px',
2754
- }}
2755
- >
2756
- {value !== null ? value : 'N/A'}
2757
- </p>
2758
- </div>
2759
- );
2760
- };
2761
-
2762
- const getHeaderLabel = (headers, parentKey) => {
2763
- const headerObj = headers.find((header) => header.id === parentKey);
2764
- return headerObj ? headerObj.label : snakeCaseToTitle(parentKey);
2765
- };
2766
-
2767
2529
  useEffect(() => {
2768
2530
  columns.forEach((column) => {
2769
2531
  if (column.filter && column.filter.url) {
@@ -2816,7 +2578,6 @@ const DataGrid = forwardRef(
2816
2578
  : 400,
2817
2579
  boxShadow: 'none',
2818
2580
  });
2819
-
2820
2581
  const headerProps = {
2821
2582
  style: style ? style : {},
2822
2583
  };
@@ -2932,29 +2693,6 @@ const DataGrid = forwardRef(
2932
2693
  userProfile={userProfile}
2933
2694
  />
2934
2695
  </Popup>
2935
- <Popup
2936
- open={modalSettingShow}
2937
- onClose={modalSettingClose}
2938
- closeOnDocumentClick={false}
2939
- nested
2940
- >
2941
- <Form
2942
- ajaxSetting={ajaxSetting}
2943
- api={api}
2944
- closeModal={modalSettingClose}
2945
- columnId={formSettingId}
2946
- fetchTable={handleReload}
2947
- formSettings={formSettingData}
2948
- formType={formSettingType}
2949
- gridRef={gridRef}
2950
- mapbox={mapbox}
2951
- modalOpen={modalSettingOpen}
2952
- paramValue={paramValue}
2953
- style={style}
2954
- updateForm={setFormSettingData}
2955
- userProfile={userProfile}
2956
- />
2957
- </Popup>
2958
2696
  <Popup
2959
2697
  open={modalGalleryShow}
2960
2698
  onClose={modalGalleryClose}
@@ -2984,100 +2722,6 @@ const DataGrid = forwardRef(
2984
2722
  </div>
2985
2723
  </div>
2986
2724
  </Popup>
2987
- <Popup
2988
- open={modalJsonShow}
2989
- onClose={modalJsonClose}
2990
- closeOnDocumentClick={false}
2991
- >
2992
- <div
2993
- className={`${styles.modalwrap} ${styles['top--modal']}`}
2994
- >
2995
- <div className={styles.modal}>
2996
- <div className={styles.modal__header}>
2997
- <h1>View Data</h1>
2998
- <button
2999
- className={styles.modal__close}
3000
- onClick={modalJsonClose}
3001
- >
3002
- <CircleX strokeWidth={1} size={24} />
3003
- </button>
3004
- </div>
3005
- <div className={styles.modal__content}>
3006
- <div className={styles.formcontainer}>
3007
- <div
3008
- style={{
3009
- lineHeight: '1.5',
3010
- }}
3011
- >
3012
- {jsonData.headers &&
3013
- jsonData.headers.map((header) => {
3014
- const parentKey = header.id;
3015
-
3016
- // Skip rendering if the parentKey is "id" or doesn't exist in jsonData
3017
- if (
3018
- parentKey === 'id' ||
3019
- !(
3020
- parentKey in
3021
- jsonData.data
3022
- )
3023
- )
3024
- return null;
3025
-
3026
- return (
3027
- <div
3028
- key={parentKey}
3029
- style={{
3030
- marginBottom:
3031
- '2rem',
3032
- }}
3033
- >
3034
- {/* Section Header */}
3035
- <h3
3036
- style={{
3037
- fontSize:
3038
- '1.4rem',
3039
- marginBottom:
3040
- '1rem',
3041
- color: '#222',
3042
- borderBottom:
3043
- '2px solid #ddd',
3044
- }}
3045
- >
3046
- {getHeaderLabel(
3047
- jsonData.headers,
3048
- parentKey
3049
- )}
3050
- </h3>
3051
- <div
3052
- style={{
3053
- paddingLeft:
3054
- '1rem',
3055
- }}
3056
- >
3057
- {/* Render fields for each section */}
3058
- {Object.keys(
3059
- jsonData.data[
3060
- parentKey
3061
- ]
3062
- ).map((childKey) =>
3063
- renderField(
3064
- childKey,
3065
- jsonData
3066
- .data[
3067
- parentKey
3068
- ][childKey]
3069
- )
3070
- )}
3071
- </div>
3072
- </div>
3073
- );
3074
- })}
3075
- </div>
3076
- </div>
3077
- </div>
3078
- </div>
3079
- </div>
3080
- </Popup>
3081
2725
  </>
3082
2726
  );
3083
2727
  }