@visns-studio/visns-components 5.0.1-8.1 → 5.0.2
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 -3
- package/src/components/crm/AsyncSelect.jsx +15 -121
- package/src/components/crm/DataGrid.jsx +5 -25
- package/src/components/crm/Field.jsx +148 -174
- package/src/components/crm/Form.jsx +28 -41
- package/src/components/crm/MultiSelect.jsx +29 -96
- package/src/components/crm/Navigation.jsx +40 -2
- package/src/components/crm/QrCode.jsx +8 -12
- package/src/components/crm/auth/Login.jsx +1 -9
- package/src/components/crm/auth/styles/Login.module.scss +3 -4
- package/src/components/crm/auth/styles/Profile.module.scss +14 -56
- package/src/components/crm/generic/GenericAuth.jsx +2 -5
- package/src/components/crm/generic/GenericDetail.jsx +18 -509
- package/src/components/crm/generic/styles/AuditLog.module.scss +0 -4
- package/src/components/crm/generic/styles/GenericDetail.module.scss +121 -261
- package/src/components/crm/generic/styles/GenericDynamic.module.scss +67 -35
- package/src/components/crm/generic/styles/GenericFormBuilder.module.scss +43 -4
- package/src/components/crm/generic/styles/GenericIndex.module.scss +1 -1
- package/src/components/crm/styles/Autocomplete.module.scss +20 -12
- package/src/components/crm/styles/DataGrid.module.scss +3 -2
- package/src/components/crm/styles/Field.module.scss +13 -19
- package/src/components/crm/styles/Form.module.scss +5 -5
- package/src/components/crm/styles/Navigation.module.scss +61 -11
- package/src/components/crm/styles/QrCode.module.scss +0 -4
- package/src/components/styles/global.css +5 -95
- package/src/components/crm/generic/GenericEditableTable.jsx +0 -407
- package/src/components/crm/generic/styles/GenericEditableTable.module.scss +0 -178
|
@@ -1,120 +1,54 @@
|
|
|
1
|
-
import React, { useEffect,
|
|
2
|
-
import
|
|
3
|
-
import Select, { createFilter
|
|
4
|
-
import CreatableSelect from 'react-select/creatable';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import SelectList from './SelectList';
|
|
3
|
+
import Select, { createFilter } from 'react-select';
|
|
5
4
|
import styles from './styles/AsyncSelect.module.scss';
|
|
6
5
|
|
|
7
|
-
const CustomOption = (props) => (
|
|
8
|
-
<components.Option {...props}>
|
|
9
|
-
<div>
|
|
10
|
-
{props.data.label}
|
|
11
|
-
{props.data.description && props.data.description !== '' && (
|
|
12
|
-
<div style={{ fontSize: '0.85em', color: '#888' }}>
|
|
13
|
-
{props.data.description}
|
|
14
|
-
</div>
|
|
15
|
-
)}
|
|
16
|
-
</div>
|
|
17
|
-
</components.Option>
|
|
18
|
-
);
|
|
19
|
-
|
|
20
6
|
function MultiSelect({
|
|
21
7
|
className,
|
|
22
|
-
inputValue
|
|
8
|
+
inputValue,
|
|
23
9
|
multi,
|
|
24
10
|
onChange,
|
|
25
|
-
options
|
|
11
|
+
options,
|
|
26
12
|
placeholder,
|
|
27
13
|
settings,
|
|
28
14
|
style,
|
|
29
|
-
isCreatable = false,
|
|
30
|
-
creatableConfig = {},
|
|
31
15
|
}) {
|
|
32
16
|
const [selectOptions, setSelectOptions] = useState([]);
|
|
33
|
-
const [selectValue, setSelectValue] = useState([]);
|
|
34
|
-
|
|
35
|
-
// Memoize transformed options
|
|
36
|
-
const memoizedOptions = useMemo(() => {
|
|
37
|
-
return options
|
|
38
|
-
.filter((a) => a?.label || a?.name || a?.description) // Filter out options with no label, name, or description
|
|
39
|
-
.map((a) => ({
|
|
40
|
-
value: a?.id,
|
|
41
|
-
label: a?.label || a?.name || a?.description || 'Unknown',
|
|
42
|
-
description: a?.description || '',
|
|
43
|
-
...a,
|
|
44
|
-
}));
|
|
45
|
-
}, [options]);
|
|
46
|
-
|
|
47
|
-
// Memoize transformed input values
|
|
48
|
-
const memoizedInputValue = useMemo(() => {
|
|
49
|
-
const normalizeInputValue = (value) =>
|
|
50
|
-
Array.isArray(value) ? value : value ? [value] : [];
|
|
51
|
-
|
|
52
|
-
return normalizeInputValue(inputValue)
|
|
53
|
-
.filter((a) => a?.label || a?.name || a?.description) // Filter out values with no label, name, or description
|
|
54
|
-
.map((a) => ({
|
|
55
|
-
value: a?.id,
|
|
56
|
-
label: a?.label || a?.name || a?.description || 'Unknown',
|
|
57
|
-
description: a?.description || '',
|
|
58
|
-
...a,
|
|
59
|
-
}));
|
|
60
|
-
}, [inputValue]);
|
|
61
|
-
|
|
62
|
-
// Set options when memoizedOptions changes
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
if (JSON.stringify(selectOptions) !== JSON.stringify(memoizedOptions)) {
|
|
65
|
-
setSelectOptions(memoizedOptions);
|
|
66
|
-
}
|
|
67
|
-
}, [memoizedOptions, selectOptions]);
|
|
68
17
|
|
|
69
|
-
// Set value when memoizedInputValue changes
|
|
70
18
|
useEffect(() => {
|
|
71
|
-
|
|
72
|
-
JSON.stringify(selectValue) !== JSON.stringify(memoizedInputValue)
|
|
73
|
-
) {
|
|
74
|
-
setSelectValue(memoizedInputValue);
|
|
75
|
-
}
|
|
76
|
-
}, [memoizedInputValue, selectValue]);
|
|
19
|
+
let _options = [];
|
|
77
20
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
{ label: inputValue }
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
if (res && res.data) {
|
|
87
|
-
const newOption = {
|
|
88
|
-
value: res.data.id,
|
|
89
|
-
label: res.data.label || inputValue,
|
|
90
|
-
description: res.data.description || 'Newly created item',
|
|
91
|
-
...res.data,
|
|
21
|
+
if (options.length > 0) {
|
|
22
|
+
options.forEach((a) => {
|
|
23
|
+
let _optionItem = {
|
|
24
|
+
value: a.id,
|
|
25
|
+
label: a.label,
|
|
92
26
|
};
|
|
93
27
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
28
|
+
Object.keys(a).forEach((b) => {
|
|
29
|
+
if (b !== 'id') {
|
|
30
|
+
_optionItem = {
|
|
31
|
+
..._optionItem,
|
|
32
|
+
[b]: a[b],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
});
|
|
98
36
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{ action: 'create-option' },
|
|
102
|
-
settings.id
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
};
|
|
37
|
+
_options.push(_optionItem);
|
|
38
|
+
});
|
|
107
39
|
|
|
108
|
-
|
|
40
|
+
setSelectOptions(_options);
|
|
41
|
+
}
|
|
42
|
+
}, [options]);
|
|
109
43
|
|
|
110
44
|
return (
|
|
111
|
-
<
|
|
112
|
-
closeMenuOnSelect={
|
|
45
|
+
<Select
|
|
46
|
+
closeMenuOnSelect={multi ? false : true}
|
|
113
47
|
isClearable
|
|
114
48
|
isSearchable
|
|
115
49
|
isMulti={multi}
|
|
116
50
|
filterOption={createFilter({ ignoreAccents: false })}
|
|
117
|
-
components={{
|
|
51
|
+
components={{ SelectList }}
|
|
118
52
|
options={selectOptions}
|
|
119
53
|
onChange={(inputValue, action) => {
|
|
120
54
|
onChange(inputValue, action, settings.id);
|
|
@@ -135,9 +69,8 @@ function MultiSelect({
|
|
|
135
69
|
: '52px',
|
|
136
70
|
}),
|
|
137
71
|
}}
|
|
138
|
-
value={
|
|
139
|
-
|
|
140
|
-
placeholder={placeholder || 'Select...'}
|
|
72
|
+
value={inputValue}
|
|
73
|
+
placeholder={placeholder ? placeholder : 'Select...'}
|
|
141
74
|
/>
|
|
142
75
|
);
|
|
143
76
|
}
|
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
|
2
2
|
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
|
3
3
|
import {
|
|
4
|
+
ArrowCycle,
|
|
5
|
+
BookClose,
|
|
6
|
+
BookOpen,
|
|
7
|
+
Briefcase,
|
|
4
8
|
Bug,
|
|
5
9
|
Calendar,
|
|
10
|
+
ChatDots,
|
|
11
|
+
Clipboard,
|
|
12
|
+
DoubleSword,
|
|
6
13
|
Draft,
|
|
14
|
+
Envelope,
|
|
15
|
+
File,
|
|
16
|
+
Folder,
|
|
17
|
+
FolderAdd,
|
|
18
|
+
Gear,
|
|
19
|
+
Grid,
|
|
20
|
+
Home,
|
|
21
|
+
HomeAlt1,
|
|
22
|
+
Inbox,
|
|
23
|
+
Info,
|
|
24
|
+
LightBulb,
|
|
25
|
+
Microphone,
|
|
26
|
+
Money,
|
|
27
|
+
Newspaper,
|
|
28
|
+
Paper,
|
|
29
|
+
PeopleGroup,
|
|
30
|
+
PeopleMultiple,
|
|
7
31
|
Person,
|
|
32
|
+
Question,
|
|
33
|
+
QuestionFill,
|
|
8
34
|
Search,
|
|
35
|
+
SettingsVertical,
|
|
36
|
+
ShippingBoxV1,
|
|
9
37
|
SignOut,
|
|
10
38
|
Shield,
|
|
39
|
+
StatisticUp,
|
|
40
|
+
TextAlignLeft,
|
|
41
|
+
Ticket,
|
|
42
|
+
Utensils,
|
|
11
43
|
} from 'akar-icons';
|
|
12
44
|
import CustomFetch from './Fetch';
|
|
13
45
|
import Notification from './Notification';
|
|
@@ -302,9 +334,15 @@ function Navigation({
|
|
|
302
334
|
return (
|
|
303
335
|
<li className={navItemClasses}>
|
|
304
336
|
{n.url ? (
|
|
305
|
-
<Link to={n.url}>
|
|
337
|
+
<Link to={n.url}>
|
|
338
|
+
<IconComponent strokeWidth={2} size={18} />
|
|
339
|
+
{n.label}
|
|
340
|
+
</Link>
|
|
306
341
|
) : (
|
|
307
|
-
<span title={n.label}>
|
|
342
|
+
<span title={n.label}>
|
|
343
|
+
<IconComponent strokeWidth={2} size={18} />
|
|
344
|
+
{n.label}
|
|
345
|
+
</span>
|
|
308
346
|
)}
|
|
309
347
|
{renderChildren()}
|
|
310
348
|
</li>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import ReactToPrint from 'react-to-print';
|
|
3
3
|
|
|
4
4
|
import CustomFetch from './Fetch';
|
|
5
5
|
import styles from './styles/QrCode.module.scss';
|
|
6
6
|
|
|
7
7
|
const QrCode = ({ config, dataId }) => {
|
|
8
|
-
const
|
|
9
|
-
const reactToPrintFn = useReactToPrint({ contentRef });
|
|
8
|
+
const printComponentRef = useRef();
|
|
10
9
|
const [qrCodeData, setQrCodeData] = useState({
|
|
11
10
|
logo: '',
|
|
12
11
|
qrCode: '',
|
|
@@ -27,13 +26,9 @@ const QrCode = ({ config, dataId }) => {
|
|
|
27
26
|
fetchQrCode(config);
|
|
28
27
|
}, []);
|
|
29
28
|
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
console.info(qrCodeData);
|
|
32
|
-
}, [qrCodeData]);
|
|
33
|
-
|
|
34
29
|
return (
|
|
35
30
|
<>
|
|
36
|
-
<div className={styles.gridtxt} ref={
|
|
31
|
+
<div className={styles.gridtxt} ref={printComponentRef}>
|
|
37
32
|
{qrCodeData.logo && qrCodeData.logo !== '' && (
|
|
38
33
|
<ul className={styles.customer__overview}>
|
|
39
34
|
<li
|
|
@@ -57,7 +52,7 @@ const QrCode = ({ config, dataId }) => {
|
|
|
57
52
|
textAlign: 'center',
|
|
58
53
|
}}
|
|
59
54
|
>
|
|
60
|
-
{qrCodeData.title
|
|
55
|
+
{qrCodeData.title}
|
|
61
56
|
</li>
|
|
62
57
|
</ul>
|
|
63
58
|
<ul className={styles.customer__overview}>
|
|
@@ -76,9 +71,10 @@ const QrCode = ({ config, dataId }) => {
|
|
|
76
71
|
</ul>
|
|
77
72
|
</div>
|
|
78
73
|
<div className={styles.polActions}>
|
|
79
|
-
<
|
|
80
|
-
Print
|
|
81
|
-
|
|
74
|
+
<ReactToPrint
|
|
75
|
+
trigger={() => <button className="btn">Print</button>}
|
|
76
|
+
content={() => printComponentRef.current}
|
|
77
|
+
/>
|
|
82
78
|
</div>
|
|
83
79
|
</>
|
|
84
80
|
);
|
|
@@ -28,15 +28,7 @@ const Login = ({ logo, providers, setSystemAuth, setUserProfile }) => {
|
|
|
28
28
|
let content =
|
|
29
29
|
providers && providers.length > 0 ? (
|
|
30
30
|
<div className="formItem fwItem lastItem forgotten">
|
|
31
|
-
<span
|
|
32
|
-
style={{
|
|
33
|
-
display: 'block',
|
|
34
|
-
textAlign: 'center',
|
|
35
|
-
width: '100%',
|
|
36
|
-
}}
|
|
37
|
-
>
|
|
38
|
-
OR
|
|
39
|
-
</span>
|
|
31
|
+
<span>OR</span>
|
|
40
32
|
</div>
|
|
41
33
|
) : null;
|
|
42
34
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
.fi__span {
|
|
13
13
|
position: absolute;
|
|
14
14
|
transition: all 200ms;
|
|
15
|
-
opacity:
|
|
15
|
+
opacity: 0.8;
|
|
16
16
|
left: 0;
|
|
17
17
|
transform-origin: top left;
|
|
18
18
|
cursor: text;
|
|
@@ -164,11 +164,10 @@
|
|
|
164
164
|
input:not(:placeholder-shown) + .fi__span,
|
|
165
165
|
textarea:not(:placeholder-shown) + .fi__span,
|
|
166
166
|
select:not(:placeholder-shown) + .fi__span {
|
|
167
|
-
transform: translateY(-
|
|
167
|
+
transform: translateY(-110%) translateX(10px) scale(0.75);
|
|
168
168
|
opacity: 1;
|
|
169
169
|
padding: 0;
|
|
170
170
|
background: var(--bg-color);
|
|
171
|
-
font-weight:
|
|
171
|
+
font-weight: 300;
|
|
172
172
|
transition: all 0.5s cubic-bezier(0.5, 0.5, 0, 1);
|
|
173
|
-
color: rgba(var(--paragraph-rgb), 0.65) !important;
|
|
174
173
|
}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
input:not(:placeholder-shown) + .fi__span,
|
|
4
4
|
textarea:not(:placeholder-shown) + .fi__span,
|
|
5
5
|
select:not(:placeholder-shown) + .fi__span {
|
|
6
|
-
transform: translateY(-40%) translateX(10px) scale(0.
|
|
6
|
+
transform: translateY(-40%) translateX(10px) scale(0.75);
|
|
7
7
|
opacity: 1;
|
|
8
|
-
padding: 0
|
|
8
|
+
padding: 0 4px;
|
|
9
9
|
background: var(--tertiary-color);
|
|
10
|
-
font-weight:
|
|
10
|
+
font-weight: 300;
|
|
11
11
|
border-radius: var(--br);
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -111,72 +111,30 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
.grid__subcontent {
|
|
114
|
-
flex: 0 1
|
|
115
|
-
background:
|
|
114
|
+
flex: 0 1 85%;
|
|
115
|
+
background: white;
|
|
116
116
|
border-radius: var(--br);
|
|
117
|
-
border: 1px solid
|
|
117
|
+
border: 1px solid var(--border-color);
|
|
118
118
|
box-sizing: border-box;
|
|
119
|
-
padding:
|
|
120
|
-
margin:
|
|
119
|
+
padding: 0;
|
|
120
|
+
margin: 0.5rem 0;
|
|
121
121
|
height: auto;
|
|
122
122
|
position: relative;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
.grid__subcontent h2 {
|
|
126
|
-
color: var(--primary-color);
|
|
127
|
-
font-size: 1.35em;
|
|
128
|
-
padding: 0;
|
|
129
|
-
margin: 0 0 30px 0;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
125
|
.gridtxt__header {
|
|
133
126
|
width: 100%;
|
|
134
127
|
display: block;
|
|
135
|
-
background:
|
|
128
|
+
background: var(--border-color);
|
|
136
129
|
box-sizing: border-box;
|
|
137
130
|
padding: 10px 20px;
|
|
138
|
-
border-radius: var(--br);
|
|
131
|
+
border-top-left-radius: var(--br);
|
|
132
|
+
border-top-right-radius: var(--br);
|
|
139
133
|
margin-bottom: 0;
|
|
140
134
|
font-weight: 700;
|
|
141
135
|
text-align: center;
|
|
142
136
|
color: var(--paragraph-color);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
.gridtxt__header span {
|
|
146
|
-
font-weight: 700;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.gridtxt > ul {
|
|
150
|
-
width: 100%;
|
|
151
|
-
display: flex;
|
|
152
|
-
justify-content: flex-start;
|
|
153
|
-
flex-direction: row;
|
|
154
|
-
flex-wrap: wrap;
|
|
155
|
-
list-style: none;
|
|
156
|
-
box-sizing: border-box;
|
|
157
|
-
padding: 0.85rem;
|
|
158
|
-
margin: 0;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.gridtxt > ul li {
|
|
162
|
-
flex: 0 0 calc(50% - 10px);
|
|
163
|
-
padding: 0.85rem;
|
|
164
|
-
box-sizing: border-box;
|
|
165
|
-
border: 1px solid rgba(var(--primary-rgb), 0.095);
|
|
166
|
-
color: var(--paragraph-color);
|
|
167
|
-
background: rgba(var(--primary-rgb), 0.015);
|
|
168
|
-
margin: 5px;
|
|
169
|
-
border-radius: var(--br);
|
|
170
|
-
line-height: 1.45;
|
|
171
|
-
font-size: 1rem;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.gridtxt > ul .fw-grid-item {
|
|
175
|
-
flex: 0 0 calc(100% - 10px);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.gridtxt > ul .notecolor {
|
|
179
|
-
border: 1px solid var(--secondary-color);
|
|
137
|
+
position: relative;
|
|
180
138
|
}
|
|
181
139
|
|
|
182
140
|
.formcontainer {
|
|
@@ -205,7 +163,7 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
205
163
|
.fi__span {
|
|
206
164
|
position: absolute;
|
|
207
165
|
transition: all 200ms;
|
|
208
|
-
opacity:
|
|
166
|
+
opacity: 0.8;
|
|
209
167
|
left: 0;
|
|
210
168
|
padding: 19px 20px;
|
|
211
169
|
transform-origin: top left;
|
|
@@ -319,7 +277,7 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
319
277
|
a {
|
|
320
278
|
text-decoration: none;
|
|
321
279
|
color: var(--secondary-color);
|
|
322
|
-
font-weight:
|
|
280
|
+
font-weight: 300;
|
|
323
281
|
}
|
|
324
282
|
|
|
325
283
|
svg {
|
|
@@ -51,11 +51,8 @@ const GenericAuth = ({
|
|
|
51
51
|
const updateAuthStatus = async () => {
|
|
52
52
|
try {
|
|
53
53
|
const { data } = await CustomFetch('/ajax/user/profile', 'GET');
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
setUserProfile(data);
|
|
57
|
-
setIsAuthenticated(true);
|
|
58
|
-
}
|
|
54
|
+
setUserProfile(data);
|
|
55
|
+
setIsAuthenticated(true);
|
|
59
56
|
setIsLoading(false);
|
|
60
57
|
|
|
61
58
|
if (location.pathname.split('/')[1] === 'login') {
|