@visns-studio/visns-components 4.4.1 → 4.4.3
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.
|
@@ -115,7 +115,7 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
|
|
|
115
115
|
setDataReload(randomNumber);
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
const getValueFromData = (data, path, id) => {
|
|
118
|
+
const getValueFromData = (data, path, id, type) => {
|
|
119
119
|
let value =
|
|
120
120
|
path.reduce((result, key) => (result ? result[key] : ''), data) ??
|
|
121
121
|
'';
|
|
@@ -128,7 +128,11 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
|
|
|
128
128
|
.join(', ');
|
|
129
129
|
} else {
|
|
130
130
|
if (Array.isArray(id)) {
|
|
131
|
-
|
|
131
|
+
if (type === 'checkbox') {
|
|
132
|
+
return value[id];
|
|
133
|
+
} else {
|
|
134
|
+
return id.map((key) => value[key]).join(' ');
|
|
135
|
+
}
|
|
132
136
|
} else {
|
|
133
137
|
return value[id];
|
|
134
138
|
}
|
|
@@ -166,8 +170,9 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
|
|
|
166
170
|
} = item;
|
|
167
171
|
const value =
|
|
168
172
|
relation && relation.length > 0 && type !== 'total'
|
|
169
|
-
? getValueFromData(data, [...relation], id)
|
|
170
|
-
: getValueFromData(data, [], id);
|
|
173
|
+
? getValueFromData(data, [...relation], id, type)
|
|
174
|
+
: getValueFromData(data, [], id, type);
|
|
175
|
+
|
|
171
176
|
const stringValue = String(value ?? ''); // Convert value to a string
|
|
172
177
|
|
|
173
178
|
// Conditionally truncate the value if the 'truncate' key is present
|
|
@@ -229,6 +234,47 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
|
|
|
229
234
|
|
|
230
235
|
const renderBoolean = () => (value ? 'Yes' : 'No');
|
|
231
236
|
|
|
237
|
+
const renderCheckbox = () => {
|
|
238
|
+
if (!value || typeof value !== 'object') {
|
|
239
|
+
return '';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const formatKey = (key) => {
|
|
243
|
+
return key
|
|
244
|
+
.toLowerCase()
|
|
245
|
+
.split('_')
|
|
246
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
247
|
+
.join(' ');
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const keys = Object.keys(value)
|
|
251
|
+
.filter((key) => value[key] && key !== 'notes')
|
|
252
|
+
.sort((a, b) => {
|
|
253
|
+
if (a === 'other') return 1;
|
|
254
|
+
if (b === 'other') return -1;
|
|
255
|
+
return a.localeCompare(b);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const formattedKeys = keys.map((key) => {
|
|
259
|
+
let formattedKey = formatKey(key);
|
|
260
|
+
if (key === 'other') {
|
|
261
|
+
const otherValue = getValueFromData(
|
|
262
|
+
data,
|
|
263
|
+
[...relation],
|
|
264
|
+
`${id}_other`,
|
|
265
|
+
type
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
if (otherValue) {
|
|
269
|
+
formattedKey += `: ${otherValue}`;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return formattedKey;
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
return formattedKeys.join(', ');
|
|
276
|
+
};
|
|
277
|
+
|
|
232
278
|
const renderDate = () => formatDateValue(value);
|
|
233
279
|
|
|
234
280
|
const renderDateTime = () => formatDateTimeValue(value);
|
|
@@ -276,6 +322,8 @@ function GenericDetail({ extraUrlParam, setting, urlParam, userProfile }) {
|
|
|
276
322
|
switch (type) {
|
|
277
323
|
case 'boolean':
|
|
278
324
|
return renderBoolean();
|
|
325
|
+
case 'checkbox':
|
|
326
|
+
return renderCheckbox();
|
|
279
327
|
case 'copyToClipboard':
|
|
280
328
|
return renderCopyToClipboard();
|
|
281
329
|
case 'date':
|
|
@@ -2,12 +2,15 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { Outlet } from 'react-router-dom';
|
|
3
3
|
import { toast } from 'react-toastify';
|
|
4
4
|
import { saveAs } from 'file-saver';
|
|
5
|
+
import _ from 'lodash';
|
|
6
|
+
|
|
5
7
|
import CustomFetch from '../Fetch';
|
|
6
8
|
import Download from '../Download';
|
|
7
9
|
import Field from '../Field';
|
|
8
10
|
import Table from '../DataGrid';
|
|
9
11
|
import TableFilter from '../TableFilter';
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
import styles from './styles/GenericIndex.module.css';
|
|
11
14
|
|
|
12
15
|
function useWindowHeight() {
|
|
13
16
|
const [windowHeight, setWindowHeight] = useState(window.innerHeight);
|
|
@@ -234,11 +237,11 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
234
237
|
const renderContent = useCallback(() => {
|
|
235
238
|
if (subnav?.length > 0) {
|
|
236
239
|
return (
|
|
237
|
-
<div className=
|
|
240
|
+
<div className={styles.grid__subrow}>
|
|
238
241
|
{layout === 'simple' ? (
|
|
239
|
-
<div className={
|
|
240
|
-
<div className=
|
|
241
|
-
<div className=
|
|
242
|
+
<div className={styles.grid__full}>
|
|
243
|
+
<div className={styles.tabcontent}>
|
|
244
|
+
<div className={styles.tabcontent__menu}>
|
|
242
245
|
<TableFilter
|
|
243
246
|
filters={subnav}
|
|
244
247
|
setFilters={setSubnav}
|
|
@@ -246,14 +249,14 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
246
249
|
type={layout}
|
|
247
250
|
/>
|
|
248
251
|
</div>
|
|
249
|
-
<div className=
|
|
252
|
+
<div className={styles.tabcontent__main}>
|
|
250
253
|
{renderContentBasedOnType()}
|
|
251
254
|
</div>
|
|
252
255
|
</div>
|
|
253
256
|
</div>
|
|
254
257
|
) : (
|
|
255
258
|
<>
|
|
256
|
-
<div className={
|
|
259
|
+
<div className={styles.grid__subnav}>
|
|
257
260
|
<TableFilter
|
|
258
261
|
filters={subnav}
|
|
259
262
|
setFilters={setSubnav}
|
|
@@ -261,7 +264,7 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
261
264
|
type={layout}
|
|
262
265
|
/>
|
|
263
266
|
</div>
|
|
264
|
-
<div className=
|
|
267
|
+
<div className={styles.grid__subcontent}>
|
|
265
268
|
{renderContentBasedOnType()}
|
|
266
269
|
</div>
|
|
267
270
|
</>
|
|
@@ -277,9 +280,9 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
277
280
|
|
|
278
281
|
return (
|
|
279
282
|
<>
|
|
280
|
-
<div className=
|
|
281
|
-
<div className=
|
|
282
|
-
<div className=
|
|
283
|
+
<div className={styles.grid}>
|
|
284
|
+
<div className={styles.grid__row}>
|
|
285
|
+
<div className={`${styles.grid__full} ${styles.crmtitle}`}>
|
|
283
286
|
<h1>{setting.page?.title}</h1>
|
|
284
287
|
<div className="titleInfo">
|
|
285
288
|
<span>
|
|
@@ -291,11 +294,14 @@ function GenericIndex({ layout = 'full', setting, userProfile }) {
|
|
|
291
294
|
</div>
|
|
292
295
|
</div>
|
|
293
296
|
|
|
294
|
-
<div className=
|
|
297
|
+
<div className={styles.grid}>{renderContent()}</div>
|
|
295
298
|
<Outlet />
|
|
296
299
|
{setting.functions?.checkboxUpdate && (
|
|
297
|
-
<div className=
|
|
298
|
-
<button
|
|
300
|
+
<div className={styles.polActions}>
|
|
301
|
+
<button
|
|
302
|
+
className={styles.btn}
|
|
303
|
+
onClick={handleCheckboxUpdate}
|
|
304
|
+
>
|
|
299
305
|
{setting.functions.checkboxUpdate.label || 'Update'}
|
|
300
306
|
</button>
|
|
301
307
|
</div>
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
.grid {
|
|
2
|
+
&__row {
|
|
3
|
+
width: 100%;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: flex-start;
|
|
6
|
+
flex-wrap: nowrap;
|
|
7
|
+
height: auto;
|
|
8
|
+
gap: 1rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
&__three {
|
|
12
|
+
width: 33%;
|
|
13
|
+
background: var(--item-color);
|
|
14
|
+
border-radius: var(--br);
|
|
15
|
+
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
overflow: visible;
|
|
18
|
+
position: relative;
|
|
19
|
+
padding: 20px;
|
|
20
|
+
margin: 8px 0;
|
|
21
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&__half {
|
|
25
|
+
width: 50%;
|
|
26
|
+
background: var(--item-color);
|
|
27
|
+
border-radius: 6px;
|
|
28
|
+
border: 1px solid #dadce0;
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
overflow: visible;
|
|
31
|
+
position: relative;
|
|
32
|
+
padding: 20px;
|
|
33
|
+
margin: 8px 0;
|
|
34
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color), 0.05);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&__full {
|
|
38
|
+
width: 100%;
|
|
39
|
+
background: var(--item-color);
|
|
40
|
+
border-radius: var(--br);
|
|
41
|
+
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
overflow: visible;
|
|
44
|
+
position: relative;
|
|
45
|
+
padding: 2px;
|
|
46
|
+
margin: 8px 0;
|
|
47
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&__dashfull {
|
|
51
|
+
width: 100%;
|
|
52
|
+
background: var(--item-color);
|
|
53
|
+
border-radius: 6px;
|
|
54
|
+
border: 1px solid #dadce0;
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
overflow: visible;
|
|
57
|
+
position: relative;
|
|
58
|
+
padding: 20px;
|
|
59
|
+
margin: 8px 0;
|
|
60
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&__subrow {
|
|
64
|
+
width: 100%;
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-wrap: wrap;
|
|
67
|
+
height: auto;
|
|
68
|
+
gap: 0.5rem;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&__subnav {
|
|
72
|
+
flex: 1;
|
|
73
|
+
background: rgba(var(--item-color-rgb), 1.01);
|
|
74
|
+
border-radius: var(--br);
|
|
75
|
+
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
padding: 5px;
|
|
78
|
+
margin: 8px 0;
|
|
79
|
+
height: auto;
|
|
80
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
|
|
81
|
+
|
|
82
|
+
> ul {
|
|
83
|
+
width: 100%;
|
|
84
|
+
list-style: none;
|
|
85
|
+
padding: 0;
|
|
86
|
+
margin: 0;
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-wrap: wrap;
|
|
89
|
+
|
|
90
|
+
li {
|
|
91
|
+
width: 100%;
|
|
92
|
+
margin-bottom: 3px;
|
|
93
|
+
|
|
94
|
+
a {
|
|
95
|
+
width: 100%;
|
|
96
|
+
padding: 8px 20px;
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
display: block;
|
|
99
|
+
text-decoration: none;
|
|
100
|
+
background: rgba(var(--primary-color-rgb), 0.05);
|
|
101
|
+
color: var(--primary-color);
|
|
102
|
+
border-radius: 5px;
|
|
103
|
+
transition: background 0.25s
|
|
104
|
+
cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
105
|
+
outline: none;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
&:hover {
|
|
110
|
+
a {
|
|
111
|
+
background: var(--primary-color);
|
|
112
|
+
color: var(--tertiary-color);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.subactive {
|
|
117
|
+
font-weight: 700;
|
|
118
|
+
background: var(--primary-color);
|
|
119
|
+
color: var(--tertiary-color);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&__minheight {
|
|
126
|
+
min-height: 300px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.noborder {
|
|
130
|
+
border: none !important;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&__subcontent {
|
|
134
|
+
flex: 0 1 80%;
|
|
135
|
+
background: var(--item-color);
|
|
136
|
+
border-radius: var(--br);
|
|
137
|
+
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
138
|
+
box-sizing: border-box;
|
|
139
|
+
padding: 2px;
|
|
140
|
+
margin: 8px 0;
|
|
141
|
+
height: auto;
|
|
142
|
+
position: relative;
|
|
143
|
+
box-shadow: 0 4px 0 rgba(var(--primary-color-rgb), 0.05);
|
|
144
|
+
|
|
145
|
+
h2 {
|
|
146
|
+
color: var(--primary-color);
|
|
147
|
+
font-size: 1.35em;
|
|
148
|
+
padding: 0;
|
|
149
|
+
margin: 0 0 30px 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.crmtitle {
|
|
155
|
+
border: none;
|
|
156
|
+
min-height: auto;
|
|
157
|
+
padding: 10px 20px;
|
|
158
|
+
margin: 0;
|
|
159
|
+
background: var(--tertiary-color);
|
|
160
|
+
border-radius: var(--br);
|
|
161
|
+
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
162
|
+
position: relative;
|
|
163
|
+
|
|
164
|
+
h1 {
|
|
165
|
+
font-weight: 700;
|
|
166
|
+
font-size: 1.45em;
|
|
167
|
+
margin: 0;
|
|
168
|
+
padding: 0.65rem 0;
|
|
169
|
+
|
|
170
|
+
a {
|
|
171
|
+
text-decoration: none;
|
|
172
|
+
color: rgba(var(--secondary-color-rgb), 1.1);
|
|
173
|
+
font-weight: 300;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
svg {
|
|
177
|
+
color: rgba(var(--primary-color-rgb), 0.25);
|
|
178
|
+
position: relative;
|
|
179
|
+
top: 2px;
|
|
180
|
+
margin: 0 0.25rem;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.titleInfo {
|
|
186
|
+
position: absolute;
|
|
187
|
+
right: 2em;
|
|
188
|
+
top: 24px;
|
|
189
|
+
|
|
190
|
+
span {
|
|
191
|
+
font-size: 0.875em;
|
|
192
|
+
color: rgba(var(--paragraph-color-rgb), 0.65);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.btn {
|
|
197
|
+
width: max-content;
|
|
198
|
+
display: inline-block;
|
|
199
|
+
position: relative;
|
|
200
|
+
padding: 0.65rem 1rem;
|
|
201
|
+
cursor: pointer;
|
|
202
|
+
font-size: 1rem;
|
|
203
|
+
color: var(--tertiary-color);
|
|
204
|
+
text-decoration: none;
|
|
205
|
+
overflow: hidden;
|
|
206
|
+
background: var(--primary-color);
|
|
207
|
+
border: 1px solid rgba(var(--primary-color--rgb), 1.1);
|
|
208
|
+
border-radius: var(--br);
|
|
209
|
+
outline: none;
|
|
210
|
+
transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
|
|
211
|
+
font-size: 1.25em;
|
|
212
|
+
|
|
213
|
+
&:hover {
|
|
214
|
+
color: var(--primary-color);
|
|
215
|
+
background: var(--highlight-color);
|
|
216
|
+
border: 1px solid rgba(var(--highlight-color-rgb), 1.05);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.polActions {
|
|
221
|
+
position: fixed;
|
|
222
|
+
bottom: 15px;
|
|
223
|
+
right: 20px;
|
|
224
|
+
width: auto;
|
|
225
|
+
|
|
226
|
+
button {
|
|
227
|
+
display: block;
|
|
228
|
+
float: left;
|
|
229
|
+
padding: 0.35em 1em;
|
|
230
|
+
margin: 0 0.15em;
|
|
231
|
+
}
|
|
232
|
+
}
|
package/package.json
CHANGED