diff --git a/client/components/Omnichannel/Tags.js b/client/components/Omnichannel/Tags.js
index c66a8d77ebcfa..4d7d20ec0c140 100644
--- a/client/components/Omnichannel/Tags.js
+++ b/client/components/Omnichannel/Tags.js
@@ -21,6 +21,7 @@ const Tags = ({ tags = [], handler = () => {}, error = '', tagRequired = false }
const dispatchToastMessage = useToastMessageDispatch();
const [tagValue, handleTagValue] = useState('');
+ const [paginatedTagValue, handlePaginatedTagValue] = useState([]);
const removeTag = (tag) => {
const tagsFiltered = tags.filter((tagArray) => tagArray !== tag);
@@ -54,7 +55,13 @@ const Tags = ({ tags = [], handler = () => {}, error = '', tagRequired = false }
{Tags && tagsList && tagsList.length > 0 ? (
-
+ {
+ handler(tags.map((tag) => tag.label));
+ handlePaginatedTagValue(tags);
+ }}
+ />
) : (
<>
diff --git a/client/contexts/ServerContext/endpoints.ts b/client/contexts/ServerContext/endpoints.ts
index deb3f9c4728c0..61c402d809bd6 100644
--- a/client/contexts/ServerContext/endpoints.ts
+++ b/client/contexts/ServerContext/endpoints.ts
@@ -18,6 +18,7 @@ import { LivechatDepartment } from './endpoints/v1/livechat/department';
import { LivechatDepartmentsByUnit } from './endpoints/v1/livechat/departmentsByUnit';
import { LivechatMonitorsList } from './endpoints/v1/livechat/monitorsList';
import { LivechatRoomOnHoldEndpoint } from './endpoints/v1/livechat/onHold';
+import { LivechatTagsList } from './endpoints/v1/livechat/tagsList';
import { LivechatVisitorInfoEndpoint } from './endpoints/v1/livechat/visitorInfo';
import { AutocompleteAvailableForTeamsEndpoint as RoomsAutocompleteTeamsEndpoint } from './endpoints/v1/rooms/autocompleteAvailableForTeams';
import { AutocompleteChannelAndPrivateEndpoint as RoomsAutocompleteEndpoint } from './endpoints/v1/rooms/autocompleteChannelAndPrivate';
@@ -50,6 +51,7 @@ export type ServerEndpoints = {
'livechat/visitors.info': LivechatVisitorInfoEndpoint;
'livechat/room.onHold': LivechatRoomOnHoldEndpoint;
'livechat/monitors.list': LivechatMonitorsList;
+ 'livechat/tags.list': LivechatTagsList;
'livechat/department': LivechatDepartment;
'livechat/departments.by-unit/': LivechatDepartmentsByUnit;
};
diff --git a/client/contexts/ServerContext/endpoints/v1/livechat/tagsList.ts b/client/contexts/ServerContext/endpoints/v1/livechat/tagsList.ts
new file mode 100644
index 0000000000000..21a1c7a80eb0c
--- /dev/null
+++ b/client/contexts/ServerContext/endpoints/v1/livechat/tagsList.ts
@@ -0,0 +1,13 @@
+import { ILivechatTag } from '../../../../../../definition/ILivechatTag';
+import { ObjectFromApi } from '../../../../../../definition/ObjectFromApi';
+
+export type LivechatTagsList = {
+ GET: (params: {
+ text: string;
+ offset: number;
+ count: number;
+ }) => {
+ tags: ObjectFromApi[];
+ total: number;
+ };
+};
diff --git a/client/views/omnichannel/currentChats/FilterByText.js b/client/views/omnichannel/currentChats/FilterByText.js
index 95302bd5480ea..3b05e0147e9de 100644
--- a/client/views/omnichannel/currentChats/FilterByText.js
+++ b/client/views/omnichannel/currentChats/FilterByText.js
@@ -84,7 +84,7 @@ const FilterByText = ({ setFilter, reload, ...props }) => {
department,
from: from && moment(new Date(from)).utc().format('YYYY-MM-DDTHH:mm:ss'),
to: to && moment(new Date(to)).utc().format('YYYY-MM-DDTHH:mm:ss'),
- tags,
+ tags: tags.map((tag) => tag.label),
customFields: customFields.reduce(reducer, {}),
});
}, [setFilter, guest, servedBy, status, department, from, to, tags, customFields]);
diff --git a/definition/ILivechatTag.ts b/definition/ILivechatTag.ts
new file mode 100644
index 0000000000000..196c74c8dfd29
--- /dev/null
+++ b/definition/ILivechatTag.ts
@@ -0,0 +1,7 @@
+export interface ILivechatTag {
+ _id: string;
+ name: string;
+ description: string;
+ numDepartments: number;
+ departments: Array;
+}
diff --git a/definition/ILivechatTagRecord.ts b/definition/ILivechatTagRecord.ts
new file mode 100644
index 0000000000000..35456ce6a36d7
--- /dev/null
+++ b/definition/ILivechatTagRecord.ts
@@ -0,0 +1,10 @@
+import { IRocketChatRecord } from './IRocketChatRecord';
+
+
+export interface ILivechatTagRecord extends IRocketChatRecord {
+ _id: string;
+ name: string;
+ description: string;
+ numDepartments: number;
+ departments: Array;
+}
diff --git a/ee/client/hooks/useTagsList.ts b/ee/client/hooks/useTagsList.ts
new file mode 100644
index 0000000000000..25e147c097451
--- /dev/null
+++ b/ee/client/hooks/useTagsList.ts
@@ -0,0 +1,58 @@
+import { useCallback, useState } from 'react';
+
+import { useEndpoint } from '../../../client/contexts/ServerContext';
+import { useScrollableRecordList } from '../../../client/hooks/lists/useScrollableRecordList';
+import { useComponentDidUpdate } from '../../../client/hooks/useComponentDidUpdate';
+import { RecordList } from '../../../client/lib/lists/RecordList';
+import { ILivechatTagRecord } from '../../../definition/ILivechatTagRecord';
+
+type TagsListOptions = {
+ filter: string;
+};
+
+export const useTagsList = (
+ options: TagsListOptions,
+): {
+ itemsList: RecordList;
+ initialItemCount: number;
+ reload: () => void;
+ loadMoreItems: (start: number, end: number) => void;
+} => {
+ const [itemsList, setItemsList] = useState(() => new RecordList());
+ const reload = useCallback(() => setItemsList(new RecordList()), []);
+
+ const getTags = useEndpoint('GET', 'livechat/tags.list');
+
+ useComponentDidUpdate(() => {
+ options && reload();
+ }, [options, reload]);
+
+ const fetchData = useCallback(
+ async (start, end) => {
+ const { tags, total } = await getTags({
+ text: options.filter,
+ offset: start,
+ count: end + start,
+ });
+ return {
+ items: tags.map((tag: any) => {
+ tag._updatedAt = new Date(tag._updatedAt);
+ tag.label = tag.name;
+ tag.value = { value: tag._id, label: tag.name };
+ return tag;
+ }),
+ itemCount: total,
+ };
+ },
+ [getTags, options.filter],
+ );
+
+ const { loadMoreItems, initialItemCount } = useScrollableRecordList(itemsList, fetchData, 25);
+
+ return {
+ reload,
+ itemsList,
+ loadMoreItems,
+ initialItemCount,
+ };
+};
diff --git a/ee/client/omnichannel/tags/CurrentChatTags.js b/ee/client/omnichannel/tags/CurrentChatTags.js
index 597abddf9d08f..41af19e487676 100644
--- a/ee/client/omnichannel/tags/CurrentChatTags.js
+++ b/ee/client/omnichannel/tags/CurrentChatTags.js
@@ -1,16 +1,35 @@
-import { MultiSelect } from '@rocket.chat/fuselage';
-import React, { useMemo } from 'react';
+import { PaginatedMultiSelectFiltered } from '@rocket.chat/fuselage';
+import React, { useMemo, useState } from 'react';
-import { useEndpointData } from '../../../../client/hooks/useEndpointData';
+import { useRecordList } from '../../../../client/hooks/lists/useRecordList';
+import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState';
+import { useTagsList } from '../../hooks/useTagsList';
-const CurrentChatTags = ({ value, handler, ...props }) => {
- const { value: data } = useEndpointData('livechat/tags.list');
- const options = useMemo(
- () => (data && data.tags ? data.tags.map(({ name }) => [name, name]) : []),
- [data],
+const CurrentChatTags = ({ value, handler }) => {
+ const [tagsFilter, setTagsFilter] = useState('');
+
+ const { itemsList: tagsList, loadMoreItems: loadMoreTags } = useTagsList(
+ useMemo(() => ({ filter: tagsFilter }), [tagsFilter]),
);
- return ;
+ const { phase: tagsPhase, items: tagsItems, itemCount: tagsTotal } = useRecordList(tagsList);
+
+ return (
+ {}
+ : (start) => loadMoreTags(start, Math.min(50, tagsTotal))
+ }
+ />
+ );
};
export default CurrentChatTags;