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:
parent
1889cf272a
commit
3daf30835a
3 changed files with 131 additions and 64 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
packages/console/src/components/Table/StickyHeaderTable.tsx
Normal file
40
packages/console/src/components/Table/StickyHeaderTable.tsx
Normal 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;
|
|
@ -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}
|
||||
|
|
Loading…
Add table
Reference in a new issue