diff --git a/apps/meteor/app/authorization/server/constant/permissions.ts b/apps/meteor/app/authorization/server/constant/permissions.ts
index 4cdc1c05d5b00..600bf15793cc9 100644
--- a/apps/meteor/app/authorization/server/constant/permissions.ts
+++ b/apps/meteor/app/authorization/server/constant/permissions.ts
@@ -156,10 +156,6 @@ export const permissions = [
_id: 'add-livechat-department-agents',
roles: ['livechat-manager', 'livechat-monitor', 'admin'],
},
- {
- _id: 'view-livechat-current-chats',
- roles: ['livechat-manager', 'livechat-monitor', 'admin'],
- },
{
_id: 'view-livechat-real-time-monitoring',
roles: ['livechat-manager', 'livechat-monitor', 'admin'],
diff --git a/apps/meteor/client/NavBarV2/NavBarSettingsToolbar/hooks/useAdministrationMenu.tsx b/apps/meteor/client/NavBarV2/NavBarSettingsToolbar/hooks/useAdministrationMenu.tsx
index 7d4190bd00b8e..a269df44206bd 100644
--- a/apps/meteor/client/NavBarV2/NavBarSettingsToolbar/hooks/useAdministrationMenu.tsx
+++ b/apps/meteor/client/NavBarV2/NavBarSettingsToolbar/hooks/useAdministrationMenu.tsx
@@ -45,7 +45,7 @@ export const useAdministrationMenu = () => {
const omnichannel: GenericMenuItemProps = {
id: 'omnichannel',
content: t('Omnichannel'),
- onClick: () => router.navigate('/omnichannel/current'),
+ onClick: () => router.navigate('/omnichannel'),
};
return {
diff --git a/apps/meteor/client/sidebar/header/actions/hooks/useAdministrationItems.tsx b/apps/meteor/client/sidebar/header/actions/hooks/useAdministrationItems.tsx
index da258f2dc5510..90c14c6be04c4 100644
--- a/apps/meteor/client/sidebar/header/actions/hooks/useAdministrationItems.tsx
+++ b/apps/meteor/client/sidebar/header/actions/hooks/useAdministrationItems.tsx
@@ -43,7 +43,7 @@ export const useAdministrationItems = (): GenericMenuItemProps[] => {
id: 'omnichannel',
content: t('Omnichannel'),
icon: 'headset',
- onClick: () => router.navigate('/omnichannel/current'),
+ onClick: () => router.navigate('/omnichannel'),
};
const workspaceItem: GenericMenuItemProps = {
diff --git a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx
deleted file mode 100644
index 1252b05cb2e3f..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx
+++ /dev/null
@@ -1,381 +0,0 @@
-import type { IOmnichannelRoomWithDepartment } from '@rocket.chat/core-typings';
-import { Callout, Pagination } from '@rocket.chat/fuselage';
-import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
-import type { GETLivechatRoomsParams } from '@rocket.chat/rest-typings';
-import {
- GenericTable,
- GenericTableBody,
- GenericTableCell,
- GenericTableHeader,
- GenericTableHeaderCell,
- GenericTableLoadingTable,
- GenericTableRow,
- usePagination,
- useSort,
- Page,
- PageHeader,
- PageContent,
-} from '@rocket.chat/ui-client';
-import { usePermission, useRouter } from '@rocket.chat/ui-contexts';
-import { hashKey } from '@tanstack/react-query';
-import moment from 'moment';
-import type { ComponentProps, ReactElement } from 'react';
-import { memo, useCallback, useMemo, useState } from 'react';
-import { Trans, useTranslation } from 'react-i18next';
-
-import CustomFieldsList from './CustomFieldsList';
-import FilterByText from './FilterByText';
-import RemoveChatButton from './RemoveChatButton';
-import { useCurrentChats } from './hooks/useCurrentChats';
-import GenericNoResults from '../../../components/GenericNoResults';
-import { links } from '../../../lib/links';
-import RoomActivityIcon from '../components/RoomActivityIcon';
-import { useCustomFieldsQuery } from '../hooks/useCustomFieldsQuery';
-import { useIsOverMacLimit } from '../hooks/useIsOverMacLimit';
-import { useOmnichannelPriorities } from '../hooks/useOmnichannelPriorities';
-import { PriorityIcon } from '../priorities/PriorityIcon';
-
-type DebouncedParams = {
- fname: string;
- guest: string;
- servedBy: string;
- department: string;
- status: string;
- from: string;
- to: string;
- tags: any[];
-};
-
-type CurrentChatQuery = {
- agents?: string[];
- offset?: number;
- roomName?: string;
- departmentId?: string;
- open?: boolean;
- createdAt?: string;
- closedAt?: string;
- tags?: string[];
- onhold?: boolean;
- customFields?: string;
- sort: string;
- count?: number;
- queued?: boolean;
-};
-
-type useQueryType = (
- debouncedParams: DebouncedParams,
- customFields: { [key: string]: string } | undefined,
- [column, direction]: [string, 'asc' | 'desc'],
- current: number,
- itemsPerPage: 25 | 50 | 100,
-) => GETLivechatRoomsParams;
-
-const sortDir = (sortDir: 'asc' | 'desc'): 1 | -1 => (sortDir === 'asc' ? 1 : -1);
-
-const currentChatQuery: useQueryType = (
- { guest, servedBy, department, status, from, to, tags },
- customFields,
- [column, direction],
- current,
- itemsPerPage,
-) => {
- const query: CurrentChatQuery = {
- ...(guest && { roomName: guest }),
- sort: JSON.stringify({
- [column]: sortDir(direction),
- ts: column === 'ts' ? sortDir(direction) : undefined,
- }),
- ...(itemsPerPage && { count: itemsPerPage }),
- ...(current && { offset: current }),
- };
-
- if (from || to) {
- query.createdAt = JSON.stringify({
- ...(from && {
- start: moment(new Date(from)).set({ hour: 0, minutes: 0, seconds: 0 }).toISOString(),
- }),
- ...(to && {
- end: moment(new Date(to)).set({ hour: 23, minutes: 59, seconds: 59 }).toISOString(),
- }),
- });
- }
-
- if (status !== 'all') {
- query.open = status === 'opened' || status === 'onhold' || status === 'queued';
- query.onhold = status === 'onhold';
- query.queued = status === 'queued';
- }
- if (servedBy && servedBy !== 'all') {
- query.agents = [servedBy];
- }
- if (department && department !== 'all') {
- query.departmentId = department;
- }
-
- if (tags && tags.length > 0) {
- query.tags = tags;
- }
-
- if (customFields && Object.keys(customFields).length > 0) {
- const customFieldsQuery = Object.fromEntries(Object.entries(customFields).filter((item) => item[1] !== undefined && item[1] !== ''));
- if (Object.keys(customFieldsQuery).length > 0) {
- query.customFields = JSON.stringify(customFieldsQuery);
- }
- }
-
- return query;
-};
-
-const CurrentChatsPage = ({ id, onRowClick }: { id?: string; onRowClick: (_id: string) => void }): ReactElement => {
- const isWorkspaceOverMacLimit = useIsOverMacLimit();
- const { sortBy, sortDirection, setSort } = useSort<'fname' | 'departmentId' | 'servedBy' | 'priorityWeight' | 'ts' | 'lm' | 'open'>(
- 'ts',
- 'desc',
- );
- const [customFields, setCustomFields] = useState<{ [key: string]: string }>();
-
- const { t } = useTranslation();
- const directoryPath = useRouter().buildRoutePath('/omnichannel-directory');
-
- const canRemoveClosedChats = usePermission('remove-closed-livechat-room');
- const { enabled: isPriorityEnabled } = useOmnichannelPriorities();
-
- const { data: allCustomFields } = useCustomFieldsQuery();
-
- const { current, itemsPerPage, setItemsPerPage, setCurrent, ...paginationProps } = usePagination();
-
- const [params, setParams] = useState({
- guest: '',
- fname: '',
- servedBy: '',
- status: 'all',
- department: '',
- from: '',
- to: '',
- tags: [] as string[],
- });
-
- const hasCustomFields = useMemo(
- () => !!allCustomFields?.customFields?.find((customField) => customField.scope === 'room'),
- [allCustomFields],
- );
-
- const query = useMemo(
- () => currentChatQuery(params, customFields, [sortBy, sortDirection], current, itemsPerPage),
- [customFields, itemsPerPage, params, sortBy, sortDirection, current],
- );
-
- const { data, isLoading, isSuccess } = useCurrentChats(query);
-
- const [defaultQuery] = useState(hashKey([query]));
- const queryHasChanged = defaultQuery !== hashKey([query]);
-
- const onFilter = useEffectEvent((params: DebouncedParams): void => {
- setParams(params);
- setCurrent(0);
- });
-
- const renderRow = useCallback(
- (room: IOmnichannelRoomWithDepartment) => {
- const { _id, fname, servedBy, ts, lm, department, open = false, onHold = false, priorityWeight } = room;
- const getStatusText = (open: boolean, onHold: boolean, servedBy: boolean): string => {
- if (!open) return t('Closed');
- if (open && !servedBy) return t('Queued');
- return onHold ? t('On_Hold_Chats') : t('Room_Status_Open');
- };
-
- return (
- onRowClick(_id)} action data-qa-id={fname}>
- {isPriorityEnabled && (
-
-
-
- )}
-
- {fname}
-
-
- {department ? department.name : ''}
-
- {servedBy?.username}
-
- {moment(ts).format('L LTS')}
-
-
- {moment(lm).format('L LTS')}
-
-
- {getStatusText(open, onHold, !!servedBy?.username)}
-
- {canRemoveClosedChats && (
-
- {!open && }
-
- )}
-
- );
- },
- [canRemoveClosedChats, onRowClick, isPriorityEnabled, t],
- );
-
- const headers = (
- <>
- {isPriorityEnabled && (
-
- {t('Priority')}
-
- )}
-
- {t('Name')}
-
-
- {t('Department')}
-
-
- {t('Served_By')}
-
-
- {t('Started_At')}
-
-
- {t('Last_Message')}
-
-
- {t('Status')}
-
- {canRemoveClosedChats && (
-
- {t('Remove')}
-
- )}
- >
- );
-
- // TODO: Missing error state
- return (
-
-
-
-
-
-
- Manage conversations in the
- contact center.
-
-
- {((isSuccess && data?.rooms.length > 0) || queryHasChanged) && (
- ['setFilter']}
- setCustomFields={setCustomFields}
- customFields={customFields}
- hasCustomFields={hasCustomFields}
- />
- )}
- {isWorkspaceOverMacLimit && (
-
- {t('Talk_to_your_workspace_admin_to_address_this_issue')}
-
- )}
- {isSuccess && data?.rooms.length === 0 && queryHasChanged && }
- {isSuccess && data?.rooms.length === 0 && !queryHasChanged && (
-
- )}
- {isLoading && (
-
- {headers}
-
-
-
-
- )}
- {isSuccess && data?.rooms?.length > 0 && (
- <>
-
- {headers}
-
- {data.rooms.map((room) => renderRow({ ...room }))}
-
-
-
- >
- )}
-
-
- {id === 'custom-fields' && hasCustomFields && (
-
- )}
-
- );
-};
-
-export default memo(CurrentChatsPage);
diff --git a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx
deleted file mode 100644
index 730cecf1e4008..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
-import { usePermission, useRouteParameter, useRouter } from '@rocket.chat/ui-contexts';
-import { memo } from 'react';
-import type { ReactElement } from 'react';
-
-import CurrentChatsPage from './CurrentChatsPage';
-import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage';
-import Chat from '../directory/chats/Chat';
-
-const CurrentChatsRoute = (): ReactElement => {
- const id = useRouteParameter('id');
-
- const canViewCurrentChats = usePermission('view-livechat-current-chats');
- const router = useRouter();
-
- const onRowClick = useEffectEvent((_id: string) => {
- router.navigate(`/omnichannel/current/${_id}`);
- });
-
- if (!canViewCurrentChats) {
- return ;
- }
-
- if (id && id !== 'custom-fields') {
- return ;
- }
-
- // TODO: Missing error state
- return ;
-};
-
-export default memo(CurrentChatsRoute);
diff --git a/apps/meteor/client/views/omnichannel/currentChats/CustomFieldsList.tsx b/apps/meteor/client/views/omnichannel/currentChats/CustomFieldsList.tsx
deleted file mode 100644
index e83e08cf32685..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/CustomFieldsList.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import type { ILivechatCustomField } from '@rocket.chat/core-typings';
-import { Field, FieldLabel, FieldRow, TextInput, Select } from '@rocket.chat/fuselage';
-import {
- ContextualbarScrollableContent,
- ContextualbarHeader,
- ContextualbarClose,
- ContextualbarDialog,
- ContextualbarTitle,
-} from '@rocket.chat/ui-client';
-import { useTranslation, useRoute } from '@rocket.chat/ui-contexts';
-import type { ReactElement, Dispatch, SetStateAction } from 'react';
-import { useEffect } from 'react';
-import { Controller, useForm } from 'react-hook-form';
-
-type CustomFieldsListProps = {
- setCustomFields: Dispatch>;
- allCustomFields: ILivechatCustomField[];
-};
-
-const CustomFieldsList = ({ setCustomFields, allCustomFields }: CustomFieldsListProps): ReactElement => {
- const { register, watch, control } = useForm({ mode: 'onChange' });
-
- // TODO: When we refactor the other CurrentChat's fields to use react-hook-form, we need to change this to use the form controller
-
- useEffect(() => {
- const subscription = watch((value) => setCustomFields(value));
- return (): void => subscription.unsubscribe();
- }, [setCustomFields, watch]);
-
- const t = useTranslation();
- const currentChatsRoute = useRoute('omnichannel-current-chats');
-
- return (
-
-
- {t('Filter_by_Custom_Fields')}
- currentChatsRoute.push({ context: '' })} />
-
-
- {/* TODO: REMOVE FILTER ONCE THE ENDPOINT SUPPORTS A SCOPE PARAMETER */}
- {allCustomFields
- .filter((customField) => customField.scope !== 'visitor')
- .map((customField: ILivechatCustomField) => {
- if (customField.type === 'select') {
- return (
-
- {customField.label}
-
- (
-
-
- );
- }
-
- return (
-
- {customField.label}
-
-
-
-
- );
- })}
-
-
- );
-};
-
-export default CustomFieldsList;
diff --git a/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx b/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx
deleted file mode 100644
index ba2c103966f05..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/FilterByText.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-import { TextInput, Box, Select, InputBox } from '@rocket.chat/fuselage';
-import { useEffectEvent, useLocalStorage } from '@rocket.chat/fuselage-hooks';
-import { GenericModal } from '@rocket.chat/ui-client';
-import { useSetModal, useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts';
-import moment from 'moment';
-import type { Dispatch, FormEvent, Key, SetStateAction } from 'react';
-import { useEffect } from 'react';
-import { useTranslation } from 'react-i18next';
-
-import { CurrentChatTags } from '../additionalForms';
-import Label from './Label';
-import RemoveAllClosed from './RemoveAllClosed';
-import AutoCompleteAgent from '../components/AutoCompleteAgent';
-import AutoCompleteDepartment from '../components/AutoCompleteDepartment';
-
-type FilterByTextTypeProps = {
- setFilter: Dispatch>>;
- setCustomFields: Dispatch>;
- customFields: { [key: string]: string } | undefined;
- hasCustomFields: boolean;
- reload?: () => void;
-};
-
-const FilterByText = ({ setFilter, reload, customFields, setCustomFields, hasCustomFields, ...props }: FilterByTextTypeProps) => {
- const setModal = useSetModal();
- const dispatchToastMessage = useToastMessageDispatch();
- const { t } = useTranslation();
-
- const statusOptions: [string, string][] = [
- ['all', t('All')],
- ['closed', t('Closed')],
- ['opened', t('Room_Status_Open')],
- ['onhold', t('On_Hold_Chats')],
- ['queued', t('Queued')],
- ];
-
- const [guest, setGuest] = useLocalStorage('guest', '');
- const [servedBy, setServedBy] = useLocalStorage('servedBy', 'all');
- const [status, setStatus] = useLocalStorage('status', 'all');
- const [department, setDepartment] = useLocalStorage('department', 'all');
- const [from, setFrom] = useLocalStorage('from', '');
- const [to, setTo] = useLocalStorage('to', '');
- const [tags, setTags] = useLocalStorage('tags', []);
-
- const handleGuest = useEffectEvent((e: FormEvent) => setGuest(e.currentTarget.value));
- const handleServedBy = useEffectEvent((e: string) => setServedBy(e));
- const handleStatus = useEffectEvent((e: Key) => setStatus(e as string));
- const handleDepartment = useEffectEvent((e: string) => setDepartment(e));
- const handleFrom = useEffectEvent((e: FormEvent) => setFrom(e.currentTarget.value));
- const handleTo = useEffectEvent((e: FormEvent) => setTo(e.currentTarget.value));
- const handleTags = useEffectEvent((e: { label: string; value: string }[]) => setTags(e));
-
- const reset = useEffectEvent(() => {
- setGuest('');
- setServedBy('all');
- setStatus('all');
- setDepartment('all');
- setFrom('');
- setTo('');
- setTags([]);
- setCustomFields(undefined);
- });
-
- const onSubmit = useEffectEvent((e: FormEvent) => e.preventDefault());
-
- useEffect(() => {
- setFilter((data) => ({
- ...data,
- guest,
- servedBy,
- status,
- department: department && department !== 'all' ? 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.map((tag) => tag.label),
- customFields,
- }));
- }, [setFilter, guest, servedBy, status, department, from, to, tags, customFields]);
-
- const handleClearFilters = useEffectEvent(() => {
- reset();
- });
-
- const removeClosedRooms = useEndpoint('POST', '/v1/livechat/rooms.removeAllClosedRooms');
-
- const handleRemoveClosed = useEffectEvent(async () => {
- const onDeleteAll = async (): Promise => {
- try {
- await removeClosedRooms();
- reload?.();
- dispatchToastMessage({ type: 'success', message: t('Chat_removed') });
- } catch (error) {
- dispatchToastMessage({ type: 'error', message: error });
- }
- setModal(null);
- };
-
- const handleClose = (): void => {
- setModal(null);
- };
-
- setModal(
- ,
- );
- });
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {CurrentChatTags && (
-
-
-
-
-
-
- )}
-
- );
-};
-
-export default FilterByText;
diff --git a/apps/meteor/client/views/omnichannel/currentChats/Label.tsx b/apps/meteor/client/views/omnichannel/currentChats/Label.tsx
deleted file mode 100644
index e0a06278a5e90..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/Label.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { Box } from '@rocket.chat/fuselage';
-import type { ComponentProps } from 'react';
-
-type LabelProps = ComponentProps;
-
-const Label = (props: LabelProps) => ;
-
-export default Label;
diff --git a/apps/meteor/client/views/omnichannel/currentChats/RemoveAllClosed.tsx b/apps/meteor/client/views/omnichannel/currentChats/RemoveAllClosed.tsx
deleted file mode 100644
index 74d8d85d1b5ea..0000000000000
--- a/apps/meteor/client/views/omnichannel/currentChats/RemoveAllClosed.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Box, Icon, Menu } from '@rocket.chat/fuselage';
-import { usePermission, useTranslation, useRoute } from '@rocket.chat/ui-contexts';
-
-type RemoveAllClosedProps = {
- handleClearFilters: any;
- handleRemoveClosed: any;
- hasCustomFields: boolean;
-};
-
-const RemoveAllClosed = ({ handleClearFilters, handleRemoveClosed, hasCustomFields, ...props }: RemoveAllClosedProps) => {
- const t = useTranslation();
- const directoryRoute = useRoute('omnichannel-current-chats');
- const canRemove = usePermission('remove-closed-livechat-rooms');
- const canViewCustomFields = usePermission('view-livechat-room-customfields');
-
- const menuOptions = {
- clearFilters: {
- label: (
-
-
- {t('Clear_filters')}
-
- ),
- action: handleClearFilters,
- },
- ...(canRemove && {
- removeClosed: {
- label: (
-
-
- {t('Delete_all_closed_chats')}
-
- ),
- action: handleRemoveClosed,
- },
- }),
- ...(canViewCustomFields &&
- hasCustomFields && {
- customFields: {
- label: (
-
-
- {t('Custom_Fields')}
-
- ),
- action: (): void => directoryRoute.push({ context: 'custom-fields' }),
- },
- }),
- };
- return ;
-};
-
-export default RemoveAllClosed;
diff --git a/apps/meteor/client/views/omnichannel/directory/ChatsContextualBar.tsx b/apps/meteor/client/views/omnichannel/directory/ChatsContextualBar.tsx
index 13e81913753a1..db42cbeb5d743 100644
--- a/apps/meteor/client/views/omnichannel/directory/ChatsContextualBar.tsx
+++ b/apps/meteor/client/views/omnichannel/directory/ChatsContextualBar.tsx
@@ -1,15 +1,17 @@
import { useRouteParameter, useRouter } from '@rocket.chat/ui-contexts';
import ChatsFiltersContextualBar from './chats/ChatsFiltersContextualBar';
+import { useOmnichannelDirectoryRouter } from './hooks/useOmnichannelDirectoryRouter';
import ContactHistoryMessagesList from '../contactHistory/MessageList/ContactHistoryMessagesList';
const ChatsContextualBar = () => {
const router = useRouter();
+ const omnichannelDirectoryRouter = useOmnichannelDirectoryRouter();
const context = useRouteParameter('context');
const id = useRouteParameter('id');
const handleOpenRoom = () => id && router.navigate(`/live/${id}`);
- const handleClose = () => router.navigate('/omnichannel-directory/chats');
+ const handleClose = () => omnichannelDirectoryRouter.navigate({ tab: 'chats' });
if (context === 'filters') {
return ;
diff --git a/apps/meteor/client/views/omnichannel/directory/ContactContextualBar.tsx b/apps/meteor/client/views/omnichannel/directory/ContactContextualBar.tsx
index f73c19a57d138..fefbdcf247663 100644
--- a/apps/meteor/client/views/omnichannel/directory/ContactContextualBar.tsx
+++ b/apps/meteor/client/views/omnichannel/directory/ContactContextualBar.tsx
@@ -1,20 +1,25 @@
-import { useRoute, useRouteParameter } from '@rocket.chat/ui-contexts';
+import { useRouteParameter } from '@rocket.chat/ui-contexts';
import ContactInfo from '../contactInfo/ContactInfo';
import ContactInfoError from '../contactInfo/ContactInfoError';
import EditContactInfo from '../contactInfo/EditContactInfo';
import EditContactInfoWithData from '../contactInfo/EditContactInfoWithData';
+import { useOmnichannelDirectoryRouter } from './hooks/useOmnichannelDirectoryRouter';
const ContactContextualBar = () => {
- const directoryRoute = useRoute('omnichannel-directory');
const contactId = useRouteParameter('id');
const context = useRouteParameter('context');
+ const omnichannelDirectoryRouter = useOmnichannelDirectoryRouter();
- const handleClose = () => {
- directoryRoute.push({ tab: 'contacts' });
- };
+ const handleClose = () => omnichannelDirectoryRouter.navigate({ tab: 'contacts' });
+
+ const handleCancel = () => {
+ if (!contactId) {
+ return;
+ }
- const handleCancel = () => contactId && directoryRoute.push({ tab: 'contacts', context: 'details', id: contactId });
+ return omnichannelDirectoryRouter.navigate({ tab: 'contacts', context: 'details', id: contactId });
+ };
if (context === 'edit' && contactId) {
return ;
diff --git a/apps/meteor/client/views/omnichannel/directory/OmnichannelDirectoryPage.tsx b/apps/meteor/client/views/omnichannel/directory/OmnichannelDirectoryPage.tsx
index 1aef1bf3ec4b9..f8b617297e0d9 100644
--- a/apps/meteor/client/views/omnichannel/directory/OmnichannelDirectoryPage.tsx
+++ b/apps/meteor/client/views/omnichannel/directory/OmnichannelDirectoryPage.tsx
@@ -1,38 +1,33 @@
-import { Tabs } from '@rocket.chat/fuselage';
+import { Box, Callout, Tabs } from '@rocket.chat/fuselage';
import { Page, PageHeader, PageContent } from '@rocket.chat/ui-client';
-import { useRouteParameter, useRouter } from '@rocket.chat/ui-contexts';
+import { useRouteParameter } from '@rocket.chat/ui-contexts';
import { useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import ContextualBarRouter from './ContextualBarRouter';
import ChatsTab from './chats/ChatsTab';
import ContactTab from './contacts/ContactTab';
+import { useOmnichannelDirectoryRouter } from './hooks/useOmnichannelDirectoryRouter';
import ChatsProvider from './providers/ChatsProvider';
-
-const DEFAULT_TAB = 'chats';
+import { useIsOverMacLimit } from '../hooks/useIsOverMacLimit';
const OmnichannelDirectoryPage = () => {
const { t } = useTranslation();
- const router = useRouter();
const tab = useRouteParameter('tab');
const context = useRouteParameter('context');
- useEffect(
- () =>
- router.subscribeToRouteChange(() => {
- if (router.getRouteName() !== 'omnichannel-directory' || !!router.getRouteParameters().tab) {
- return;
- }
-
- router.navigate({
- name: 'omnichannel-directory',
- params: { tab: DEFAULT_TAB },
- });
- }),
- [router],
- );
+ const isWorkspaceOverMacLimit = useIsOverMacLimit();
+ const omnichannelDirectoryRouter = useOmnichannelDirectoryRouter();
+
+ useEffect(() => {
+ if (!omnichannelDirectoryRouter.getRouteName() || (omnichannelDirectoryRouter.getRouteName() && !!tab)) {
+ return;
+ }
+
+ omnichannelDirectoryRouter.navigate({ tab: 'chats' });
+ }, [omnichannelDirectoryRouter, tab]);
- const handleTabClick = useCallback((tab: string) => router.navigate({ name: 'omnichannel-directory', params: { tab } }), [router]);
+ const handleTabClick = useCallback((tab: string) => omnichannelDirectoryRouter.navigate({ tab }), [omnichannelDirectoryRouter]);
return (
@@ -48,6 +43,13 @@ const OmnichannelDirectoryPage = () => {
+ {isWorkspaceOverMacLimit && (
+
+
+ {t('Talk_to_your_workspace_admin_to_address_this_issue')}
+
+
+ )}
{tab === 'chats' && }
{tab === 'contacts' && }
diff --git a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTable.tsx b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTable.tsx
index e95cccbf2e0d6..b5590ea120c5d 100644
--- a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTable.tsx
+++ b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTable.tsx
@@ -15,10 +15,10 @@ import { useTranslation } from 'react-i18next';
import ChatFilterByText from './ChatsTableFilter';
import ChatsTableRow from './ChatsTableRow';
+import { useCurrentChats } from './hooks/useCurrentChats';
import { useChatsQuery } from './useChatsQuery';
import GenericNoResults from '../../../../../components/GenericNoResults/GenericNoResults';
import { links } from '../../../../../lib/links';
-import { useCurrentChats } from '../../../currentChats/hooks/useCurrentChats';
import { useOmnichannelPriorities } from '../../../hooks/useOmnichannelPriorities';
import { useChatsContext } from '../../contexts/ChatsContext';
@@ -90,7 +90,7 @@ const ChatsTable = () => {
)}
{isSuccess && data?.rooms.length > 0 && (
<>
-
+
{headers}
{data?.rooms.map((room) => )}
diff --git a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx
index a19b1858d8818..731b6d690756d 100644
--- a/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx
+++ b/apps/meteor/client/views/omnichannel/directory/chats/ChatsTable/ChatsTableFilter.tsx
@@ -1,18 +1,19 @@
import { Box, Button, Chip } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { GenericMenu, GenericModal } from '@rocket.chat/ui-client';
-import { useEndpoint, useRoute, useSetModal, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
+import { useEndpoint, useSetModal, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import FilterByText from '../../../../../components/FilterByText';
import { useChatsContext } from '../../contexts/ChatsContext';
+import { useOmnichannelDirectoryRouter } from '../../hooks/useOmnichannelDirectoryRouter';
const ChatsTableFilter = () => {
const { t } = useTranslation();
const setModal = useSetModal();
const dispatchToastMessage = useToastMessageDispatch();
- const directoryRoute = useRoute('omnichannel-directory');
+ const omnichannelDirectoryRouter = useOmnichannelDirectoryRouter();
const queryClient = useQueryClient();
const removeClosedRooms = useEndpoint('POST', '/v1/livechat/rooms.removeAllClosedRooms');
@@ -65,7 +66,7 @@ const ChatsTableFilter = () => {
>