@visns-studio/visns-components 3.5.0 → 3.5.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.
@@ -34,7 +34,10 @@ const SortableItem = ({
34
34
  ) : (
35
35
  <div className="sortimg">
36
36
  {/* Placeholder image */}
37
- <img src="data:image/png;base64,..." />
37
+ <img
38
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAJ3UlEQVR4nO3b60/aXhwG8KflJijIJQgTt8y5mLkxl73w//8HzBbdXLLFqJsg3rjKnUJ/L0wJpYUC9ovbL8/nlRbac077tOf0tCiHh4c6iFymPncF6P+JwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQjvc1eAFqPrOprNJrrdLnRdRyQSgdf79xzOpdWkVCrh/PwcnU4Huq5jd3cXyWRyWcXPrVgs4uLiQry+i+6XX79+4e7ubvj//v4+IpGI6/Vb1ELBOjo6wsPDw/B/RVEQCAQQCAQQDAaRSqUQDodN61xdXaHVaj2ttktUKBSWUt9F90utVhOojXsWCla32zX9r+s62u022u02qtUqrq+vkclksL29PfxOv99/Wk2XbFn1XbQcXdddrom7xAbv+Xwe19fXUpunv5wrwYrH40gkEpbluVzOjc3TP8iVYGUyGezt7WFzc9O0vN1uo9FouFEE/WNc7Qrj8bhlWb1ed7MI+ke4Giy/329Z1uv13CyC/hGuzmOpqjWns9z1aJqGu7s7VKvV4aRfv9+Hx+NBIBBAIpFAJpOBx+OxrDsYDHB9fY1isYh2u41erwe/3490Oo2trS3Td3VdR6FQQLlcRqvVQq/XQzAYRCKRwNbWFhRFmVhHXddxc3OD29tbNBoNeDweRCIR7OzsWCYmO50OcrkcyuUyut0u/H4/QqEQYrEY0un01HLstFotnJ+fo1qtQlVVxGIxDAYDx/XmbW+/30ehUECpVEKr1YKmaQgEAtje3rYdQ0/jarDsGmsXhvF1vn79ik6nY/lM0zRomoZGo4FarYZsNmv5/OTkxDSnBjyO7S4uLhAKhYbdc7/fx8nJiWX+p16vo16vo1Kp4OPHjxPreXZ2Bk3TTGXf3d1B0zR8+PBhuPzh4QHfv383nVDGVEypVEKlUsHe3t7UfTLelqOjo2HZ/X4ft7e3juvN295CoYDfv3+b2miUn8vl5g6Wq12hXbfn9Jih0+nYhmpcpVKxBOj09NSybFJ9Li4upk4qVqtV3N/fT/x8fIeP1mv0oP/48WPqVbpYLJpmzJ2cnp5OLHuaedt7e3u7UDmTuBosu4F6KBSauo7f75+5a2g2m8O/G42GJQherxfxeBzRaBRerxerq6sAHsM7PqcWjUYtdXOad1tZWbHU1ZgcBh5n0UfDrCgKksmk5eS6urqaWo6h0WigUqlY6rCxsTF1n7nVXoOxH+fhWlc4GAwsl2hVVbG2tjZ1PY/Hg1evXsHj8SAcDsPv98Pn86HX6+Ho6Mg0yz/6983NjWU7+/v7w52n6/pw59/f35tmqqPRKLLZLJrNJr58+TJcbgTEzps3b7C5uYlyuYyTkxPTZ8aZPn4lSqfT2NnZwdXVFc7OzobL6/X6cAw5TbFYtCx7//49QqEQKpWK5QmIwY32JhIJvH37FoqizDSeG+dKsE5PT9Hr9SyX0lQqZTugH/fy5UvLskAggPX1ddPBGt1Z45f5jY0N0xk5ekaPn/XGeCEYDJqWT+uSfT4fANieKLquo9frma6owOMBtVvHeDNh/HnquPE2hkIhxx4AcKe94XB42OZFuNIVGncQo3w+n21g5jHpcm8cmFHr6+sTtzP+XePg2HVrTnexk8aM42UAjycHANsDNMu4clK9F11vkfYuSuS1mUAggL29Pdt5rUmazSbOzs5Qr9eh6zrW1tYmDiZ7vZ7l8ryysmL73cFgYDmIxoFe5C52ErugGCG0u2o7DZQHg4Glq5vlCrKs9jpxJVjGazMrKyuIRqNIp9NzvXRWr9dxfHxsani1WrUtB7A/KJPKs/tuo9FAq9WylPGUnWx35huBsrvyOo1b7LY3S/3cau+8c23jXAlWNpud2hU5+fPnz1wDxGkHcZzddn/+/Gn73XmusLOUM43Tay9225vlYC+rvU6e/Z13XddRLpdNy1KpFA4ODp4UVsM8Y4hZxzB2pt2k2IXI6abGbp1ZgrWs9jp59pekW62WZSem02kEAoGJZ5TdQZl0xbD7rqIo8Hg8UFUVXq932I3PO7vsVI7RLruQOHVr87TRaT2J9jp59mDZjQkmBco4Y+0OSrfbtR3A233306dPjvNr87Irx7h6zNPGWbY373oS7XXyV3SFs35mBMvuoEx6tOPz+SxnscSrPMbUwihjFt7ujnF8Tmmcx+Ox3JBMm9A0LKu9Tp49WHZ3c8Zt9qRgqapqCdfNzY3pjDa6DUVRLAfx8vIS1WoVmqah1WqhVCrh9PQUl5eXC7fDLijGAR0PvfHDEyfjj1IeHh6GbZx0Qi6rvU6evSsMBoNQFMW0o87PzxGNRi0zz6OD10gkYnpW2Gw2cXh4iHA4DE3TUK/XcXBwAJ/Ph3g8bnqTtdPp4Nu3b5a6xGKxhdthPJscLSeXy0HTNBQKBdN3Zx3bxGIx0xSBpmk4Pj4ezvRP4kZ7nzrd8OxXLFVVh48+DLVaDX/+/LHsvNHxg91v73q9HkqlEmq1GgaDwfBnVbM+WnrqLPTGxoalPpeXl6btqqqKTCYz8/bGx0yNRsN2ln/Usto7zbMHCwBev3490+Tf6MxzIpGwfRXaYEzaAo+z8js7O47bf+oPUl+8eDH1+Z+iKNjd3Z2pGwQex5LGg2Ano99ZVnuneXJX6PP55n5Y6fV6TWOk1dVVfP78Gfl8fvjWpaIo8Pv98Pv9iEQiSKVSlru+d+/eIZ/Po1KpDJ9Xer1eRCIRZDIZ0wE01i8UCmg2m2i321BVFT6fD+vr60gmkxPnzcbra1AUBT6fb/iZqqrIZrPI5/OoVqtot9vodrvDMra2tqa+gmJXTjKZRCAQQD6fR7PZRKfTgaqqw+mYSCSCZDJp2TdPaa/x5u5TKIeHh3/3Lx/pn/RXdIX0/8NgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEvEfmhiBahNiQpEAAAAASUVORK5CYII="
39
+ alt="Placeholder"
40
+ />
38
41
  </div>
39
42
  );
40
43
  }
@@ -42,6 +42,7 @@ function Field({
42
42
  style,
43
43
  }) {
44
44
  const editorRef = useRef(null);
45
+ const fileImageInputRef = useRef(null);
45
46
  const [colorPickerShow, setColorPickerShow] = useState(false);
46
47
  const [dataOptions, setDataOptions] = useState([]);
47
48
  const [formItemStyle, setFormItemStyle] = useState({});
@@ -869,30 +870,34 @@ function Field({
869
870
  style={{
870
871
  display: 'inline-flex',
871
872
  alignItems: 'center',
873
+ cursor: 'pointer',
874
+ }}
875
+ onClick={() => {
876
+ fileImageInputRef.current.click();
872
877
  }}
873
878
  >
874
879
  <input
875
880
  type="file"
876
881
  data-name={settings.id}
877
- className={inputClass[settings.id]}
882
+ className={inputClass[settings.id]} // Assuming inputClass is defined elsewhere in your code
878
883
  onChange={onChange}
879
- />{' '}
880
- {inputValue && inputValue.key && inputValue.uuid && (
881
- <div
884
+ ref={fileImageInputRef}
885
+ style={{ display: 'none' }} // Hide the file input
886
+ />
887
+ {inputValue.imageSrc ? (
888
+ <img
889
+ src={inputValue.imageSrc}
890
+ alt="Uploaded"
882
891
  style={{
883
892
  marginLeft: '10px',
884
- cursor: 'pointer',
893
+ maxHeight: '100px', // Set a maximum height for the image
885
894
  }}
886
- data-tooltip-id="system-tooltip"
887
- data-tooltip-content={inputValue.filename}
888
- onClick={(e) => {
889
- e.preventDefault();
890
-
891
- onFileDownload(inputValue);
892
- }}
893
- >
894
- <CloudDownload size={24} />
895
- </div>
895
+ />
896
+ ) : (
897
+ <img
898
+ src="data:image/png;base64,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"
899
+ alt="Placeholder"
900
+ />
896
901
  )}
897
902
  </div>
898
903
  );
@@ -38,7 +38,7 @@ const renderValue = (field) => {
38
38
  }
39
39
  };
40
40
 
41
- const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
41
+ const GenericDynamic = ({ data, fetchData, label, setData, setting, type }) => {
42
42
  const toastId = useRef(null);
43
43
  const [activeForm, setActiveForm] = useState([]);
44
44
  const [activeFormKey, setActiveFormKey] = useState(0);
@@ -55,16 +55,17 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
55
55
 
56
56
  if (checked) {
57
57
  newValue = checked;
58
-
59
58
  setActiveForm((prevState) =>
60
59
  updateField(prevState, name, newValue)
61
60
  );
62
61
  } else if (files && files[0]) {
62
+ // Start the upload process and read the file if it's an image
63
63
  Vapor.store(files[0], {
64
64
  progress: (progress) => {
65
+ // Update or show the toast based on upload progress
65
66
  if (
66
67
  toastId.current === null ||
67
- toast.isActive(toastId.current) === false
68
+ !toast.isActive(toastId.current)
68
69
  ) {
69
70
  toastId.current = toast(`File Upload in Progress`, {
70
71
  progress,
@@ -74,22 +75,45 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
74
75
  }
75
76
  },
76
77
  }).then((response) => {
77
- setActiveForm((prevState) =>
78
- updateField(prevState, name, {
79
- extension: response.extension,
80
- key: response.key,
81
- url: response.url,
82
- uuid: response.uuid,
83
- bucket: response.bucket,
84
- filename: files[0].name,
85
- filesize: files[0].size,
86
- })
87
- );
78
+ if (files[0].type.startsWith('image/')) {
79
+ // Use FileReader to asynchronously read the file as a data URL for image preview
80
+ const reader = new FileReader();
81
+ reader.onload = (e) => {
82
+ const imageSrc = e.target.result; // This is the data URL
83
+
84
+ // Set active form state with file details and imageSrc for preview
85
+ setActiveForm((prevState) =>
86
+ updateField(prevState, name, {
87
+ extension: response.extension,
88
+ key: response.key,
89
+ url: response.url,
90
+ uuid: response.uuid,
91
+ bucket: response.bucket,
92
+ filename: files[0].name,
93
+ filesize: files[0].size,
94
+ imageSrc: imageSrc, // Add the data URL as imageSrc
95
+ })
96
+ );
97
+ };
98
+ reader.readAsDataURL(files[0]);
99
+ } else {
100
+ // Handle non-image files
101
+ setActiveForm((prevState) =>
102
+ updateField(prevState, name, {
103
+ extension: response.extension,
104
+ key: response.key,
105
+ url: response.url,
106
+ uuid: response.uuid,
107
+ bucket: response.bucket,
108
+ filename: files[0].name,
109
+ filesize: files[0].size,
110
+ })
111
+ );
112
+ }
88
113
  toast.dismiss(toastId.current);
89
114
  });
90
115
  } else {
91
116
  newValue = value;
92
-
93
117
  setActiveForm((prevState) =>
94
118
  updateField(prevState, name, newValue)
95
119
  );
@@ -133,8 +157,9 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
133
157
  };
134
158
 
135
159
  const handleFileDownload = async (d) => {
160
+ const toastId = toast.loading('Downloading file...'); // Show loading toast
136
161
  try {
137
- const res = await Download('/ajax/clients/download', 'POST', {
162
+ const res = await Download(setting.file, 'POST', {
138
163
  extension: d.extension,
139
164
  uuid: d.uuid,
140
165
  filename: d.filename,
@@ -142,12 +167,33 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
142
167
 
143
168
  if (res.data) {
144
169
  saveAs(res.data, d.filename);
170
+ toast.update(toastId, {
171
+ render: 'Download successful!',
172
+ type: 'success',
173
+ isLoading: false,
174
+ autoClose: 5000,
175
+ closeButton: true,
176
+ });
145
177
  } else {
146
- toast.error('Error downloading file');
178
+ // Update the toast to show an error message
179
+ toast.update(toastId, {
180
+ render: 'Error downloading form',
181
+ type: 'error',
182
+ isLoading: false,
183
+ autoClose: 5000,
184
+ closeButton: true,
185
+ });
147
186
  }
148
187
  } catch (err) {
149
188
  console.error(err);
150
- toast.error('Error downloading file');
189
+ // Update the toast to show an error message
190
+ toast.update(toastId, {
191
+ render: 'Error downloading form',
192
+ type: 'error',
193
+ isLoading: false,
194
+ autoClose: 5000,
195
+ closeButton: true,
196
+ });
151
197
  }
152
198
  };
153
199
 
@@ -159,7 +205,7 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
159
205
  const handleAddNewForm = async () => {
160
206
  try {
161
207
  if (activeForm && activeForm.id) {
162
- await CustomFetch('/ajax/clients/saveForm', 'POST', {
208
+ await CustomFetch(setting.save, 'POST', {
163
209
  client_id: data.id,
164
210
  form_data: {
165
211
  ...activeForm,
@@ -169,7 +215,7 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
169
215
  });
170
216
  }
171
217
 
172
- const res = await CustomFetch('/ajax/clients/addNewForm', 'POST', {
218
+ const res = await CustomFetch(setting.add, 'POST', {
173
219
  client_id: data.id,
174
220
  form_name: type,
175
221
  });
@@ -196,41 +242,58 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
196
242
  };
197
243
 
198
244
  const handleDownloadForm = async (item, key) => {
245
+ // Show loading toast and keep its ID
246
+ const toastId = toast.loading('Downloading form...');
247
+
199
248
  try {
200
- const res = await Download(
201
- '/ajax/pdf/viewParticipantForm',
202
- 'POST',
203
- {
204
- data: item,
205
- label: label,
206
- }
207
- );
249
+ const res = await Download(setting.download, 'POST', {
250
+ data: item,
251
+ label: label,
252
+ });
208
253
 
209
254
  if (res.data) {
210
- const fileName = slugify(label) + '.pdf';
211
- saveAs(res.data, fileName); // Use file-saver to save the file with a slugified label as the filename
255
+ // Update loading toast to a success message before closing it
256
+ toast.update(toastId, {
257
+ render: 'Download successful!',
258
+ type: 'success',
259
+ isLoading: false,
260
+ autoClose: 5000,
261
+ closeButton: true,
262
+ });
263
+ // Perform the download
264
+ saveAs(res.data);
212
265
  } else {
213
- toast.error('Error downloading form');
266
+ // Update the toast to show an error message
267
+ toast.update(toastId, {
268
+ render: 'Error downloading form',
269
+ type: 'error',
270
+ isLoading: false,
271
+ autoClose: 5000,
272
+ closeButton: true,
273
+ });
214
274
  }
215
275
  } catch (err) {
216
276
  console.error(err);
217
- toast.error('Error downloading form');
277
+ // Update the toast to show an error message
278
+ toast.update(toastId, {
279
+ render: 'Error downloading form',
280
+ type: 'error',
281
+ isLoading: false,
282
+ autoClose: 5000,
283
+ closeButton: true,
284
+ });
218
285
  }
219
286
  };
220
287
 
221
288
  const handleDeleteForm = async (id, key) => {
222
289
  const deleteForm = async () => {
223
290
  try {
224
- const res = await CustomFetch(
225
- '/ajax/clients/deleteForm',
226
- 'POST',
227
- {
228
- client_id: data.id,
229
- form_id: id,
230
- form_key: key,
231
- form_type: type,
232
- }
233
- );
291
+ const res = await CustomFetch(setting.delete, 'POST', {
292
+ client_id: data.id,
293
+ form_id: id,
294
+ form_key: key,
295
+ form_type: type,
296
+ });
234
297
 
235
298
  if (res.data.error === '') {
236
299
  toast.success('Form deleted successfully.');
@@ -275,18 +338,14 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
275
338
  });
276
339
 
277
340
  if (error === '') {
278
- const res = await CustomFetch(
279
- '/ajax/clients/saveForm',
280
- 'POST',
281
- {
282
- client_id: data.id,
283
- form_data: {
284
- ...activeForm,
285
- },
286
- form_key: activeFormKey,
287
- form_type: type,
288
- }
289
- );
341
+ const res = await CustomFetch(setting.save, 'POST', {
342
+ client_id: data.id,
343
+ form_data: {
344
+ ...activeForm,
345
+ },
346
+ form_key: activeFormKey,
347
+ form_type: type,
348
+ });
290
349
 
291
350
  if (res.data.error === '') {
292
351
  toast.success('Form saved successfully.');
@@ -477,7 +536,8 @@ const GenericDynamic = ({ data, fetchData, label, setData, type }) => {
477
536
  return (
478
537
  <Field
479
538
  settings={field}
480
- key={`field-${field.id}`}
539
+ key={`field-${key}-${field.id}`}
540
+ formData={activeForm}
481
541
  inputClass={''}
482
542
  inputValue={renderValue(
483
543
  field
@@ -330,26 +330,63 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
330
330
  const renderField = (field) => {
331
331
  switch (field.type) {
332
332
  case 'checkbox':
333
- return renderLabel(
334
- field,
335
- field.options.length > 0 && (
336
- <div className="fi__optionscontainer">
337
- {field.options.map((option, index) => (
338
- <div
339
- key={`${field.id}-checkbox-option-${index}`}
340
- className="fi__checkboxcontainer"
341
- >
342
- <input
343
- type="checkbox"
344
- className="fi__customcheckbox"
345
- />
346
- <label className="fi__checkboxlabel">
347
- {option.label}
348
- </label>{' '}
349
- </div>
350
- ))}
351
- </div>
352
- )
333
+ return (
334
+ <label className="fi__label">
335
+ <span className="fi__spancheckbox">
336
+ {field.label}{' '}
337
+ {field.required === 'yes' ? '*' : null}
338
+ </span>
339
+ {field.options.length > 0 ? (
340
+ <div className="fi__optionscontainer">
341
+ {field.options.map((option, index) => (
342
+ <div
343
+ key={`${field.id}-checkbox-option-${index}`}
344
+ className="fi__checkboxcontainer"
345
+ >
346
+ <input
347
+ type="checkbox"
348
+ className="fi__customcheckbox"
349
+ />
350
+ <label className="fi__checkboxlabel">
351
+ {option.label}
352
+ </label>{' '}
353
+ </div>
354
+ ))}
355
+ </div>
356
+ ) : null}
357
+ </label>
358
+ );
359
+ case 'date':
360
+ return (
361
+ <label className="fi__label">
362
+ <input type="date" />
363
+ <span className="fi__span">
364
+ {field.label}{' '}
365
+ {field.required === 'yes' ? '*' : null}
366
+ </span>
367
+ </label>
368
+ );
369
+ case 'datetime':
370
+ return (
371
+ <label className="fi__label">
372
+ <input type="datetime-local" />
373
+ <span className="fi__span">
374
+ {field.label}{' '}
375
+ {field.required === 'yes' ? '*' : null}
376
+ </span>
377
+ </label>
378
+ );
379
+ case 'dropdown':
380
+ return (
381
+ <label className="fi__label">
382
+ <select>
383
+ <option>Please Select an Option</option>
384
+ </select>
385
+ <span className="fi__span">
386
+ {field.label}{' '}
387
+ {field.required === 'yes' ? '*' : null}
388
+ </span>
389
+ </label>
353
390
  );
354
391
  case 'dynamicdata':
355
392
  return (
@@ -357,6 +394,26 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
357
394
  <strong>{field.label}</strong> [Dynamic Data]
358
395
  </label>
359
396
  );
397
+ case 'file':
398
+ return (
399
+ <label className="fi__label">
400
+ <input type="file" />
401
+ <span className="fi__span">
402
+ {field.label}{' '}
403
+ {field.required === 'yes' ? '*' : null}
404
+ </span>
405
+ </label>
406
+ );
407
+ case 'image':
408
+ return (
409
+ <label className="fi__label">
410
+ <input type="file" />
411
+ <span className="fi__span">
412
+ {field.label}{' '}
413
+ {field.required === 'yes' ? '*' : null}
414
+ </span>
415
+ </label>
416
+ );
360
417
  case 'plaintextheading':
361
418
  return (
362
419
  <label className="fi__label">
@@ -369,6 +426,36 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
369
426
  {field.description ? parse(field.description) : null}
370
427
  </label>
371
428
  );
429
+ case 'number':
430
+ return (
431
+ <label className="fi__label">
432
+ <input type="number" />
433
+ <span className="fi__span">
434
+ {field.label}{' '}
435
+ {field.required === 'yes' ? '*' : null}
436
+ </span>
437
+ </label>
438
+ );
439
+ case 'textarea':
440
+ return (
441
+ <label className="fi__label">
442
+ <textarea rows="5"></textarea>
443
+ <span className="fi__span">
444
+ {field.label}{' '}
445
+ {field.required === 'yes' ? '*' : null}
446
+ </span>
447
+ </label>
448
+ );
449
+ case 'time':
450
+ return (
451
+ <label className="fi__label">
452
+ <input type="time" />
453
+ <span className="fi__span">
454
+ {field.label}{' '}
455
+ {field.required === 'yes' ? '*' : null}
456
+ </span>
457
+ </label>
458
+ );
372
459
  case 'toggle':
373
460
  return (
374
461
  <div>
@@ -380,22 +467,15 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
380
467
  </div>
381
468
  );
382
469
  default:
383
- const inputType =
384
- field.type === 'dropdown' ? (
385
- <select>
386
- <option>Please Select an Option</option>
387
- </select>
388
- ) : (
389
- <input
390
- type={
391
- field.type === 'datetime'
392
- ? 'datetime-local'
393
- : field.type
394
- }
395
- />
396
- );
397
-
398
- return renderLabel(field, inputType);
470
+ return (
471
+ <label className="fi__label">
472
+ <input type="text" />
473
+ <span className="fi__span">
474
+ {field.label}{' '}
475
+ {field.required === 'yes' ? '*' : null}
476
+ </span>
477
+ </label>
478
+ );
399
479
  }
400
480
  };
401
481
 
package/package.json CHANGED
@@ -37,6 +37,7 @@
37
37
  "react-window": "^1.8.10",
38
38
  "reactjs-popup": "^2.0.6",
39
39
  "truncate": "^3.0.0",
40
+ "uuid": "^9.0.1",
40
41
  "validator": "^13.11.0",
41
42
  "yarn": "^1.22.21"
42
43
  },
@@ -49,7 +50,7 @@
49
50
  "react-dom": "^17.0.1"
50
51
  },
51
52
  "name": "@visns-studio/visns-components",
52
- "version": "3.5.0",
53
+ "version": "3.5.2",
53
54
  "description": "Various packages to assist in the development of our Custom Applications.",
54
55
  "main": "index.js",
55
56
  "scripts": {