@visns-studio/visns-components 5.6.8 → 5.6.10
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 +1 -1
- package/src/components/cms/sorting/Item.jsx +24 -18
- package/src/components/cms/sorting/List.jsx +3 -1
- package/src/components/cms/sorting/styles/Item.module.scss +38 -0
- package/src/components/cms/sorting/styles/List.module.scss +74 -0
- package/src/components/crm/TableFilter.jsx +287 -102
- package/src/components/crm/auth/TwoFactorAuth.jsx +7 -9
- package/src/components/crm/auth/styles/TwoFactorAuth.module.scss +154 -25
- package/src/components/crm/examples/FilterExample.jsx +207 -0
- package/src/components/crm/examples/README.md +113 -0
- package/src/components/crm/generic/GenericFormBuilder.jsx +21 -3
- package/src/components/crm/generic/GenericIndex.jsx +244 -87
- package/src/components/crm/generic/styles/GenericFormBuilder.module.scss +57 -29
- package/src/components/crm/generic/styles/GenericSort.module.scss +34 -12
- package/src/components/crm/generic/styles/ReportForm.module.scss +150 -0
- package/src/components/crm/sorting/Item.jsx +22 -18
- package/src/components/crm/sorting/styles/Item.module.scss +31 -10
- package/src/components/crm/sorting/styles/List.module.scss +21 -9
- package/src/components/crm/styles/TableFilter.module.scss +121 -23
|
@@ -7,6 +7,7 @@ import { saveAs } from 'file-saver';
|
|
|
7
7
|
import _ from 'lodash';
|
|
8
8
|
import parse from 'html-react-parser';
|
|
9
9
|
import moment from 'moment';
|
|
10
|
+
import { CloudDownload } from 'akar-icons';
|
|
10
11
|
|
|
11
12
|
import CustomFetch from '../Fetch';
|
|
12
13
|
import Download from '../Download';
|
|
@@ -15,6 +16,7 @@ import Table from '../DataGrid';
|
|
|
15
16
|
import TableFilter from '../TableFilter';
|
|
16
17
|
|
|
17
18
|
import styles from './styles/GenericIndex.module.scss';
|
|
19
|
+
import reportStyles from './styles/ReportForm.module.scss';
|
|
18
20
|
|
|
19
21
|
function useWindowHeight() {
|
|
20
22
|
const [windowHeight, setWindowHeight] = useState(window.innerHeight);
|
|
@@ -33,7 +35,7 @@ function useConfig(setting, tabs, filters, setRowsSelected, tableSetting) {
|
|
|
33
35
|
const [subnav, setSubnav] = useState(filters || []);
|
|
34
36
|
|
|
35
37
|
useEffect(() => {
|
|
36
|
-
|
|
38
|
+
const newConfig = {
|
|
37
39
|
export: setting.export || {},
|
|
38
40
|
ajaxSetting: setting.ajaxSetting,
|
|
39
41
|
form: setting.form,
|
|
@@ -43,28 +45,142 @@ function useConfig(setting, tabs, filters, setRowsSelected, tableSetting) {
|
|
|
43
45
|
style: setting.style || {},
|
|
44
46
|
tableSetting,
|
|
45
47
|
type: setting.type ? setting.type : 'table',
|
|
46
|
-
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
setConfig(newConfig);
|
|
47
51
|
setSubnav(filters);
|
|
48
52
|
}, [setting, filters, setRowsSelected, tableSetting]);
|
|
49
53
|
|
|
50
54
|
useEffect(() => {
|
|
51
55
|
if (tabs?.length > 0 && subnav) {
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
// Find active item (direct or child)
|
|
57
|
+
const findActiveItem = (items) => {
|
|
58
|
+
// First check direct items that are not parents
|
|
59
|
+
const directActive = items.find(
|
|
60
|
+
(item) => item.show === true && !item.isParent
|
|
61
|
+
);
|
|
62
|
+
if (directActive) {
|
|
63
|
+
return { item: directActive, isChild: false };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Then check children of parent items
|
|
67
|
+
for (const item of items) {
|
|
68
|
+
if (
|
|
69
|
+
item.isParent &&
|
|
70
|
+
item.children &&
|
|
71
|
+
item.children.length > 0
|
|
72
|
+
) {
|
|
73
|
+
const activeChild = item.children.find(
|
|
74
|
+
(child) => child.show === true
|
|
75
|
+
);
|
|
76
|
+
if (activeChild) {
|
|
77
|
+
return {
|
|
78
|
+
item: activeChild,
|
|
79
|
+
isChild: true,
|
|
80
|
+
parent: item,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Finally, check for active parent items
|
|
87
|
+
const activeParent = items.find(
|
|
88
|
+
(item) => item.show === true && item.isParent
|
|
89
|
+
);
|
|
90
|
+
if (activeParent) {
|
|
91
|
+
// If parent is active but no child is active, activate the first child
|
|
92
|
+
if (
|
|
93
|
+
activeParent.children &&
|
|
94
|
+
activeParent.children.length > 0
|
|
95
|
+
) {
|
|
96
|
+
const firstChild = activeParent.children[0];
|
|
97
|
+
return {
|
|
98
|
+
item: firstChild,
|
|
99
|
+
isChild: true,
|
|
100
|
+
parent: activeParent,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { item: activeParent, isChild: false };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return null;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const activeItemResult = findActiveItem(subnav);
|
|
111
|
+
|
|
112
|
+
if (activeItemResult) {
|
|
113
|
+
const activeItem = activeItemResult.item;
|
|
114
|
+
|
|
115
|
+
// Find the tab config for this item
|
|
116
|
+
const activeTabConfig = tabs.find(
|
|
117
|
+
(t) => t.id === activeItem.id
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
if (activeTabConfig) {
|
|
121
|
+
// We found a matching tab config, use it
|
|
122
|
+
const updatedConfig = {
|
|
123
|
+
...config,
|
|
124
|
+
id: activeTabConfig.id,
|
|
125
|
+
ajaxSetting: activeTabConfig.ajaxSetting,
|
|
126
|
+
form: activeTabConfig.form,
|
|
127
|
+
columns: activeTabConfig.columns,
|
|
128
|
+
settings: activeTabConfig.settings,
|
|
129
|
+
// Preserve the style from the original config or use the tab config's style
|
|
130
|
+
style:
|
|
131
|
+
config.style ||
|
|
132
|
+
activeTabConfig.style ||
|
|
133
|
+
setting.style ||
|
|
134
|
+
{},
|
|
135
|
+
type: activeTabConfig.type
|
|
136
|
+
? activeTabConfig.type
|
|
137
|
+
: 'table',
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
setConfig(updatedConfig);
|
|
141
|
+
} else if (activeItemResult.isChild) {
|
|
142
|
+
// If this is a child item but we couldn't find a tab config,
|
|
143
|
+
// try to use the base config but update the filter
|
|
144
|
+
|
|
145
|
+
// Create a new config based on the base settings
|
|
146
|
+
const baseConfig = {
|
|
147
|
+
export: setting.export || {},
|
|
148
|
+
ajaxSetting: setting.ajaxSetting
|
|
149
|
+
? { ...setting.ajaxSetting }
|
|
150
|
+
: undefined,
|
|
151
|
+
form: setting.form,
|
|
152
|
+
columns: setting.columns,
|
|
153
|
+
setRowsSelected,
|
|
154
|
+
settings: setting.settings,
|
|
155
|
+
// Make sure we have a style property
|
|
156
|
+
style: config.style || setting.style || {},
|
|
157
|
+
tableSetting,
|
|
158
|
+
type: setting.type ? setting.type : 'table',
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Add the filter for the active child
|
|
162
|
+
if (
|
|
163
|
+
baseConfig.ajaxSetting &&
|
|
164
|
+
baseConfig.ajaxSetting.where
|
|
165
|
+
) {
|
|
166
|
+
// Remove any existing filter with this ID
|
|
167
|
+
baseConfig.ajaxSetting.where =
|
|
168
|
+
baseConfig.ajaxSetting.where.filter(
|
|
169
|
+
(w) => w.id !== activeItem.id
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// Add the new filter
|
|
173
|
+
baseConfig.ajaxSetting.where.push({
|
|
174
|
+
id: activeItem.id,
|
|
175
|
+
value: activeItem.value || '',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setConfig(baseConfig);
|
|
180
|
+
}
|
|
65
181
|
}
|
|
66
182
|
}
|
|
67
|
-
}, [subnav, tabs]);
|
|
183
|
+
}, [subnav, tabs, config, setting, setRowsSelected, tableSetting]);
|
|
68
184
|
|
|
69
185
|
return { config, setConfig, subnav, setSubnav };
|
|
70
186
|
}
|
|
@@ -85,7 +201,7 @@ const ReportForm = ({ config, userProfile }) => {
|
|
|
85
201
|
setFormData((prevData) => ({ ...prevData, [id]: date }));
|
|
86
202
|
};
|
|
87
203
|
|
|
88
|
-
const handleChangeSelect = (inputValue,
|
|
204
|
+
const handleChangeSelect = (inputValue, _, id) => {
|
|
89
205
|
setFormData((prevData) => ({ ...prevData, [id]: inputValue }));
|
|
90
206
|
};
|
|
91
207
|
|
|
@@ -106,6 +222,8 @@ const ReportForm = ({ config, userProfile }) => {
|
|
|
106
222
|
const errorMessage = `Please fill in a value for the following field(s): ${fieldNames}.`;
|
|
107
223
|
toast.error(errorMessage);
|
|
108
224
|
} else {
|
|
225
|
+
toast.info('Preparing your export...');
|
|
226
|
+
|
|
109
227
|
const res = await Download(
|
|
110
228
|
config.form.url,
|
|
111
229
|
config.form.method,
|
|
@@ -119,6 +237,7 @@ const ReportForm = ({ config, userProfile }) => {
|
|
|
119
237
|
if (res.data && res.data instanceof Blob) {
|
|
120
238
|
const fileName = `${config.form.filename}`;
|
|
121
239
|
saveAs(res.data, fileName);
|
|
240
|
+
toast.success('Export completed successfully');
|
|
122
241
|
} else {
|
|
123
242
|
// Handle the case where the response is not a Blob
|
|
124
243
|
toast.error('Invalid file format received.');
|
|
@@ -127,6 +246,7 @@ const ReportForm = ({ config, userProfile }) => {
|
|
|
127
246
|
}
|
|
128
247
|
} catch (err) {
|
|
129
248
|
console.error(err);
|
|
249
|
+
toast.error('An error occurred during export');
|
|
130
250
|
}
|
|
131
251
|
};
|
|
132
252
|
|
|
@@ -138,36 +258,63 @@ const ReportForm = ({ config, userProfile }) => {
|
|
|
138
258
|
setFormData(tmpForm);
|
|
139
259
|
}, [config.form?.filters]);
|
|
140
260
|
|
|
261
|
+
// Determine if the form has a title
|
|
262
|
+
const formTitle = config.form?.title || 'Export Report';
|
|
263
|
+
const formDescription =
|
|
264
|
+
config.form?.description || 'Select your export criteria below.';
|
|
265
|
+
|
|
141
266
|
return (
|
|
142
|
-
<div className=
|
|
143
|
-
<form className=
|
|
267
|
+
<div className={reportStyles.reportFormContainer}>
|
|
268
|
+
<form className={reportStyles.reportForm}>
|
|
269
|
+
<h2 className={reportStyles.formTitle}>{formTitle}</h2>
|
|
270
|
+
<p className={reportStyles.formDescription}>
|
|
271
|
+
{formDescription}
|
|
272
|
+
</p>
|
|
273
|
+
|
|
144
274
|
{config.form?.filters.map((item, key) => (
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
275
|
+
<div
|
|
276
|
+
key={`filter-container-${key}`}
|
|
277
|
+
className={`${reportStyles.formField} ${
|
|
278
|
+
item.fullWidth ? reportStyles.fullWidthField : ''
|
|
279
|
+
}`}
|
|
280
|
+
>
|
|
281
|
+
<Field
|
|
282
|
+
api={userProfile.settings.api}
|
|
283
|
+
autocompleteCallback={() => {}}
|
|
284
|
+
childDropdownCallback={() => {}}
|
|
285
|
+
fetchData={() => {}}
|
|
286
|
+
formData={formData}
|
|
287
|
+
inputClass={''}
|
|
288
|
+
inputValue={formData[item.id]}
|
|
289
|
+
key={`filter-fields-${key}`}
|
|
290
|
+
mapbox={{}}
|
|
291
|
+
onChange={handleChange}
|
|
292
|
+
onChangeCheckbox={() => {}}
|
|
293
|
+
onChangeDate={handleChangeDate}
|
|
294
|
+
onChangeNumberFormat={() => {}}
|
|
295
|
+
onChangeRicheditor={() => {}}
|
|
296
|
+
onChangeSelect={handleChangeSelect}
|
|
297
|
+
onChangeToggle={() => {}}
|
|
298
|
+
settings={item}
|
|
299
|
+
setFormData={setFormData}
|
|
300
|
+
style={userProfile.settings.style}
|
|
301
|
+
uploadProgress={0}
|
|
302
|
+
userProfile={userProfile}
|
|
303
|
+
/>
|
|
304
|
+
</div>
|
|
168
305
|
))}
|
|
169
|
-
|
|
170
|
-
|
|
306
|
+
|
|
307
|
+
<div className={reportStyles.formActions}>
|
|
308
|
+
<button
|
|
309
|
+
className={reportStyles.exportButton}
|
|
310
|
+
onClick={handleExport}
|
|
311
|
+
type="button"
|
|
312
|
+
>
|
|
313
|
+
<CloudDownload
|
|
314
|
+
strokeWidth={2}
|
|
315
|
+
size={18}
|
|
316
|
+
style={{ marginRight: '8px' }}
|
|
317
|
+
/>{' '}
|
|
171
318
|
Export
|
|
172
319
|
</button>
|
|
173
320
|
</div>
|
|
@@ -184,7 +331,7 @@ function GenericIndex({
|
|
|
184
331
|
userProfile,
|
|
185
332
|
}) {
|
|
186
333
|
const gridRef = useRef(null);
|
|
187
|
-
|
|
334
|
+
useParams(); // Using router params if needed in the future
|
|
188
335
|
const [rowsSelected, setRowsSelected] = useState({});
|
|
189
336
|
const [tableData, setTableData] = useState([]);
|
|
190
337
|
const [tableInfo, setTableInfo] = useState({});
|
|
@@ -208,12 +355,18 @@ function GenericIndex({
|
|
|
208
355
|
|
|
209
356
|
const handleCustomAction = async () => {
|
|
210
357
|
try {
|
|
211
|
-
|
|
212
|
-
|
|
358
|
+
// Get the custom action configuration
|
|
359
|
+
const customActionConfig = setting?.functions?.customAction
|
|
213
360
|
? setting.functions.customAction
|
|
214
361
|
: config.form.functions.customAction;
|
|
362
|
+
|
|
363
|
+
if (customActionConfig) {
|
|
364
|
+
// Implementation will be added when needed
|
|
365
|
+
console.log('Custom action triggered', customActionConfig);
|
|
366
|
+
}
|
|
215
367
|
} catch (err) {
|
|
216
368
|
console.error(err);
|
|
369
|
+
toast.error('An error occurred while performing the custom action');
|
|
217
370
|
}
|
|
218
371
|
};
|
|
219
372
|
|
|
@@ -340,55 +493,43 @@ function GenericIndex({
|
|
|
340
493
|
|
|
341
494
|
const renderTable = useCallback(() => {
|
|
342
495
|
const isConfigValid = (config) => {
|
|
496
|
+
// Check if config exists and has the required properties
|
|
497
|
+
if (!config) return false;
|
|
498
|
+
|
|
343
499
|
return (
|
|
344
500
|
config.ajaxSetting &&
|
|
345
501
|
config.form &&
|
|
346
502
|
config.columns &&
|
|
347
|
-
config.settings
|
|
503
|
+
config.settings !== undefined // Allow empty settings array
|
|
348
504
|
);
|
|
349
505
|
};
|
|
350
506
|
|
|
351
|
-
const renderTableComponent = () =>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
setConfig={setConfig}
|
|
358
|
-
setTableData={setTableData}
|
|
359
|
-
setTotal={setTotal}
|
|
360
|
-
style={userProfile?.settings?.style || {}}
|
|
361
|
-
userProfile={userProfile}
|
|
362
|
-
/>
|
|
363
|
-
);
|
|
364
|
-
|
|
365
|
-
if (subnav) {
|
|
366
|
-
// Find the active subnav item with show: true
|
|
367
|
-
const activeSubnav = subnav.find((item) => item.show === true);
|
|
368
|
-
|
|
369
|
-
// Check if the config.id matches the active subnav id
|
|
370
|
-
if (
|
|
371
|
-
activeSubnav &&
|
|
372
|
-
activeSubnav.id === config.id &&
|
|
373
|
-
isConfigValid(config)
|
|
374
|
-
) {
|
|
375
|
-
return renderTableComponent();
|
|
376
|
-
}
|
|
507
|
+
const renderTableComponent = () => {
|
|
508
|
+
// Ensure config has a style property
|
|
509
|
+
const configWithStyle = {
|
|
510
|
+
...config,
|
|
511
|
+
style: config.style || userProfile?.settings?.style || {},
|
|
512
|
+
};
|
|
377
513
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
514
|
+
return (
|
|
515
|
+
<Table
|
|
516
|
+
{...configWithStyle}
|
|
517
|
+
ref={gridRef}
|
|
518
|
+
hoverColor={configWithStyle.style?.hoverColor}
|
|
519
|
+
gridHeight={windowHeight * 0.65}
|
|
520
|
+
setConfig={setConfig}
|
|
521
|
+
setTableData={setTableData}
|
|
522
|
+
setTotal={setTotal}
|
|
523
|
+
style={userProfile?.settings?.style || {}}
|
|
524
|
+
userProfile={userProfile}
|
|
525
|
+
/>
|
|
382
526
|
);
|
|
527
|
+
};
|
|
383
528
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
parseInt(w.value) === parseInt(activeAltSubNav?.value)
|
|
389
|
-
) || false;
|
|
390
|
-
|
|
391
|
-
if (isConfigValid(config) && activeTabExist) {
|
|
529
|
+
if (subnav) {
|
|
530
|
+
// Simply check if the config is valid - we've already set up the config
|
|
531
|
+
// in the useConfig hook based on the active filter
|
|
532
|
+
if (isConfigValid(config)) {
|
|
392
533
|
return renderTableComponent();
|
|
393
534
|
}
|
|
394
535
|
} else if (isConfigValid(config)) {
|
|
@@ -409,6 +550,20 @@ function GenericIndex({
|
|
|
409
550
|
}
|
|
410
551
|
}, [config, renderTable]);
|
|
411
552
|
|
|
553
|
+
// Custom handler for filter changes
|
|
554
|
+
const handleFilterChange = useCallback(
|
|
555
|
+
(newFilters, newSettings) => {
|
|
556
|
+
// Update the filters
|
|
557
|
+
setSubnav(newFilters);
|
|
558
|
+
|
|
559
|
+
// Update the settings
|
|
560
|
+
if (newSettings) {
|
|
561
|
+
setConfig(newSettings);
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
[setSubnav, setConfig]
|
|
565
|
+
);
|
|
566
|
+
|
|
412
567
|
const renderContent = useCallback(() => {
|
|
413
568
|
if (subnav?.length > 0) {
|
|
414
569
|
return (
|
|
@@ -422,6 +577,7 @@ function GenericIndex({
|
|
|
422
577
|
setFilters={setSubnav}
|
|
423
578
|
setSettings={setConfig}
|
|
424
579
|
type={layout}
|
|
580
|
+
onFilterChange={handleFilterChange}
|
|
425
581
|
/>
|
|
426
582
|
</div>
|
|
427
583
|
<div className={styles.tabcontent__main}>
|
|
@@ -443,6 +599,7 @@ function GenericIndex({
|
|
|
443
599
|
setFilters={setSubnav}
|
|
444
600
|
setSettings={setConfig}
|
|
445
601
|
type={layout}
|
|
602
|
+
onFilterChange={handleFilterChange}
|
|
446
603
|
/>
|
|
447
604
|
</div>
|
|
448
605
|
<div className={styles.grid__subcontent}>
|
|
@@ -459,7 +616,7 @@ function GenericIndex({
|
|
|
459
616
|
</div>
|
|
460
617
|
);
|
|
461
618
|
}
|
|
462
|
-
}, [layout, subnav, setSubnav, setConfig, renderTable]);
|
|
619
|
+
}, [layout, subnav, setSubnav, setConfig, renderTable, handleFilterChange]);
|
|
463
620
|
|
|
464
621
|
useEffect(() => {
|
|
465
622
|
if (setting.page?.tableInfo?.hasOwnProperty('url')) {
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
&__subrow {
|
|
23
23
|
width: 100%;
|
|
24
24
|
display: flex;
|
|
25
|
-
flex-wrap:
|
|
25
|
+
flex-wrap: nowrap;
|
|
26
26
|
height: auto;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
&__subnav {
|
|
30
|
-
flex:
|
|
30
|
+
flex: 0 0 20%;
|
|
31
31
|
background: white;
|
|
32
32
|
border-radius: var(--br);
|
|
33
33
|
box-sizing: border-box;
|
|
34
|
-
padding:
|
|
35
|
-
margin: 8px 0;
|
|
34
|
+
padding: 8px;
|
|
35
|
+
margin: 8px 8px 8px 0;
|
|
36
36
|
height: auto;
|
|
37
|
-
box-shadow: 0
|
|
37
|
+
box-shadow: 0 5px 15px rgba(var(--primary-rgb), 0.05);
|
|
38
38
|
|
|
39
39
|
> ul {
|
|
40
40
|
width: 100%;
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
&__subcontent {
|
|
117
|
-
flex: 0 1
|
|
117
|
+
flex: 0 1 80%;
|
|
118
118
|
background: white;
|
|
119
119
|
border-radius: var(--br);
|
|
120
120
|
border: 1px solid var(--border-color);
|
|
@@ -138,14 +138,14 @@
|
|
|
138
138
|
display: block;
|
|
139
139
|
background: var(--border-color);
|
|
140
140
|
box-sizing: border-box;
|
|
141
|
-
padding: 10px
|
|
142
|
-
border-
|
|
143
|
-
border-top-right-radius: var(--br);
|
|
141
|
+
padding: 10px 15px;
|
|
142
|
+
border-radius: var(--br);
|
|
144
143
|
margin-bottom: 0;
|
|
145
|
-
font-weight:
|
|
144
|
+
font-weight: 600;
|
|
146
145
|
text-align: center;
|
|
147
146
|
color: var(--paragraph-color);
|
|
148
147
|
position: relative;
|
|
148
|
+
font-size: 0.95rem;
|
|
149
149
|
|
|
150
150
|
span {
|
|
151
151
|
font-weight: 700;
|
|
@@ -257,7 +257,7 @@ input[type='file']:hover {
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
.formBuilderItem {
|
|
260
|
-
width:
|
|
260
|
+
width: 50%;
|
|
261
261
|
padding: 0.35em;
|
|
262
262
|
position: relative;
|
|
263
263
|
box-sizing: border-box;
|
|
@@ -318,7 +318,7 @@ input[type='file']:hover {
|
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
.qtrBuilderItem {
|
|
321
|
-
flex-basis:
|
|
321
|
+
flex-basis: 50%;
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
.halfBuilderItem {
|
|
@@ -871,45 +871,73 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
871
871
|
.sortableListContainer {
|
|
872
872
|
max-height: 800px; /* Optional for scrollable content */
|
|
873
873
|
overflow-y: auto;
|
|
874
|
+
padding: 0.75rem;
|
|
875
|
+
border-radius: var(--br);
|
|
876
|
+
background-color: rgba(var(--primary-rgb), 0.02);
|
|
874
877
|
}
|
|
875
878
|
|
|
876
879
|
.dragitem {
|
|
877
880
|
list-style: none;
|
|
878
881
|
display: flex;
|
|
879
|
-
justify-content:
|
|
882
|
+
justify-content: flex-start;
|
|
880
883
|
align-items: center;
|
|
881
884
|
flex-wrap: wrap;
|
|
882
|
-
border-radius:
|
|
885
|
+
border-radius: 6px;
|
|
883
886
|
border: 1px solid rgba(var(--primary-rgb), 0.2);
|
|
884
|
-
box-shadow: 0px 0px
|
|
885
|
-
padding:
|
|
887
|
+
box-shadow: 0px 0px 15px rgba(var(--primary-rgb), 0.15);
|
|
888
|
+
padding: 0.8rem 5rem 0.8rem 2rem;
|
|
886
889
|
box-sizing: border-box;
|
|
887
890
|
cursor: grab;
|
|
888
891
|
list-style: none;
|
|
889
892
|
color: var(--paragraph-color);
|
|
893
|
+
font-size: 0.9rem;
|
|
894
|
+
font-weight: 500;
|
|
890
895
|
|
|
891
|
-
svg {
|
|
896
|
+
> svg:first-child {
|
|
892
897
|
width: 100%;
|
|
893
898
|
max-width: 18px;
|
|
894
899
|
position: absolute;
|
|
895
|
-
left:
|
|
896
|
-
top:
|
|
900
|
+
left: 6px;
|
|
901
|
+
top: 50%;
|
|
902
|
+
transform: translateY(-50%);
|
|
903
|
+
color: var(--primary-color);
|
|
897
904
|
}
|
|
898
905
|
|
|
899
|
-
.
|
|
900
|
-
width: 100%;
|
|
901
|
-
max-width: 18px;
|
|
906
|
+
.actionIcons {
|
|
902
907
|
position: absolute;
|
|
903
|
-
|
|
904
|
-
top:
|
|
908
|
+
right: 10px;
|
|
909
|
+
top: 50%;
|
|
910
|
+
transform: translateY(-50%);
|
|
911
|
+
display: flex;
|
|
912
|
+
gap: 12px;
|
|
913
|
+
align-items: center;
|
|
914
|
+
z-index: 10;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
.edit {
|
|
918
|
+
width: 22px;
|
|
919
|
+
height: 22px;
|
|
920
|
+
color: var(--primary-color);
|
|
921
|
+
transition: color 0.2s ease;
|
|
922
|
+
cursor: pointer;
|
|
923
|
+
display: block;
|
|
924
|
+
|
|
925
|
+
&:hover {
|
|
926
|
+
color: var(--secondary-color);
|
|
927
|
+
}
|
|
905
928
|
}
|
|
906
929
|
|
|
907
930
|
.delete {
|
|
908
|
-
width:
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
931
|
+
width: 22px;
|
|
932
|
+
height: 22px;
|
|
933
|
+
color: var(--primary-color);
|
|
934
|
+
transition: color 0.2s ease;
|
|
935
|
+
cursor: pointer;
|
|
936
|
+
display: block;
|
|
937
|
+
|
|
938
|
+
&:hover {
|
|
939
|
+
color: #d32f2f;
|
|
940
|
+
}
|
|
913
941
|
}
|
|
914
942
|
|
|
915
943
|
.sortimg {
|
|
@@ -124,28 +124,50 @@
|
|
|
124
124
|
color: var(--paragraph-color);
|
|
125
125
|
font-size: 0.8rem;
|
|
126
126
|
|
|
127
|
-
svg {
|
|
127
|
+
> svg:first-child {
|
|
128
128
|
width: 100%;
|
|
129
129
|
max-width: 16px;
|
|
130
130
|
position: absolute;
|
|
131
131
|
left: 4px;
|
|
132
|
-
top:
|
|
132
|
+
top: 50%;
|
|
133
|
+
transform: translateY(-50%);
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
.
|
|
136
|
-
width: 100%;
|
|
137
|
-
max-width: 16px;
|
|
136
|
+
.actionIcons {
|
|
138
137
|
position: absolute;
|
|
139
|
-
|
|
140
|
-
top:
|
|
138
|
+
right: 10px;
|
|
139
|
+
top: 50%;
|
|
140
|
+
transform: translateY(-50%);
|
|
141
|
+
display: flex;
|
|
142
|
+
gap: 12px;
|
|
143
|
+
align-items: center;
|
|
144
|
+
z-index: 10;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.pencil-edit {
|
|
148
|
+
width: 22px;
|
|
149
|
+
height: 22px;
|
|
150
|
+
color: var(--primary-color);
|
|
151
|
+
transition: color 0.2s ease;
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
display: block;
|
|
154
|
+
|
|
155
|
+
&:hover {
|
|
156
|
+
color: var(--secondary-color);
|
|
157
|
+
}
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
.trash-delete {
|
|
144
|
-
width:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
161
|
+
width: 22px;
|
|
162
|
+
height: 22px;
|
|
163
|
+
color: var(--primary-color);
|
|
164
|
+
transition: color 0.2s ease;
|
|
165
|
+
cursor: pointer;
|
|
166
|
+
display: block;
|
|
167
|
+
|
|
168
|
+
&:hover {
|
|
169
|
+
color: #d32f2f;
|
|
170
|
+
}
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
.sortimg {
|