import { Box, Pagination } from '@rocket.chat/fuselage'; import { useDebouncedValue, useStableCallback } from '@rocket.chat/fuselage-hooks'; import { UserAvatar } from '@rocket.chat/ui-avatar'; import { GenericTable, GenericTableBody, GenericTableHeader, GenericTableHeaderCell, GenericTableLoadingRow, GenericTableRow, GenericTableCell, usePagination, useSort, } from '@rocket.chat/ui-client'; import { useTranslation, usePermission, useToastMessageDispatch, useEndpoint, useRouter } from '@rocket.chat/ui-contexts'; import { hashKey, useQuery } from '@tanstack/react-query'; import { useMemo, useState } from 'react'; import CannedResponseFilter from './CannedResponseFilter'; import GenericNoResults from '../../../../components/GenericNoResults'; import { useFormatDateAndTime } from '../../../../hooks/useFormatDateAndTime'; import { links } from '../../../../lib/links'; import RemoveCannedResponseButton from '../RemoveCannedResponseButton'; type Scope = 'global' | 'department' | 'user'; const CannedResponsesTable = () => { const t = useTranslation(); const router = useRouter(); const dispatchToastMessage = useToastMessageDispatch(); const getTime = useFormatDateAndTime(); const isMonitor = usePermission('save-department-canned-responses'); const isManager = usePermission('save-all-canned-responses'); const [createdBy, setCreatedBy] = useState('all'); const [sharing, setSharing] = useState<'' | 'user' | 'global' | 'department'>(''); const [text, setText] = useState(''); const debouncedText = useDebouncedValue(text, 500); const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination(); const { sortBy, setSort, sortDirection } = useSort<'shortcut' | 'scope' | 'tags' | '_createdAt' | 'createdBy'>('shortcut'); const query = useMemo( () => ({ text: debouncedText, sort: JSON.stringify({ [sortBy]: sortDirection === 'asc' ? 1 : -1 }), ...(sharing && { scope: sharing }), ...(createdBy && createdBy !== 'all' && { createdBy }), ...(itemsPerPage && { count: itemsPerPage }), ...(current && { offset: current }), }), [createdBy, current, debouncedText, itemsPerPage, sharing, sortBy, sortDirection], ); const [defaultQuery] = useState(hashKey([query])); const queryHasChanged = defaultQuery !== hashKey([query]); const getCannedResponses = useEndpoint('GET', '/v1/canned-responses'); const { data, isLoading, isSuccess } = useQuery({ queryKey: ['getCannedResponses', query], queryFn: () => getCannedResponses(query), refetchOnWindowFocus: false, }); const handleAddNew = useStableCallback(() => router.navigate('/omnichannel/canned-responses/new')); const onRowClick = useStableCallback((id: string, scope: string) => (): void => { if (scope === 'global' && isMonitor && !isManager) { return dispatchToastMessage({ type: 'error', message: t('Not_authorized'), }); } router.navigate(`/omnichannel/canned-responses/edit/${id}`); }); const defaultOptions = useMemo( () => ({ global: t('Public'), department: t('Department'), user: t('Private'), }), [t], ); const headers = ( <> {t('Shortcut')} {t('Sharing')} {t('Created_by')} {t('Created_at')} {t('Tags')} {t('Remove')} ); return ( <> {((isSuccess && data?.cannedResponses.length > 0) || queryHasChanged) && ( )} {isLoading && ( {headers} )} {isSuccess && data?.cannedResponses.length === 0 && queryHasChanged && } {isSuccess && data?.cannedResponses.length === 0 && !queryHasChanged && ( )} {isSuccess && data?.cannedResponses.length > 0 && ( <> {headers} {data?.cannedResponses.map(({ _id, shortcut, scope, createdBy, _createdAt, tags = [] }) => ( {shortcut} {defaultOptions[scope as Scope]} {createdBy.username} {getTime(_createdAt)} {tags.join(', ')} {!(scope === 'global' && isMonitor && !isManager) && } ))} )} ); }; export default CannedResponsesTable;