@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
|
@@ -265,15 +265,11 @@ const TwoFactorAuth = ({ logo, setSystemAuth, setUserProfile }) => {
|
|
|
265
265
|
alt="CRM"
|
|
266
266
|
className={styles.loginlogo}
|
|
267
267
|
/>
|
|
268
|
-
<
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
Please enter the 6-digit code from your
|
|
274
|
-
authenticator app.
|
|
275
|
-
</p>
|
|
276
|
-
</div>
|
|
268
|
+
<h2>Two-Factor Authentication</h2>
|
|
269
|
+
<p className={styles.instructions}>
|
|
270
|
+
Please enter the 6-digit code from your
|
|
271
|
+
authenticator app.
|
|
272
|
+
</p>
|
|
277
273
|
<div
|
|
278
274
|
className={`${styles.formItem} ${styles.fwItem}`}
|
|
279
275
|
>
|
|
@@ -308,6 +304,7 @@ const TwoFactorAuth = ({ logo, setSystemAuth, setUserProfile }) => {
|
|
|
308
304
|
className={styles.btn}
|
|
309
305
|
type="submit"
|
|
310
306
|
disabled={isLoading}
|
|
307
|
+
tabIndex="2"
|
|
311
308
|
>
|
|
312
309
|
{isLoading ? 'Verifying...' : 'Verify'}
|
|
313
310
|
</button>
|
|
@@ -330,6 +327,7 @@ const TwoFactorAuth = ({ logo, setSystemAuth, setUserProfile }) => {
|
|
|
330
327
|
e.preventDefault();
|
|
331
328
|
navigate('/login');
|
|
332
329
|
}}
|
|
330
|
+
tabIndex="3"
|
|
333
331
|
>
|
|
334
332
|
Back to Login
|
|
335
333
|
</a>
|
|
@@ -1,47 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
.formItem {
|
|
2
|
+
width: 100%;
|
|
3
|
+
position: relative;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
margin-bottom: 1rem;
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
.fi__label {
|
|
8
|
+
position: relative;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.fi__span {
|
|
14
|
+
position: absolute;
|
|
15
|
+
transition: all 200ms;
|
|
16
|
+
opacity: 0.7;
|
|
17
|
+
left: 0;
|
|
18
|
+
transform-origin: top left;
|
|
19
|
+
cursor: text;
|
|
20
|
+
padding: 0 1rem;
|
|
21
|
+
font-size: 0.9rem;
|
|
22
|
+
color: #6b7280;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
input[name='verificationCode'] {
|
|
26
|
+
letter-spacing: 0.25rem;
|
|
27
|
+
font-size: 1.2rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
11
30
|
}
|
|
12
31
|
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
.fwItem,
|
|
33
|
+
.fwBuilderItem {
|
|
34
|
+
grid-column: 1 / -1;
|
|
35
|
+
width: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.lastItem .btn {
|
|
39
|
+
width: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.loginlogo {
|
|
43
|
+
display: block;
|
|
44
|
+
width: 100%;
|
|
45
|
+
max-width: 150px;
|
|
46
|
+
height: auto;
|
|
47
|
+
margin: 0 auto;
|
|
48
|
+
padding-bottom: 1.5rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.logincontainer {
|
|
52
|
+
width: 100%;
|
|
53
|
+
min-height: 100vh;
|
|
54
|
+
display: grid;
|
|
55
|
+
place-items: center;
|
|
16
56
|
padding: 1rem;
|
|
57
|
+
background-color: #f9fafb;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.login {
|
|
61
|
+
width: 28rem;
|
|
62
|
+
padding: 2rem;
|
|
17
63
|
margin: 0;
|
|
18
64
|
display: grid;
|
|
19
65
|
grid-template-columns: 1fr;
|
|
20
|
-
gap:
|
|
66
|
+
gap: 1rem;
|
|
67
|
+
background-color: white;
|
|
68
|
+
border-radius: 0.75rem;
|
|
69
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
70
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
71
|
+
|
|
72
|
+
> .formItem {
|
|
73
|
+
padding: 0;
|
|
74
|
+
|
|
75
|
+
small {
|
|
76
|
+
position: absolute;
|
|
77
|
+
width: 18px;
|
|
78
|
+
height: 18px;
|
|
79
|
+
right: 14px;
|
|
80
|
+
top: 14px;
|
|
81
|
+
opacity: 0.4;
|
|
82
|
+
color: #6b7280;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
21
85
|
|
|
22
86
|
h2 {
|
|
23
87
|
text-align: center;
|
|
24
|
-
margin: 0;
|
|
25
|
-
color:
|
|
88
|
+
margin-bottom: 0.5rem;
|
|
89
|
+
color: #111827;
|
|
90
|
+
font-weight: 600;
|
|
91
|
+
font-size: 1.5rem;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.instructions {
|
|
96
|
+
text-align: center;
|
|
97
|
+
margin: 0 0 1.5rem;
|
|
98
|
+
color: var(--paragraph-color, #6b7280);
|
|
99
|
+
font-size: 0.95rem;
|
|
100
|
+
line-height: 1.4;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.forgotten span {
|
|
104
|
+
display: block;
|
|
105
|
+
text-align: center;
|
|
106
|
+
color: #6b7280;
|
|
107
|
+
padding: 1rem 0;
|
|
108
|
+
font-size: 0.875rem;
|
|
109
|
+
|
|
110
|
+
a {
|
|
111
|
+
color: var(--primary-color, #4f46e5);
|
|
112
|
+
text-decoration: none;
|
|
26
113
|
font-weight: 500;
|
|
114
|
+
|
|
115
|
+
&:hover {
|
|
116
|
+
text-decoration: underline;
|
|
117
|
+
}
|
|
27
118
|
}
|
|
28
119
|
}
|
|
29
120
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
121
|
+
.lcontainer {
|
|
122
|
+
min-height: 100vh;
|
|
123
|
+
display: flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
background-color: #f9fafb;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.lwrap {
|
|
130
|
+
display: grid;
|
|
131
|
+
grid-template-columns: 1fr;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.btn {
|
|
135
|
+
width: max-content;
|
|
136
|
+
display: inline-block;
|
|
34
137
|
position: relative;
|
|
35
|
-
|
|
36
|
-
|
|
138
|
+
padding: 0.75rem 1rem;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
font-size: 0.875rem;
|
|
141
|
+
font-weight: 500;
|
|
142
|
+
color: white;
|
|
143
|
+
text-decoration: none;
|
|
144
|
+
overflow: hidden;
|
|
145
|
+
background: var(--primary-color, #4f46e5);
|
|
146
|
+
border: 1px solid var(--primary-color, #4f46e5);
|
|
147
|
+
border-radius: 0.5rem;
|
|
148
|
+
outline: none;
|
|
149
|
+
transition: all 0.2s ease;
|
|
150
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
37
151
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
152
|
+
&:hover {
|
|
153
|
+
background: #4338ca;
|
|
154
|
+
border-color: #4338ca;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:focus {
|
|
158
|
+
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.25);
|
|
42
159
|
}
|
|
43
160
|
}
|
|
44
161
|
|
|
162
|
+
input:not(:placeholder-shown) + .fi__span,
|
|
163
|
+
textarea:not(:placeholder-shown) + .fi__span,
|
|
164
|
+
select:not(:placeholder-shown) + .fi__span {
|
|
165
|
+
transform: translateY(-135%) translateX(10px) scale(0.85);
|
|
166
|
+
opacity: 1;
|
|
167
|
+
padding: 0;
|
|
168
|
+
background: white;
|
|
169
|
+
font-weight: 500;
|
|
170
|
+
transition: all 0.3s ease;
|
|
171
|
+
color: var(--primary-color, #4f46e5) !important;
|
|
172
|
+
}
|
|
173
|
+
|
|
45
174
|
.rememberMeIndicator {
|
|
46
175
|
display: flex;
|
|
47
176
|
align-items: center;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import TableFilter from '../TableFilter';
|
|
3
|
+
|
|
4
|
+
const FilterExample = () => {
|
|
5
|
+
// Initial filter structure with parent-child relationships
|
|
6
|
+
const initialFilters = [
|
|
7
|
+
{
|
|
8
|
+
id: "personnelLicensesAndRecords",
|
|
9
|
+
label: "Personnel Licenses and Records",
|
|
10
|
+
isParent: true,
|
|
11
|
+
show: false,
|
|
12
|
+
class: "",
|
|
13
|
+
children: [
|
|
14
|
+
{
|
|
15
|
+
id: "completedSiteInduction",
|
|
16
|
+
show: false,
|
|
17
|
+
label: "Completed Site Induction",
|
|
18
|
+
class: ""
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "unapprovedWhiteCard",
|
|
22
|
+
show: false,
|
|
23
|
+
label: "Unapproved White Card",
|
|
24
|
+
class: ""
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "unapprovedLicense",
|
|
28
|
+
show: false,
|
|
29
|
+
label: "Unapproved License",
|
|
30
|
+
class: ""
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "outstandingLicense",
|
|
34
|
+
show: false,
|
|
35
|
+
label: "Outstanding License",
|
|
36
|
+
class: ""
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "unapprovedCovid",
|
|
40
|
+
show: false,
|
|
41
|
+
label: "Unapproved COVID",
|
|
42
|
+
class: ""
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "insurance",
|
|
48
|
+
label: "Insurance",
|
|
49
|
+
isParent: true,
|
|
50
|
+
show: false,
|
|
51
|
+
class: "",
|
|
52
|
+
children: [
|
|
53
|
+
{
|
|
54
|
+
id: "allInsurance",
|
|
55
|
+
show: false,
|
|
56
|
+
label: "All Insurance",
|
|
57
|
+
class: ""
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "unapprovedInsurance",
|
|
61
|
+
show: false,
|
|
62
|
+
label: "Unapproved Insurance",
|
|
63
|
+
class: ""
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "expiredInsurance",
|
|
67
|
+
show: false,
|
|
68
|
+
label: "Expired Insurance",
|
|
69
|
+
class: ""
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "outstandingInsurance",
|
|
73
|
+
show: false,
|
|
74
|
+
label: "Outstanding Insurance",
|
|
75
|
+
class: ""
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "workingHours",
|
|
81
|
+
label: "Working Hours",
|
|
82
|
+
isParent: true,
|
|
83
|
+
show: false,
|
|
84
|
+
class: "",
|
|
85
|
+
children: [
|
|
86
|
+
{
|
|
87
|
+
id: "projectTotalHours",
|
|
88
|
+
show: false,
|
|
89
|
+
label: "Project Total Hours",
|
|
90
|
+
class: ""
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: "contractorTotalHours",
|
|
94
|
+
show: false,
|
|
95
|
+
label: "Contractor Total Hours",
|
|
96
|
+
class: ""
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "sitePersonnelWorkHours",
|
|
100
|
+
show: false,
|
|
101
|
+
label: "Site Personnel Work Hours",
|
|
102
|
+
class: ""
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "sitePersonnelRecords",
|
|
106
|
+
show: false,
|
|
107
|
+
label: "Site Personnel Records",
|
|
108
|
+
class: ""
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "prequalifications",
|
|
114
|
+
label: "Prequalifications",
|
|
115
|
+
isParent: true,
|
|
116
|
+
show: false,
|
|
117
|
+
class: "",
|
|
118
|
+
children: [
|
|
119
|
+
{
|
|
120
|
+
id: "prequalificationsUnapproved",
|
|
121
|
+
show: false,
|
|
122
|
+
label: "Unapproved Prequalifications",
|
|
123
|
+
class: ""
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "prequalificationsExpiring",
|
|
127
|
+
show: false,
|
|
128
|
+
label: "Expiring Prequalifications",
|
|
129
|
+
class: ""
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "prequalifiedContractors",
|
|
133
|
+
show: false,
|
|
134
|
+
label: "Prequalified Contractors",
|
|
135
|
+
class: ""
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
const [filters, setFilters] = useState(initialFilters);
|
|
142
|
+
const [settings, setSettings] = useState({
|
|
143
|
+
ajaxSetting: {
|
|
144
|
+
where: []
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Find the active filter to display content
|
|
149
|
+
const getActiveFilter = () => {
|
|
150
|
+
let activeFilter = null;
|
|
151
|
+
|
|
152
|
+
// Check each parent filter
|
|
153
|
+
filters.forEach(parent => {
|
|
154
|
+
if (parent.children) {
|
|
155
|
+
// Check if any child is active
|
|
156
|
+
parent.children.forEach(child => {
|
|
157
|
+
if (child.show) {
|
|
158
|
+
activeFilter = {
|
|
159
|
+
parent: parent.label,
|
|
160
|
+
child: child.label,
|
|
161
|
+
id: child.id
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return activeFilter;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const activeFilter = getActiveFilter();
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
|
|
175
|
+
<h1 style={{ marginBottom: '20px' }}>Reports</h1>
|
|
176
|
+
|
|
177
|
+
<div style={{ display: 'flex', gap: '20px' }}>
|
|
178
|
+
<div style={{ width: '300px' }}>
|
|
179
|
+
<TableFilter
|
|
180
|
+
filters={filters}
|
|
181
|
+
setFilters={setFilters}
|
|
182
|
+
setSettings={setSettings}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div style={{ flex: 1, padding: '20px', backgroundColor: '#f9f9f9', borderRadius: '8px', minHeight: '300px' }}>
|
|
187
|
+
{activeFilter ? (
|
|
188
|
+
<div>
|
|
189
|
+
<h2>{activeFilter.child}</h2>
|
|
190
|
+
<p>Category: {activeFilter.parent}</p>
|
|
191
|
+
<p>Filter ID: {activeFilter.id}</p>
|
|
192
|
+
<div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#fff', borderRadius: '4px' }}>
|
|
193
|
+
<p>This is the content area that would display data based on the selected filter.</p>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
) : (
|
|
197
|
+
<div style={{ textAlign: 'center', color: '#666' }}>
|
|
198
|
+
<p>Please select a filter option to view content</p>
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export default FilterExample;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# TableFilter Component with Parent-Child Structure
|
|
2
|
+
|
|
3
|
+
This document explains how to use the updated TableFilter component with parent-child relationships.
|
|
4
|
+
|
|
5
|
+
## Structure of Filter Data
|
|
6
|
+
|
|
7
|
+
The TableFilter component now supports a hierarchical structure with parent categories and child filters. Here's how to structure your filter data:
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const filters = [
|
|
11
|
+
{
|
|
12
|
+
id: "parentCategoryId",
|
|
13
|
+
label: "Parent Category Name",
|
|
14
|
+
isParent: true, // Important: mark as parent
|
|
15
|
+
show: false,
|
|
16
|
+
class: "",
|
|
17
|
+
children: [
|
|
18
|
+
{
|
|
19
|
+
id: "childFilter1",
|
|
20
|
+
show: false,
|
|
21
|
+
label: "Child Filter 1",
|
|
22
|
+
class: ""
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "childFilter2",
|
|
26
|
+
show: false,
|
|
27
|
+
label: "Child Filter 2",
|
|
28
|
+
class: ""
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
// More parent categories...
|
|
33
|
+
];
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Key Features
|
|
37
|
+
|
|
38
|
+
1. **Collapsible Parent Categories**: Click on a parent category to show/hide its children
|
|
39
|
+
2. **Visual Indicators**: Arrow indicators show whether a parent category is expanded
|
|
40
|
+
3. **Styling**: Distinct styling for parent categories and child filters
|
|
41
|
+
4. **Active States**: Visual indication of active filters
|
|
42
|
+
5. **Mobile Responsive**: Adapts to smaller screens with a toggle menu
|
|
43
|
+
|
|
44
|
+
## Usage Example
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
import React, { useState } from 'react';
|
|
48
|
+
import TableFilter from '../TableFilter';
|
|
49
|
+
|
|
50
|
+
function MyComponent() {
|
|
51
|
+
const [filters, setFilters] = useState([
|
|
52
|
+
// Your filter structure here
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
const [settings, setSettings] = useState({
|
|
56
|
+
ajaxSetting: {
|
|
57
|
+
where: []
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<TableFilter
|
|
63
|
+
filters={filters}
|
|
64
|
+
setFilters={setFilters}
|
|
65
|
+
setSettings={setSettings}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## How It Works
|
|
72
|
+
|
|
73
|
+
1. **Parent Categories**: When you click on a parent category, it toggles the visibility of its children
|
|
74
|
+
2. **Child Filters**: When you click on a child filter:
|
|
75
|
+
- It becomes active (highlighted)
|
|
76
|
+
- The `show` property is set to `true`
|
|
77
|
+
- The `settings` object is updated with the filter's ID and value
|
|
78
|
+
- The content area should update based on the selected filter
|
|
79
|
+
|
|
80
|
+
## Handling Filter Selection
|
|
81
|
+
|
|
82
|
+
To display content based on the selected filter, check which filter has `show: true`:
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
// Find the active filter
|
|
86
|
+
const getActiveFilter = () => {
|
|
87
|
+
let activeFilter = null;
|
|
88
|
+
|
|
89
|
+
filters.forEach(parent => {
|
|
90
|
+
if (parent.children) {
|
|
91
|
+
parent.children.forEach(child => {
|
|
92
|
+
if (child.show) {
|
|
93
|
+
activeFilter = {
|
|
94
|
+
parent: parent.label,
|
|
95
|
+
child: child.label,
|
|
96
|
+
id: child.id
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return activeFilter;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Use the active filter to display content
|
|
107
|
+
const activeFilter = getActiveFilter();
|
|
108
|
+
if (activeFilter) {
|
|
109
|
+
// Display content for the active filter
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
See the `FilterExample.jsx` file for a complete working example.
|
|
@@ -424,7 +424,7 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
424
424
|
const sizeClassMap = {
|
|
425
425
|
full: styles.fwBuilderItem,
|
|
426
426
|
half: styles.halfBuilderItem,
|
|
427
|
-
quarter: styles.
|
|
427
|
+
quarter: styles.halfBuilderItem, // Changed to halfBuilderItem to ensure max 2 per row
|
|
428
428
|
};
|
|
429
429
|
|
|
430
430
|
return `${styles.formBuilderItem} ${
|
|
@@ -855,6 +855,12 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
855
855
|
<div className={styles.grid}>
|
|
856
856
|
<div className={styles.grid__subrow}>
|
|
857
857
|
<div className={styles.grid__subnav}>
|
|
858
|
+
<div
|
|
859
|
+
className={styles.gridtxt__header}
|
|
860
|
+
style={{ marginBottom: '10px' }}
|
|
861
|
+
>
|
|
862
|
+
<span>Form Fields</span>
|
|
863
|
+
</div>
|
|
858
864
|
{data.detail && data.detail.length > 0 ? (
|
|
859
865
|
<div className={styles.sortableListContainer}>
|
|
860
866
|
<SortableList
|
|
@@ -869,7 +875,19 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
869
875
|
useDragHandle
|
|
870
876
|
/>
|
|
871
877
|
</div>
|
|
872
|
-
) :
|
|
878
|
+
) : (
|
|
879
|
+
<div
|
|
880
|
+
style={{
|
|
881
|
+
padding: '10px',
|
|
882
|
+
textAlign: 'center',
|
|
883
|
+
color: 'rgba(var(--paragraph-color-rgb), 0.7)',
|
|
884
|
+
fontSize: '0.9rem',
|
|
885
|
+
}}
|
|
886
|
+
>
|
|
887
|
+
No fields added yet. Click "Add Field" to get
|
|
888
|
+
started.
|
|
889
|
+
</div>
|
|
890
|
+
)}
|
|
873
891
|
</div>
|
|
874
892
|
<div className={styles.grid__subcontent}>
|
|
875
893
|
<div className={styles.formSplit}>
|
|
@@ -1165,7 +1183,7 @@ function GenericFormBuilder({ setting, urlParam, userProfile }) {
|
|
|
1165
1183
|
'description'
|
|
1166
1184
|
);
|
|
1167
1185
|
}}
|
|
1168
|
-
onInit={(
|
|
1186
|
+
onInit={(_, editor) =>
|
|
1169
1187
|
(editorRef.current = editor)
|
|
1170
1188
|
}
|
|
1171
1189
|
value={
|