Added SettingsTable.

This commit is contained in:
Mike Cao 2023-04-12 13:40:19 -07:00
parent f84e41e198
commit e2fcd40c2b
19 changed files with 335 additions and 300 deletions

View file

@ -1,126 +1,90 @@
import Link from 'next/link';
import {
Button,
Flexbox,
Icon,
Icons,
Modal,
ModalTrigger,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
Text,
} from 'react-basics';
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
import TeamDeleteForm from './TeamDeleteForm';
import TeamLeaveForm from './TeamLeaveForm';
import useMessages from 'hooks/useMessages';
import useUser from 'hooks/useUser';
import { ROLES } from 'lib/constants';
import SettingsTable from 'components/common/SettingsTable';
export default function TeamsTable({ data = [], onDelete }) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const columns = [
{ name: 'name', label: formatMessage(labels.name), style: { flex: 2 } },
{ name: 'name', label: formatMessage(labels.name) },
{ name: 'owner', label: formatMessage(labels.owner) },
{ name: 'action', label: ' ' },
];
const cellRender = (row, data, key) => {
if (key === 'owner') {
return row.teamUser.find(({ role }) => role === ROLES.teamOwner)?.user?.username;
}
return data[key];
};
return (
<Table columns={columns} rows={data}>
<TableHeader>
{(column, index) => {
return (
<TableColumn key={index} style={{ ...column.style }}>
{column.label}
</TableColumn>
);
}}
</TableHeader>
<TableBody>
{(row, keys, rowIndex) => {
const { id, teamUser } = row;
const owner = row.teamUser.find(({ role }) => role === ROLES.teamOwner);
const showDelete = user.id === owner?.userId;
const teamUserId = teamUser.find(a => a.userId === user.id).id;
<SettingsTable data={data} columns={columns} cellRender={cellRender}>
{row => {
const { id, teamUser } = row;
const owner = teamUser.find(({ role }) => role === ROLES.teamOwner);
const showDelete = user.id === owner?.userId;
const rowData = {
...row,
owner: owner?.user?.username,
action: (
<Flexbox flex={1} gap={10} justifyContent="end">
<Link href={`/settings/teams/${id}`}>
<Button>
<Icon>
<Icons.Show />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
{showDelete && (
<ModalTrigger>
<Button>
<Icon>
<Icons.Trash />
</Icon>
<Text>{formatMessage(labels.delete)}</Text>
</Button>
<Modal title={formatMessage(labels.deleteTeam)}>
{close => (
<TeamDeleteForm
teamId={row.id}
teamName={row.name}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
)}
{!showDelete && (
<ModalTrigger>
<Button>
<Icon>
<Icons.ArrowRight />
</Icon>
<Text>{formatMessage(labels.leave)}</Text>
</Button>
<Modal title={formatMessage(labels.leaveTeam)}>
{close => (
<TeamLeaveForm
teamId={id}
userId={user.id}
teamName={row.name}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
)}
</Flexbox>
),
};
return (
<TableRow key={rowIndex} data={rowData} keys={keys}>
{(data, key, colIndex) => {
return (
<TableCell key={colIndex} style={{ ...columns[colIndex]?.style }}>
<Flexbox flex={1} alignItems="center">
{data[key]}
</Flexbox>
</TableCell>
);
}}
</TableRow>
);
}}
</TableBody>
</Table>
return (
<>
<Link href={`/settings/teams/${id}`}>
<Button>
<Icon>
<Icons.Show />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
{showDelete && (
<ModalTrigger>
<Button>
<Icon>
<Icons.Trash />
</Icon>
<Text>{formatMessage(labels.delete)}</Text>
</Button>
<Modal title={formatMessage(labels.deleteTeam)}>
{close => (
<TeamDeleteForm
teamId={row.id}
teamName={row.name}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
)}
{!showDelete && (
<ModalTrigger>
<Button>
<Icon>
<Icons.ArrowRight />
</Icon>
<Text>{formatMessage(labels.leave)}</Text>
</Button>
<Modal title={formatMessage(labels.leaveTeam)}>
{close => (
<TeamLeaveForm
teamId={id}
userId={user.id}
teamName={row.name}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
)}
</>
);
}}
</SettingsTable>
);
}

View file

@ -1,109 +1,71 @@
import {
Button,
Text,
Icon,
Table,
TableBody,
TableCell,
TableColumn,
TableHeader,
TableRow,
Flexbox,
Icons,
ModalTrigger,
Modal,
} from 'react-basics';
import { Button, Text, Icon, Icons, ModalTrigger, Modal } from 'react-basics';
import { formatDistance } from 'date-fns';
import Link from 'next/link';
import useUser from 'hooks/useUser';
import UserDeleteForm from './UserDeleteForm';
import { ROLES } from 'lib/constants';
import useMessages from 'hooks/useMessages';
import SettingsTable from 'components/common/SettingsTable';
export default function UsersTable({ data = [], onDelete }) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const columns = [
{ name: 'username', label: formatMessage(labels.username), style: { flex: 2 } },
{ name: 'role', label: formatMessage(labels.role), style: { flex: 1 } },
{ name: 'created', label: formatMessage(labels.created), style: { flex: 1 } },
{ name: 'action', label: ' ', style: { flex: 2 } },
{ name: 'username', label: formatMessage(labels.username), style: { flex: 1.5 } },
{ name: 'role', label: formatMessage(labels.role) },
{ name: 'created', label: formatMessage(labels.created) },
{ name: 'action', label: ' ' },
];
return (
<Table columns={columns} rows={data}>
<TableHeader>
{(column, index) => {
return (
<TableColumn key={index} style={{ ...column.style }}>
{column.label}
</TableColumn>
);
}}
</TableHeader>
<TableBody>
{(row, keys, rowIndex) => {
const rowData = {
...row,
created: formatDistance(new Date(row.createdAt), new Date(), {
addSuffix: true,
}),
role: formatMessage(
labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown,
),
action: (
<>
<Link href={`/settings/users/${row.id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<ModalTrigger disabled={row.id === user.id}>
<Button disabled={row.id === user.id}>
<Icon>
<Icons.Trash />
</Icon>
<Text>{formatMessage(labels.delete)}</Text>
</Button>
<Modal>
{close => (
<UserDeleteForm
userId={row.id}
username={row.username}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
</>
),
};
const cellRender = (row, data, key) => {
if (key === 'created') {
return formatDistance(new Date(row.createdAt), new Date(), {
addSuffix: true,
});
}
if (key === 'role') {
return formatMessage(
labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown,
);
}
return data[key];
};
return (
<TableRow key={rowIndex} data={rowData} keys={keys}>
{(data, key, colIndex) => {
return (
<TableCell key={colIndex} style={{ ...columns[colIndex]?.style }}>
<Flexbox
flex={1}
gap={10}
alignItems="center"
justifyContent={key === 'action' ? 'end' : undefined}
>
{data[key]}
</Flexbox>
</TableCell>
);
}}
</TableRow>
);
}}
</TableBody>
</Table>
return (
<SettingsTable data={data} columns={columns} cellRender={cellRender}>
{(row, keys, rowIndex) => {
return (
<>
<Link href={`/settings/users/${row.id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<ModalTrigger disabled={row.id === user.id}>
<Button disabled={row.id === user.id}>
<Icon>
<Icons.Trash />
</Icon>
<Text>{formatMessage(labels.delete)}</Text>
</Button>
<Modal>
{close => (
<UserDeleteForm
userId={row.id}
username={row.username}
onSave={onDelete}
onClose={close}
/>
)}
</Modal>
</ModalTrigger>
</>
);
}}
</SettingsTable>
);
}

View file

@ -1,83 +1,45 @@
import Link from 'next/link';
import {
Table,
TableHeader,
TableBody,
TableRow,
TableCell,
TableColumn,
Button,
Text,
Icon,
Icons,
Flexbox,
useBreakpoint,
} from 'react-basics';
import { Button, Text, Icon, Icons } from 'react-basics';
import SettingsTable from 'components/common/SettingsTable';
import useMessages from 'hooks/useMessages';
import useConfig from 'hooks/useConfig';
export default function WebsitesTable({ data = [] }) {
const { formatMessage, labels } = useMessages();
const { openExternal } = useConfig();
const breakPoint = useBreakpoint();
const columns = [
{ name: 'name', label: formatMessage(labels.name), style: { flex: 2 } },
{ name: 'name', label: formatMessage(labels.name) },
{ name: 'domain', label: formatMessage(labels.domain) },
{ name: 'action', label: ' ', style: { flexBasis: '100%' } },
{ name: 'action', label: ' ' },
];
return (
<Table columns={columns} rows={data}>
<TableHeader>
{(column, index) => {
return (
<TableColumn key={index} style={{ ...column.style }}>
{column.label}
</TableColumn>
);
}}
</TableHeader>
<TableBody>
{(row, keys, rowIndex) => {
const { id } = row;
<SettingsTable columns={columns} data={data}>
{row => {
const { id } = row;
row.action = (
<Flexbox flex={1} justifyContent="end" gap={10}>
<Link href={`/settings/websites/${id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<Link href={`/websites/${id}`} target={openExternal ? '_blank' : null}>
<Button>
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
</Flexbox>
);
return (
<TableRow key={rowIndex} data={row} keys={keys}>
{(data, key, colIndex) => {
return (
<TableCell key={colIndex} style={{ ...columns[colIndex]?.style }}>
<Flexbox flex={1} alignItems="center">
{data[key]}
</Flexbox>
</TableCell>
);
}}
</TableRow>
);
}}
</TableBody>
</Table>
return (
<>
<Link href={`/settings/websites/${id}`}>
<Button>
<Icon>
<Icons.Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
</Button>
</Link>
<Link href={`/websites/${id}`} target={openExternal ? '_blank' : null}>
<Button>
<Icon>
<Icons.External />
</Icon>
<Text>{formatMessage(labels.view)}</Text>
</Button>
</Link>
</>
);
}}
</SettingsTable>
);
}

View file

@ -0,0 +1,13 @@
@media screen and (max-width: 992px) {
.row {
flex-wrap: wrap;
}
.header .actions {
display: none;
}
.actions {
flex-basis: 100%;
}
}