Skip to content

Commit

Permalink
Chore: Invites Empty State (#27631)
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris authored Jan 12, 2023
1 parent d332c36 commit 303e836
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 29 deletions.
2 changes: 1 addition & 1 deletion apps/meteor/client/views/admin/invites/InviteRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const isExpired = (expires: IInvite['expires']): boolean => {
};

type InviteRowProps = Omit<IInvite, 'createdAt' | 'expires' | '_updatedAt'> & {
onRemove: (removeInvite: () => void) => void;
onRemove: (removeInvite: () => Promise<boolean>) => void;
_updatedAt: string;
createdAt: string;
expires: string | null;
Expand Down
88 changes: 61 additions & 27 deletions apps/meteor/client/views/admin/invites/InvitesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { States, StatesIcon, StatesTitle, StatesActions, StatesAction } from '@rocket.chat/fuselage';
import { useMediaQuery } from '@rocket.chat/fuselage-hooks';
import { useSetModal, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import { useSetModal, useToastMessageDispatch, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React from 'react';
import React, { useMemo } from 'react';

import GenericModal from '../../../components/GenericModal';
import {
Expand All @@ -12,23 +14,22 @@ import {
GenericTableLoadingTable,
} from '../../../components/GenericTable';
import Page from '../../../components/Page';
import { useEndpointData } from '../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../lib/asyncState';
import InviteRow from './InviteRow';

const InvitesPage = (): ReactElement => {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const setModal = useSetModal();

const { phase, value, reload } = useEndpointData('/v1/listInvites');
const getInvitesList = useEndpoint('GET', '/v1/listInvites');
const { data, isLoading, isSuccess, isError, refetch } = useQuery(['invites'], () => getInvitesList());

const onRemove = (removeInvite: () => void): void => {
const onRemove = (removeInvite: () => Promise<boolean>): void => {
const confirmRemove = async (): Promise<void> => {
try {
await removeInvite();
dispatchToastMessage({ type: 'success', message: t('Invite_removed') });
reload();
refetch();
} catch (error) {
if (typeof error === 'string' || error instanceof Error) {
dispatchToastMessage({ type: 'error', message: error });
Expand All @@ -54,30 +55,63 @@ const InvitesPage = (): ReactElement => {

const notSmall = useMediaQuery('(min-width: 768px)');

const headers = useMemo(
() => [
<GenericTableHeaderCell w={notSmall ? '20%' : '80%'}>{t('Token')}</GenericTableHeaderCell>,
notSmall && [
<GenericTableHeaderCell w='35%'>{t('Created_at')}</GenericTableHeaderCell>,
<GenericTableHeaderCell w='20%'>{t('Expiration')}</GenericTableHeaderCell>,
<GenericTableHeaderCell w='10%'>{t('Uses')}</GenericTableHeaderCell>,
<GenericTableHeaderCell w='10%'>{t('Uses_left')}</GenericTableHeaderCell>,
<GenericTableHeaderCell />,
],
],
[notSmall, t],
);

return (
<Page>
<Page.Header title={t('Invites')} />
<Page.Content>
<GenericTable>
<GenericTableHeader>
<GenericTableHeaderCell w={notSmall ? '20%' : '80%'}>{t('Token')}</GenericTableHeaderCell>
{notSmall && (
<>
<GenericTableHeaderCell w='35%'>{t('Created_at')}</GenericTableHeaderCell>
<GenericTableHeaderCell w='20%'>{t('Expiration')}</GenericTableHeaderCell>
<GenericTableHeaderCell w='10%'>{t('Uses')}</GenericTableHeaderCell>
<GenericTableHeaderCell w='10%'>{t('Uses_left')}</GenericTableHeaderCell>
</>
)}
<GenericTableHeaderCell />
</GenericTableHeader>
<GenericTableBody>
{phase === AsyncStatePhase.LOADING && <GenericTableLoadingTable headerCells={notSmall ? 4 : 1} />}
{phase === AsyncStatePhase.RESOLVED &&
Array.isArray(value) &&
value.map((invite) => <InviteRow key={invite._id} {...invite} onRemove={onRemove} />)}
</GenericTableBody>
</GenericTable>
<>
{isLoading && (
<GenericTable>
<GenericTableHeader>{headers}</GenericTableHeader>
<GenericTableBody>
<GenericTableLoadingTable headerCells={4} />
</GenericTableBody>
</GenericTable>
)}

{isSuccess && data && data.length > 0 && (
<GenericTable>
<GenericTableHeader>{headers}</GenericTableHeader>
<GenericTableBody>
{isLoading && <GenericTableLoadingTable headerCells={notSmall ? 4 : 1} />}
{data.map((invite) => (
<InviteRow key={invite._id} {...invite} onRemove={onRemove} />
))}
</GenericTableBody>
</GenericTable>
)}

{isSuccess && data && data.length === 0 && (
<States>
<StatesIcon name='magnifier' />
<StatesTitle>{t('No_results_found')}</StatesTitle>
</States>
)}

{isError && (
<States>
<StatesIcon name='warning' variation='danger' />
<StatesTitle>{t('Something_went_wrong')}</StatesTitle>
<StatesActions>
<StatesAction onClick={() => refetch()}>{t('Reload_page')}</StatesAction>
</StatesActions>
</States>
)}
</>
</Page.Content>
</Page>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const UsersTable = ({ reload }: UsersTableProps): ReactElement | null => {

return (
<>
<FilterByText placeholder={t('Search_Users')} onChange={({ text }): void => setText(text)} />
<FilterByText autoFocus placeholder={t('Search_Users')} onChange={({ text }): void => setText(text)} />
{phase === AsyncStatePhase.LOADING && (
<GenericTable>
<GenericTableHeader>{headers}</GenericTableHeader>
Expand Down

0 comments on commit 303e836

Please sign in to comment.