Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Clear filters button not being active after submit #33699

Merged
merged 6 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useRouteParameter, useRouter } from '@rocket.chat/ui-contexts';
import React from 'react';

import ContactHistoryMessagesList from '../contactHistory/MessageList/ContactHistoryMessagesList';
import ChatFiltersContextualBar from './chats/ChatFiltersContextualBar';
import ChatsFiltersContextualBar from './chats/ChatsFiltersContextualBar';

const ChatsContextualBar = () => {
const router = useRouter();
Expand All @@ -13,7 +13,7 @@ const ChatsContextualBar = () => {
const handleClose = () => router.navigate('/omnichannel-directory/chats');

if (context === 'filters') {
return <ChatFiltersContextualBar onClose={handleClose} />;
return <ChatsFiltersContextualBar onClose={handleClose} />;
}

if (context === 'info' && id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { ContextualbarDialog } from '../../../components/Contextualbar';
import { Page, PageHeader, PageContent } from '../../../components/Page';
import ContextualBarRouter from './ContextualBarRouter';
import CallTab from './calls/CallTab';
import ChatTab from './chats/ChatTab';
import ChatsTab from './chats/ChatsTab';
import ContactTab from './contacts/ContactTab';
import ChatsProvider from './providers/ChatsProvider';

const DEFAULT_TAB = 'chats';

Expand Down Expand Up @@ -35,32 +36,34 @@ const OmnichannelDirectoryPage = () => {
const handleTabClick = useCallback((tab) => router.navigate({ name: 'omnichannel-directory', params: { tab } }), [router]);

return (
<Page flexDirection='row'>
<Page>
<PageHeader title={t('Omnichannel_Contact_Center')} />
<Tabs flexShrink={0}>
<Tabs.Item selected={tab === 'chats'} onClick={() => handleTabClick('chats')}>
{t('Chats')}
</Tabs.Item>
<Tabs.Item selected={tab === 'contacts'} onClick={() => handleTabClick('contacts')}>
{t('Contacts')}
</Tabs.Item>
<Tabs.Item selected={tab === 'calls'} onClick={() => handleTabClick('calls')}>
{t('Calls')}
</Tabs.Item>
</Tabs>
<PageContent>
{tab === 'chats' && <ChatTab />}
{tab === 'contacts' && <ContactTab />}
{tab === 'calls' && <CallTab />}
</PageContent>
<ChatsProvider>
<Page flexDirection='row'>
<Page>
<PageHeader title={t('Omnichannel_Contact_Center')} />
<Tabs flexShrink={0}>
<Tabs.Item selected={tab === 'chats'} onClick={() => handleTabClick('chats')}>
{t('Chats')}
</Tabs.Item>
<Tabs.Item selected={tab === 'contacts'} onClick={() => handleTabClick('contacts')}>
{t('Contacts')}
</Tabs.Item>
<Tabs.Item selected={tab === 'calls'} onClick={() => handleTabClick('calls')}>
{t('Calls')}
</Tabs.Item>
</Tabs>
<PageContent>
{tab === 'chats' && <ChatsTab />}
{tab === 'contacts' && <ContactTab />}
{tab === 'calls' && <CallTab />}
</PageContent>
</Page>
{context && (
<ContextualbarDialog>
<ContextualBarRouter />
</ContextualbarDialog>
)}
</Page>
{context && (
<ContextualbarDialog>
<ContextualBarRouter />
</ContextualbarDialog>
)}
</Page>
</ChatsProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import {
ContextualbarFooter,
} from '../../../../components/Contextualbar';
import { CurrentChatTags } from '../../additionalForms';
import type { ChatsFiltersQuery } from './useChatsFilters';
import { useChatsFilters } from './useChatsFilters';
import type { ChatsFiltersQuery } from '../contexts/ChatsContext';
import { useChatsContext } from '../contexts/ChatsContext';

type ChatFiltersContextualBarProps = {
type ChatsFiltersContextualBarProps = {
onClose: () => void;
};

const ChatFiltersContextualBar = ({ onClose }: ChatFiltersContextualBarProps) => {
const ChatsFiltersContextualBar = ({ onClose }: ChatsFiltersContextualBarProps) => {
const t = useTranslation();
const canViewLivechatRooms = usePermission('view-livechat-rooms');
const canViewCustomFields = usePermission('view-livechat-room-customfields');
Expand All @@ -32,15 +32,10 @@ const ChatFiltersContextualBar = ({ onClose }: ChatFiltersContextualBarProps) =>
const { data } = useQuery(['livechat/custom-fields'], async () => allCustomFields());
const contactCustomFields = data?.customFields.filter((customField) => customField.scope !== 'visitor');

const { filtersQuery, setFiltersQuery, resetFiltersQuery } = useChatsFilters();
const { filtersQuery, setFiltersQuery, resetFiltersQuery, hasAppliedFilters } = useChatsContext();
const queryClient = useQueryClient();

const {
formState: { isDirty },
handleSubmit,
control,
reset,
} = useForm<ChatsFiltersQuery>({
const { handleSubmit, control, reset } = useForm<ChatsFiltersQuery>({
values: filtersQuery,
});

Expand Down Expand Up @@ -171,7 +166,7 @@ const ChatFiltersContextualBar = ({ onClose }: ChatFiltersContextualBarProps) =>
</ContextualbarScrollableContent>
<ContextualbarFooter>
<ButtonGroup stretch>
<Button disabled={!isDirty} onClick={handleResetFilters}>
<Button disabled={!hasAppliedFilters} onClick={handleResetFilters}>
{t('Clear_filters')}
</Button>
<Button onClick={handleSubmit(handleSubmitFilters)} primary>
Expand All @@ -183,4 +178,4 @@ const ChatFiltersContextualBar = ({ onClose }: ChatFiltersContextualBarProps) =>
);
};

export default ChatFiltersContextualBar;
export default ChatsFiltersContextualBar;
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { usePermission } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

import NotAuthorizedPage from '../../../notAuthorized/NotAuthorizedPage';
import ChatTable from './ChatTable';
import ChatsTable from './ChatsTable';

const ChatTab = (): ReactElement => {
const ChatsTab = () => {
const hasAccess = usePermission('view-l-room');

if (hasAccess) {
return <ChatTable />;
return <ChatsTable />;
}

return <NotAuthorizedPage />;
};

export default ChatTab;
export default ChatsTab;
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,36 @@ import { usePermission, useTranslation } from '@rocket.chat/ui-contexts';
import { hashQueryKey } from '@tanstack/react-query';
import React, { useState, useMemo } from 'react';

import GenericNoResults from '../../../../components/GenericNoResults/GenericNoResults';
import GenericNoResults from '../../../../../components/GenericNoResults/GenericNoResults';
import {
GenericTable,
GenericTableBody,
GenericTableHeader,
GenericTableHeaderCell,
GenericTableLoadingTable,
} from '../../../../components/GenericTable';
import { usePagination } from '../../../../components/GenericTable/hooks/usePagination';
import { useSort } from '../../../../components/GenericTable/hooks/useSort';
import { useOmnichannelPriorities } from '../../../../omnichannel/hooks/useOmnichannelPriorities';
import { useCurrentChats } from '../../currentChats/hooks/useCurrentChats';
import ChatFilterByText from './ChatFilterByText';
import ChatTableRow from './ChatTableRow';
import { useChatsFilters } from './useChatsFilters';
} from '../../../../../components/GenericTable';
import { usePagination } from '../../../../../components/GenericTable/hooks/usePagination';
import { useSort } from '../../../../../components/GenericTable/hooks/useSort';
import { useOmnichannelPriorities } from '../../../../../omnichannel/hooks/useOmnichannelPriorities';
import { useCurrentChats } from '../../../currentChats/hooks/useCurrentChats';
import { useChatsContext } from '../../contexts/ChatsContext';
import ChatFilterByText from './ChatsTableFilter';
import ChatsTableRow from './ChatsTableRow';
import { useChatsQuery } from './useChatsQuery';

const ChatTable = () => {
const ChatsTable = () => {
const t = useTranslation();
const canRemoveClosedChats = usePermission('remove-closed-livechat-room');
const { filtersQuery: filters } = useChatsContext();

const { enabled: isPriorityEnabled } = useOmnichannelPriorities();
const { filtersQuery: filters } = useChatsFilters();

const chatsQuery = useChatsQuery();

const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination();
const { sortBy, sortDirection, setSort } = useSort<'fname' | 'priorityWeight' | 'department.name' | 'servedBy' | 'ts' | 'lm' | 'status'>(
'fname',
'lm',
'desc',
);

const query = useMemo(
Expand Down Expand Up @@ -112,7 +114,7 @@ const ChatTable = () => {
<GenericTableHeader>{headers}</GenericTableHeader>
<GenericTableBody>
{data?.rooms.map((room) => (
<ChatTableRow key={room._id} {...room} />
<ChatsTableRow key={room._id} {...room} />
))}
</GenericTableBody>
</GenericTable>
Expand Down Expand Up @@ -140,4 +142,4 @@ const ChatTable = () => {
);
};

export default ChatTable;
export default ChatsTable;
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import { useMethod, useRoute, useSetModal, useToastMessageDispatch, useTranslati
import { useQueryClient } from '@tanstack/react-query';
import React from 'react';

import FilterByText from '../../../../components/FilterByText';
import GenericModal from '../../../../components/GenericModal';
import { useChatsFilters } from './useChatsFilters';
import FilterByText from '../../../../../components/FilterByText';
import GenericModal from '../../../../../components/GenericModal';
import { useChatsContext } from '../../contexts/ChatsContext';

const ChatFilterByText = () => {
const ChatsTableFilter = () => {
const t = useTranslation();
const setModal = useSetModal();
const dispatchToastMessage = useToastMessageDispatch();
const directoryRoute = useRoute('omnichannel-directory');
const removeClosedChats = useMethod('livechat:removeAllClosedRooms');
const queryClient = useQueryClient();

const { displayFilters, setFiltersQuery, removeFilter } = useChatsFilters();
const { displayFilters, setFiltersQuery, removeFilter } = useChatsContext();

const handleRemoveAllClosed = useEffectEvent(async () => {
const onDeleteAll = async () => {
Expand Down Expand Up @@ -90,4 +90,4 @@ const ChatFilterByText = () => {
);
};

export default ChatFilterByText;
export default ChatsTableFilter;
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { usePermission, useRoute, useTranslation } from '@rocket.chat/ui-context
import moment from 'moment';
import React from 'react';

import { GenericTableCell, GenericTableRow } from '../../../../components/GenericTable';
import { RoomActivityIcon } from '../../../../omnichannel/components/RoomActivityIcon';
import { useOmnichannelPriorities } from '../../../../omnichannel/hooks/useOmnichannelPriorities';
import { PriorityIcon } from '../../../../omnichannel/priorities/PriorityIcon';
import RemoveChatButton from '../../currentChats/RemoveChatButton';
import { GenericTableCell, GenericTableRow } from '../../../../../components/GenericTable';
import { RoomActivityIcon } from '../../../../../omnichannel/components/RoomActivityIcon';
import { useOmnichannelPriorities } from '../../../../../omnichannel/hooks/useOmnichannelPriorities';
import { PriorityIcon } from '../../../../../omnichannel/priorities/PriorityIcon';
import RemoveChatButton from '../../../currentChats/RemoveChatButton';

const ChatTableRow = (room: IOmnichannelRoomWithDepartment) => {
const ChatsTableRow = (room: IOmnichannelRoomWithDepartment) => {
const t = useTranslation();
const { _id, fname, tags, servedBy, ts, lm, department, open, onHold, priorityWeight } = room;
const { enabled: isPriorityEnabled } = useOmnichannelPriorities();
Expand Down Expand Up @@ -85,4 +85,4 @@ const ChatTableRow = (room: IOmnichannelRoomWithDepartment) => {
);
};

export default ChatTableRow;
export default ChatsTableRow;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ChatsTable';
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { GETLivechatRoomsParams } from '@rocket.chat/rest-typings';
import { usePermission, useUserId } from '@rocket.chat/ui-contexts';
import moment from 'moment';
import { useCallback } from 'react';

import type { ChatsFiltersQuery } from '../../contexts/ChatsContext';

type useQueryType = (
debouncedParams: ChatsFiltersQuery,
[column, direction]: [string, 'asc' | 'desc'],
current: number,
itemsPerPage: 25 | 50 | 100,
) => GETLivechatRoomsParams;

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;
};

const sortDir = (sortDir: 'asc' | 'desc'): 1 | -1 => (sortDir === 'asc' ? 1 : -1);

export const useChatsQuery = () => {
const userIdLoggedIn = useUserId();
const canViewLivechatRooms = usePermission('view-livechat-rooms');

const chatsQuery: useQueryType = useCallback(
({ 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 (!canViewLivechatRooms) {
query.agents = userIdLoggedIn ? [userIdLoggedIn] : [];
}

if (canViewLivechatRooms && servedBy && servedBy !== 'all') {
query.agents = [servedBy];
}

if (department && department !== 'all') {
query.departmentId = department;
}

if (tags && tags.length > 0) {
query.tags = tags.map((tag) => tag.value);
}

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;
},
[canViewLivechatRooms, userIdLoggedIn],
);

return chatsQuery;
};
Loading
Loading