From e2c6ef33e90f7056b96630f48ec622ff43c3a73a Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Thu, 2 Jun 2022 15:10:46 -0300 Subject: [PATCH 1/8] fix yarn conf duplication --- .yarnrc.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index 155880f91223d..d5cd2a9e7967c 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -13,5 +13,3 @@ plugins: spec: '@yarnpkg/plugin-typescript' yarnPath: .yarn/releases/yarn-3.2.0.cjs - -checksumBehavior: 'update' From b65db93f7d6737a0ccd0b39f0f2cf17aa0a48b94 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Thu, 2 Jun 2022 15:11:51 -0300 Subject: [PATCH 2/8] fix --- apps/meteor/client/components/FilterByText.tsx | 6 +++--- .../client/views/omnichannel/agents/AgentsRoute.tsx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/meteor/client/components/FilterByText.tsx b/apps/meteor/client/components/FilterByText.tsx index d75050a578431..d2396a6301e66 100644 --- a/apps/meteor/client/components/FilterByText.tsx +++ b/apps/meteor/client/components/FilterByText.tsx @@ -4,7 +4,7 @@ import React, { FC, ChangeEvent, FormEvent, memo, useCallback, useEffect, useSta type FilterByTextProps = { placeholder?: string; - onChange: (filter: { text: string }) => void; + setFilter: (filter: { text: string }) => void; inputRef?: () => void; }; @@ -17,7 +17,7 @@ type FilterByTextPropsWithButton = FilterByTextProps & { const isFilterByTextPropsWithButton = (props: any): props is FilterByTextPropsWithButton => 'displayButton' in props && props.displayButton === true; -const FilterByText: FC = ({ placeholder, onChange: setFilter, inputRef, children, ...props }) => { +const FilterByText: FC = ({ placeholder, setFilter, inputRef, children, ...props }) => { const t = useTranslation(); const [text, setText] = useState(''); @@ -27,7 +27,7 @@ const FilterByText: FC = ({ placeholder, onChange: setFilter, }, []); useEffect(() => { - setFilter({ text }); + setFilter?.({ text }); }, [setFilter, text]); const handleFormSubmit = useCallback((event: FormEvent) => { diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx index c47c96f596a54..11af3524fd8a0 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx @@ -63,9 +63,9 @@ const AgentsRoute: FC = () => { const context = useRouteParameter('context'); const id = useRouteParameter('id'); - if (!id) { - throw new Error('Agent id is required'); - } + // if (!id) { + // throw new Error('Agent id is required'); + // } const onHeaderClick = useMutableCallback((id) => { if (sortBy === id) { @@ -180,8 +180,8 @@ const AgentsRoute: FC = () => { - {context === 'edit' && } - {context === 'info' && ( + {context === 'edit' && id && } + {context === 'info' && id && ( From 3c97ef9d624b3e42bebbdbd2a06d8016f86d8de1 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Thu, 2 Jun 2022 15:27:39 -0300 Subject: [PATCH 3/8] remove comments --- apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx index 11af3524fd8a0..3a6c62a71e760 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx @@ -63,10 +63,6 @@ const AgentsRoute: FC = () => { const context = useRouteParameter('context'); const id = useRouteParameter('id'); - // if (!id) { - // throw new Error('Agent id is required'); - // } - const onHeaderClick = useMutableCallback((id) => { if (sortBy === id) { setSort(id, sortDirection === 'asc' ? 'desc' : 'asc'); From dfb94d0657f3aaa97e63a2211441e04d723989dd Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Thu, 2 Jun 2022 15:45:33 -0300 Subject: [PATCH 4/8] -.-' --- apps/meteor/client/components/FilterByText.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/components/FilterByText.tsx b/apps/meteor/client/components/FilterByText.tsx index d2396a6301e66..128557b461ff5 100644 --- a/apps/meteor/client/components/FilterByText.tsx +++ b/apps/meteor/client/components/FilterByText.tsx @@ -4,7 +4,7 @@ import React, { FC, ChangeEvent, FormEvent, memo, useCallback, useEffect, useSta type FilterByTextProps = { placeholder?: string; - setFilter: (filter: { text: string }) => void; + onChange: (filter: { text: string }) => void; inputRef?: () => void; }; @@ -17,7 +17,7 @@ type FilterByTextPropsWithButton = FilterByTextProps & { const isFilterByTextPropsWithButton = (props: any): props is FilterByTextPropsWithButton => 'displayButton' in props && props.displayButton === true; -const FilterByText: FC = ({ placeholder, setFilter, inputRef, children, ...props }) => { +const FilterByText: FC = ({ placeholder, onChange: setFilter, inputRef, children, ...props }) => { const t = useTranslation(); const [text, setText] = useState(''); From f6a1a78f43beb5c2d8ce646b024f07ade83d377f Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Fri, 3 Jun 2022 13:34:38 -0300 Subject: [PATCH 5/8] fix + rewrite --- .../meteor/client/components/FilterByText.tsx | 2 +- .../views/omnichannel/agents/AddAgent.tsx | 7 +- .../omnichannel/agents/AgentEditWithData.tsx | 6 +- .../omnichannel/agents/AgentInfoActions.tsx | 10 +- .../views/omnichannel/agents/AgentsPage.tsx | 134 +++++++++--- .../omnichannel/agents/AgentsPageRow.tsx | 63 ++++++ .../views/omnichannel/agents/AgentsRoute.tsx | 200 ------------------ .../views/omnichannel/agents/AgentsTab.tsx | 35 +++ .../omnichannel/agents/RemoveAgentButton.tsx | 11 +- .../omnichannel/agents/hooks/useQuery.ts | 30 +++ .../currentChats/CurrentChatsPage.tsx | 21 +- .../currentChats/CurrentChatsRoute.tsx | 9 +- .../meteor/client/views/omnichannel/routes.js | 2 +- 13 files changed, 267 insertions(+), 263 deletions(-) create mode 100644 apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx delete mode 100644 apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx create mode 100644 apps/meteor/client/views/omnichannel/agents/AgentsTab.tsx create mode 100644 apps/meteor/client/views/omnichannel/agents/hooks/useQuery.ts diff --git a/apps/meteor/client/components/FilterByText.tsx b/apps/meteor/client/components/FilterByText.tsx index 128557b461ff5..d75050a578431 100644 --- a/apps/meteor/client/components/FilterByText.tsx +++ b/apps/meteor/client/components/FilterByText.tsx @@ -27,7 +27,7 @@ const FilterByText: FC = ({ placeholder, onChange: setFilter, }, []); useEffect(() => { - setFilter?.({ text }); + setFilter({ text }); }, [setFilter, text]); const handleFormSubmit = useCallback((event: FormEvent) => { diff --git a/apps/meteor/client/views/omnichannel/agents/AddAgent.tsx b/apps/meteor/client/views/omnichannel/agents/AddAgent.tsx index e0bbee433a4ed..dc1e7a9166d94 100644 --- a/apps/meteor/client/views/omnichannel/agents/AddAgent.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AddAgent.tsx @@ -1,17 +1,16 @@ import { Button, Box, Field } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useState, FC } from 'react'; +import React, { useState, ReactElement } from 'react'; import UserAutoComplete from '../../../components/UserAutoComplete'; import { useEndpointAction } from '../../../hooks/useEndpointAction'; type AddAgentProps = { reload: () => void; - pi?: 'x24'; }; -const AddAgent: FC = ({ reload, ...props }) => { +const AddAgent = ({ reload }: AddAgentProps): ReactElement => { const t = useTranslation(); const [username, setUsername] = useState(''); @@ -29,7 +28,7 @@ const AddAgent: FC = ({ reload, ...props }) => { setUsername(username); }); return ( - + {t('Username')} diff --git a/apps/meteor/client/views/omnichannel/agents/AgentEditWithData.tsx b/apps/meteor/client/views/omnichannel/agents/AgentEditWithData.tsx index 04357e5469008..3ff846618622e 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentEditWithData.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentEditWithData.tsx @@ -1,6 +1,6 @@ import { Box } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { FC } from 'react'; +import React, { ReactElement } from 'react'; import { FormSkeleton } from '../../../components/Skeleton'; import { AsyncStatePhase } from '../../../hooks/useAsyncState'; @@ -12,7 +12,7 @@ type AgentEditWithDataProps = { reload: () => void; }; -const AgentEditWithData: FC = ({ uid, reload }) => { +const AgentEditWithData = ({ uid, reload }: AgentEditWithDataProps): ReactElement => { const t = useTranslation(); const { value: data, phase: state, error } = useEndpointData(`livechat/users/agent/${uid}`); const { @@ -35,7 +35,7 @@ const AgentEditWithData: FC = ({ uid, reload }) => { } if (error || userDepartmentsError || availableDepartmentsError || !data || !data.user) { - return {t('User_not_found')}; + return {t('User_not_found')}; } return ; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentInfoActions.tsx b/apps/meteor/client/views/omnichannel/agents/AgentInfoActions.tsx index ddd50628da4d1..089bb43078ffd 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentInfoActions.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentInfoActions.tsx @@ -1,14 +1,12 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useSetModal, useToastMessageDispatch, useRouteParameter, useRoute, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { VFC } from 'react'; +import React, { ReactElement } from 'react'; import GenericModal from '../../../components/GenericModal'; import { useEndpointAction } from '../../../hooks/useEndpointAction'; import AgentInfo from './AgentInfo'; -const AgentInfoActions: VFC<{ - reload: () => void; -}> = ({ reload }) => { +const AgentInfoActions = ({ reload }: { reload: () => void }): ReactElement => { const t = useTranslation(); const _id = useRouteParameter('id'); const agentsRoute = useRoute('omnichannel-agents'); @@ -48,8 +46,8 @@ const AgentInfoActions: VFC<{ return ( <> - , - , + + ); }; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx index 84293e15582fc..eeddfd1d6887a 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx @@ -1,39 +1,113 @@ -import React, { FC, Key, ReactNode, ReactElement } from 'react'; +import { Box, Pagination } from '@rocket.chat/fuselage'; +import { useDebouncedValue, useMediaQuery, useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import { usePermission, useRouteParameter, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useMemo, useState } from 'react'; import FilterByText from '../../../components/FilterByText'; -import GenericTable from '../../../components/GenericTable'; +import { GenericTableBody, GenericTableHeader, GenericTableHeaderCell, GenericTableLoadingTable } from '../../../components/GenericTable'; +import { GenericTable } from '../../../components/GenericTable/V2/GenericTable'; +import { usePagination } from '../../../components/GenericTable/hooks/usePagination'; +import { useSort } from '../../../components/GenericTable/hooks/useSort'; import Page from '../../../components/Page'; +import { useEndpointData } from '../../../hooks/useEndpointData'; +import { AsyncStatePhase } from '../../../lib/asyncState'; +import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; import AddAgent from './AddAgent'; +import AgentsPageRow from './AgentsPageRow'; +import AgentsTab from './AgentsTab'; +import { useQuery } from './hooks/useQuery'; -type AgentPageProps = { - reload: () => void; - data: any; - header: ReactNode; - setParams: (params: any) => void; - params: any; - title: string; - renderRow: (props: { _id?: Key }) => ReactElement; -}; +const AgentsPage = (): ReactElement => { + const t = useTranslation(); + const canViewAgents = usePermission('manage-livechat-agents'); + const mediaQuery = useMediaQuery('(min-width: 1024px)'); + + const context = useRouteParameter('context'); + const id = useRouteParameter('id'); + + const { sortBy, sortDirection, setSort } = useSort<'name' | 'username' | 'emails.address' | 'statusLivechat'>('name'); + const [filter, setFilter] = useState(''); + const debouncedFilter = useDebouncedValue(filter, 500); + const debouncedSort = useDebouncedValue( + useMemo(() => [sortBy, sortDirection], [sortBy, sortDirection]), + 500, + ) as ['name' | 'username' | 'emails.address' | 'statusLivechat', 'asc' | 'desc']; + + const { current, itemsPerPage, setItemsPerPage, setCurrent, ...paginationProps } = usePagination(); -const AgentsPage: FC = ({ data, reload, header, setParams, params, title, renderRow, children }) => ( - - - - - - } - /> - + const query = useQuery({ text: debouncedFilter, current, itemsPerPage }, debouncedSort); + const { value: data, reload, phase } = useEndpointData('livechat/users/agent', query); + + const onHeaderClick = useMutableCallback((id) => { + if (sortBy === id) { + setSort(id, sortDirection === 'asc' ? 'desc' : 'asc'); + return; + } + setSort(id, 'asc'); + }); + + if (!canViewAgents) { + return ; + } + + return ( + + + + + + setFilter(text)} /> + + + + + + {t('Name')} + + {mediaQuery && ( + + {t('Username')} + + )} + + {t('Email')} + + + {t('Livechat_status')} + + {t('Remove')} + + + {phase === AsyncStatePhase.LOADING && } + {phase === AsyncStatePhase.RESOLVED && + data.users.map((user) => )} + + + {phase === AsyncStatePhase.RESOLVED && ( + + )} + + + {context && id && } - {children} - -); + ); +}; export default AgentsPage; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx new file mode 100644 index 0000000000000..a40634ff6ca64 --- /dev/null +++ b/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx @@ -0,0 +1,63 @@ +import { Box } from '@rocket.chat/fuselage'; +import { useRoute, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useCallback } from 'react'; + +import { GenericTableRow, GenericTableCell } from '../../../components/GenericTable'; +import UserAvatar from '../../../components/avatar/UserAvatar'; +import RemoveAgentButton from './RemoveAgentButton'; + +const AgentsPageRow = ({ + user: { _id, name, username, avatarETag, emails, statusLivechat }, + mediaQuery, + reload, +}: { + user: { _id: string; name?: string; username?: string; avatarETag?: string; emails?: { address: string }[]; statusLivechat: string }; + mediaQuery: boolean; + reload: () => void; +}): ReactElement => { + const t = useTranslation(); + const agentsRoute = useRoute('omnichannel-agents'); + + const onRowClick = useCallback(() => { + agentsRoute.push({ + context: 'info', + id: _id, + }); + }, [_id, agentsRoute]); + + return ( + + + + {username && } + + + + {name || username} + + {!mediaQuery && name && ( + + {' '} + {`@${username}`}{' '} + + )} + + + + + {mediaQuery && ( + + + {username} + {' '} + + + )} + {emails?.length && emails[0].address} + {statusLivechat === 'available' ? t('Available') : t('Not_Available')} + + + ); +}; + +export default AgentsPageRow; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx deleted file mode 100644 index 3a6c62a71e760..0000000000000 --- a/apps/meteor/client/views/omnichannel/agents/AgentsRoute.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import { Box, Table } from '@rocket.chat/fuselage'; -import { useDebouncedValue, useMediaQuery, useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { PaginatedRequest } from '@rocket.chat/rest-typings'; -import { useRouteParameter, useRoute, usePermission, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo, useCallback, useState, FC, ReactElement } from 'react'; - -import GenericTable from '../../../components/GenericTable'; -import { useSort } from '../../../components/GenericTable/hooks/useSort'; -import VerticalBar from '../../../components/VerticalBar'; -import UserAvatar from '../../../components/avatar/UserAvatar'; -import { useEndpointData } from '../../../hooks/useEndpointData'; -import NotAuthorizedPage from '../../notAuthorized/NotAuthorizedPage'; -import AgentEditWithData from './AgentEditWithData'; -import AgentInfo from './AgentInfo'; -import AgentInfoActions from './AgentInfoActions'; -import AgentsPage from './AgentsPage'; -import RemoveAgentButton from './RemoveAgentButton'; - -const sortDir = (sortDir: 'asc' | 'desc'): 1 | -1 => (sortDir === 'asc' ? 1 : -1); - -const useQuery = ( - { - text, - itemsPerPage, - current, - }: { - text: string; - itemsPerPage: number; - current: number; - }, - [column, direction]: [string, 'asc' | 'desc'], -): PaginatedRequest<{ text: string }> => - useMemo( - () => ({ - fields: JSON.stringify({ name: 1, username: 1, emails: 1, avatarETag: 1 }), - text, - sort: JSON.stringify({ - [column]: sortDir(direction), - usernames: column === 'name' ? sortDir(direction) : undefined, - }), - ...(itemsPerPage && { count: itemsPerPage }), - ...(current && { offset: current }), - }), - [text, itemsPerPage, current, column, direction], - ); - -const AgentsRoute: FC = () => { - const t = useTranslation(); - const canViewAgents = usePermission('manage-livechat-agents'); - - const [params, setParams] = useState({ text: '', current: 0, itemsPerPage: 25 }); - const { sortBy, sortDirection, setSort } = useSort<'name' | 'username' | 'emails.address' | 'statusLivechat'>('name'); - - const mediaQuery = useMediaQuery('(min-width: 1024px)'); - - const debouncedParams = useDebouncedValue(params, 500); - const debouncedSort = useDebouncedValue([sortBy, sortDirection], 500) as [ - 'name' | 'username' | 'emails.address' | 'statusLivechat', - 'asc' | 'desc', - ]; - const query = useQuery(debouncedParams, debouncedSort); - const agentsRoute = useRoute('omnichannel-agents'); - const context = useRouteParameter('context'); - const id = useRouteParameter('id'); - - const onHeaderClick = useMutableCallback((id) => { - if (sortBy === id) { - setSort(id, sortDirection === 'asc' ? 'desc' : 'asc'); - return; - } - setSort(id, 'asc'); - }); - - const onRowClick = useMutableCallback( - (id) => (): void => - agentsRoute.push({ - context: 'info', - id, - }), - ); - - const { value: data, reload } = useEndpointData('livechat/users/agent', query); - - const header = useMemo( - () => - [ - - {t('Name')} - , - mediaQuery && ( - - {t('Username')} - - ), - - {t('Email')} - , - - {t('Livechat_status')} - , - - {t('Remove')} - , - ].filter(Boolean), - [sortDirection, sortBy, onHeaderClick, t, mediaQuery], - ) as ReactElement[]; - - const renderRow = useCallback( - ({ emails, _id, username, name, avatarETag, statusLivechat }) => ( - - - - - - - - {name || username} - - {!mediaQuery && name && ( - - {' '} - {`@${username}`}{' '} - - )} - - - - - {mediaQuery && ( - - - {username} - {' '} - - - )} - {emails?.length && emails[0].address} - {statusLivechat === 'available' ? t('Available') : t('Not_Available')} - - - ), - [mediaQuery, reload, onRowClick, t], - ); - - const EditAgentsTab = useCallback((): ReactElement => { - if (!context) { - return <>; - } - const handleVerticalBarCloseButtonClick = (): void => { - agentsRoute.push({}); - }; - - return ( - - - {context === 'edit' && t('Edit_User')} - {context === 'info' && t('User_Info')} - - - - {context === 'edit' && id && } - {context === 'info' && id && ( - - - - )} - - ); - }, [t, context, id, agentsRoute, reload]); - - if (!canViewAgents) { - return ; - } - - return ( - - - - ); -}; - -export default AgentsRoute; diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsTab.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsTab.tsx new file mode 100644 index 0000000000000..7662c1f6840c5 --- /dev/null +++ b/apps/meteor/client/views/omnichannel/agents/AgentsTab.tsx @@ -0,0 +1,35 @@ +import { useRoute, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useCallback } from 'react'; + +import VerticalBar from '../../../components/VerticalBar'; +import AgentEditWithData from './AgentEditWithData'; +import AgentInfo from './AgentInfo'; +import AgentInfoActions from './AgentInfoActions'; + +const AgentsTab = ({ reload, context, id }: { reload: () => void; context: string; id: string }): ReactElement => { + const t = useTranslation(); + const agentsRoute = useRoute('omnichannel-agents'); + + const handleVerticalBarCloseButtonClick = useCallback((): void => { + agentsRoute.push({}); + }, [agentsRoute]); + + return ( + + + {context === 'edit' && t('Edit_User')} + {context === 'info' && t('User_Info')} + + + + {context === 'edit' && } + {context === 'info' && ( + + + + )} + + ); +}; + +export default AgentsTab; diff --git a/apps/meteor/client/views/omnichannel/agents/RemoveAgentButton.tsx b/apps/meteor/client/views/omnichannel/agents/RemoveAgentButton.tsx index b37303a3ca59f..a5f48da05a383 100644 --- a/apps/meteor/client/views/omnichannel/agents/RemoveAgentButton.tsx +++ b/apps/meteor/client/views/omnichannel/agents/RemoveAgentButton.tsx @@ -1,9 +1,10 @@ -import { Table, Icon, Button } from '@rocket.chat/fuselage'; +import { Icon, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useSetModal, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { FC } from 'react'; +import React, { ReactElement } from 'react'; import GenericModal from '../../../components/GenericModal'; +import { GenericTableCell } from '../../../components/GenericTable'; import { useEndpointAction } from '../../../hooks/useEndpointAction'; type RemoveAgentButtonProps = { @@ -11,7 +12,7 @@ type RemoveAgentButtonProps = { reload: () => void; }; -const RemoveAgentButton: FC = ({ _id, reload }) => { +const RemoveAgentButton = ({ _id, reload }: RemoveAgentButtonProps): ReactElement => { const deleteAction = useEndpointAction('DELETE', `livechat/users/agent/${_id}`); const setModal = useSetModal(); const dispatchToastMessage = useToastMessageDispatch(); @@ -40,11 +41,11 @@ const RemoveAgentButton: FC = ({ _id, reload }) => { }); return ( - + - + ); }; diff --git a/apps/meteor/client/views/omnichannel/agents/hooks/useQuery.ts b/apps/meteor/client/views/omnichannel/agents/hooks/useQuery.ts new file mode 100644 index 0000000000000..fa98e888ca86e --- /dev/null +++ b/apps/meteor/client/views/omnichannel/agents/hooks/useQuery.ts @@ -0,0 +1,30 @@ +import { PaginatedRequest } from '@rocket.chat/rest-typings'; +import { useMemo } from 'react'; + +const sortDir = (sortDir: 'asc' | 'desc'): 1 | -1 => (sortDir === 'asc' ? 1 : -1); + +export const useQuery = ( + { + text, + itemsPerPage, + current, + }: { + text: string; + itemsPerPage: number; + current: number; + }, + [column, direction]: [string, 'asc' | 'desc'], +): PaginatedRequest<{ text: string }> => + useMemo( + () => ({ + fields: JSON.stringify({ name: 1, username: 1, emails: 1, avatarETag: 1 }), + text, + sort: JSON.stringify({ + [column]: sortDir(direction), + usernames: column === 'name' ? sortDir(direction) : undefined, + }), + ...(itemsPerPage && { count: itemsPerPage }), + ...(current && { offset: current }), + }), + [text, itemsPerPage, current, column, direction], + ); diff --git a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx index b5a20852c467c..c970bb2a4f156 100644 --- a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx +++ b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsPage.tsx @@ -1,6 +1,6 @@ import type { IOmnichannelRoom } from '@rocket.chat/core-typings'; import { Serialized } from '@rocket.chat/core-typings'; -import React, { Dispatch, FC, Key, memo, ReactElement, ReactNode, SetStateAction } from 'react'; +import React, { Key, memo, ReactElement, ReactNode } from 'react'; import GenericTable from '../../../components/GenericTable'; import Page from '../../../components/Page'; @@ -23,19 +23,25 @@ type CurrentChatsPageDataParams = { to: string; customFields: any; current: number; - itemsPerPage: number; + itemsPerPage: 25 | 50 | 100; tags: string[]; }; -const CurrentChatsPage: FC<{ +const CurrentChatsPage = ({ + data, + header, + setParams, + params, + title, + renderRow, +}: { data?: CurrentChatsPageData; header: ReactNode; - setParams: Dispatch>; + setParams: (params: any) => void; // TODO: Change to GenericTable V2 params: CurrentChatsPageDataParams; title: string; renderRow: (props: { _id?: Key }) => ReactElement; - reload: () => void; -}> = ({ data, header, setParams, params, title, renderRow, reload }) => ( +}): ReactElement => ( @@ -46,8 +52,7 @@ const CurrentChatsPage: FC<{ total={data?.total} params={params} setParams={setParams} - reload={reload} - renderFilter={({ onChange, ...props }: any): any => } + renderFilter={({ onChange, ...props }: any): ReactElement => } /> diff --git a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx index fc69981b09a99..f2e7ad337ec7b 100644 --- a/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx +++ b/apps/meteor/client/views/omnichannel/currentChats/CurrentChatsRoute.tsx @@ -2,7 +2,7 @@ import { Table } from '@rocket.chat/fuselage'; import { useDebouncedValue, useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useRoute, useRouteParameter, usePermission, useTranslation } from '@rocket.chat/ui-contexts'; import moment from 'moment'; -import React, { useMemo, useCallback, useState, FC } from 'react'; +import React, { useMemo, useCallback, useState, ReactElement } from 'react'; import GenericTable from '../../../components/GenericTable'; import { useEndpointData } from '../../../hooks/useEndpointData'; @@ -22,7 +22,7 @@ type useQueryType = ( to: string; tags: any[]; customFields: any; - itemsPerPage: number; + itemsPerPage: 25 | 50 | 100; current: number; }, debouncedSort: any[], @@ -90,7 +90,7 @@ const useQuery: useQueryType = ( return query; }, [guest, column, direction, itemsPerPage, current, from, to, status, servedBy, department, tags, customFields]); -const CurrentChatsRoute: FC = () => { +const CurrentChatsRoute = (): ReactElement => { const t = useTranslation(); const canViewCurrentChats = usePermission('view-livechat-current-chats'); const canRemoveClosedChats = usePermission('remove-closed-livechat-room'); @@ -107,7 +107,7 @@ const CurrentChatsRoute: FC = () => { to: '', customFields: {}, current: 0, - itemsPerPage: 25, + itemsPerPage: 25 as 25 | 50 | 100, tags: [] as string[], }); const [sort, setSort] = useState<[string, 'asc' | 'desc' | undefined]>(['ts', 'desc']); @@ -207,7 +207,6 @@ const CurrentChatsRoute: FC = () => { setParams={setParams} params={params} data={data} - reload={reload} header={header} renderRow={renderRow} title={t('Current_Chats')} diff --git a/apps/meteor/client/views/omnichannel/routes.js b/apps/meteor/client/views/omnichannel/routes.js index 8fd4c1e5fa45a..16fcb57aa8d26 100644 --- a/apps/meteor/client/views/omnichannel/routes.js +++ b/apps/meteor/client/views/omnichannel/routes.js @@ -14,7 +14,7 @@ registerOmnichannelRoute('/managers', { registerOmnichannelRoute('/agents/:context?/:id?', { name: 'omnichannel-agents', - lazyRouteComponent: () => import('./agents/AgentsRoute'), + lazyRouteComponent: () => import('./agents/AgentsPage'), }); registerOmnichannelRoute('/webhooks', { From db359ebcc5466e3bfce744db7b41bc00df458f8f Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Mon, 6 Jun 2022 15:48:19 -0300 Subject: [PATCH 6/8] fix weird typecheck error --- apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx index eeddfd1d6887a..4d873488468fb 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx @@ -90,14 +90,14 @@ const AgentsPage = (): ReactElement => { {phase === AsyncStatePhase.LOADING && } {phase === AsyncStatePhase.RESOLVED && - data.users.map((user) => )} + data?.users.map((user) => )} {phase === AsyncStatePhase.RESOLVED && ( Date: Mon, 6 Jun 2022 16:07:20 -0300 Subject: [PATCH 7/8] ts again --- .../client/views/omnichannel/agents/AgentsPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx index 4d873488468fb..94045e8e982f7 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsPage.tsx @@ -36,7 +36,7 @@ const AgentsPage = (): ReactElement => { const { current, itemsPerPage, setItemsPerPage, setCurrent, ...paginationProps } = usePagination(); const query = useQuery({ text: debouncedFilter, current, itemsPerPage }, debouncedSort); - const { value: data, reload, phase } = useEndpointData('livechat/users/agent', query); + const { reload, ...result } = useEndpointData('livechat/users/agent', query); const onHeaderClick = useMutableCallback((id) => { if (sortBy === id) { @@ -88,16 +88,16 @@ const AgentsPage = (): ReactElement => { {t('Remove')} - {phase === AsyncStatePhase.LOADING && } - {phase === AsyncStatePhase.RESOLVED && - data?.users.map((user) => )} + {result.phase === AsyncStatePhase.LOADING && } + {result.phase === AsyncStatePhase.RESOLVED && + result.value.users.map((user) => )} - {phase === AsyncStatePhase.RESOLVED && ( + {result.phase === AsyncStatePhase.RESOLVED && ( Date: Tue, 7 Jun 2022 10:32:06 -0300 Subject: [PATCH 8/8] fix m --- .../meteor/client/views/omnichannel/agents/AgentsPageRow.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx b/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx index a40634ff6ca64..b67fa10033c6c 100644 --- a/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx +++ b/apps/meteor/client/views/omnichannel/agents/AgentsPageRow.tsx @@ -37,8 +37,7 @@ const AgentsPageRow = ({ {!mediaQuery && name && ( - {' '} - {`@${username}`}{' '} + {`@${username}`} )} @@ -49,7 +48,7 @@ const AgentsPageRow = ({ {username} - {' '} + )}