0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-04-14 23:11:31 -05:00

fix(console): table scrollbar on the applications page (#2703)

This commit is contained in:
Xiao Yijun 2022-12-22 11:15:21 +08:00 committed by GitHub
parent 1889cf272a
commit 3daf30835a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 64 deletions

View file

@ -0,0 +1,27 @@
@use '@/scss/underscore' as _;
.container {
background-color: var(--color-layer-1);
border-radius: 12px;
overflow: hidden;
display: flex;
flex-direction: column;
table {
border: none;
}
.bodyTable {
flex: 1;
overflow-y: scroll;
padding-bottom: _.unit(2);
tr {
&:last-child {
td {
border-bottom: unset;
}
}
}
}
}

View file

@ -0,0 +1,40 @@
import { assert } from '@silverhand/essentials';
import classNames from 'classnames';
import type { ReactElement } from 'react';
import * as styles from './StickyHeaderTable.module.scss';
type Props = {
header: ReactElement<HTMLTableSectionElement>;
colGroup?: ReactElement<HTMLTableColElement>;
className?: string;
children: ReactElement<HTMLTableSectionElement>;
};
const StickyHeaderTable = ({ header, colGroup, className, children: body }: Props) => {
assert(header.props.tagName !== 'THEAD', new Error('Expected <thead> for the `header` prop'));
assert(
colGroup?.props.tagName !== 'COLGROUP',
new Error('Expected <colgroup> for the `colGroup` prop')
);
assert(body.props.tagName !== 'TBODY', new Error('Expected <tbody> for the `children` prop'));
return (
<div className={classNames(styles.container, className)}>
<table>
{colGroup}
{header}
</table>
<div className={styles.bodyTable}>
<table>
{colGroup}
{body}
</table>
</div>
</div>
);
};
export default StickyHeaderTable;

View file

@ -1,5 +1,4 @@
import type { Application } from '@logto/schemas';
import classNames from 'classnames';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import Modal from 'react-modal';
@ -13,6 +12,7 @@ import CardTitle from '@/components/CardTitle';
import CopyToClipboard from '@/components/CopyToClipboard';
import ItemPreview from '@/components/ItemPreview';
import Pagination from '@/components/Pagination';
import StickyHeaderTable from '@/components/Table/StickyHeaderTable';
import TableEmpty from '@/components/Table/TableEmpty';
import TableError from '@/components/Table/TableError';
import TableLoading from '@/components/Table/TableLoading';
@ -88,70 +88,70 @@ const Applications = () => {
}}
/>
</Modal>
</div>{' '}
<div className={resourcesStyles.table}>
<div className={tableStyles.scrollable}>
<table className={classNames(!data && tableStyles.empty)}>
<colgroup>
<col className={styles.applicationName} />
<col />
</colgroup>
<thead>
<tr>
<th>{t('applications.application_name')}</th>
<th>{t('applications.app_id')}</th>
</tr>
</thead>
<tbody>
{!data && error && (
<TableError
columns={2}
content={error.body?.message ?? error.message}
onRetry={async () => mutate(undefined, true)}
/>
)}
{isLoading && <TableLoading columns={2} />}
{applications?.length === 0 && (
<TableEmpty columns={2}>
<Button
title="applications.create"
type="outline"
onClick={() => {
navigate({
pathname: createApplicationPathname,
search,
});
}}
/>
</TableEmpty>
)}
{applications?.map(({ id, name, type }) => (
<tr
key={id}
className={tableStyles.clickable}
onClick={() => {
navigate(buildDetailsPathname(id));
}}
>
<td>
<ItemPreview
title={name}
subtitle={t(`${applicationTypeI18nKey[type]}.title`)}
icon={<ApplicationIcon className={styles.icon} type={type} />}
to={buildDetailsPathname(id)}
/>
</td>
<td>
<CopyToClipboard value={id} variant="text" />
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
<StickyHeaderTable
className={resourcesStyles.table}
header={
<thead>
<tr>
<th>{t('applications.application_name')}</th>
<th>{t('applications.app_id')}</th>
</tr>
</thead>
}
colGroup={
<colgroup>
<col className={styles.applicationName} />
<col />
</colgroup>
}
>
<tbody>
{!data && error && (
<TableError
columns={2}
content={error.body?.message ?? error.message}
onRetry={async () => mutate(undefined, true)}
/>
)}
{isLoading && <TableLoading columns={2} />}
{applications?.length === 0 && (
<TableEmpty columns={2}>
<Button
title="applications.create"
type="outline"
onClick={() => {
navigate({
pathname: createApplicationPathname,
search,
});
}}
/>
</TableEmpty>
)}
{applications?.map(({ id, name, type }) => (
<tr
key={id}
className={tableStyles.clickable}
onClick={() => {
navigate(buildDetailsPathname(id));
}}
>
<td>
<ItemPreview
title={name}
subtitle={t(`${applicationTypeI18nKey[type]}.title`)}
icon={<ApplicationIcon className={styles.icon} type={type} />}
to={buildDetailsPathname(id)}
/>
</td>
<td>
<CopyToClipboard value={id} variant="text" />
</td>
</tr>
))}
</tbody>
</StickyHeaderTable>
<Pagination
pageIndex={pageIndex}
totalCount={totalCount}