@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.
@@ -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
- const url = form.url.replace('/ajax', '');
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: form,
769
+ form,
734
770
  page: {
735
771
  data: pageData,
736
772
  setting: pageSetting,
737
773
  },
738
- paramValue: paramValue,
774
+ paramValue,
739
775
  };
740
776
 
741
- navigate(`${url}/${paramValue}/sort`, {
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]) {
@@ -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('formItem');
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
- if (settings.size === 'full') {
144
- setFormItemClass('formItem fwItem');
145
- } else if (settings.size === 'quarter') {
146
- setFormItemClass('formItem qtrItem');
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="preloader" style={loaderStyle}>
19
- <div className="preloader__icn">
20
- <div className="preloader__cut">
21
- <div className="preloader__donut"></div>
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>
@@ -235,6 +235,7 @@ function GenericDetail({
235
235
  {size === 'full' && truncatedValue
236
236
  ? parse(`<br /><p>${truncatedValue}</p>`)
237
237
  : truncatedValue}
238
+ aaa
238
239
  <CopyToClipboard
239
240
  text={
240
241
  truncatedValue && truncatedValue !== 'null'
@@ -1,12 +1,22 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { Link, useLocation } from 'react-router-dom';
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 '../../cms/sorting/List';
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 + '/sort_update',
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: { data, setting },
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.url;
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.json) {
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.json) {
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 className={`${styles.grid__full} ${styles.crmtitle}`}>
127
- <h1>
128
- <Link
129
- to={
130
- setting && setting.previousUrl
131
- ? setting.previousUrl
132
- : null
133
- }
134
- >
135
- {setting && setting.title
136
- ? setting.title
137
- : null}
138
- </Link>{' '}
139
- {data && data[setting.titleKey] ? (
140
- <Link
141
- to={
142
- setting && setting.previousUrl
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="dragitem"
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(--primary-color);
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(--tertiary-color-rgb), 0.5);
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,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"
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
@@ -59,7 +59,7 @@
59
59
  "react-dom": "^17.0.1"
60
60
  },
61
61
  "name": "@visns-studio/visns-components",
62
- "version": "4.6.10",
62
+ "version": "4.6.12",
63
63
  "description": "Various packages to assist in the development of our Custom Applications.",
64
64
  "main": "index.js",
65
65
  "scripts": {