Typescript refactor.

This commit is contained in:
Mike Cao 2023-12-03 03:07:03 -08:00
parent b578162cb6
commit 7c42f0da82
173 changed files with 968 additions and 549 deletions

View file

@ -1,4 +1,3 @@
import { useRef } from 'react';
import {
Form,
FormRow,
@ -12,11 +11,12 @@ import { setValue } from 'store/cache';
import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
export function TeamAddForm({ onSave, onClose }) {
export function TeamAddForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
const { formatMessage, labels } = useMessages();
const { post, useMutation } = useApi();
const { mutate, error, isLoading } = useMutation(data => post('/teams', data));
const ref = useRef(null);
const { mutate, error, isPending } = useMutation({
mutationFn: (data: any) => post('/teams', data),
});
const handleSubmit = async data => {
mutate(data, {
@ -29,17 +29,17 @@ export function TeamAddForm({ onSave, onClose }) {
};
return (
<Form ref={ref} onSubmit={handleSubmit} error={error}>
<Form onSubmit={handleSubmit} error={error}>
<FormRow label={formatMessage(labels.name)}>
<FormInput name="name" rules={{ required: formatMessage(labels.required) }}>
<TextField autoComplete="off" />
</FormInput>
</FormRow>
<FormButtons flex>
<SubmitButton variant="primary" disabled={isLoading}>
<SubmitButton variant="primary" disabled={isPending}>
{formatMessage(labels.save)}
</SubmitButton>
<Button disabled={isLoading} onClick={onClose}>
<Button disabled={isPending} onClick={onClose}>
{formatMessage(labels.cancel)}
</Button>
</FormButtons>

View file

@ -2,7 +2,15 @@ import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
import TeamDeleteForm from './TeamDeleteForm';
export function TeamDeleteButton({ teamId, teamName, onDelete }) {
export function TeamDeleteButton({
teamId,
teamName,
onDelete,
}: {
teamId: string;
teamName: string;
onDelete?: () => void;
}) {
const { formatMessage, labels } = useMessages();
return (
@ -14,7 +22,7 @@ export function TeamDeleteButton({ teamId, teamName, onDelete }) {
<Text>{formatMessage(labels.delete)}</Text>
</Button>
<Modal title={formatMessage(labels.deleteTeam)}>
{close => (
{(close: any) => (
<TeamDeleteForm teamId={teamId} teamName={teamName} onSave={onDelete} onClose={close} />
)}
</Modal>

View file

@ -3,10 +3,22 @@ import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
import { setValue } from 'store/cache';
export function TeamDeleteForm({ teamId, teamName, onSave, onClose }) {
export function TeamDeleteForm({
teamId,
teamName,
onSave,
onClose,
}: {
teamId: string;
teamName: string;
onSave: () => void;
onClose: () => void;
}) {
const { formatMessage, labels, messages, FormattedMessage } = useMessages();
const { del, useMutation } = useApi();
const { mutate, error, isLoading } = useMutation(data => del(`/teams/${teamId}`, data));
const { mutate, error, isPending } = useMutation({
mutationFn: (data: any) => del(`/teams/${teamId}`, data),
});
const handleSubmit = async data => {
mutate(data, {
@ -24,7 +36,7 @@ export function TeamDeleteForm({ teamId, teamName, onSave, onClose }) {
<FormattedMessage {...messages.confirmDelete} values={{ target: <b>{teamName}</b> }} />
</p>
<FormButtons flex>
<SubmitButton variant="danger" disabled={isLoading}>
<SubmitButton variant="danger" disabled={isPending}>
{formatMessage(labels.delete)}
</SubmitButton>
<Button onClick={onClose}>{formatMessage(labels.cancel)}</Button>

View file

@ -12,10 +12,10 @@ import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
import { setValue } from 'store/cache';
export function TeamJoinForm({ onSave, onClose }) {
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
const { formatMessage, labels, getMessage } = useMessages();
const { post, useMutation } = useApi();
const { mutate, error } = useMutation(data => post('/teams/join', data));
const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) });
const ref = useRef(null);
const handleSubmit = async data => {

View file

@ -4,7 +4,15 @@ import useLocale from 'components/hooks/useLocale';
import useUser from 'components/hooks/useUser';
import TeamDeleteForm from './TeamLeaveForm';
export function TeamLeaveButton({ teamId, teamName, onLeave }) {
export function TeamLeaveButton({
teamId,
teamName,
onLeave,
}: {
teamId: string;
teamName: string;
onLeave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
const { dir } = useLocale();
const { user } = useUser();

View file

@ -3,22 +3,33 @@ import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
import { setValue } from 'store/cache';
export function TeamLeaveForm({ teamId, userId, teamName, onSave, onClose }) {
export function TeamLeaveForm({
teamId,
userId,
teamName,
onSave,
onClose,
}: {
teamId: string;
userId: string;
teamName: string;
onSave: () => void;
onClose: () => void;
}) {
const { formatMessage, labels, messages, FormattedMessage } = useMessages();
const { del, useMutation } = useApi();
const { mutate, error, isLoading } = useMutation(() => del(`/teams/${teamId}/users/${userId}`));
const { mutate, error, isPending } = useMutation({
mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
});
const handleSubmit = async () => {
mutate(
{},
{
onSuccess: async () => {
setValue('team:members', Date.now());
onSave();
onClose();
},
mutate(null, {
onSuccess: async () => {
setValue('team:members', Date.now());
onSave();
onClose();
},
);
});
};
return (
@ -27,7 +38,7 @@ export function TeamLeaveForm({ teamId, userId, teamName, onSave, onClose }) {
<FormattedMessage {...messages.confirmDelete} values={{ target: <b>{teamName}</b> }} />
</p>
<FormButtons flex>
<SubmitButton variant="danger" disabled={isLoading}>
<SubmitButton variant="danger" disabled={isPending}>
{formatMessage(labels.leave)}
</SubmitButton>
<Button onClick={onClose}>{formatMessage(labels.cancel)}</Button>

View file

@ -3,7 +3,7 @@ import Icons from 'components/icons';
import useMessages from 'components/hooks/useMessages';
import TeamAddForm from './TeamAddForm';
export function TeamsAddButton({ onAdd }) {
export function TeamsAddButton({ onAdd }: { onAdd?: () => void }) {
const { formatMessage, labels } = useMessages();
return (
@ -15,7 +15,7 @@ export function TeamsAddButton({ onAdd }) {
<Text>{formatMessage(labels.createTeam)}</Text>
</Button>
<Modal title={formatMessage(labels.createTeam)}>
{close => <TeamAddForm onSave={onAdd} onClose={close} />}
{(close: () => void) => <TeamAddForm onSave={onAdd} onClose={close} />}
</Modal>
</ModalTrigger>
);

View file

@ -7,10 +7,10 @@ import useCache from 'store/cache';
export function TeamsDataTable() {
const { get } = useApi();
const modified = useCache(state => state?.teams);
const modified = useCache((state: any) => state?.teams);
const queryResult = useFilterQuery({
queryKey: ['teams', { modified }],
queryFn: params => {
queryFn: (params: any) => {
return get(`/teams`, {
...params,
});

View file

@ -7,7 +7,7 @@ import { Button, GridColumn, GridTable, Icon, Icons, Text, useBreakpoint } from
import TeamDeleteButton from './TeamDeleteButton';
import TeamLeaveButton from './TeamLeaveButton';
export function TeamsTable({ data = [] }) {
export function TeamsTable({ data = [] }: { data: any[] }) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const breakpoint = useBreakpoint();

View file

@ -1,7 +1,15 @@
import { Button, Icon, Icons, Text } from 'react-basics';
import styles from './WebsiteTags.module.css';
export function WebsiteTags({ items = [], websites = [], onClick }) {
export function WebsiteTags({
items = [],
websites = [],
onClick,
}: {
items: any[];
websites: any[];
onClick: (e: Event) => void;
}) {
if (websites.length === 0) {
return null;
}

View file

@ -3,28 +3,37 @@ import useMessages from 'components/hooks/useMessages';
import { Icon, Icons, LoadingButton, Text } from 'react-basics';
import { setValue } from 'store/cache';
export function TeamMemberRemoveButton({ teamId, userId, disabled, onSave }) {
export function TeamMemberRemoveButton({
teamId,
userId,
disabled,
onSave,
}: {
teamId: string;
userId: string;
disabled?: boolean;
onSave?: () => void;
}) {
const { formatMessage, labels } = useMessages();
const { del, useMutation } = useApi();
const { mutate, isLoading } = useMutation(() => del(`/teams/${teamId}/users/${userId}`));
const { mutate, isPending } = useMutation({
mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
});
const handleRemoveTeamMember = () => {
mutate(
{},
{
onSuccess: () => {
setValue('team:members', Date.now());
onSave?.();
},
mutate(null, {
onSuccess: () => {
setValue('team:members', Date.now());
onSave?.();
},
);
});
};
return (
<LoadingButton
onClick={() => handleRemoveTeamMember()}
disabled={disabled}
isLoading={isLoading}
isLoading={isPending}
>
<Icon>
<Icons.Close />

View file

@ -4,7 +4,7 @@ import useFilterQuery from 'components/hooks/useFilterQuery';
import DataTable from 'components/common/DataTable';
import useCache from 'store/cache';
export function TeamMembers({ teamId, readOnly }) {
export function TeamMembers({ teamId, readOnly }: { teamId: string; readOnly: boolean }) {
const { get } = useApi();
const modified = useCache(state => state?.['team:members']);
const queryResult = useFilterQuery({

View file

@ -4,7 +4,15 @@ import useUser from 'components/hooks/useUser';
import { ROLES } from 'lib/constants';
import TeamMemberRemoveButton from './TeamMemberRemoveButton';
export function TeamMembersTable({ data = [], teamId, readOnly }) {
export function TeamMembersTable({
data = [],
teamId,
readOnly,
}: {
data: any[];
teamId: string;
readOnly: boolean;
}) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const breakpoint = useBreakpoint();

View file

@ -10,7 +10,7 @@ import TeamEditForm from './TeamEditForm';
import TeamMembers from './TeamMembers';
import TeamWebsites from './TeamWebsites';
export function TeamSettings({ teamId }) {
export function TeamSettings({ teamId }: { teamId: string }) {
const { formatMessage, labels, messages } = useMessages();
const { user } = useUser();
const [values, setValues] = useState(null);
@ -24,7 +24,7 @@ export function TeamSettings({ teamId }) {
return get(`/teams/${teamId}`);
}
},
cacheTime: 0,
gcTime: 0,
});
const canEdit = data?.teamUser?.find(
({ userId, role }) => role === ROLES.teamOwner && userId === user.id,
@ -48,7 +48,7 @@ export function TeamSettings({ teamId }) {
return (
<Flexbox direction="column">
<PageHeader title={values?.name} />
<Tabs selectedKey={tab} onSelect={setTab} style={{ marginBottom: 30 }}>
<Tabs selectedKey={tab} onSelect={(value: any) => setTab(value)} style={{ marginBottom: 30 }}>
<Item key="details">{formatMessage(labels.details)}</Item>
<Item key="members">{formatMessage(labels.members)}</Item>
<Item key="websites">{formatMessage(labels.websites)}</Item>

View file

@ -7,11 +7,21 @@ import Empty from 'components/common/Empty';
import { setValue } from 'store/cache';
import { useUser } from 'components/hooks';
export function TeamWebsiteAddForm({ teamId, onSave, onClose }) {
export function TeamWebsiteAddForm({
teamId,
onSave,
onClose,
}: {
teamId: string;
onSave: () => void;
onClose: () => void;
}) {
const { user } = useUser();
const { formatMessage, labels } = useMessages();
const { get, post, useQuery, useMutation } = useApi();
const { mutate, error } = useMutation(data => post(`/teams/${teamId}/websites`, data));
const { mutate, error } = useMutation({
mutationFn: (data: any) => post(`/teams/${teamId}/websites`, data),
});
const { data: websites, isLoading } = useQuery({
queryKey: ['websites'],
queryFn: () => get('/websites'),
@ -42,7 +52,7 @@ export function TeamWebsiteAddForm({ teamId, onSave, onClose }) {
{!isLoading && !hasData && <Empty />}
{hasData && (
<Form onSubmit={handleSubmit} error={error}>
<WebsitesDataTable userId={user.id} showHeader={false} showActions={false}>
<WebsitesDataTable userId={user.id} showActions={false}>
<GridColumn name="select" label={formatMessage(labels.selectWebsite)} alignment="end">
{row => (
<Toggle

View file

@ -8,7 +8,7 @@ import useFilterQuery from 'components/hooks/useFilterQuery';
import DataTable from 'components/common/DataTable';
import useCache from 'store/cache';
export function TeamWebsites({ teamId }) {
export function TeamWebsites({ teamId, readOnly }: { teamId: string; readOnly: boolean }) {
const { formatMessage, labels, messages } = useMessages();
const { user } = useUser();
const { get } = useApi();
@ -24,7 +24,7 @@ export function TeamWebsites({ teamId }) {
});
const handleChange = () => {
queryResult.refetch();
queryResult.query.refetch();
};
return (
@ -43,7 +43,9 @@ export function TeamWebsites({ teamId }) {
</ModalTrigger>
</ActionForm>
<DataTable queryResult={queryResult}>
{({ data }) => <TeamWebsitesTable data={data} onRemove={handleChange} />}
{({ data }) => (
<TeamWebsitesTable data={data} onRemove={handleChange} readOnly={readOnly} />
)}
</DataTable>
</>
);

View file

@ -4,7 +4,15 @@ import useMessages from 'components/hooks/useMessages';
import useUser from 'components/hooks/useUser';
import TeamWebsiteRemoveButton from './TeamWebsiteRemoveButton';
export function TeamWebsitesTable({ data = [], onRemove }) {
export function TeamWebsitesTable({
data = [],
readOnly,
onRemove,
}: {
data: any[];
readOnly: boolean;
onRemove: () => void;
}) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
@ -17,7 +25,7 @@ export function TeamWebsitesTable({ data = [], onRemove }) {
const { id: teamId, teamUser } = row.teamWebsite[0].team;
const { id: websiteId, userId } = row;
const owner = teamUser[0];
const canRemove = user.id === userId || user.id === owner.userId;
const canRemove = !readOnly && (user.id === userId || user.id === owner.userId);
return (
<>
{canRemove && (