@visns-studio/visns-components 4.2.4 → 4.2.5

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.
@@ -8,7 +8,8 @@ import { BlockPicker } from 'react-color';
8
8
  import { CopyToClipboard } from 'react-copy-to-clipboard';
9
9
  import { NumericFormat, PatternFormat } from 'react-number-format';
10
10
  import { Editor } from '@tinymce/tinymce-react';
11
- import { CloudDownload, Copy, TrashCan } from 'akar-icons';
11
+ import { CirclePlus, CloudDownload, Copy, TrashCan } from 'akar-icons';
12
+ import { toast } from 'react-toastify';
12
13
  import styles from './styles/Field.module.css';
13
14
 
14
15
  import CustomFetch from './Fetch';
@@ -38,6 +39,9 @@ function Field({
38
39
  onChangeSelect,
39
40
  onChangeSignature,
40
41
  onChangeRicheditor,
42
+ onChangeTableRadio,
43
+ onChangeAddTableTextRow,
44
+ onChangeTableText,
41
45
  onChangeToggle,
42
46
  onFileDownload,
43
47
  setFormData,
@@ -1106,7 +1110,20 @@ function Field({
1106
1110
  onClick={(e) => {
1107
1111
  e.preventDefault();
1108
1112
 
1109
- onChangeSignature(settings.id);
1113
+ if (settings.role) {
1114
+ if (
1115
+ userProfile?.roles[0]?.name ===
1116
+ settings.role
1117
+ ) {
1118
+ onChangeSignature(settings.id);
1119
+ } else {
1120
+ toast.error(
1121
+ `A user with the role of ${settings.role} is required to sign this document`
1122
+ );
1123
+ }
1124
+ } else {
1125
+ onChangeSignature(settings.id);
1126
+ }
1110
1127
  }}
1111
1128
  >
1112
1129
  Click to Sign
@@ -1128,6 +1145,8 @@ function Field({
1128
1145
  }
1129
1146
  }
1130
1147
 
1148
+ console.info(inputValue);
1149
+
1131
1150
  return (
1132
1151
  <table className={styles.contentTable}>
1133
1152
  <thead>
@@ -1164,8 +1183,17 @@ function Field({
1164
1183
  key={`table-radio-cell-${settings.id}-${rowKey}-${columnKey}`}
1165
1184
  >
1166
1185
  <input
1167
- type="radio"
1168
- name={`radio-${settings.id}-${rowKey}`}
1186
+ type="checkbox"
1187
+ name={row.id}
1188
+ data-id={settings.id}
1189
+ onChange={
1190
+ onChangeTableRadio
1191
+ }
1192
+ checked={
1193
+ row.value === true
1194
+ ? true
1195
+ : false
1196
+ }
1169
1197
  />
1170
1198
  </td>
1171
1199
  )
@@ -1177,11 +1205,13 @@ function Field({
1177
1205
  );
1178
1206
  case 'table_text':
1179
1207
  let tableTextColumns = [];
1208
+ let tableTextValues = [];
1180
1209
 
1181
1210
  for (const key in formData) {
1182
1211
  if (formData[key].id === settings.id) {
1183
1212
  if (formData[key].hasOwnProperty('options')) {
1184
1213
  tableTextColumns = formData[key].options;
1214
+ tableTextValues = formData[key].value;
1185
1215
  break; // Assuming there's only one match needed, break out of the loop
1186
1216
  }
1187
1217
  }
@@ -1191,22 +1221,51 @@ function Field({
1191
1221
  <thead>
1192
1222
  <tr>
1193
1223
  {tableTextColumns.map((column, columnKey) => (
1194
- <th key={`${settings.id}-${columnKey.id}`}>
1224
+ <th
1225
+ key={`${settings.id}-${column.id}-${columnKey}`}
1226
+ >
1195
1227
  {column.label}
1196
1228
  </th>
1197
1229
  ))}
1230
+ <th style={{ textAlign: 'center' }}>
1231
+ <CirclePlus
1232
+ onClick={() => {
1233
+ onChangeAddTableTextRow(
1234
+ settings.id
1235
+ );
1236
+ }}
1237
+ size={24}
1238
+ data-id={settings.id}
1239
+ />
1240
+ </th>
1198
1241
  </tr>
1199
1242
  </thead>
1200
1243
  <tbody>
1201
- <tr>
1202
- {tableTextColumns.map((column, columnKey) => (
1203
- <td
1204
- key={`${settings.id}-${columnKey.id}-input`}
1244
+ {tableTextValues?.length > 0 &&
1245
+ tableTextValues?.map((row, rowKey) => (
1246
+ <tr
1247
+ key={`${settings.id}-${row.id}-${rowKey}-row`}
1205
1248
  >
1206
- <input type="text" />
1207
- </td>
1249
+ {row?.map((cell, cellKey) => (
1250
+ <td
1251
+ key={`${settings.id}}-${cellKey}-input`}
1252
+ >
1253
+ <input
1254
+ type="text"
1255
+ value={cell || ''}
1256
+ data-id={settings.id}
1257
+ onChange={(e) =>
1258
+ onChangeTableText(
1259
+ e,
1260
+ rowKey,
1261
+ cellKey
1262
+ )
1263
+ }
1264
+ />
1265
+ </td>
1266
+ ))}
1267
+ </tr>
1208
1268
  ))}
1209
- </tr>
1210
1269
  </tbody>
1211
1270
  </table>
1212
1271
  );
@@ -209,6 +209,111 @@ const GenericDynamic = ({
209
209
  }
210
210
  };
211
211
 
212
+ const handleChangeTableRadio = (e) => {
213
+ const {
214
+ name,
215
+ dataset: { id },
216
+ } = e.target;
217
+
218
+ // console.info('Checkbox changed:', { name, id });
219
+
220
+ setActiveForm((prevActiveForm) => {
221
+ // console.info('Previous activeForm:', prevActiveForm);
222
+
223
+ // Find the form that matches the given id
224
+ const formKey = Object.keys(prevActiveForm).find(
225
+ (key) => prevActiveForm[key].id === id
226
+ );
227
+
228
+ if (!formKey || !prevActiveForm[formKey]?.rows) {
229
+ console.info(
230
+ `Form with id ${id} does not exist or has no rows`
231
+ );
232
+ return prevActiveForm;
233
+ }
234
+
235
+ // console.info('Found formKey:', formKey);
236
+
237
+ // Create a new rows array with toggled value properties
238
+ const updatedRows = prevActiveForm[formKey].rows.map((row) => ({
239
+ ...row,
240
+ value: row.id === name ? !row.value : row.value ?? false, // Toggle value if it exists, else set default to false
241
+ }));
242
+
243
+ // console.info('Updated rows:', updatedRows);
244
+
245
+ // Return the updated activeForm state
246
+ return {
247
+ ...prevActiveForm,
248
+ [formKey]: {
249
+ ...prevActiveForm[formKey],
250
+ rows: updatedRows,
251
+ },
252
+ };
253
+ });
254
+ };
255
+
256
+ const handleChangeAddTableTextRow = (id) => {
257
+ setActiveForm((prevActiveForm) => {
258
+ // Find the key of the form that matches the id
259
+ const formKey = Object.keys(prevActiveForm).find(
260
+ (key) => prevActiveForm[key].id === id
261
+ );
262
+
263
+ if (!formKey) {
264
+ console.info(`Form with id ${id} does not exist.`);
265
+ return prevActiveForm;
266
+ }
267
+
268
+ console.info(prevActiveForm);
269
+
270
+ // Create a new row with placeholders based on the options length
271
+ const numOptions = prevActiveForm[formKey].options.length;
272
+ const newRow = Array(numOptions).fill(''); // Create an array of empty strings
273
+
274
+ return {
275
+ ...prevActiveForm,
276
+ [formKey]: {
277
+ ...prevActiveForm[formKey],
278
+ value: [
279
+ ...(prevActiveForm[formKey].value || []), // Handle null by initializing to empty array
280
+ newRow,
281
+ ],
282
+ },
283
+ };
284
+ });
285
+ };
286
+
287
+ const handleChangeTableText = (e, rowIndex, columnIndex) => {
288
+ const { value } = e.target;
289
+ const { id } = e.target.dataset;
290
+
291
+ setActiveForm((prevActiveForm) => {
292
+ const formKey = Object.keys(prevActiveForm).find(
293
+ (key) => prevActiveForm[key].id === id
294
+ );
295
+
296
+ if (!formKey) return prevActiveForm;
297
+
298
+ const updatedRows = (prevActiveForm[formKey].value || []).map(
299
+ (row, index) =>
300
+ index === rowIndex
301
+ ? row.map((cell, colIndex) =>
302
+ colIndex === columnIndex ? value : cell
303
+ )
304
+ : row
305
+ );
306
+
307
+ return {
308
+ ...prevActiveForm,
309
+ [formKey]: {
310
+ ...prevActiveForm[formKey],
311
+ value: updatedRows,
312
+ },
313
+ };
314
+ });
315
+ };
316
+
212
317
  const handleChangeToggle = (e) => {
213
318
  if (!e) {
214
319
  return;
@@ -648,6 +753,15 @@ const GenericDynamic = ({
648
753
  onChangeSignature={
649
754
  handleChangeSignature
650
755
  }
756
+ onChangeTableRadio={
757
+ handleChangeTableRadio
758
+ }
759
+ onChangeAddTableTextRow={
760
+ handleChangeAddTableTextRow
761
+ }
762
+ onChangeTableText={
763
+ handleChangeTableText
764
+ }
651
765
  onChangeToggle={
652
766
  handleChangeToggle
653
767
  }
@@ -655,6 +769,9 @@ const GenericDynamic = ({
655
769
  handleFileDownload
656
770
  }
657
771
  style={{}}
772
+ userProfile={
773
+ userProfile
774
+ }
658
775
  />
659
776
  )
660
777
  )
@@ -678,6 +795,15 @@ const GenericDynamic = ({
678
795
  onChangeDate={
679
796
  handleChangeDate
680
797
  }
798
+ onChangeTableRadio={
799
+ handleChangeTableRadio
800
+ }
801
+ onChangeAddTableTextRow={
802
+ handleChangeAddTableTextRow
803
+ }
804
+ onChangeTableText={
805
+ handleChangeTableText
806
+ }
681
807
  onChangeToggle={
682
808
  handleChangeToggle
683
809
  }
@@ -685,6 +811,7 @@ const GenericDynamic = ({
685
811
  handleFileDownload
686
812
  }
687
813
  style={{}}
814
+ userProfile={userProfile}
688
815
  />
689
816
  )
690
817
  )}
@@ -53,6 +53,7 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
53
53
  key: '',
54
54
  });
55
55
  const [modalFormShow, setModalFormShow] = useState(false);
56
+ const [roles, setRoles] = useState([]);
56
57
 
57
58
  /** Data Option Functionalities */
58
59
  const handleDataOption = (e) => {
@@ -727,6 +728,16 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
727
728
  }
728
729
  };
729
730
 
731
+ const fetchRoles = async () => {
732
+ try {
733
+ const res = await CustomFetch('/ajax/roles/dropdown', 'POST', {});
734
+
735
+ setRoles(res.data.data);
736
+ } catch (err) {
737
+ console.info(err);
738
+ }
739
+ };
740
+
730
741
  useEffect(() => {
731
742
  if (data.detail && data.detail.length > 0) {
732
743
  saveOnSort();
@@ -735,6 +746,7 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
735
746
 
736
747
  useEffect(() => {
737
748
  fetchData();
749
+ fetchRoles();
738
750
  }, []);
739
751
 
740
752
  return (
@@ -1293,6 +1305,37 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
1293
1305
  </div>
1294
1306
  ) : null}
1295
1307
 
1308
+ {['signature'].includes(dataField.type) ? (
1309
+ <div className={styles.formItem}>
1310
+ <label className={styles.fi__label}>
1311
+ <select
1312
+ name="role"
1313
+ value={dataField.role}
1314
+ onChange={handleChangeForm}
1315
+ >
1316
+ <option>
1317
+ No Role Associated
1318
+ </option>
1319
+ {roles.map(
1320
+ (role, roleKey) => (
1321
+ <option
1322
+ value={role.id}
1323
+ key={roleKey}
1324
+ >
1325
+ {role.label}
1326
+ </option>
1327
+ )
1328
+ )}
1329
+ </select>
1330
+ <span
1331
+ className={styles.fi__span}
1332
+ >
1333
+ Single or Bulk Image?
1334
+ </span>
1335
+ </label>
1336
+ </div>
1337
+ ) : null}
1338
+
1296
1339
  {['table_radio'].includes(
1297
1340
  dataField.type
1298
1341
  ) ? (
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "axios": "^1.7.2",
14
14
  "dayjs": "^1.11.11",
15
15
  "file-saver": "^2.0.5",
16
- "framer-motion": "^11.2.10",
16
+ "framer-motion": "^11.2.11",
17
17
  "html-react-parser": "^5.1.10",
18
18
  "lodash": "^4.17.21",
19
19
  "lodash.debounce": "^4.0.8",
@@ -57,7 +57,7 @@
57
57
  "react-dom": "^17.0.1"
58
58
  },
59
59
  "name": "@visns-studio/visns-components",
60
- "version": "4.2.4",
60
+ "version": "4.2.5",
61
61
  "description": "Various packages to assist in the development of our Custom Applications.",
62
62
  "main": "index.js",
63
63
  "scripts": {