@visns-studio/visns-components 5.0.13 → 5.0.14

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
@@ -75,7 +75,7 @@
75
75
  "react-dom": "^17.0.0 || ^18.0.0"
76
76
  },
77
77
  "name": "@visns-studio/visns-components",
78
- "version": "5.0.13",
78
+ "version": "5.0.14",
79
79
  "description": "Various packages to assist in the development of our Custom Applications.",
80
80
  "main": "src/index.js",
81
81
  "files": [
@@ -82,6 +82,7 @@ function Field({
82
82
  useEffect(() => {
83
83
  const fetchOptions = () => {
84
84
  let filter = {};
85
+
85
86
  if (settings.where?.length > 0) {
86
87
  filter = {
87
88
  where: settings.where,
@@ -1328,9 +1328,8 @@ function GenericDetail({
1328
1328
  schedulingConfig={activeTabConfig}
1329
1329
  data={data}
1330
1330
  dataId={routeParams[urlParam]}
1331
- handleReload={handleReload}
1331
+ modalOpen={modalOpen}
1332
1332
  preloadedOptions={preloadedOptions}
1333
- userProfile={userProfile}
1334
1333
  />
1335
1334
  );
1336
1335
  default:
@@ -16,9 +16,8 @@ const GenericEditableTable = ({
16
16
  schedulingConfig,
17
17
  data,
18
18
  dataId,
19
- handleReload,
19
+ modalOpen,
20
20
  preloadedOptions,
21
- userProfile,
22
21
  }) => {
23
22
  const { columns, rows, form } = schedulingConfig;
24
23
 
@@ -56,29 +55,37 @@ const GenericEditableTable = ({
56
55
 
57
56
  const groupCategoriesByType = (data) => {
58
57
  const grouped = {};
59
- data.forEach((category) => {
58
+
59
+ data.forEach((category, categoryKey) => {
60
60
  const categoryType =
61
- category[rows.categoryKey.id]?.[rows.categoryKey.label] ||
62
- 'Miscellaneous';
61
+ category[rows.categoryKey.id]?.[rows.categoryKey.label] || null;
62
+
63
+ const categoryId = category[rows.categoryKey.id]?.id || null;
63
64
 
64
- const categoryId =
65
- category[rows.categoryKey.id]?.id || Number.MAX_SAFE_INTEGER;
65
+ const groupKey = categoryId || 'no_category';
66
66
 
67
- if (!grouped[categoryId]) {
68
- grouped[categoryId] = {
69
- id: categoryId,
70
- category: categoryType,
67
+ if (!grouped[groupKey]) {
68
+ grouped[groupKey] = {
69
+ id: categoryId || 'no_category',
70
+ category: categoryType || '',
71
71
  entries: [],
72
72
  };
73
73
  }
74
- grouped[categoryId].entries.push(category);
74
+ grouped[groupKey].entries.push({
75
+ ...category,
76
+ keyCounter: categoryKey,
77
+ });
75
78
  });
76
79
 
77
80
  Object.values(grouped).forEach((group) => {
78
81
  group.entries.sort((a, b) => a.sort_order - b.sort_order);
79
82
  });
80
83
 
81
- return Object.values(grouped);
84
+ // Ensure 'no_category' group is at the top
85
+ const groupedArray = Object.values(grouped);
86
+ return groupedArray.sort((a, b) =>
87
+ a.id === 'no_category' ? -1 : b.id === 'no_category' ? 1 : 0
88
+ );
82
89
  };
83
90
 
84
91
  const handleFieldChange = (value, fieldId, keyCounter) => {
@@ -89,7 +96,7 @@ const GenericEditableTable = ({
89
96
  [fieldId]: value,
90
97
  };
91
98
 
92
- debouncedUpdate({ detail: updatedDetail });
99
+ debouncedUpdate({ [rows.key]: updatedDetail });
93
100
 
94
101
  return updatedDetail;
95
102
  });
@@ -130,7 +137,7 @@ const GenericEditableTable = ({
130
137
  : item;
131
138
  });
132
139
 
133
- debouncedUpdate({ detail: reordered });
140
+ debouncedUpdate({ [rows.key]: reordered });
134
141
  return reordered;
135
142
  }
136
143
  }
@@ -139,6 +146,30 @@ const GenericEditableTable = ({
139
146
  });
140
147
  };
141
148
 
149
+ const handleDeleteRow = (entry) => {
150
+ confirmAlert({
151
+ title: 'Confirm to Delete',
152
+ message: 'Are you sure you want to delete this entry?',
153
+ buttons: [
154
+ {
155
+ label: 'Yes',
156
+ onClick: async () => {
157
+ setLocalData((prev) => {
158
+ const updatedDetail = prev.filter(
159
+ (item) => item.id !== entry.id
160
+ );
161
+ debouncedUpdate({ [rows.key]: updatedDetail });
162
+ return updatedDetail;
163
+ });
164
+ },
165
+ },
166
+ {
167
+ label: 'No',
168
+ },
169
+ ],
170
+ });
171
+ };
172
+
142
173
  const renderScheduledTableField = (entry, column, keyCounter) => {
143
174
  if (!entry || !column) return null;
144
175
 
@@ -159,6 +190,21 @@ const GenericEditableTable = ({
159
190
  style={{ textAlign: 'right' }}
160
191
  />
161
192
  );
193
+ case 'date':
194
+ return (
195
+ <input
196
+ type="date"
197
+ value={entry[column.id] || ''}
198
+ onChange={(e) =>
199
+ handleFieldChange(
200
+ e.target.value,
201
+ column.id,
202
+ keyCounter
203
+ )
204
+ }
205
+ style={{ textAlign: 'right' }}
206
+ />
207
+ );
162
208
  case 'dropdown':
163
209
  return (
164
210
  <select
@@ -287,43 +333,49 @@ const GenericEditableTable = ({
287
333
  </td>
288
334
  ))}
289
335
  <td>
290
- {idx > 0 && (
291
- <ArrowUp
292
- size={18}
293
- onClick={() =>
294
- handleSortChange(
295
- group.id,
296
- entry.id,
297
- 'up'
298
- )
299
- }
300
- style={{
301
- cursor: 'pointer',
302
- }}
303
- />
304
- )}
305
- {idx < group.entries.length - 1 && (
306
- <ArrowDown
336
+ <div className={styles.tdactions}>
337
+ {idx > 0 && (
338
+ <ArrowUp
339
+ size={18}
340
+ onClick={() =>
341
+ handleSortChange(
342
+ group.id,
343
+ entry.id,
344
+ 'up'
345
+ )
346
+ }
347
+ style={{
348
+ cursor: 'pointer',
349
+ }}
350
+ />
351
+ )}
352
+ {idx <
353
+ group.entries.length -
354
+ 1 && (
355
+ <ArrowDown
356
+ size={18}
357
+ onClick={() =>
358
+ handleSortChange(
359
+ group.id,
360
+ entry.id,
361
+ 'down'
362
+ )
363
+ }
364
+ style={{
365
+ cursor: 'pointer',
366
+ }}
367
+ />
368
+ )}
369
+ <TrashCan
307
370
  size={18}
308
371
  onClick={() =>
309
- handleSortChange(
310
- group.id,
311
- entry.id,
312
- 'down'
313
- )
372
+ handleDeleteRow(entry)
314
373
  }
315
374
  style={{
316
375
  cursor: 'pointer',
317
376
  }}
318
377
  />
319
- )}
320
- <TrashCan
321
- size={18}
322
- onClick={() =>
323
- handleDeleteRow(entry)
324
- }
325
- style={{ cursor: 'pointer' }}
326
- />
378
+ </div>
327
379
  </td>
328
380
  </tr>
329
381
  ))}
@@ -332,8 +384,22 @@ const GenericEditableTable = ({
332
384
  </tbody>
333
385
  </table>
334
386
  ) : (
335
- <div>No data available.</div>
387
+ <div className={styles.noDataMessage}>
388
+ No data available. Please check your filters or try
389
+ reloading the data.
390
+ </div>
336
391
  )}
392
+
393
+ <div className={styles.polActions}>
394
+ <button
395
+ className={styles.btn}
396
+ onClick={() => {
397
+ modalOpen('create', 0);
398
+ }}
399
+ >
400
+ Add
401
+ </button>
402
+ </div>
337
403
  </div>
338
404
  );
339
405
  };
@@ -134,3 +134,45 @@
134
134
  background: var(--highlight-color);
135
135
  border: 1px solid rgba(var(--highlight-rgb), 1.05);
136
136
  }
137
+
138
+ .tdactions {
139
+ width: 100%;
140
+ display: flex;
141
+ flex-wrap: nowrap;
142
+ justify-content: flex-start;
143
+ align-items: center;
144
+ gap: 0.1rem;
145
+
146
+ span {
147
+ display: flex;
148
+ align-items: center;
149
+ position: relative;
150
+ width: 18px;
151
+ height: 18px;
152
+
153
+ svg {
154
+ width: 18px;
155
+ height: 18px;
156
+ }
157
+ }
158
+ }
159
+
160
+ .noDataMessage {
161
+ text-align: center;
162
+ color: var(--primary-color);
163
+ font-size: 1rem;
164
+ padding: 2rem;
165
+ margin: 2rem auto;
166
+ background-color: var(--secondary-bg-color, #f8f8f8);
167
+ border: 1px solid rgba(var(--primary-rgb), 0.15);
168
+ border-radius: 6px;
169
+ max-width: 80%;
170
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
171
+ font-weight: 500;
172
+ font-family: var(--font-family, Arial, sans-serif);
173
+ }
174
+
175
+ .noDataMessage:hover {
176
+ background-color: rgba(var(--primary-rgb), 0.05);
177
+ border-color: rgba(var(--primary-rgb), 0.2);
178
+ }