@visns-studio/visns-components 5.8.11 → 5.8.13

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.
@@ -0,0 +1,266 @@
1
+ import React from 'react';
2
+ import SectionHeader from '../SectionHeader';
3
+ import Field from '../Field';
4
+
5
+ /**
6
+ * Example form component that demonstrates how to use the SectionHeader component
7
+ * This shows how to implement the form seen in the screenshot with improved styling
8
+ */
9
+ const FormWithSectionHeaders = ({ formData, setFormData, onChange }) => {
10
+ // Sample form settings for demonstration
11
+ const formSettings = {
12
+ // Form settings would go here
13
+ };
14
+
15
+ // Sample input classes
16
+ const inputClass = {
17
+ // Input classes would go here
18
+ };
19
+
20
+ return (
21
+ <form>
22
+ {/* Site Details Section */}
23
+ <SectionHeader label="Site Details" />
24
+
25
+ {/* Site Name Field */}
26
+ <Field
27
+ settings={{
28
+ id: 'site_name',
29
+ type: 'text',
30
+ label: 'Site Name',
31
+ required: true,
32
+ size: 'half'
33
+ }}
34
+ inputValue={formData.site_name}
35
+ inputClass={inputClass}
36
+ onChange={onChange}
37
+ />
38
+
39
+ {/* Address Fields */}
40
+ <Field
41
+ settings={{
42
+ id: 'address_1',
43
+ type: 'text',
44
+ label: 'Address #1',
45
+ required: true,
46
+ size: 'half'
47
+ }}
48
+ inputValue={formData.address_1}
49
+ inputClass={inputClass}
50
+ onChange={onChange}
51
+ />
52
+
53
+ <Field
54
+ settings={{
55
+ id: 'address_2',
56
+ type: 'text',
57
+ label: 'Address #2',
58
+ size: 'half'
59
+ }}
60
+ inputValue={formData.address_2}
61
+ inputClass={inputClass}
62
+ onChange={onChange}
63
+ />
64
+
65
+ {/* Suburb Field */}
66
+ <Field
67
+ settings={{
68
+ id: 'suburb',
69
+ type: 'text',
70
+ label: 'Suburb',
71
+ required: true,
72
+ size: 'half'
73
+ }}
74
+ inputValue={formData.suburb}
75
+ inputClass={inputClass}
76
+ onChange={onChange}
77
+ />
78
+
79
+ {/* Postcode Field */}
80
+ <Field
81
+ settings={{
82
+ id: 'postcode',
83
+ type: 'text',
84
+ label: 'Postcode',
85
+ required: true,
86
+ size: 'half'
87
+ }}
88
+ inputValue={formData.postcode}
89
+ inputClass={inputClass}
90
+ onChange={onChange}
91
+ />
92
+
93
+ {/* State Field */}
94
+ <Field
95
+ settings={{
96
+ id: 'state',
97
+ type: 'text',
98
+ label: 'State',
99
+ required: true,
100
+ size: 'half'
101
+ }}
102
+ inputValue={formData.state}
103
+ inputClass={inputClass}
104
+ onChange={onChange}
105
+ />
106
+
107
+ {/* Country Field */}
108
+ <Field
109
+ settings={{
110
+ id: 'country',
111
+ type: 'text',
112
+ label: 'Country',
113
+ required: true,
114
+ size: 'half'
115
+ }}
116
+ inputValue={formData.country}
117
+ inputClass={inputClass}
118
+ onChange={onChange}
119
+ />
120
+
121
+ {/* Delivery Address Section */}
122
+ <Field
123
+ settings={{
124
+ id: 'delivery_address_section',
125
+ type: 'line-break',
126
+ label: 'Delivery Address #1',
127
+ size: 'full'
128
+ }}
129
+ inputValue=""
130
+ inputClass={inputClass}
131
+ />
132
+
133
+ {/* Delivery Address Fields */}
134
+ <Field
135
+ settings={{
136
+ id: 'delivery_address_1',
137
+ type: 'text',
138
+ label: 'Delivery Address #1',
139
+ required: true,
140
+ size: 'half'
141
+ }}
142
+ inputValue={formData.delivery_address_1}
143
+ inputClass={inputClass}
144
+ onChange={onChange}
145
+ />
146
+
147
+ <Field
148
+ settings={{
149
+ id: 'delivery_address_2',
150
+ type: 'text',
151
+ label: 'Delivery Address #2',
152
+ size: 'half'
153
+ }}
154
+ inputValue={formData.delivery_address_2}
155
+ inputClass={inputClass}
156
+ onChange={onChange}
157
+ />
158
+
159
+ {/* Delivery Suburb Field */}
160
+ <Field
161
+ settings={{
162
+ id: 'delivery_suburb',
163
+ type: 'text',
164
+ label: 'Delivery Suburb',
165
+ required: true,
166
+ size: 'half'
167
+ }}
168
+ inputValue={formData.delivery_suburb}
169
+ inputClass={inputClass}
170
+ onChange={onChange}
171
+ />
172
+
173
+ {/* Delivery Postcode Field */}
174
+ <Field
175
+ settings={{
176
+ id: 'delivery_postcode',
177
+ type: 'text',
178
+ label: 'Delivery Postcode',
179
+ required: true,
180
+ size: 'half'
181
+ }}
182
+ inputValue={formData.delivery_postcode}
183
+ inputClass={inputClass}
184
+ onChange={onChange}
185
+ />
186
+
187
+ {/* Delivery State Field */}
188
+ <Field
189
+ settings={{
190
+ id: 'delivery_state',
191
+ type: 'text',
192
+ label: 'Delivery State',
193
+ required: true,
194
+ size: 'half'
195
+ }}
196
+ inputValue={formData.delivery_state}
197
+ inputClass={inputClass}
198
+ onChange={onChange}
199
+ />
200
+
201
+ {/* Delivery Country Field */}
202
+ <Field
203
+ settings={{
204
+ id: 'delivery_country',
205
+ type: 'text',
206
+ label: 'Delivery Country',
207
+ required: true,
208
+ size: 'half'
209
+ }}
210
+ inputValue={formData.delivery_country}
211
+ inputClass={inputClass}
212
+ onChange={onChange}
213
+ />
214
+
215
+ {/* Contact Details Section */}
216
+ <SectionHeader label="Contact Details" />
217
+
218
+ {/* Firstname Field */}
219
+ <Field
220
+ settings={{
221
+ id: 'firstname',
222
+ type: 'text',
223
+ label: 'Firstname',
224
+ required: true,
225
+ size: 'half'
226
+ }}
227
+ inputValue={formData.firstname}
228
+ inputClass={inputClass}
229
+ onChange={onChange}
230
+ />
231
+
232
+ {/* Surname Field */}
233
+ <Field
234
+ settings={{
235
+ id: 'surname',
236
+ type: 'text',
237
+ label: 'Surname',
238
+ size: 'half'
239
+ }}
240
+ inputValue={formData.surname}
241
+ inputClass={inputClass}
242
+ onChange={onChange}
243
+ />
244
+
245
+ {/* Save Button */}
246
+ <div style={{ width: '100%', textAlign: 'center', marginTop: '20px' }}>
247
+ <button
248
+ type="submit"
249
+ style={{
250
+ background: 'var(--primary-color, #2684FF)',
251
+ color: 'var(--secondary-color, #fff)',
252
+ padding: '10px 20px',
253
+ border: 'none',
254
+ borderRadius: 'var(--br, 3px)',
255
+ cursor: 'pointer',
256
+ fontWeight: 'bold'
257
+ }}
258
+ >
259
+ Save & Close
260
+ </button>
261
+ </div>
262
+ </form>
263
+ );
264
+ };
265
+
266
+ export default FormWithSectionHeaders;
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import Swal from 'sweetalert2';
3
+ import './styles/SweetAlert.module.css';
4
+
5
+ /**
6
+ * A utility function that uses SweetAlert2 for confirmation dialogs
7
+ *
8
+ * @param {Object} options - Configuration options
9
+ * @param {string} options.title - The title of the confirmation dialog
10
+ * @param {string} options.message - The message to display in the dialog
11
+ * @param {string} options.confirmLabel - Label for the confirm button
12
+ * @param {string} options.cancelLabel - Label for the cancel button
13
+ * @param {Function} options.onConfirm - Function to call when confirmed
14
+ * @param {Function} options.onCancel - Function to call when cancelled
15
+ * @param {Object} options.data - Optional data object to pass to the dialog
16
+ * @returns {Promise} - A promise that resolves when the dialog is closed
17
+ */
18
+ export const showConfirmDialog = ({
19
+ title = 'Confirm',
20
+ message = 'Are you sure?',
21
+ confirmLabel = 'Yes',
22
+ cancelLabel = 'No',
23
+ onConfirm = () => {},
24
+ onCancel = () => {},
25
+ data = null,
26
+ }) => {
27
+ // Enhanced message with item details if available
28
+ let enhancedMessage = message;
29
+ let itemDetails = '';
30
+
31
+ // Extract meaningful information from the data object if available
32
+ if (data) {
33
+ // Common identifiers that might be present in data objects
34
+ const identifiers = [
35
+ 'name',
36
+ 'label',
37
+ 'title',
38
+ 'email',
39
+ 'username',
40
+ 'id',
41
+ 'code',
42
+ 'reference',
43
+ 'description',
44
+ ];
45
+
46
+ // Find the first available identifier
47
+ for (const id of identifiers) {
48
+ if (
49
+ data[id] &&
50
+ typeof data[id] === 'string' &&
51
+ data[id].trim() !== ''
52
+ ) {
53
+ itemDetails = data[id];
54
+ break;
55
+ }
56
+ }
57
+
58
+ // If we found an identifier, enhance the message
59
+ if (itemDetails && !message.includes(itemDetails)) {
60
+ // If the message already contains a question mark, add the details before it
61
+ if (message.includes('?')) {
62
+ enhancedMessage = message.replace('?', `"${itemDetails}"?`);
63
+ } else {
64
+ // Otherwise, append the details
65
+ enhancedMessage = `${message} "${itemDetails}"`;
66
+ }
67
+ }
68
+ }
69
+
70
+ // Configure SweetAlert2 options
71
+ const swalOptions = {
72
+ title: title,
73
+ html: enhancedMessage,
74
+ icon: 'question',
75
+ showCancelButton: true,
76
+ confirmButtonText: confirmLabel,
77
+ cancelButtonText: cancelLabel,
78
+ confirmButtonColor: 'var(--primary-color, #4f46e5)',
79
+ cancelButtonColor: '#6b7280',
80
+ allowOutsideClick: true,
81
+ allowEscapeKey: true,
82
+ reverseButtons: true,
83
+ focusCancel: false,
84
+ buttonsStyling: true,
85
+ };
86
+
87
+ // Show SweetAlert2 dialog
88
+ return Swal.fire(swalOptions).then((result) => {
89
+ if (result.isConfirmed) {
90
+ onConfirm();
91
+ } else if (result.dismiss === Swal.DismissReason.cancel) {
92
+ onCancel();
93
+ }
94
+ });
95
+ };
96
+
97
+ export default showConfirmDialog;
@@ -1496,6 +1496,8 @@ function GenericIndex({
1496
1496
 
1497
1497
  // Add a ref to store the latest rowsSelected value
1498
1498
  const rowsSelectedRef = useRef({});
1499
+ // Create a ref to track if we've already processed active filter combinations
1500
+ const activeFilterRef = useRef(null);
1499
1501
 
1500
1502
  // Update the ref whenever rowsSelected changes
1501
1503
  useEffect(() => {
@@ -1847,9 +1849,6 @@ function GenericIndex({
1847
1849
  return;
1848
1850
  }
1849
1851
 
1850
- // Create a ref to track if we've already processed this combination
1851
- const activeFilterRef = useRef(null);
1852
-
1853
1852
  // Find the active filter and its child
1854
1853
  const activeFilter = subnav?.find((filter) => {
1855
1854
  if (filter.isParent) {