Refactored teams components.

This commit is contained in:
Mike Cao 2024-02-05 20:29:00 -08:00
parent 0e144269ee
commit be5592446a
25 changed files with 122 additions and 81 deletions

View File

@ -11,7 +11,7 @@ import { ROLES } from 'lib/constants';
export function ProfileSettings() { export function ProfileSettings() {
const { user } = useLogin(); const { user } = useLogin();
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const cloudMode = Boolean(process.env.cloudMode); const cloudMode = !!process.env.cloudMode;
if (!user) { if (!user) {
return null; return null;
@ -24,7 +24,7 @@ export function ProfileSettings() {
return formatMessage(labels.user); return formatMessage(labels.user);
} }
if (value === ROLES.admin) { if (value === ROLES.admin) {
return formatMessage(labels.admin); return formatMessage(labels.administrator);
} }
if (value === ROLES.viewOnly) { if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly); return formatMessage(labels.viewOnly);

View File

@ -1,15 +1,17 @@
'use client'; 'use client';
import TeamMembers from 'app/(main)/settings/teams/[teamId]/TeamMembers'; import TeamMembersDataTable from './TeamMembersDataTable';
import PageHeader from 'components/layout/PageHeader'; import PageHeader from 'components/layout/PageHeader';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
export default function ({ teamId }: { teamId: string }) { export function TeamMembers({ teamId }: { teamId: string }) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
return ( return (
<> <>
<PageHeader title={formatMessage(labels.members)} /> <PageHeader title={formatMessage(labels.members)} />
<TeamMembers teamId={teamId} allowEdit={true} /> <TeamMembersDataTable teamId={teamId} allowEdit={true} />
</> </>
); );
} }
export default TeamMembers;

View File

@ -3,7 +3,13 @@ import DataTable from 'components/common/DataTable';
import TeamMembersTable from './TeamMembersTable'; import TeamMembersTable from './TeamMembersTable';
import { useTeamMembers } from 'components/hooks'; import { useTeamMembers } from 'components/hooks';
export function TeamMembers({ teamId, allowEdit }: { teamId: string; allowEdit: boolean }) { export function TeamMembersDataTable({
teamId,
allowEdit = false,
}: {
teamId: string;
allowEdit?: boolean;
}) {
const queryResult = useTeamMembers(teamId); const queryResult = useTeamMembers(teamId);
return ( return (
@ -13,4 +19,4 @@ export function TeamMembers({ teamId, allowEdit }: { teamId: string; allowEdit:
); );
} }
export default TeamMembers; export default TeamMembersDataTable;

View File

@ -0,0 +1,15 @@
import TeamMembers from './TeamMembers';
import TeamProvider from 'app/(main)/teams/[teamId]/TeamProvider';
import { Metadata } from 'next';
export default function ({ params: { teamId } }) {
return (
<TeamProvider teamId={teamId}>
<TeamMembers teamId={teamId} />
</TeamProvider>
);
}
export const metadata: Metadata = {
title: 'Team members - Umami',
};

View File

@ -6,13 +6,11 @@ import { ROLES } from 'lib/constants';
import Icons from 'components/icons'; import Icons from 'components/icons';
import { useLogin, useMessages } from 'components/hooks'; import { useLogin, useMessages } from 'components/hooks';
import TeamEditForm from './TeamEditForm'; import TeamEditForm from './TeamEditForm';
import TeamMembers from './TeamMembers'; import TeamAdmin from './TeamAdmin';
import TeamWebsites from './TeamWebsites';
import TeamData from './TeamData';
import LinkButton from 'components/common/LinkButton'; import LinkButton from 'components/common/LinkButton';
import { TeamContext } from 'app/(main)/teams/[teamId]/TeamProvider'; import { TeamContext } from 'app/(main)/teams/[teamId]/TeamProvider';
export function TeamSettings({ teamId }: { teamId: string }) { export function Team({ teamId }: { teamId: string }) {
const team = useContext(TeamContext); const team = useContext(TeamContext);
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { user } = useLogin(); const { user } = useLogin();
@ -25,25 +23,23 @@ export function TeamSettings({ teamId }: { teamId: string }) {
return ( return (
<Flexbox direction="column"> <Flexbox direction="column">
<PageHeader title={team?.name} icon={<Icons.Users />}> <PageHeader title={team?.name} icon={<Icons.Users />}>
<LinkButton href={`/teams/${teamId}`} variant="primary"> {!canEdit && (
<Icon> <LinkButton href={`/teams/${teamId}`}>
<Icons.Change /> <Icon>
</Icon> <Icons.Logout />
<Text>{formatMessage(labels.view)}</Text> </Icon>
</LinkButton> <Text>{formatMessage(labels.leaveTeam)}</Text>
</LinkButton>
)}
</PageHeader> </PageHeader>
<Tabs selectedKey={tab} onSelect={(value: any) => setTab(value)} style={{ marginBottom: 30 }}> <Tabs selectedKey={tab} onSelect={(value: any) => setTab(value)} style={{ marginBottom: 30 }}>
<Item key="details">{formatMessage(labels.details)}</Item> <Item key="details">{formatMessage(labels.details)}</Item>
<Item key="members">{formatMessage(labels.members)}</Item> <Item key="admin">{formatMessage(labels.admin)}</Item>
<Item key="websites">{formatMessage(labels.websites)}</Item>
<Item key="data">{formatMessage(labels.data)}</Item>
</Tabs> </Tabs>
{tab === 'details' && <TeamEditForm teamId={teamId} allowEdit={canEdit} />} {tab === 'details' && <TeamEditForm teamId={teamId} allowEdit={canEdit} />}
{tab === 'members' && <TeamMembers teamId={teamId} allowEdit={canEdit} />} {canEdit && tab === 'admin' && <TeamAdmin teamId={teamId} />}
{tab === 'websites' && <TeamWebsites teamId={teamId} allowEdit={canEdit} />}
{canEdit && tab === 'data' && <TeamData teamId={teamId} />}
</Flexbox> </Flexbox>
); );
} }
export default TeamSettings; export default Team;

View File

@ -1,9 +1,9 @@
'use client'; 'use client';
import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics'; import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
import TeamDeleteForm from '../TeamDeleteForm'; import TeamDeleteForm from './TeamDeleteForm';
export function TeamData({ teamId }: { teamId: string }) { export function TeamAdmin({ teamId }: { teamId: string }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
return ( return (
@ -21,4 +21,4 @@ export function TeamData({ teamId }: { teamId: string }) {
); );
} }
export default TeamData; export default TeamAdmin;

View File

@ -1,10 +1,15 @@
import TeamSettings from './TeamSettings'; import Team from './Team';
import TeamProvider from 'app/(main)/teams/[teamId]/TeamProvider'; import TeamProvider from 'app/(main)/teams/[teamId]/TeamProvider';
import { Metadata } from 'next';
export default function ({ params: { teamId } }) { export default function ({ params: { teamId } }) {
return ( return (
<TeamProvider teamId={teamId}> <TeamProvider teamId={teamId}>
<TeamSettings teamId={teamId} /> <Team teamId={teamId} />
</TeamProvider> </TeamProvider>
); );
} }
export const metadata: Metadata = {
title: 'Teams Settings - Umami',
};

View File

@ -0,0 +1,17 @@
'use client';
import TeamWebsitesDataTable from './TeamWebsitesDataTable';
import PageHeader from 'components/layout/PageHeader';
import { useMessages } from 'components/hooks';
export function TeamWebsites({ teamId }: { teamId: string }) {
const { formatMessage, labels } = useMessages();
return (
<>
<PageHeader title={formatMessage(labels.websites)} />
<TeamWebsitesDataTable teamId={teamId} allowEdit={true} />
</>
);
}
export default TeamWebsites;

View File

@ -3,7 +3,13 @@ import DataTable from 'components/common/DataTable';
import { useTeamWebsites } from 'components/hooks'; import { useTeamWebsites } from 'components/hooks';
import TeamWebsitesTable from './TeamWebsitesTable'; import TeamWebsitesTable from './TeamWebsitesTable';
export function TeamWebsites({ teamId, allowEdit }: { teamId: string; allowEdit: boolean }) { export function TeamWebsitesDataTable({
teamId,
allowEdit = false,
}: {
teamId: string;
allowEdit?: boolean;
}) {
const queryResult = useTeamWebsites(teamId); const queryResult = useTeamWebsites(teamId);
return ( return (
@ -13,4 +19,4 @@ export function TeamWebsites({ teamId, allowEdit }: { teamId: string; allowEdit:
); );
} }
export default TeamWebsites; export default TeamWebsitesDataTable;

View File

@ -35,7 +35,7 @@ export function TeamWebsitesTable({
)} )}
<LinkButton href={`/teams/${teamId}/websites/${websiteId}`}> <LinkButton href={`/teams/${teamId}/websites/${websiteId}`}>
<Icon> <Icon>
<Icons.Change /> <Icons.ArrowRight />
</Icon> </Icon>
<Text>{formatMessage(labels.view)}</Text> <Text>{formatMessage(labels.view)}</Text>
</LinkButton> </LinkButton>

View File

@ -0,0 +1,15 @@
import TeamWebsites from './TeamWebsites';
import TeamProvider from 'app/(main)/teams/[teamId]/TeamProvider';
import { Metadata } from 'next';
export default function ({ params: { teamId } }) {
return (
<TeamProvider teamId={teamId}>
<TeamWebsites teamId={teamId} />
</TeamProvider>
);
}
export const metadata: Metadata = {
title: 'Teams websites - Umami',
};

View File

@ -30,12 +30,12 @@ export function UserAddForm({ onSave, onClose }) {
}); });
}; };
const renderValue = value => { const renderValue = (value: string) => {
if (value === ROLES.user) { if (value === ROLES.user) {
return formatMessage(labels.user); return formatMessage(labels.user);
} }
if (value === ROLES.admin) { if (value === ROLES.admin) {
return formatMessage(labels.admin); return formatMessage(labels.administrator);
} }
if (value === ROLES.viewOnly) { if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly); return formatMessage(labels.viewOnly);
@ -59,7 +59,7 @@ export function UserAddForm({ onSave, onClose }) {
<Dropdown renderValue={renderValue}> <Dropdown renderValue={renderValue}>
<Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item> <Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item>
<Item key={ROLES.user}>{formatMessage(labels.user)}</Item> <Item key={ROLES.user}>{formatMessage(labels.user)}</Item>
<Item key={ROLES.admin}>{formatMessage(labels.admin)}</Item> <Item key={ROLES.admin}>{formatMessage(labels.administrator)}</Item>
</Dropdown> </Dropdown>
</FormInput> </FormInput>
</FormRow> </FormRow>

View File

@ -49,7 +49,7 @@ export function UserEditForm({
return formatMessage(labels.user); return formatMessage(labels.user);
} }
if (value === ROLES.admin) { if (value === ROLES.admin) {
return formatMessage(labels.admin); return formatMessage(labels.administrator);
} }
if (value === ROLES.viewOnly) { if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly); return formatMessage(labels.viewOnly);
@ -78,7 +78,7 @@ export function UserEditForm({
<Dropdown renderValue={renderValue}> <Dropdown renderValue={renderValue}>
<Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item> <Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item>
<Item key={ROLES.user}>{formatMessage(labels.user)}</Item> <Item key={ROLES.user}>{formatMessage(labels.user)}</Item>
<Item key={ROLES.admin}>{formatMessage(labels.admin)}</Item> <Item key={ROLES.admin}>{formatMessage(labels.administrator)}</Item>
</Dropdown> </Dropdown>
</FormInput> </FormInput>
</FormRow> </FormRow>

View File

@ -1,5 +1,3 @@
import Members from './Members'; import Page from 'app/(main)/settings/teams/[teamId]/members/page';
export default function ({ params: { teamId } }) { export default Page;
return <Members teamId={teamId} />;
}

View File

@ -1,23 +0,0 @@
'use client';
import { useContext } from 'react';
import { useLogin, useMessages } from 'components/hooks';
import PageHeader from 'components/layout/PageHeader';
import { ROLES } from 'lib/constants';
import TeamEditForm from 'app/(main)/settings/teams/[teamId]/TeamEditForm';
import { TeamContext } from 'app/(main)/teams/[teamId]/TeamProvider';
export default function Team({ teamId }: { teamId: string }) {
const team = useContext(TeamContext);
const { user } = useLogin();
const { formatMessage, labels } = useMessages();
const allowEdit = !!team?.teamUser?.find(
({ userId, role }) => role === ROLES.teamOwner && userId === user.id,
);
return (
<>
<PageHeader title={formatMessage(labels.team)} />
<TeamEditForm teamId={teamId} allowEdit={allowEdit} />
</>
);
}

View File

@ -1,5 +1,3 @@
import Team from './Team'; import Page from 'app/(main)/settings/teams/[teamId]/team/page';
export default function ({ params: { teamId } }) { export default Page;
return <Team teamId={teamId} />;
}

View File

@ -1,3 +1,3 @@
import Page from 'app/(main)/settings/websites/[websiteId]/page'; import Page from 'app/(main)/websites/[websiteId]/page';
export default Page; export default Page;

View File

@ -1,3 +1,3 @@
import Page from 'app/(main)/settings/websites/page'; import Page from 'app/(main)/settings/teams/[teamId]/websites/page';
export default Page; export default Page;

View File

@ -17,7 +17,8 @@ export const labels = defineMessages({
role: { id: 'label.role', defaultMessage: 'Role' }, role: { id: 'label.role', defaultMessage: 'Role' },
user: { id: 'label.user', defaultMessage: 'User' }, user: { id: 'label.user', defaultMessage: 'User' },
viewOnly: { id: 'label.view-only', defaultMessage: 'View only' }, viewOnly: { id: 'label.view-only', defaultMessage: 'View only' },
admin: { id: 'label.admin', defaultMessage: 'Administrator' }, admin: { id: 'label.admin', defaultMessage: 'Admin' },
administrator: { id: 'label.administrator', defaultMessage: 'Administrator' },
confirm: { id: 'label.confirm', defaultMessage: 'Confirm' }, confirm: { id: 'label.confirm', defaultMessage: 'Confirm' },
details: { id: 'label.details', defaultMessage: 'Details' }, details: { id: 'label.details', defaultMessage: 'Details' },
website: { id: 'label.website', defaultMessage: 'Website' }, website: { id: 'label.website', defaultMessage: 'Website' },

View File

@ -1,16 +1,21 @@
export * from 'components/hooks'; export * from 'components/hooks';
export * from 'app/(main)/settings/teams/[teamId]/TeamData'; export * from 'app/(main)/settings/teams/[teamId]/members/TeamMemberRemoveButton';
export * from 'app/(main)/settings/teams/[teamId]/TeamEditForm'; export * from 'app/(main)/settings/teams/[teamId]/members/TeamMembers';
export * from 'app/(main)/settings/teams/[teamId]/TeamMemberRemoveButton'; export * from 'app/(main)/settings/teams/[teamId]/members/TeamMembersDataTable';
export * from 'app/(main)/settings/teams/[teamId]/TeamMembers'; export * from 'app/(main)/settings/teams/[teamId]/members/TeamMembersTable';
export * from 'app/(main)/settings/teams/[teamId]/TeamMembersTable';
export * from 'app/(main)/settings/teams/[teamId]/TeamSettings'; export * from 'app/(main)/settings/teams/[teamId]/team/Team';
export * from 'app/(main)/settings/teams/[teamId]/TeamWebsiteRemoveButton'; export * from 'app/(main)/settings/teams/[teamId]/team/TeamAdmin';
export * from 'app/(main)/settings/teams/[teamId]/TeamWebsites'; export * from 'app/(main)/settings/teams/[teamId]/team/TeamDeleteForm';
export * from 'app/(main)/settings/teams/[teamId]/TeamWebsitesTable'; export * from 'app/(main)/settings/teams/[teamId]/team/TeamEditForm';
export * from 'app/(main)/settings/teams/[teamId]/websites/TeamWebsiteRemoveButton';
export * from 'app/(main)/settings/teams/[teamId]/websites/TeamWebsites';
export * from 'app/(main)/settings/teams/[teamId]/websites/TeamWebsitesDataTable';
export * from 'app/(main)/settings/teams/[teamId]/websites/TeamWebsitesTable';
export * from 'app/(main)/settings/teams/TeamAddForm'; export * from 'app/(main)/settings/teams/TeamAddForm';
export * from 'app/(main)/settings/teams/TeamDeleteForm';
export * from 'app/(main)/settings/teams/TeamsHeader'; export * from 'app/(main)/settings/teams/TeamsHeader';
export * from 'app/(main)/settings/teams/TeamJoinForm'; export * from 'app/(main)/settings/teams/TeamJoinForm';
export * from 'app/(main)/settings/teams/TeamLeaveForm'; export * from 'app/(main)/settings/teams/TeamLeaveForm';