Teams refactor: removed team websites.

This commit is contained in:
Mike Cao 2024-01-25 23:20:53 -08:00
parent 0d442b751d
commit f85393f8df
23 changed files with 190 additions and 351 deletions

View file

@ -17,6 +17,12 @@ export function TeamsTable({ data = [] }: { data: any[] }) {
<GridColumn name="owner" label={formatMessage(labels.owner)}>
{row => row.teamUser.find(({ role }) => role === ROLES.teamOwner)?.user?.username}
</GridColumn>
<GridColumn name="websites" label={formatMessage(labels.websites)}>
{row => row._count.website}
</GridColumn>
<GridColumn name="members" label={formatMessage(labels.members)}>
{row => row._count.teamUser}
</GridColumn>
<GridColumn name="action" label=" " alignment="end">
{row => {
const { id, name, teamUser } = row;

View file

@ -1,8 +1,8 @@
import useApi from 'components/hooks/useApi';
import TeamMembersTable from './TeamMembersTable';
import useFilterQuery from 'components/hooks/useFilterQuery';
import DataTable from 'components/common/DataTable';
import useCache from 'store/cache';
import TeamMembersTable from './TeamMembersTable';
export function TeamMembers({ teamId, readOnly }: { teamId: string; readOnly: boolean }) {
const { get } = useApi();
@ -18,11 +18,9 @@ export function TeamMembers({ teamId, readOnly }: { teamId: string; readOnly: bo
});
return (
<>
<DataTable queryResult={queryResult}>
{({ data }) => <TeamMembersTable data={data} teamId={teamId} readOnly={readOnly} />}
</DataTable>
</>
<DataTable queryResult={queryResult}>
{({ data }) => <TeamMembersTable data={data} teamId={teamId} readOnly={readOnly} />}
</DataTable>
);
}

View file

@ -25,7 +25,6 @@ export function TeamSettings({ teamId }: { teamId: string }) {
return get(`/teams/${teamId}`);
}
},
gcTime: 0,
});
const canEdit = data?.teamUser?.find(
({ userId, role }) => role === ROLES.teamOwner && userId === user.id,

View file

@ -1,79 +0,0 @@
import useApi from 'components/hooks/useApi';
import { useState } from 'react';
import { Button, Form, FormButtons, GridColumn, Loading, SubmitButton, Toggle } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
import WebsitesDataTable from 'app/(main)/settings/websites/WebsitesDataTable';
import Empty from 'components/common/Empty';
import { setValue } from 'store/cache';
import { useUser } from 'components/hooks';
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({
mutationFn: (data: any) => post(`/teams/${teamId}/websites`, data),
});
const { data: websites, isLoading } = useQuery({
queryKey: ['websites'],
queryFn: () => get('/websites'),
});
const [selected, setSelected] = useState([]);
const hasData = websites && websites.data.length > 0;
const handleSubmit = () => {
mutate(
{ websiteIds: selected },
{
onSuccess: async () => {
setValue('team:websites', Date.now());
onSave?.();
onClose?.();
},
},
);
};
const handleSelect = id => {
setSelected(state => (state.includes(id) ? state.filter(n => n !== id) : state.concat(id)));
};
return (
<>
{isLoading && !hasData && <Loading icon="dots" position="center" />}
{!isLoading && !hasData && <Empty />}
{hasData && (
<Form onSubmit={handleSubmit} error={error}>
<WebsitesDataTable userId={user.id} showActions={false}>
<GridColumn name="select" label={formatMessage(labels.selectWebsite)} alignment="end">
{row => (
<Toggle
key={row.id}
value={row.id}
checked={selected?.includes(row.id)}
onChange={handleSelect.bind(null, row.id)}
/>
)}
</GridColumn>
</WebsitesDataTable>
<FormButtons flex>
<SubmitButton variant="primary" disabled={selected?.length === 0}>
{formatMessage(labels.addWebsite)}
</SubmitButton>
<Button onClick={onClose}>{formatMessage(labels.cancel)}</Button>
</FormButtons>
</Form>
)}
</>
);
}
export default TeamWebsiteAddForm;

View file

@ -1,13 +1,13 @@
import useFilterQuery from 'components/hooks/useFilterQuery';
import WebsitesTable from 'app/(main)/settings/websites/WebsitesTable';
import DataTable from 'components/common/DataTable';
import useFilterQuery from 'components/hooks/useFilterQuery';
import useApi from 'components/hooks/useApi';
import useUser from 'components/hooks/useUser';
import useCache from 'store/cache';
import WebsitesTable from '../../websites/WebsitesTable';
export function TeamWebsites({ teamId }: { teamId: string; readOnly: boolean }) {
const { user } = useUser();
const { get } = useApi();
const { user } = useUser();
const modified = useCache(state => state?.['team:websites']);
const queryResult = useFilterQuery({
queryKey: ['team:websites', { teamId, modified }],

View file

@ -1,6 +1,6 @@
import { Metadata } from 'next';
import TeamsDataTable from './TeamsDataTable';
import TeamsHeader from './TeamsHeader';
import { Metadata } from 'next';
export default function () {
if (process.env.cloudMode) {
@ -16,5 +16,5 @@ export default function () {
}
export const metadata: Metadata = {
title: 'Teams Settings | umami',
title: 'Teams Settings - Umami',
};

View file

@ -3,10 +3,9 @@ import useApi from 'components/hooks/useApi';
import useFilterQuery from 'components/hooks/useFilterQuery';
import DataTable from 'components/common/DataTable';
import UsersTable from './UsersTable';
import UsersHeader from './UsersHeader';
import useCache from 'store/cache';
export function UsersDataTable() {
export function UsersDataTable({ showActions }: { showActions: boolean }) {
const { get } = useApi();
const modified = useCache((state: any) => state?.users);
const queryResult = useFilterQuery({
@ -15,10 +14,9 @@ export function UsersDataTable() {
});
return (
<>
<UsersHeader />
<DataTable queryResult={queryResult}>{({ data }) => <UsersTable data={data} />}</DataTable>
</>
<DataTable queryResult={queryResult}>
{({ data }) => <UsersTable data={data} showActions={showActions} />}
</DataTable>
);
}

View file

@ -6,7 +6,13 @@ import useMessages from 'components/hooks/useMessages';
import useLocale from 'components/hooks/useLocale';
import UserDeleteButton from './UserDeleteButton';
export function UsersTable({ data = [] }: { data: any[] }) {
export function UsersTable({
data = [],
showActions = true,
}: {
data: any[];
showActions?: boolean;
}) {
const { formatMessage, labels } = useMessages();
const { dateLocale } = useLocale();
const breakpoint = useBreakpoint();
@ -29,24 +35,26 @@ export function UsersTable({ data = [] }: { data: any[] }) {
})
}
</GridColumn>
<GridColumn name="action" label=" " alignment="end">
{row => {
const { id, username } = row;
return (
<>
<Link href={`/settings/users/${id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<UserDeleteButton userId={id} username={username} />
</>
);
}}
</GridColumn>
{showActions && (
<GridColumn name="action" label=" " alignment="end">
{row => {
const { id, username } = row;
return (
<>
<Link href={`/settings/users/${id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<UserDeleteButton userId={id} username={username} />
</>
);
}}
</GridColumn>
)}
</GridTable>
);
}

View file

@ -1,8 +1,14 @@
import UsersDataTable from './UsersDataTable';
import { Metadata } from 'next';
import UsersDataTable from './UsersDataTable';
import UsersHeader from './UsersHeader';
export default function () {
return <UsersDataTable />;
return (
<>
<UsersHeader />
<UsersDataTable />
</>
);
}
export const metadata: Metadata = {
title: 'Users | umami',