@visns-studio/visns-components 5.6.14 → 5.7.1
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 -5
- package/src/components/cms/DataGrid.jsx +70 -7
- package/src/components/cms/DropZone.jsx +3 -4
- package/src/components/cms/Form.jsx +3 -4
- package/src/components/cms/generic/CmsDetail.jsx +0 -2
- package/src/components/crm/Autocomplete.jsx +161 -127
- package/src/components/crm/DataGrid.jsx +218 -75
- package/src/components/crm/Download.jsx +15 -4
- package/src/components/crm/Fetch.jsx +69 -16
- package/src/components/crm/Form.jsx +3 -3
- package/src/components/crm/Notification.jsx +237 -106
- package/src/components/crm/QuickAction.jsx +318 -91
- package/src/components/crm/generic/GenericDashboard.jsx +3 -3
- package/src/components/crm/generic/GenericDetail.jsx +46 -130
- package/src/components/crm/generic/GenericDynamic.jsx +3 -3
- package/src/components/crm/generic/GenericEditableTable.jsx +3 -4
- package/src/components/crm/generic/GenericFormBuilder.jsx +3 -3
- package/src/components/crm/generic/NotificationList.jsx +76 -7
- package/src/components/crm/generic/styles/NotificationList.module.scss +90 -2
- package/src/components/crm/generic/styles/SweetAlertCustom.css +27 -3
- package/src/components/crm/styles/DataGrid.module.scss +5 -0
- package/src/components/crm/styles/Notification.module.scss +313 -96
- package/src/components/crm/styles/QuickAction.module.scss +168 -46
- package/src/components/styles/global.css +5 -0
- package/src/components/utils/ConfirmDialog.js +155 -0
- package/src/utils/fetchUtil.js +240 -0
package/package.json
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@emotion/is-prop-valid": "^1.3.1",
|
|
4
4
|
"@fontsource/barlow": "^5.2.5",
|
|
5
|
-
"@inovua/reactdatagrid-community": "^5.10.2",
|
|
6
|
-
"@inovua/reactdatagrid-enterprise": "^5.10.2",
|
|
7
5
|
"@nivo/bar": "^0.88.0",
|
|
8
6
|
"@nivo/core": "^0.88.0",
|
|
9
7
|
"@nivo/line": "^0.88.0",
|
|
@@ -16,7 +14,6 @@
|
|
|
16
14
|
"akar-icons": "^1.9.31",
|
|
17
15
|
"array-move": "^4.0.0",
|
|
18
16
|
"awesome-debounce-promise": "^2.1.0",
|
|
19
|
-
"axios": "^1.9.0",
|
|
20
17
|
"browser-image-compression": "^2.0.2",
|
|
21
18
|
"dayjs": "^1.11.13",
|
|
22
19
|
"fabric": "^6.6.4",
|
|
@@ -33,7 +30,6 @@
|
|
|
33
30
|
"quill-image-uploader": "^1.3.0",
|
|
34
31
|
"react-big-calendar": "^1.18.0",
|
|
35
32
|
"react-color": "^2.19.3",
|
|
36
|
-
"react-confirm-alert": "^3.0.6",
|
|
37
33
|
"react-copy-to-clipboard": "^5.1.0",
|
|
38
34
|
"react-datepicker": "^8.3.0",
|
|
39
35
|
"react-dropzone": "^14.3.8",
|
|
@@ -84,7 +80,7 @@
|
|
|
84
80
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
85
81
|
},
|
|
86
82
|
"name": "@visns-studio/visns-components",
|
|
87
|
-
"version": "5.
|
|
83
|
+
"version": "5.7.1",
|
|
88
84
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
89
85
|
"main": "src/index.js",
|
|
90
86
|
"files": [
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { useNavigate } from 'react-router-dom';
|
|
3
|
-
import axios from 'axios';
|
|
4
3
|
import debounce from 'lodash.debounce';
|
|
5
4
|
import moment from 'moment';
|
|
6
5
|
import numeral from 'numeral';
|
|
@@ -10,9 +9,10 @@ import NumberFilter from '@visns-studio/visns-datagrid-enterprise/NumberFilter';
|
|
|
10
9
|
import SelectFilter from '@visns-studio/visns-datagrid-enterprise/SelectFilter';
|
|
11
10
|
import DateFilter from '@visns-studio/visns-datagrid-enterprise/DateFilter';
|
|
12
11
|
import ReactDataGrid from '@visns-studio/visns-datagrid-enterprise';
|
|
13
|
-
import { confirmAlert } from 'react-confirm-alert';
|
|
14
12
|
import { toast } from 'react-toastify';
|
|
15
13
|
import Toggle from 'react-toggle';
|
|
14
|
+
import fetchUtil from '../../utils/fetchUtil';
|
|
15
|
+
import { confirmDialog } from '../utils/ConfirmDialog';
|
|
16
16
|
import {
|
|
17
17
|
Backspace,
|
|
18
18
|
Check,
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
} from 'akar-icons';
|
|
33
33
|
|
|
34
34
|
import '@visns-studio/visns-datagrid-enterprise/index.css';
|
|
35
|
-
import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
36
35
|
import 'react-toggle/style.css';
|
|
37
36
|
|
|
38
37
|
import CustomFetch from '../crm/Fetch';
|
|
@@ -82,7 +81,7 @@ const loadData = async (
|
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
try {
|
|
85
|
-
const response = await
|
|
84
|
+
const response = await fetchUtil.post(url, params);
|
|
86
85
|
const { data, total } = response.data;
|
|
87
86
|
return { data, count: total };
|
|
88
87
|
} catch (error) {
|
|
@@ -171,11 +170,12 @@ const DataGrid = ({
|
|
|
171
170
|
modalOpen('update', d.id);
|
|
172
171
|
break;
|
|
173
172
|
case 'delete':
|
|
174
|
-
|
|
173
|
+
confirmDialog({
|
|
175
174
|
title: 'Delete Item',
|
|
176
175
|
message: `Are you sure you want to delete ${
|
|
177
176
|
d.name ? d.name : d.label ? d.label : 'this item'
|
|
178
177
|
}?`,
|
|
178
|
+
data: d, // Pass the row data
|
|
179
179
|
buttons: [
|
|
180
180
|
{
|
|
181
181
|
label: 'Yes',
|
|
@@ -213,9 +213,10 @@ const DataGrid = ({
|
|
|
213
213
|
});
|
|
214
214
|
break;
|
|
215
215
|
default:
|
|
216
|
-
|
|
216
|
+
confirmDialog({
|
|
217
217
|
title: s.title,
|
|
218
218
|
message: '',
|
|
219
|
+
data: d, // Pass the row data
|
|
219
220
|
buttons: [
|
|
220
221
|
{
|
|
221
222
|
label: 'Yes',
|
|
@@ -1208,7 +1209,69 @@ const DataGrid = ({
|
|
|
1208
1209
|
onClick={(e) => {
|
|
1209
1210
|
e.preventDefault();
|
|
1210
1211
|
e.stopPropagation();
|
|
1211
|
-
|
|
1212
|
+
|
|
1213
|
+
// Actions that should have confirmation dialogs
|
|
1214
|
+
const actionsRequiringConfirmation = [
|
|
1215
|
+
'complete',
|
|
1216
|
+
'primary',
|
|
1217
|
+
'ssa',
|
|
1218
|
+
];
|
|
1219
|
+
|
|
1220
|
+
// If this action requires confirmation and is not delete (which has its own confirmation)
|
|
1221
|
+
if (
|
|
1222
|
+
actionsRequiringConfirmation.includes(
|
|
1223
|
+
setting.id
|
|
1224
|
+
) &&
|
|
1225
|
+
setting.id !== 'delete'
|
|
1226
|
+
) {
|
|
1227
|
+
// Get tooltip content for the message
|
|
1228
|
+
const tooltipContent =
|
|
1229
|
+
setting.active &&
|
|
1230
|
+
data.hasOwnProperty(
|
|
1231
|
+
setting.active.id
|
|
1232
|
+
) &&
|
|
1233
|
+
data[setting.active.id] ===
|
|
1234
|
+
setting.active.value
|
|
1235
|
+
? setting.active.title
|
|
1236
|
+
: setting.title;
|
|
1237
|
+
|
|
1238
|
+
// Create a message based on the tooltip
|
|
1239
|
+
let message = `Are you sure you want to ${tooltipContent.toLowerCase()}?`;
|
|
1240
|
+
|
|
1241
|
+
// Add item identifier if available
|
|
1242
|
+
const itemName =
|
|
1243
|
+
data.name ||
|
|
1244
|
+
data.label ||
|
|
1245
|
+
data.title ||
|
|
1246
|
+
data.id;
|
|
1247
|
+
if (itemName) {
|
|
1248
|
+
message += ` Item: "${itemName}"`;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// Show confirmation dialog
|
|
1252
|
+
confirmDialog({
|
|
1253
|
+
title: tooltipContent,
|
|
1254
|
+
message: message,
|
|
1255
|
+
data: data,
|
|
1256
|
+
buttons: [
|
|
1257
|
+
{
|
|
1258
|
+
label: 'Yes',
|
|
1259
|
+
onClick: () =>
|
|
1260
|
+
handleSettingClick(
|
|
1261
|
+
setting,
|
|
1262
|
+
data
|
|
1263
|
+
),
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
label: 'No',
|
|
1267
|
+
onClick: () => {},
|
|
1268
|
+
},
|
|
1269
|
+
],
|
|
1270
|
+
});
|
|
1271
|
+
} else {
|
|
1272
|
+
// For actions that don't need confirmation or already have it (delete)
|
|
1273
|
+
handleSettingClick(setting, data);
|
|
1274
|
+
}
|
|
1212
1275
|
}}
|
|
1213
1276
|
>
|
|
1214
1277
|
{renderSetting(setting, data)}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
2
|
import { motion } from 'framer-motion';
|
|
3
3
|
import { useDropzone } from 'react-dropzone';
|
|
4
|
-
import { confirmAlert } from 'react-confirm-alert';
|
|
5
4
|
import { CircleX, File, TrashCan } from 'akar-icons';
|
|
6
5
|
import { toast } from 'react-toastify';
|
|
7
6
|
import { arrayMoveImmutable } from 'array-move';
|
|
8
7
|
import Popup from 'reactjs-popup';
|
|
9
8
|
import imageCompression from 'browser-image-compression';
|
|
10
9
|
|
|
11
|
-
import '
|
|
12
|
-
|
|
10
|
+
import { confirmDialog } from '../utils/ConfirmDialog';
|
|
13
11
|
import CustomFetch from '../crm/Fetch';
|
|
14
12
|
import SortableList from './sorting/List';
|
|
15
13
|
|
|
@@ -122,9 +120,10 @@ function VisnsDropZone({ fetchData, files, settings }) {
|
|
|
122
120
|
|
|
123
121
|
const handleDelete = (id, name) => {
|
|
124
122
|
if (id && id > 0) {
|
|
125
|
-
|
|
123
|
+
confirmDialog({
|
|
126
124
|
title: 'Confirm to Delete File',
|
|
127
125
|
message: 'Are you sure you want to delete ' + name,
|
|
126
|
+
data: { name: name }, // Pass the file name as data
|
|
128
127
|
buttons: [
|
|
129
128
|
{
|
|
130
129
|
label: 'Yes',
|
|
@@ -5,11 +5,9 @@ import slugify from 'react-slugify';
|
|
|
5
5
|
import moment from 'moment';
|
|
6
6
|
import Reveal from 'react-reveal/Reveal';
|
|
7
7
|
import parse from 'html-react-parser';
|
|
8
|
-
import { confirmAlert } from 'react-confirm-alert';
|
|
9
8
|
import { toast } from 'react-toastify';
|
|
10
9
|
import { Copy, TrashBin } from 'akar-icons';
|
|
11
|
-
|
|
12
|
-
import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
10
|
+
import { confirmDialog } from '../utils/ConfirmDialog';
|
|
13
11
|
|
|
14
12
|
function Form(props) {
|
|
15
13
|
const { dataId, navigate, form } = props;
|
|
@@ -245,9 +243,10 @@ function Form(props) {
|
|
|
245
243
|
|
|
246
244
|
const handleDelete = (e) => {
|
|
247
245
|
if (e) {
|
|
248
|
-
|
|
246
|
+
confirmDialog({
|
|
249
247
|
title: 'Delete this entry',
|
|
250
248
|
message: 'Are you sure you want to delete it?',
|
|
249
|
+
data: data, // Pass the data object for context
|
|
251
250
|
buttons: [
|
|
252
251
|
{
|
|
253
252
|
label: 'Yes',
|
|
@@ -4,8 +4,6 @@ import Reveal from 'react-reveal/Reveal';
|
|
|
4
4
|
import { ToastContainer } from 'react-toastify';
|
|
5
5
|
import CmsForm from '../Form';
|
|
6
6
|
|
|
7
|
-
import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
8
|
-
|
|
9
7
|
function CmsDetail({ setting }) {
|
|
10
8
|
const { dataId } = useParams();
|
|
11
9
|
const navigate = useNavigate();
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import axios from 'axios';
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo, memo } from 'react';
|
|
3
2
|
import AwesomeDebouncePromise from 'awesome-debounce-promise';
|
|
4
3
|
import { ToggleOffFill, ToggleOnFill } from 'akar-icons';
|
|
5
4
|
import styles from './styles/Autocomplete.module.scss';
|
|
5
|
+
import fetchUtil from '../../utils/fetchUtil';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// Create the debounced function outside the component to prevent recreation
|
|
8
|
+
const createDebouncedSearch = (fn) =>
|
|
9
|
+
AwesomeDebouncePromise(fn, 500, {
|
|
10
|
+
key: (id) => id,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const VisnsAutocomplete = memo((props) => {
|
|
8
14
|
const {
|
|
9
15
|
api,
|
|
10
16
|
country,
|
|
@@ -15,160 +21,188 @@ const VisnsAutocomplete = (props) => {
|
|
|
15
21
|
setFormData,
|
|
16
22
|
style,
|
|
17
23
|
} = props;
|
|
24
|
+
|
|
18
25
|
const [search, setSearch] = useState('');
|
|
19
26
|
const [results, setResults] = useState([]);
|
|
20
27
|
const [isLoading, setIsLoading] = useState(false);
|
|
21
28
|
const [overwrite, setOverwrite] = useState(false);
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
setIsLoading(false);
|
|
28
|
-
} else {
|
|
29
|
-
let url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${value}.json?types=address,poi&access_token=${api}`;
|
|
30
|
+
// Memoize URL building logic to avoid recalculations
|
|
31
|
+
const buildSearchUrl = useCallback(
|
|
32
|
+
(value) => {
|
|
33
|
+
if (!value || !api) return null;
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
url += `&country=${country}`;
|
|
33
|
-
}
|
|
35
|
+
let url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${value}.json?types=address,poi&access_token=${api}`;
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
37
|
+
if (country) {
|
|
38
|
+
url += `&country=${country}`;
|
|
39
|
+
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
41
|
+
if (mapbox) {
|
|
42
|
+
if (mapbox.proximity) {
|
|
43
|
+
url += `&proximity=${mapbox.proximity}`;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
setResults(response.data.features);
|
|
49
|
-
setIsLoading(false);
|
|
50
|
-
})
|
|
51
|
-
.catch(function (error) {
|
|
52
|
-
console.log(error);
|
|
53
|
-
});
|
|
46
|
+
if (mapbox.bbox) {
|
|
47
|
+
url += `&bbox=${mapbox.bbox}`;
|
|
48
|
+
}
|
|
54
49
|
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
return url;
|
|
52
|
+
},
|
|
53
|
+
[api, country, mapbox]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const performSearch = useCallback(
|
|
57
|
+
(id, value) => {
|
|
58
|
+
if (id <= 0 || !value) {
|
|
59
|
+
setResults([]);
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const url = buildSearchUrl(value);
|
|
65
|
+
if (!url) return;
|
|
66
|
+
|
|
67
|
+
fetchUtil
|
|
68
|
+
.get(url)
|
|
69
|
+
.then((response) => {
|
|
70
|
+
setResults(response.data.features || []);
|
|
71
|
+
setIsLoading(false);
|
|
72
|
+
})
|
|
73
|
+
.catch((error) => {
|
|
74
|
+
console.log(error);
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
[buildSearchUrl]
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Create the debounced search function using our memoized performSearch
|
|
82
|
+
const performSearchDebounced = useMemo(
|
|
83
|
+
() => createDebouncedSearch(performSearch),
|
|
84
|
+
[performSearch]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const handleSearchChange = useCallback(
|
|
88
|
+
async (e) => {
|
|
89
|
+
if (!e) return;
|
|
90
|
+
|
|
91
|
+
const newValue = e.target.value;
|
|
92
|
+
setSearch(newValue);
|
|
61
93
|
setFormData((prevState) => ({
|
|
62
94
|
...prevState,
|
|
63
|
-
[field]:
|
|
95
|
+
[field]: newValue,
|
|
64
96
|
}));
|
|
65
97
|
|
|
66
|
-
if (overwrite
|
|
98
|
+
if (!overwrite) {
|
|
67
99
|
setIsLoading(true);
|
|
100
|
+
await performSearchDebounced(1, newValue);
|
|
68
101
|
}
|
|
102
|
+
},
|
|
103
|
+
[field, overwrite, performSearchDebounced, setFormData]
|
|
104
|
+
);
|
|
69
105
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const performSearchDebounced = AwesomeDebouncePromise(performSearch, 500, {
|
|
77
|
-
key: (id, value) => id,
|
|
78
|
-
});
|
|
106
|
+
const handleItemClicked = useCallback(
|
|
107
|
+
(place) => {
|
|
108
|
+
const address = place.address || '';
|
|
109
|
+
const text = place.text || '';
|
|
110
|
+
const search = address && text ? `${address} ${text}` : text;
|
|
79
111
|
|
|
80
|
-
|
|
81
|
-
const address =
|
|
82
|
-
place.address !== undefined && place.address !== null
|
|
83
|
-
? place.address
|
|
84
|
-
: '';
|
|
85
|
-
const text =
|
|
86
|
-
place.text !== undefined && place.text !== null ? place.text : '';
|
|
87
|
-
|
|
88
|
-
const search = address && text ? `${address} ${text}` : text;
|
|
89
|
-
setSearch(search);
|
|
90
|
-
setResults([]);
|
|
91
|
-
onSelect(place, field);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const handleOverwrite = () => {
|
|
95
|
-
if (overwrite === false) {
|
|
96
|
-
setOverwrite(true);
|
|
112
|
+
setSearch(search);
|
|
97
113
|
setResults([]);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
onSelect(place, field);
|
|
115
|
+
},
|
|
116
|
+
[field, onSelect]
|
|
117
|
+
);
|
|
102
118
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
119
|
+
const handleOverwrite = useCallback(() => {
|
|
120
|
+
setOverwrite((prevState) => {
|
|
121
|
+
if (!prevState) {
|
|
122
|
+
setResults([]);
|
|
107
123
|
}
|
|
124
|
+
return !prevState;
|
|
125
|
+
});
|
|
126
|
+
}, []);
|
|
127
|
+
|
|
128
|
+
// Effect to handle overwrite toggle
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (!overwrite && search) {
|
|
131
|
+
setIsLoading(true);
|
|
132
|
+
performSearch(1, search);
|
|
108
133
|
}
|
|
109
|
-
}, [overwrite]);
|
|
134
|
+
}, [overwrite, search, performSearch]);
|
|
110
135
|
|
|
136
|
+
// Effect to sync with inputValue prop
|
|
111
137
|
useEffect(() => {
|
|
112
|
-
|
|
138
|
+
if (inputValue !== undefined) {
|
|
139
|
+
setSearch(inputValue);
|
|
140
|
+
}
|
|
113
141
|
}, [inputValue]);
|
|
114
142
|
|
|
143
|
+
// Memoize the input style to prevent recalculation
|
|
144
|
+
const inputStyle = useMemo(
|
|
145
|
+
() => ({
|
|
146
|
+
height: style?.multi_select_height || '52px',
|
|
147
|
+
}),
|
|
148
|
+
[style]
|
|
149
|
+
);
|
|
150
|
+
|
|
115
151
|
return (
|
|
116
|
-
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
152
|
+
<div className={styles.AutocompletePlace}>
|
|
153
|
+
<input
|
|
154
|
+
className={styles['AutocompletePlace-input']}
|
|
155
|
+
style={inputStyle}
|
|
156
|
+
type="text"
|
|
157
|
+
value={search || ''}
|
|
158
|
+
onChange={handleSearchChange}
|
|
159
|
+
placeholder="Type an address"
|
|
160
|
+
autoComplete="off"
|
|
161
|
+
/>
|
|
162
|
+
|
|
163
|
+
{overwrite ? (
|
|
164
|
+
<ToggleOnFill
|
|
165
|
+
data-tooltip-id="system-tooltip"
|
|
166
|
+
data-tooltip-content="Enable Autocomplete"
|
|
167
|
+
strokeWidth={2}
|
|
168
|
+
size={24}
|
|
169
|
+
onClick={handleOverwrite}
|
|
170
|
+
className={styles.toggleActive}
|
|
131
171
|
/>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
{isLoading && (
|
|
163
|
-
<li className={styles['AutocompletePlace-items']}>
|
|
164
|
-
Loading...
|
|
165
|
-
</li>
|
|
166
|
-
)}
|
|
167
|
-
</ul>
|
|
168
|
-
) : null}
|
|
169
|
-
</div>
|
|
170
|
-
</>
|
|
172
|
+
) : (
|
|
173
|
+
<ToggleOffFill
|
|
174
|
+
data-tooltip-id="system-tooltip"
|
|
175
|
+
data-tooltip-content="Disable Autocomplete"
|
|
176
|
+
strokeWidth={2}
|
|
177
|
+
size={24}
|
|
178
|
+
onClick={handleOverwrite}
|
|
179
|
+
/>
|
|
180
|
+
)}
|
|
181
|
+
|
|
182
|
+
{results.length > 0 && (
|
|
183
|
+
<ul className="AutocompletePlace-results">
|
|
184
|
+
{results.map((place) => (
|
|
185
|
+
<li
|
|
186
|
+
key={place.id}
|
|
187
|
+
className={styles['AutocompletePlace-items']}
|
|
188
|
+
onClick={() => handleItemClicked(place)}
|
|
189
|
+
>
|
|
190
|
+
{place.place_name}
|
|
191
|
+
</li>
|
|
192
|
+
))}
|
|
193
|
+
|
|
194
|
+
{isLoading && (
|
|
195
|
+
<li className={styles['AutocompletePlace-items']}>
|
|
196
|
+
Loading...
|
|
197
|
+
</li>
|
|
198
|
+
)}
|
|
199
|
+
</ul>
|
|
200
|
+
)}
|
|
201
|
+
</div>
|
|
171
202
|
);
|
|
172
|
-
};
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Add display name for debugging
|
|
206
|
+
VisnsAutocomplete.displayName = 'VisnsAutocomplete';
|
|
173
207
|
|
|
174
208
|
export default VisnsAutocomplete;
|