@visns-studio/visns-components 4.6.10 → 4.6.12
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/components/crm/DataGrid.jsx +61 -8
- package/components/crm/Field.jsx +11 -5
- package/components/crm/Loader.jsx +4 -4
- package/components/crm/generic/GenericDetail.jsx +1 -0
- package/components/crm/generic/GenericSort.jsx +42 -43
- package/components/crm/generic/styles/GenericSort.module.css +60 -4
- package/components/crm/sorting/Item.jsx +117 -0
- package/components/crm/sorting/List.jsx +32 -0
- package/components/crm/sorting/styles/Item.module.css +68 -0
- package/components/crm/sorting/styles/List.module.css +68 -0
- package/components/crm/styles/Field.module.css +25 -1
- package/package.json +1 -1
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
Image,
|
|
44
44
|
Inbox,
|
|
45
45
|
LinkOut,
|
|
46
|
+
LockOn,
|
|
46
47
|
Network,
|
|
47
48
|
Ribbon,
|
|
48
49
|
Search,
|
|
@@ -378,6 +379,34 @@ const DataGrid = forwardRef(
|
|
|
378
379
|
toast.success(result.message);
|
|
379
380
|
});
|
|
380
381
|
break;
|
|
382
|
+
case 'oauth2':
|
|
383
|
+
let oauth2Payload = d;
|
|
384
|
+
|
|
385
|
+
if (s.key?.detailKey?.length > 0) {
|
|
386
|
+
for (const k of s.key.detailKey) {
|
|
387
|
+
if (oauth2Payload?.[k]) {
|
|
388
|
+
oauth2Payload = oauth2Payload[k];
|
|
389
|
+
} else {
|
|
390
|
+
oauth2Payload = undefined;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
CustomFetch(
|
|
396
|
+
s.key.redirect,
|
|
397
|
+
'POST',
|
|
398
|
+
{ ...oauth2Payload, id: d.id },
|
|
399
|
+
(result) => {
|
|
400
|
+
if (result.url !== '') {
|
|
401
|
+
window.location.href = result.url;
|
|
402
|
+
} else {
|
|
403
|
+
toast.error(
|
|
404
|
+
'An error occurred while processing the request.'
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
break;
|
|
381
410
|
case 'delete':
|
|
382
411
|
const getDataId = () => {
|
|
383
412
|
for (const item of ajaxSetting.where) {
|
|
@@ -727,20 +756,25 @@ const DataGrid = forwardRef(
|
|
|
727
756
|
};
|
|
728
757
|
|
|
729
758
|
const sortTrigger = () => {
|
|
730
|
-
|
|
759
|
+
let baseUrl = form.url.replace('/ajax', '');
|
|
760
|
+
let sortUrl = paramValue
|
|
761
|
+
? `${baseUrl}/${paramValue}/sort`
|
|
762
|
+
: `${baseUrl}/sort`;
|
|
763
|
+
|
|
764
|
+
if (form.sort?.url) {
|
|
765
|
+
sortUrl = form.sort.url;
|
|
766
|
+
}
|
|
731
767
|
|
|
732
768
|
const newState = {
|
|
733
|
-
form
|
|
769
|
+
form,
|
|
734
770
|
page: {
|
|
735
771
|
data: pageData,
|
|
736
772
|
setting: pageSetting,
|
|
737
773
|
},
|
|
738
|
-
paramValue
|
|
774
|
+
paramValue,
|
|
739
775
|
};
|
|
740
776
|
|
|
741
|
-
navigate(
|
|
742
|
-
state: newState,
|
|
743
|
-
});
|
|
777
|
+
navigate(sortUrl, { state: newState });
|
|
744
778
|
};
|
|
745
779
|
|
|
746
780
|
const renderCreateButton = () => {
|
|
@@ -1014,12 +1048,33 @@ const DataGrid = forwardRef(
|
|
|
1014
1048
|
}
|
|
1015
1049
|
}
|
|
1016
1050
|
|
|
1051
|
+
if (s.id === 'oauth2') {
|
|
1052
|
+
let tmpCheckValue = d;
|
|
1053
|
+
|
|
1054
|
+
if (s.key?.check?.length > 0) {
|
|
1055
|
+
for (const k of s.key.check) {
|
|
1056
|
+
if (tmpCheckValue?.[k]) {
|
|
1057
|
+
tmpCheckValue = tmpCheckValue[k];
|
|
1058
|
+
} else {
|
|
1059
|
+
tmpCheckValue = undefined;
|
|
1060
|
+
break;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if (!tmpCheckValue) {
|
|
1066
|
+
allow = false;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1017
1070
|
if (allow) {
|
|
1018
1071
|
switch (s.id) {
|
|
1019
1072
|
case 'activate':
|
|
1020
1073
|
return getIconComponent(CircleCheck);
|
|
1021
1074
|
case 'archive':
|
|
1022
1075
|
return getIconComponent(ShippingBoxV1);
|
|
1076
|
+
case 'oauth2':
|
|
1077
|
+
return getIconComponent(LockOn);
|
|
1023
1078
|
case 'complete':
|
|
1024
1079
|
return getIconComponent(Check);
|
|
1025
1080
|
case 'copy':
|
|
@@ -1851,8 +1906,6 @@ const DataGrid = forwardRef(
|
|
|
1851
1906
|
}
|
|
1852
1907
|
}, '');
|
|
1853
1908
|
|
|
1854
|
-
console.info(value);
|
|
1855
|
-
|
|
1856
1909
|
if (value) {
|
|
1857
1910
|
if (Array.isArray(value)) {
|
|
1858
1911
|
if (value[0]) {
|
package/components/crm/Field.jsx
CHANGED
|
@@ -59,7 +59,7 @@ function Field({
|
|
|
59
59
|
const [counter, setCounter] = useState(0);
|
|
60
60
|
const [dataOptions, setDataOptions] = useState([]);
|
|
61
61
|
const [formItemStyle, setFormItemStyle] = useState({});
|
|
62
|
-
const [formItemClass, setFormItemClass] = useState('
|
|
62
|
+
const [formItemClass, setFormItemClass] = useState('');
|
|
63
63
|
const [options, setOptions] = useState([]);
|
|
64
64
|
|
|
65
65
|
const cover = {
|
|
@@ -140,10 +140,16 @@ function Field({
|
|
|
140
140
|
break;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
switch (settings.size) {
|
|
144
|
+
case 'full':
|
|
145
|
+
setFormItemClass(`${styles.formItem} ${styles.fwItem}`);
|
|
146
|
+
break;
|
|
147
|
+
case 'quarter':
|
|
148
|
+
setFormItemClass(`${styles.formItem} ${styles.qtrItem}`);
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
setFormItemClass(`${styles.formItem}`);
|
|
152
|
+
break;
|
|
147
153
|
}
|
|
148
154
|
}, [settings, counter]);
|
|
149
155
|
|
|
@@ -15,10 +15,10 @@ function VisnsLoader({}) {
|
|
|
15
15
|
}, [promiseInProgress]);
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
|
-
<div className=
|
|
19
|
-
<div className=
|
|
20
|
-
<div className=
|
|
21
|
-
<div className=
|
|
18
|
+
<div className={styles.preloader} style={loaderStyle}>
|
|
19
|
+
<div className={styles.preloader__icn}>
|
|
20
|
+
<div className={styles.preloader__cut}>
|
|
21
|
+
<div className={styles.preloader__donut}></div>
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
24
|
<span>Processing Data</span>
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useLocation, useParams } from 'react-router-dom';
|
|
3
3
|
import { arrayMoveImmutable } from 'array-move';
|
|
4
4
|
import { toast } from 'react-toastify';
|
|
5
|
-
import { CircleChevronRight } from 'akar-icons';
|
|
6
5
|
import CustomFetch from '../../crm/Fetch';
|
|
7
|
-
import SortableList from '
|
|
6
|
+
import SortableList from '../sorting/List';
|
|
7
|
+
import Breadcrumb from '../Breadcrumb';
|
|
8
8
|
import styles from './styles/GenericSort.module.css';
|
|
9
9
|
|
|
10
|
+
// Utility function to convert camelCase to space-separated words with uppercase first letters
|
|
11
|
+
function camelCaseToUcFirst(str) {
|
|
12
|
+
return str
|
|
13
|
+
.replace(/([A-Z])/g, ' $1') // Add a space before each uppercase letter
|
|
14
|
+
.replace(/^./, function (str) {
|
|
15
|
+
return str.toUpperCase();
|
|
16
|
+
}) // Capitalize the first letter
|
|
17
|
+
.trim(); // Remove leading and trailing whitespace
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
const ChildSort = ({ item, url }) => {
|
|
11
21
|
const [data, setData] = useState(item.child);
|
|
12
22
|
|
|
@@ -17,13 +27,14 @@ const ChildSort = ({ item, url }) => {
|
|
|
17
27
|
useEffect(() => {
|
|
18
28
|
if (data.length > 0) {
|
|
19
29
|
CustomFetch(
|
|
20
|
-
url
|
|
30
|
+
`${url}/sort_update`,
|
|
21
31
|
'POST',
|
|
22
32
|
{
|
|
23
33
|
list: data,
|
|
24
34
|
},
|
|
25
35
|
function (result) {
|
|
26
36
|
if (result.error === '') {
|
|
37
|
+
toast.success('Sort updated successfully');
|
|
27
38
|
} else {
|
|
28
39
|
toast.error(String(result.error));
|
|
29
40
|
}
|
|
@@ -47,15 +58,18 @@ const ChildSort = ({ item, url }) => {
|
|
|
47
58
|
);
|
|
48
59
|
};
|
|
49
60
|
|
|
50
|
-
const GenericSort = ({ category = false }) => {
|
|
61
|
+
const GenericSort = ({ category = false, layout = 'full' }) => {
|
|
51
62
|
const location = useLocation();
|
|
63
|
+
const routeParams = useParams();
|
|
52
64
|
const {
|
|
53
65
|
form,
|
|
54
|
-
page
|
|
66
|
+
page = {}, // Provide a default empty object for page
|
|
55
67
|
paramValue,
|
|
56
|
-
} = location.state;
|
|
68
|
+
} = location.state || {}; // Safely access location.state
|
|
69
|
+
|
|
57
70
|
const [sortData, setSortData] = useState([]);
|
|
58
|
-
const url = form
|
|
71
|
+
const url = form?.url;
|
|
72
|
+
const data = page?.data || {}; // Safely access data from page, default to an empty object
|
|
59
73
|
|
|
60
74
|
const onSortEnd = ({ oldIndex, newIndex }) => {
|
|
61
75
|
setSortData((prevItem) =>
|
|
@@ -68,7 +82,7 @@ const GenericSort = ({ category = false }) => {
|
|
|
68
82
|
let fetchUrl = url;
|
|
69
83
|
let payload = {};
|
|
70
84
|
|
|
71
|
-
if (form
|
|
85
|
+
if (form?.json) {
|
|
72
86
|
fetchUrl = fetchUrl + '/jsonSortList';
|
|
73
87
|
payload.id = paramValue;
|
|
74
88
|
} else {
|
|
@@ -76,7 +90,6 @@ const GenericSort = ({ category = false }) => {
|
|
|
76
90
|
}
|
|
77
91
|
|
|
78
92
|
const res = await CustomFetch(fetchUrl, 'POST', payload);
|
|
79
|
-
|
|
80
93
|
setSortData(res.data);
|
|
81
94
|
} catch (err) {
|
|
82
95
|
console.log(err);
|
|
@@ -90,7 +103,7 @@ const GenericSort = ({ category = false }) => {
|
|
|
90
103
|
list: sortData,
|
|
91
104
|
};
|
|
92
105
|
|
|
93
|
-
if (form
|
|
106
|
+
if (form?.json) {
|
|
94
107
|
fetchUrl = fetchUrl + '/jsonSortUpdate';
|
|
95
108
|
payload.id = paramValue;
|
|
96
109
|
} else {
|
|
@@ -123,37 +136,23 @@ const GenericSort = ({ category = false }) => {
|
|
|
123
136
|
<>
|
|
124
137
|
<div className={styles.grid}>
|
|
125
138
|
<div className={styles.grid__row}>
|
|
126
|
-
<div
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
? `${setting.previousUrl}/${paramValue}`
|
|
144
|
-
: null
|
|
145
|
-
}
|
|
146
|
-
>
|
|
147
|
-
<CircleChevronRight
|
|
148
|
-
strokeWidth={2}
|
|
149
|
-
size={18}
|
|
150
|
-
/>{' '}
|
|
151
|
-
{data[setting.titleKey]}{' '}
|
|
152
|
-
</Link>
|
|
153
|
-
) : null}
|
|
154
|
-
<CircleChevronRight strokeWidth={2} size={18} />{' '}
|
|
155
|
-
{form?.sort?.title}
|
|
156
|
-
</h1>
|
|
139
|
+
<div
|
|
140
|
+
className={`${styles.grid__full} ${
|
|
141
|
+
layout === 'full'
|
|
142
|
+
? styles.crmtitle
|
|
143
|
+
: styles.crmtitleSimple
|
|
144
|
+
}`}
|
|
145
|
+
>
|
|
146
|
+
<Breadcrumb
|
|
147
|
+
data={{
|
|
148
|
+
label: camelCaseToUcFirst(routeParams.dataId),
|
|
149
|
+
}} // Use utility function here
|
|
150
|
+
page={{
|
|
151
|
+
parentTitle: 'Settings',
|
|
152
|
+
parentUrl: '/settings',
|
|
153
|
+
titleKey: 'label',
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
157
156
|
</div>
|
|
158
157
|
</div>
|
|
159
158
|
</div>
|
|
@@ -165,7 +164,7 @@ const GenericSort = ({ category = false }) => {
|
|
|
165
164
|
items={sortData}
|
|
166
165
|
onSortEnd={onSortEnd}
|
|
167
166
|
axis="xy"
|
|
168
|
-
helperClass=
|
|
167
|
+
helperClass={styles.dragitem}
|
|
169
168
|
transitionDuration={250}
|
|
170
169
|
useDragHandle
|
|
171
170
|
/>
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
min-height: auto;
|
|
35
35
|
padding: 5px 20px;
|
|
36
36
|
margin: 0;
|
|
37
|
-
background: var(--
|
|
37
|
+
background: var(--tertiary-color);
|
|
38
38
|
border-radius: var(--br);
|
|
39
39
|
border: 1px solid rgba(var(--item-color-rgb), 1.15);
|
|
40
40
|
position: relative;
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
align-items: center;
|
|
43
43
|
|
|
44
44
|
h1 {
|
|
45
|
-
color: var(--background-color);
|
|
46
45
|
font-weight: 700;
|
|
47
46
|
font-size: 1.15em;
|
|
48
47
|
margin: 0;
|
|
@@ -53,11 +52,11 @@
|
|
|
53
52
|
|
|
54
53
|
a {
|
|
55
54
|
text-decoration: none;
|
|
56
|
-
color: var(--secondary-color);
|
|
55
|
+
color: rgba(var(--secondary-color-rgb), 1.1);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
svg {
|
|
60
|
-
color: rgba(var(--
|
|
59
|
+
color: rgba(var(--primary-color-rgb), 0.25);
|
|
61
60
|
position: relative;
|
|
62
61
|
top: 0;
|
|
63
62
|
margin: 0 0.5rem;
|
|
@@ -65,3 +64,60 @@
|
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
}
|
|
67
|
+
|
|
68
|
+
.dragitem {
|
|
69
|
+
list-style: none;
|
|
70
|
+
display: flex;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
align-items: center;
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
border-radius: 5px;
|
|
75
|
+
border: 1px solid rgba(var(--primary-color-rgb), 0.2);
|
|
76
|
+
box-shadow: 0px 0px 20px rgba(var(--primary-color-rgb), 0.25);
|
|
77
|
+
padding: 1.25rem;
|
|
78
|
+
box-sizing: border-box;
|
|
79
|
+
cursor: grab;
|
|
80
|
+
list-style: none;
|
|
81
|
+
color: var(--paragraph-color);
|
|
82
|
+
|
|
83
|
+
svg {
|
|
84
|
+
width: 100%;
|
|
85
|
+
max-width: 18px;
|
|
86
|
+
position: absolute;
|
|
87
|
+
left: 5px;
|
|
88
|
+
top: 5px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.pencil-edit {
|
|
92
|
+
width: 100%;
|
|
93
|
+
max-width: 18px;
|
|
94
|
+
position: absolute;
|
|
95
|
+
left: 5px;
|
|
96
|
+
top: 30px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.trash-delete {
|
|
100
|
+
width: 100%;
|
|
101
|
+
max-width: 18px;
|
|
102
|
+
position: absolute;
|
|
103
|
+
left: 5px;
|
|
104
|
+
top: 60px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sortimg {
|
|
108
|
+
width: 50px;
|
|
109
|
+
position: relative;
|
|
110
|
+
height: 50px;
|
|
111
|
+
margin-left: auto;
|
|
112
|
+
border-radius: 5px;
|
|
113
|
+
overflow: hidden;
|
|
114
|
+
|
|
115
|
+
img {
|
|
116
|
+
display: block;
|
|
117
|
+
object-fit: cover;
|
|
118
|
+
height: 100%;
|
|
119
|
+
width: 100%;
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SortableElement, sortableHandle } from 'react-sortable-hoc';
|
|
3
|
+
import { ChevronVertical, Pencil, TrashCan } from 'akar-icons';
|
|
4
|
+
|
|
5
|
+
import styles from './styles/Item.module.css';
|
|
6
|
+
|
|
7
|
+
const DragHandle = sortableHandle(() => (
|
|
8
|
+
<ChevronVertical className="drag-handle" strokeWidth={1} size={26} />
|
|
9
|
+
));
|
|
10
|
+
|
|
11
|
+
// Utility function to truncate text
|
|
12
|
+
const truncateText = (text, maxLength) => {
|
|
13
|
+
if (text && text.length > maxLength) {
|
|
14
|
+
return `${text.substring(0, maxLength)}...`;
|
|
15
|
+
}
|
|
16
|
+
return text;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const SortableItem = ({
|
|
20
|
+
containerIndex,
|
|
21
|
+
handleClick,
|
|
22
|
+
handleEdit,
|
|
23
|
+
handleDelete,
|
|
24
|
+
showImage,
|
|
25
|
+
value,
|
|
26
|
+
}) => {
|
|
27
|
+
const renderImage = (d) => {
|
|
28
|
+
let htmlContainer = '';
|
|
29
|
+
|
|
30
|
+
if (showImage) {
|
|
31
|
+
const imageUrl = d.image_url || d.file_url;
|
|
32
|
+
htmlContainer = imageUrl ? (
|
|
33
|
+
<div className={styles.sortimg}>
|
|
34
|
+
<img src={imageUrl} alt="" />
|
|
35
|
+
</div>
|
|
36
|
+
) : (
|
|
37
|
+
<div className={styles.sortimg}>
|
|
38
|
+
{/* Placeholder image */}
|
|
39
|
+
<img
|
|
40
|
+
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAJ3UlEQVR4nO3b60/aXhwG8KflJijIJQgTt8y5mLkxl73w//8HzBbdXLLFqJsg3rjKnUJ/L0wJpYUC9ovbL8/nlRbac077tOf0tCiHh4c6iFymPncF6P+JwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQjvc1eAFqPrOprNJrrdLnRdRyQSgdf79xzOpdWkVCrh/PwcnU4Huq5jd3cXyWRyWcXPrVgs4uLiQry+i+6XX79+4e7ubvj//v4+IpGI6/Vb1ELBOjo6wsPDw/B/RVEQCAQQCAQQDAaRSqUQDodN61xdXaHVaj2ttktUKBSWUt9F90utVhOojXsWCla32zX9r+s62u022u02qtUqrq+vkclksL29PfxOv99/Wk2XbFn1XbQcXdddrom7xAbv+Xwe19fXUpunv5wrwYrH40gkEpbluVzOjc3TP8iVYGUyGezt7WFzc9O0vN1uo9FouFEE/WNc7Qrj8bhlWb1ed7MI+ke4Giy/329Z1uv13CyC/hGuzmOpqjWns9z1aJqGu7s7VKvV4aRfv9+Hx+NBIBBAIpFAJpOBx+OxrDsYDHB9fY1isYh2u41erwe/3490Oo2trS3Td3VdR6FQQLlcRqvVQq/XQzAYRCKRwNbWFhRFmVhHXddxc3OD29tbNBoNeDweRCIR7OzsWCYmO50OcrkcyuUyut0u/H4/QqEQYrEY0un01HLstFotnJ+fo1qtQlVVxGIxDAYDx/XmbW+/30ehUECpVEKr1YKmaQgEAtje3rYdQ0/jarDsGmsXhvF1vn79ik6nY/lM0zRomoZGo4FarYZsNmv5/OTkxDSnBjyO7S4uLhAKhYbdc7/fx8nJiWX+p16vo16vo1Kp4OPHjxPreXZ2Bk3TTGXf3d1B0zR8+PBhuPzh4QHfv383nVDGVEypVEKlUsHe3t7UfTLelqOjo2HZ/X4ft7e3juvN295CoYDfv3+b2miUn8vl5g6Wq12hXbfn9Jih0+nYhmpcpVKxBOj09NSybFJ9Li4upk4qVqtV3N/fT/x8fIeP1mv0oP/48WPqVbpYLJpmzJ2cnp5OLHuaedt7e3u7UDmTuBosu4F6KBSauo7f75+5a2g2m8O/G42GJQherxfxeBzRaBRerxerq6sAHsM7PqcWjUYtdXOad1tZWbHU1ZgcBh5n0UfDrCgKksmk5eS6urqaWo6h0WigUqlY6rCxsTF1n7nVXoOxH+fhWlc4GAwsl2hVVbG2tjZ1PY/Hg1evXsHj8SAcDsPv98Pn86HX6+Ho6Mg0yz/6983NjWU7+/v7w52n6/pw59/f35tmqqPRKLLZLJrNJr58+TJcbgTEzps3b7C5uYlyuYyTkxPTZ8aZPn4lSqfT2NnZwdXVFc7OzobL6/X6cAw5TbFYtCx7//49QqEQKpWK5QmIwY32JhIJvH37FoqizDSeG+dKsE5PT9Hr9SyX0lQqZTugH/fy5UvLskAggPX1ddPBGt1Z45f5jY0N0xk5ekaPn/XGeCEYDJqWT+uSfT4fANieKLquo9frma6owOMBtVvHeDNh/HnquPE2hkIhxx4AcKe94XB42OZFuNIVGncQo3w+n21g5jHpcm8cmFHr6+sTtzP+XePg2HVrTnexk8aM42UAjycHANsDNMu4clK9F11vkfYuSuS1mUAggL29Pdt5rUmazSbOzs5Qr9eh6zrW1tYmDiZ7vZ7l8ryysmL73cFgYDmIxoFe5C52ErugGCG0u2o7DZQHg4Glq5vlCrKs9jpxJVjGazMrKyuIRqNIp9NzvXRWr9dxfHxsani1WrUtB7A/KJPKs/tuo9FAq9WylPGUnWx35huBsrvyOo1b7LY3S/3cau+8c23jXAlWNpud2hU5+fPnz1wDxGkHcZzddn/+/Gn73XmusLOUM43Tay9225vlYC+rvU6e/Z13XddRLpdNy1KpFA4ODp4UVsM8Y4hZxzB2pt2k2IXI6abGbp1ZgrWs9jp59pekW62WZSem02kEAoGJZ5TdQZl0xbD7rqIo8Hg8UFUVXq932I3PO7vsVI7RLruQOHVr87TRaT2J9jp59mDZjQkmBco4Y+0OSrfbtR3A233306dPjvNr87Irx7h6zNPGWbY373oS7XXyV3SFs35mBMvuoEx6tOPz+SxnscSrPMbUwihjFt7ujnF8Tmmcx+Ox3JBMm9A0LKu9Tp49WHZ3c8Zt9qRgqapqCdfNzY3pjDa6DUVRLAfx8vIS1WoVmqah1WqhVCrh9PQUl5eXC7fDLijGAR0PvfHDEyfjj1IeHh6GbZx0Qi6rvU6evSsMBoNQFMW0o87PzxGNRi0zz6OD10gkYnpW2Gw2cXh4iHA4DE3TUK/XcXBwAJ/Ph3g8bnqTtdPp4Nu3b5a6xGKxhdthPJscLSeXy0HTNBQKBdN3Zx3bxGIx0xSBpmk4Pj4ezvRP4kZ7nzrd8OxXLFVVh48+DLVaDX/+/LHsvNHxg91v73q9HkqlEmq1GgaDwfBnVbM+WnrqLPTGxoalPpeXl6btqqqKTCYz8/bGx0yNRsN2ln/Usto7zbMHCwBev3490+Tf6MxzIpGwfRXaYEzaAo+z8js7O47bf+oPUl+8eDH1+Z+iKNjd3Z2pGwQex5LGg2Ano99ZVnuneXJX6PP55n5Y6fV6TWOk1dVVfP78Gfl8fvjWpaIo8Pv98Pv9iEQiSKVSlru+d+/eIZ/Po1KpDJ9Xer1eRCIRZDIZ0wE01i8UCmg2m2i321BVFT6fD+vr60gmkxPnzcbra1AUBT6fb/iZqqrIZrPI5/OoVqtot9vodrvDMra2tqa+gmJXTjKZRCAQQD6fR7PZRKfTgaqqw+mYSCSCZDJp2TdPaa/x5u5TKIeHh3/3Lx/pn/RXdIX0/8NgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEsFgkQgGi0QwWCSCwSIRDBaJYLBIBINFIhgsEvEfmhiBahNiQpEAAAAASUVORK5CYII="
|
|
41
|
+
alt="Placeholder"
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return htmlContainer;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const renderEditButton = () => {
|
|
51
|
+
if (!handleEdit) return null;
|
|
52
|
+
|
|
53
|
+
if (showImage) {
|
|
54
|
+
if (
|
|
55
|
+
value.hasOwnProperty('file_title') &&
|
|
56
|
+
value.hasOwnProperty('file_description')
|
|
57
|
+
) {
|
|
58
|
+
return <EditButton />;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return <EditButton />;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const EditButton = () => (
|
|
67
|
+
<Pencil
|
|
68
|
+
className={styles['pencil-edit']}
|
|
69
|
+
strokeWidth={1}
|
|
70
|
+
size={26}
|
|
71
|
+
onClick={(e) => {
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
e.stopPropagation();
|
|
74
|
+
handleEdit(value);
|
|
75
|
+
}}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<li
|
|
81
|
+
onClick={(e) => {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
if (handleClick) {
|
|
84
|
+
handleClick(containerIndex);
|
|
85
|
+
}
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<DragHandle />
|
|
89
|
+
{truncateText(
|
|
90
|
+
value.label || value.file_title || value.file_name,
|
|
91
|
+
30
|
|
92
|
+
)}
|
|
93
|
+
|
|
94
|
+
{renderImage(value)}
|
|
95
|
+
|
|
96
|
+
{renderEditButton()}
|
|
97
|
+
|
|
98
|
+
{handleDelete && (
|
|
99
|
+
<TrashCan
|
|
100
|
+
className={styles['trash-delete']}
|
|
101
|
+
strokeWidth={1}
|
|
102
|
+
size={26}
|
|
103
|
+
onClick={(e) => {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
handleDelete(
|
|
107
|
+
value.id || containerIndex,
|
|
108
|
+
value.label || value.file_name
|
|
109
|
+
);
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
)}
|
|
113
|
+
</li>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export default SortableElement(SortableItem);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import VisnsSortableItem from './Item';
|
|
3
|
+
import { SortableContainer } from 'react-sortable-hoc';
|
|
4
|
+
|
|
5
|
+
import styles from './styles/List.module.css';
|
|
6
|
+
|
|
7
|
+
const SortableList = ({
|
|
8
|
+
handleClick,
|
|
9
|
+
handleDelete,
|
|
10
|
+
handleEdit,
|
|
11
|
+
items,
|
|
12
|
+
showImage,
|
|
13
|
+
}) => {
|
|
14
|
+
return (
|
|
15
|
+
<ul className={styles.sortlist}>
|
|
16
|
+
{items.map((value, index) => (
|
|
17
|
+
<VisnsSortableItem
|
|
18
|
+
key={`item-${index}`}
|
|
19
|
+
containerIndex={index}
|
|
20
|
+
index={index}
|
|
21
|
+
handleClick={handleClick}
|
|
22
|
+
handleDelete={handleDelete}
|
|
23
|
+
handleEdit={handleEdit}
|
|
24
|
+
showImage={showImage}
|
|
25
|
+
value={value}
|
|
26
|
+
/>
|
|
27
|
+
))}
|
|
28
|
+
</ul>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default SortableContainer(SortableList);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
.sortlist {
|
|
2
|
+
width: 100%;
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-gap: 0.5rem;
|
|
5
|
+
grid-template-columns: repeat(4, 1fr);
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
padding: 0;
|
|
8
|
+
margin: 0;
|
|
9
|
+
list-style: none;
|
|
10
|
+
|
|
11
|
+
li {
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
border-radius: 5px;
|
|
17
|
+
border: 1px solid rgba(var(--primary-color-rgb), 0.2);
|
|
18
|
+
box-shadow: 0px 0px 20px rgba(var(--primary-color-rgb), 0.1);
|
|
19
|
+
padding: 1.25rem;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
list-style: none;
|
|
23
|
+
position: relative;
|
|
24
|
+
color: var(--paragraph-color);
|
|
25
|
+
user-select: none;
|
|
26
|
+
|
|
27
|
+
svg {
|
|
28
|
+
width: 100%;
|
|
29
|
+
max-width: 18px;
|
|
30
|
+
position: absolute;
|
|
31
|
+
left: 5px;
|
|
32
|
+
top: 5px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pencil-edit {
|
|
36
|
+
width: 100%;
|
|
37
|
+
max-width: 18px;
|
|
38
|
+
position: absolute;
|
|
39
|
+
left: 5px;
|
|
40
|
+
top: 30px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.trash-delete {
|
|
44
|
+
width: 100%;
|
|
45
|
+
max-width: 18px;
|
|
46
|
+
position: absolute;
|
|
47
|
+
left: 5px;
|
|
48
|
+
top: 60px;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.sortimg {
|
|
53
|
+
width: 50px;
|
|
54
|
+
position: relative;
|
|
55
|
+
height: 50px;
|
|
56
|
+
margin-left: auto;
|
|
57
|
+
border-radius: 5px;
|
|
58
|
+
overflow: hidden;
|
|
59
|
+
|
|
60
|
+
img {
|
|
61
|
+
display: block;
|
|
62
|
+
object-fit: cover;
|
|
63
|
+
height: 100%;
|
|
64
|
+
width: 100%;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
.sortlist {
|
|
2
|
+
width: 100%;
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-gap: 0.5rem;
|
|
5
|
+
grid-template-columns: repeat(4, 1fr);
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
padding: 0;
|
|
8
|
+
margin: 0;
|
|
9
|
+
list-style: none;
|
|
10
|
+
|
|
11
|
+
li {
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
border-radius: 5px;
|
|
17
|
+
border: 1px solid rgba(var(--primary-color-rgb), 0.2);
|
|
18
|
+
box-shadow: 0px 0px 20px rgba(var(--primary-color-rgb), 0.1);
|
|
19
|
+
padding: 1.25rem;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
list-style: none;
|
|
23
|
+
position: relative;
|
|
24
|
+
color: var(--paragraph-color);
|
|
25
|
+
user-select: none;
|
|
26
|
+
|
|
27
|
+
svg {
|
|
28
|
+
width: 100%;
|
|
29
|
+
max-width: 18px;
|
|
30
|
+
position: absolute;
|
|
31
|
+
left: 5px;
|
|
32
|
+
top: 5px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pencil-edit {
|
|
36
|
+
width: 100%;
|
|
37
|
+
max-width: 18px;
|
|
38
|
+
position: absolute;
|
|
39
|
+
left: 5px;
|
|
40
|
+
top: 30px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.trash-delete {
|
|
44
|
+
width: 100%;
|
|
45
|
+
max-width: 18px;
|
|
46
|
+
position: absolute;
|
|
47
|
+
left: 5px;
|
|
48
|
+
top: 60px;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.sortimg {
|
|
53
|
+
width: 50px;
|
|
54
|
+
position: relative;
|
|
55
|
+
height: 50px;
|
|
56
|
+
margin-left: auto;
|
|
57
|
+
border-radius: 5px;
|
|
58
|
+
overflow: hidden;
|
|
59
|
+
|
|
60
|
+
img {
|
|
61
|
+
display: block;
|
|
62
|
+
object-fit: cover;
|
|
63
|
+
height: 100%;
|
|
64
|
+
width: 100%;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -36,9 +36,24 @@
|
|
|
36
36
|
color: var(--primary-color);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
.formItem {
|
|
40
|
+
width: 50%;
|
|
41
|
+
padding: 0.5em;
|
|
42
|
+
position: relative;
|
|
43
|
+
box-sizing: border-box;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
.formItem .fi__label {
|
|
40
47
|
position: relative;
|
|
41
48
|
display: block;
|
|
49
|
+
|
|
50
|
+
> svg {
|
|
51
|
+
position: absolute;
|
|
52
|
+
right: 0.5em;
|
|
53
|
+
top: 1em;
|
|
54
|
+
color: var(--paragraph-color);
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
}
|
|
42
57
|
}
|
|
43
58
|
|
|
44
59
|
.fi__span {
|
|
@@ -88,6 +103,16 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
88
103
|
top: 0;
|
|
89
104
|
}
|
|
90
105
|
|
|
106
|
+
.fwItem {
|
|
107
|
+
flex-basis: 100%;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.lastItem {
|
|
111
|
+
.btn {
|
|
112
|
+
width: 100%;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
91
116
|
.fi__button--right {
|
|
92
117
|
position: absolute;
|
|
93
118
|
right: 50px;
|
|
@@ -119,7 +144,6 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
119
144
|
) {
|
|
120
145
|
background: var(--item-color);
|
|
121
146
|
border-radius: var(--br);
|
|
122
|
-
border: 1px solid transparent;
|
|
123
147
|
padding: 1rem;
|
|
124
148
|
outline: none;
|
|
125
149
|
width: 100%;
|
package/package.json
CHANGED