@evergis/react 4.0.136 → 4.0.137
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/dist/components/Dashboard/containers/AttachmentContainer/constants.d.ts +1 -0
- package/dist/components/Dashboard/containers/AttachmentContainer/utils/saveBlobAsFile.d.ts +7 -0
- package/dist/components/Dashboard/hooks/index.d.ts +1 -0
- package/dist/components/Dashboard/hooks/useAttachmentDownload.d.ts +9 -0
- package/dist/index.js +129 -62
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +129 -63
- package/dist/react.esm.js.map +1 -1
- package/package.json +3 -3
|
@@ -14,6 +14,7 @@ export declare const SHP_MIME_TYPE = "application/octet-stream";
|
|
|
14
14
|
export declare const KML_MIME_TYPE = "application/octet-stream";
|
|
15
15
|
export declare const ZIP_MIME_TYPE = "application/zip";
|
|
16
16
|
export declare const PYTHON_MIME_TYPES: string[];
|
|
17
|
+
export declare const DOWNLOAD_ERROR_DURATION = 5000;
|
|
17
18
|
export declare enum AddAttachmentSource {
|
|
18
19
|
Pc = "pc",
|
|
19
20
|
Catalog = "catalog",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Отдаёт браузеру уже загруженный файл под именем `fileName`.
|
|
3
|
+
*
|
|
4
|
+
* Адрес отзывается не сразу: часть браузеров дочитывает поток уже после клика, и мгновенный
|
|
5
|
+
* `revokeObjectURL` обрывает сохранение.
|
|
6
|
+
*/
|
|
7
|
+
export declare const saveBlobAsFile: (blob: Blob, fileName: string) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Attachment } from '../containers/AttachmentContainer/types';
|
|
2
|
+
/**
|
|
3
|
+
* Скачивание вложения по требованию — файл запрашивается в момент клика, а не заранее.
|
|
4
|
+
*
|
|
5
|
+
* Свой файл лежит за авторизацией (`Authorization: Bearer`), поэтому ссылкой его не отдать:
|
|
6
|
+
* он тянется через api и сохраняется из памяти. Чужой открывается ссылкой — кросс-доменный
|
|
7
|
+
* `download` браузер всё равно игнорирует.
|
|
8
|
+
*/
|
|
9
|
+
export declare const useAttachmentDownload: (items: Attachment[]) => ((index: number) => void);
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ var dateFns = require('date-fns');
|
|
|
12
12
|
var locale = require('date-fns/locale');
|
|
13
13
|
var wkt = require('wkt');
|
|
14
14
|
var turf = require('@turf/turf');
|
|
15
|
+
var uuid = require('uuid');
|
|
15
16
|
var signalr = require('@microsoft/signalr');
|
|
16
17
|
var MapboxDraw = require('@mapbox/mapbox-gl-draw');
|
|
17
18
|
var react = require('swiper/react');
|
|
@@ -21,7 +22,6 @@ var rehypeRaw = require('rehype-raw');
|
|
|
21
22
|
var rehypeSanitize = require('rehype-sanitize');
|
|
22
23
|
var remarkGfm = require('remark-gfm');
|
|
23
24
|
var MapGL = require('react-map-gl/maplibre');
|
|
24
|
-
var uuid = require('uuid');
|
|
25
25
|
require('@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css');
|
|
26
26
|
require('mapbox-gl/dist/mapbox-gl.css');
|
|
27
27
|
var jspdf = require('jspdf');
|
|
@@ -5694,6 +5694,127 @@ const ServerNotificationsProvider = ({ url, initialized, apiClient, children })
|
|
|
5694
5694
|
}, children: children }));
|
|
5695
5695
|
};
|
|
5696
5696
|
|
|
5697
|
+
const useGlobalContext = () => {
|
|
5698
|
+
const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = React.useContext(GlobalContext) || {};
|
|
5699
|
+
const translate = React.useCallback((value, options) => {
|
|
5700
|
+
if (t)
|
|
5701
|
+
return t(value, options);
|
|
5702
|
+
return options?.defaultValue ?? value;
|
|
5703
|
+
}, [t]);
|
|
5704
|
+
return React.useMemo(() => ({
|
|
5705
|
+
t: translate,
|
|
5706
|
+
language,
|
|
5707
|
+
themeName,
|
|
5708
|
+
api,
|
|
5709
|
+
ewktGeometry,
|
|
5710
|
+
ewktExtent,
|
|
5711
|
+
zoomLevel,
|
|
5712
|
+
notification,
|
|
5713
|
+
}), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
|
|
5714
|
+
};
|
|
5715
|
+
|
|
5716
|
+
const GRID_TILE_SIZE = "4.5rem";
|
|
5717
|
+
const LIST_ICON_SIZE = "1.5rem";
|
|
5718
|
+
const JPG_MIME_TYPE = "image/jpeg";
|
|
5719
|
+
const PNG_MIME_TYPE = "image/png";
|
|
5720
|
+
const IMAGE_MIME_TYPES = [
|
|
5721
|
+
"image/apng",
|
|
5722
|
+
"image/avif",
|
|
5723
|
+
"image/gif",
|
|
5724
|
+
"image/jpeg",
|
|
5725
|
+
"image/png",
|
|
5726
|
+
"image/svg+xml",
|
|
5727
|
+
"image/webp",
|
|
5728
|
+
];
|
|
5729
|
+
const XLSX_MIME_TYPES = [
|
|
5730
|
+
"application/vnd.ms-excel",
|
|
5731
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
5732
|
+
];
|
|
5733
|
+
const PDF_MIME_TYPE = "application/pdf";
|
|
5734
|
+
const DOCX_MIME_TYPES = [
|
|
5735
|
+
"application/msword",
|
|
5736
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
5737
|
+
];
|
|
5738
|
+
const CSV_MIME_TYPE = "text/csv";
|
|
5739
|
+
const JSON_MIME_TYPE = "application/json";
|
|
5740
|
+
const TXT_MIME_TYPE = "text/plain";
|
|
5741
|
+
const PPTX_MIME_TYPES = [
|
|
5742
|
+
"application/vnd.ms-powerpoint",
|
|
5743
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
5744
|
+
];
|
|
5745
|
+
const SHP_MIME_TYPE = "application/octet-stream";
|
|
5746
|
+
const KML_MIME_TYPE = "application/octet-stream";
|
|
5747
|
+
const ZIP_MIME_TYPE = "application/zip";
|
|
5748
|
+
const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
|
|
5749
|
+
const DOWNLOAD_ERROR_DURATION = 5000;
|
|
5750
|
+
var AddAttachmentSource;
|
|
5751
|
+
(function (AddAttachmentSource) {
|
|
5752
|
+
AddAttachmentSource["Pc"] = "pc";
|
|
5753
|
+
AddAttachmentSource["Catalog"] = "catalog";
|
|
5754
|
+
AddAttachmentSource["Link"] = "link";
|
|
5755
|
+
})(AddAttachmentSource || (AddAttachmentSource = {}));
|
|
5756
|
+
|
|
5757
|
+
const REVOKE_DELAY = 1000;
|
|
5758
|
+
/**
|
|
5759
|
+
* Отдаёт браузеру уже загруженный файл под именем `fileName`.
|
|
5760
|
+
*
|
|
5761
|
+
* Адрес отзывается не сразу: часть браузеров дочитывает поток уже после клика, и мгновенный
|
|
5762
|
+
* `revokeObjectURL` обрывает сохранение.
|
|
5763
|
+
*/
|
|
5764
|
+
const saveBlobAsFile = (blob, fileName) => {
|
|
5765
|
+
const url = URL.createObjectURL(blob);
|
|
5766
|
+
const link = document.createElement("a");
|
|
5767
|
+
link.href = url;
|
|
5768
|
+
link.download = fileName;
|
|
5769
|
+
link.style.display = "none";
|
|
5770
|
+
document.body.appendChild(link);
|
|
5771
|
+
link.click();
|
|
5772
|
+
document.body.removeChild(link);
|
|
5773
|
+
window.setTimeout(() => URL.revokeObjectURL(url), REVOKE_DELAY);
|
|
5774
|
+
};
|
|
5775
|
+
|
|
5776
|
+
/**
|
|
5777
|
+
* Скачивание вложения по требованию — файл запрашивается в момент клика, а не заранее.
|
|
5778
|
+
*
|
|
5779
|
+
* Свой файл лежит за авторизацией (`Authorization: Bearer`), поэтому ссылкой его не отдать:
|
|
5780
|
+
* он тянется через api и сохраняется из памяти. Чужой открывается ссылкой — кросс-доменный
|
|
5781
|
+
* `download` браузер всё равно игнорирует.
|
|
5782
|
+
*/
|
|
5783
|
+
const useAttachmentDownload = (items) => {
|
|
5784
|
+
const { api, notification, t } = useGlobalContext();
|
|
5785
|
+
const inFlightRef = React.useRef(new Set());
|
|
5786
|
+
return React.useCallback((index) => {
|
|
5787
|
+
const item = items[index];
|
|
5788
|
+
if (!item)
|
|
5789
|
+
return;
|
|
5790
|
+
if (item.isExternal) {
|
|
5791
|
+
window.open(item.link, "_blank", "noopener,noreferrer");
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
if (!api?.catalog?.getFile || inFlightRef.current.has(item.link))
|
|
5795
|
+
return;
|
|
5796
|
+
inFlightRef.current.add(item.link);
|
|
5797
|
+
api.catalog
|
|
5798
|
+
.getFile(item.link)
|
|
5799
|
+
.then(blob => saveBlobAsFile(blob, item.name))
|
|
5800
|
+
.catch(error => {
|
|
5801
|
+
notification?.add({
|
|
5802
|
+
id: uuid.v4(),
|
|
5803
|
+
title: t("attachments.downloadError", {
|
|
5804
|
+
ns: "common",
|
|
5805
|
+
defaultValue: "Не удалось скачать вложение",
|
|
5806
|
+
}),
|
|
5807
|
+
description: error instanceof Error ? error.message : item.name,
|
|
5808
|
+
error: true,
|
|
5809
|
+
duration: DOWNLOAD_ERROR_DURATION,
|
|
5810
|
+
});
|
|
5811
|
+
})
|
|
5812
|
+
.finally(() => {
|
|
5813
|
+
inFlightRef.current.delete(item.link);
|
|
5814
|
+
});
|
|
5815
|
+
}, [items, api, notification, t]);
|
|
5816
|
+
};
|
|
5817
|
+
|
|
5697
5818
|
/**
|
|
5698
5819
|
* Контекст виджет-фрейма. Возвращаемый объект включает поля и {@link DashboardContext},
|
|
5699
5820
|
* и {@link FeatureCardContext}, а гибридные (`config`, `isEditing`, `isLoading`, `pageIndex`,
|
|
@@ -5810,65 +5931,6 @@ const useAttachmentItems = ({ type, elementConfig, valueOverride, }) => {
|
|
|
5810
5931
|
};
|
|
5811
5932
|
};
|
|
5812
5933
|
|
|
5813
|
-
const useGlobalContext = () => {
|
|
5814
|
-
const { t, language, themeName, api, ewktGeometry, ewktExtent, zoomLevel, notification } = React.useContext(GlobalContext) || {};
|
|
5815
|
-
const translate = React.useCallback((value, options) => {
|
|
5816
|
-
if (t)
|
|
5817
|
-
return t(value, options);
|
|
5818
|
-
return options?.defaultValue ?? value;
|
|
5819
|
-
}, [t]);
|
|
5820
|
-
return React.useMemo(() => ({
|
|
5821
|
-
t: translate,
|
|
5822
|
-
language,
|
|
5823
|
-
themeName,
|
|
5824
|
-
api,
|
|
5825
|
-
ewktGeometry,
|
|
5826
|
-
ewktExtent,
|
|
5827
|
-
zoomLevel,
|
|
5828
|
-
notification,
|
|
5829
|
-
}), [language, translate, api, ewktGeometry, ewktExtent, zoomLevel, themeName, notification]);
|
|
5830
|
-
};
|
|
5831
|
-
|
|
5832
|
-
const GRID_TILE_SIZE = "4.5rem";
|
|
5833
|
-
const LIST_ICON_SIZE = "1.5rem";
|
|
5834
|
-
const JPG_MIME_TYPE = "image/jpeg";
|
|
5835
|
-
const PNG_MIME_TYPE = "image/png";
|
|
5836
|
-
const IMAGE_MIME_TYPES = [
|
|
5837
|
-
"image/apng",
|
|
5838
|
-
"image/avif",
|
|
5839
|
-
"image/gif",
|
|
5840
|
-
"image/jpeg",
|
|
5841
|
-
"image/png",
|
|
5842
|
-
"image/svg+xml",
|
|
5843
|
-
"image/webp",
|
|
5844
|
-
];
|
|
5845
|
-
const XLSX_MIME_TYPES = [
|
|
5846
|
-
"application/vnd.ms-excel",
|
|
5847
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
5848
|
-
];
|
|
5849
|
-
const PDF_MIME_TYPE = "application/pdf";
|
|
5850
|
-
const DOCX_MIME_TYPES = [
|
|
5851
|
-
"application/msword",
|
|
5852
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
5853
|
-
];
|
|
5854
|
-
const CSV_MIME_TYPE = "text/csv";
|
|
5855
|
-
const JSON_MIME_TYPE = "application/json";
|
|
5856
|
-
const TXT_MIME_TYPE = "text/plain";
|
|
5857
|
-
const PPTX_MIME_TYPES = [
|
|
5858
|
-
"application/vnd.ms-powerpoint",
|
|
5859
|
-
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
5860
|
-
];
|
|
5861
|
-
const SHP_MIME_TYPE = "application/octet-stream";
|
|
5862
|
-
const KML_MIME_TYPE = "application/octet-stream";
|
|
5863
|
-
const ZIP_MIME_TYPE = "application/zip";
|
|
5864
|
-
const PYTHON_MIME_TYPES = ["application/x-python-code", "text/x-python"];
|
|
5865
|
-
var AddAttachmentSource;
|
|
5866
|
-
(function (AddAttachmentSource) {
|
|
5867
|
-
AddAttachmentSource["Pc"] = "pc";
|
|
5868
|
-
AddAttachmentSource["Catalog"] = "catalog";
|
|
5869
|
-
AddAttachmentSource["Link"] = "link";
|
|
5870
|
-
})(AddAttachmentSource || (AddAttachmentSource = {}));
|
|
5871
|
-
|
|
5872
5934
|
var FileType;
|
|
5873
5935
|
(function (FileType) {
|
|
5874
5936
|
FileType[FileType["UNKNOWN"] = 0] = "UNKNOWN";
|
|
@@ -9202,9 +9264,11 @@ const AttachmentContainer = React.memo(({ type, elementConfig, renderElement })
|
|
|
9202
9264
|
setPreviewIndex(idx);
|
|
9203
9265
|
}, [items]);
|
|
9204
9266
|
const handleClosePreview = React.useCallback(() => setPreviewIndex(null), []);
|
|
9267
|
+
const downloadByIndex = useAttachmentDownload(items);
|
|
9268
|
+
const handleDownload = React.useCallback((_image, index) => downloadByIndex(index), [downloadByIndex]);
|
|
9205
9269
|
const handleShowMore = React.useCallback(() => setShowMore(true), [setShowMore]);
|
|
9206
9270
|
const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
|
|
9207
|
-
return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
|
|
9271
|
+
return (jsxRuntime.jsxs(ContainerRoot, { ...root, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { ...body, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, onDownload: handleDownload, errorTitleText: t("attachments.resourceUnavailable", {
|
|
9208
9272
|
ns: "common",
|
|
9209
9273
|
defaultValue: "Ресурс недоступен",
|
|
9210
9274
|
}) }, previewIndex))] }) }))] }));
|
|
@@ -13249,6 +13313,8 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
|
|
|
13249
13313
|
setPreviewIndex(idx);
|
|
13250
13314
|
}, [items]);
|
|
13251
13315
|
const handleClosePreview = React.useCallback(() => setPreviewIndex(null), []);
|
|
13316
|
+
const downloadByIndex = useAttachmentDownload(items);
|
|
13317
|
+
const handleDownload = React.useCallback((_image, index) => downloadByIndex(index), [downloadByIndex]);
|
|
13252
13318
|
const handleShowMore = React.useCallback(() => setShowMore(true), [setShowMore]);
|
|
13253
13319
|
const handleDelete = React.useCallback((link) => {
|
|
13254
13320
|
persist(items.filter(item => item.link !== link));
|
|
@@ -13299,7 +13365,7 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
|
|
|
13299
13365
|
setUploading(false);
|
|
13300
13366
|
}
|
|
13301
13367
|
}, [api, items, parentResourceId, persist]);
|
|
13302
|
-
return (jsxRuntime.jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsxRuntime.jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsxRuntime.jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview }, previewIndex))] }));
|
|
13368
|
+
return (jsxRuntime.jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, ...bgHost, children: [jsxRuntime.jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsxRuntime.jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsxRuntime.jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: previewImages, initialIndex: previewIndex, isOpen: previewIndex !== null, onClose: handleClosePreview, onDownload: handleDownload }, previewIndex))] }));
|
|
13303
13369
|
});
|
|
13304
13370
|
|
|
13305
13371
|
// `ProgressContainer` и `RoundedBackgroundContainer` исторически принимают `InnerContainerProps`
|
|
@@ -18854,6 +18920,7 @@ exports.transparentizeColor = transparentizeColor;
|
|
|
18854
18920
|
exports.updateDataSource = updateDataSource;
|
|
18855
18921
|
exports.useAfterSave = useAfterSave;
|
|
18856
18922
|
exports.useAppHeight = useAppHeight;
|
|
18923
|
+
exports.useAttachmentDownload = useAttachmentDownload;
|
|
18857
18924
|
exports.useAttachmentItems = useAttachmentItems;
|
|
18858
18925
|
exports.useAttachmentPreviewImages = useAttachmentPreviewImages;
|
|
18859
18926
|
exports.useAutoCompleteControl = useAutoCompleteControl;
|