RocketChat/Rocket.Chat

View on GitHub
apps/meteor/client/views/admin/customUserStatus/CustomUserStatusTable/CustomUserStatusTable.tsx

Summary

Maintainability
A
3 hrs
Test Coverage
import { Pagination } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { useEndpoint, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import type { ReactElement, MutableRefObject } from 'react';
import React, { useState, useMemo, useEffect } from 'react';

import FilterByText from '../../../../components/FilterByText';
import GenericNoResult from '../../../../components/GenericNoResults';
import {
    GenericTable,
    GenericTableHeader,
    GenericTableHeaderCell,
    GenericTableBody,
    GenericTableLoadingTable,
} from '../../../../components/GenericTable';
import { usePagination } from '../../../../components/GenericTable/hooks/usePagination';
import { useSort } from '../../../../components/GenericTable/hooks/useSort';
import CustomUserStatusRow from './CustomUserStatusRow';

type CustomUserStatusProps = {
    reload: MutableRefObject<() => void>;
    onClick: (id: string) => void;
};

// TODO: Missing error state
const CustomUserStatus = ({ reload, onClick }: CustomUserStatusProps): ReactElement | null => {
    const t = useTranslation();
    const [text, setText] = useState('');
    const { current, itemsPerPage, setItemsPerPage: onSetItemsPerPage, setCurrent: onSetCurrent, ...paginationProps } = usePagination();
    const { sortBy, sortDirection, setSort } = useSort<'name' | 'statusType'>('name');

    const query = useDebouncedValue(
        useMemo(
            () => ({
                query: JSON.stringify({ name: { $regex: escapeRegExp(text), $options: 'i' } }),
                sort: `{ "${sortBy}": ${sortDirection === 'asc' ? 1 : -1} }`,
                count: itemsPerPage,
                offset: current,
            }),
            [text, itemsPerPage, current, sortBy, sortDirection],
        ),
        500,
    );

    const getCustomUserStatus = useEndpoint('GET', '/v1/custom-user-status.list');
    const dispatchToastMessage = useToastMessageDispatch();

    const { data, isLoading, refetch, isFetched } = useQuery(
        ['custom-user-statuses', query],
        async () => {
            const { statuses } = await getCustomUserStatus(query);
            return statuses;
        },
        {
            onError: (error) => {
                dispatchToastMessage({ type: 'error', message: error });
            },
        },
    );

    useEffect(() => {
        reload.current = refetch;
    }, [reload, refetch]);

    if (!data) {
        return null;
    }

    return (
        <>
            <FilterByText onChange={setText} />
            {data.length === 0 && <GenericNoResult />}
            {data && data.length > 0 && (
                <>
                    <GenericTable>
                        <GenericTableHeader>
                            <GenericTableHeaderCell key='name' direction={sortDirection} active={sortBy === 'name'} onClick={setSort} sort='name'>
                                {t('Name')}
                            </GenericTableHeaderCell>
                            <GenericTableHeaderCell
                                key='presence'
                                direction={sortDirection}
                                active={sortBy === 'statusType'}
                                onClick={setSort}
                                sort='statusType'
                            >
                                {t('Presence')}
                            </GenericTableHeaderCell>
                        </GenericTableHeader>
                        <GenericTableBody>
                            {isLoading && <GenericTableLoadingTable headerCells={2} />}
                            {data?.map((status) => (
                                <CustomUserStatusRow key={status._id} status={status} onClick={onClick} />
                            ))}
                        </GenericTableBody>
                    </GenericTable>
                    {isFetched && (
                        <Pagination
                            current={current}
                            itemsPerPage={itemsPerPage}
                            count={data.length}
                            onSetItemsPerPage={onSetItemsPerPage}
                            onSetCurrent={onSetCurrent}
                            {...paginationProps}
                        />
                    )}
                </>
            )}
        </>
    );
};

export default CustomUserStatus;