mirror of
https://github.com/logto-io/logto.git
synced 2025-03-10 22:22:45 -05:00
refactor(console): use colgroup in table (#445)
This commit is contained in:
parent
2ee88d19ee
commit
b46cfd2bc3
8 changed files with 64 additions and 82 deletions
|
@ -4,5 +4,5 @@
|
||||||
background: var(--color-on-primary);
|
background: var(--color-on-primary);
|
||||||
border-radius: _.unit(4);
|
border-radius: _.unit(4);
|
||||||
padding: _.unit(6);
|
padding: _.unit(6);
|
||||||
height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,36 @@
|
||||||
import React, { ReactNode } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
|
import ItemPreviewLoading from './ItemPreviewLoading';
|
||||||
import * as styles from './TableLoading.module.scss';
|
import * as styles from './TableLoading.module.scss';
|
||||||
|
|
||||||
export { default as ItemPreviewLoading } from './ItemPreviewLoading';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: ReactNode;
|
columns: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TableLoading = ({ children }: Props) => (
|
const TableLoading = ({ columns }: Props) => {
|
||||||
<>
|
const row = useMemo(
|
||||||
<tr className={styles.loading}>{children}</tr>
|
() => (
|
||||||
<tr className={styles.loading}>{children}</tr>
|
<tr className={styles.loading}>
|
||||||
</>
|
<td>
|
||||||
);
|
<ItemPreviewLoading />
|
||||||
|
</td>
|
||||||
|
{Array.from({ length: columns - 1 }).map((_, index) => (
|
||||||
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
<td key={index}>
|
||||||
|
<div />
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
),
|
||||||
|
[columns]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{row}
|
||||||
|
{row}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default TableLoading;
|
export default TableLoading;
|
||||||
|
|
|
@ -14,7 +14,7 @@ import CopyToClipboard from '@/components/CopyToClipboard';
|
||||||
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
||||||
import ItemPreview from '@/components/ItemPreview';
|
import ItemPreview from '@/components/ItemPreview';
|
||||||
import TableError from '@/components/Table/TableError';
|
import TableError from '@/components/Table/TableError';
|
||||||
import TableLoading, { ItemPreviewLoading } from '@/components/Table/TableLoading';
|
import TableLoading from '@/components/Table/TableLoading';
|
||||||
import { RequestError } from '@/hooks/use-api';
|
import { RequestError } from '@/hooks/use-api';
|
||||||
import * as modalStyles from '@/scss/modal.module.scss';
|
import * as modalStyles from '@/scss/modal.module.scss';
|
||||||
|
|
||||||
|
@ -62,9 +62,13 @@ const ApiResources = () => {
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
|
<colgroup>
|
||||||
|
<col className={styles.apiResourceName} />
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className={styles.apiResourceName}>{t('api_resources.api_name')}</th>
|
<th>{t('api_resources.api_name')}</th>
|
||||||
<th>{t('api_resources.api_identifier')}</th>
|
<th>{t('api_resources.api_identifier')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -75,16 +79,7 @@ const ApiResources = () => {
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isLoading && (
|
{isLoading && <TableLoading columns={2} />}
|
||||||
<TableLoading>
|
|
||||||
<td className={styles.apiResourceName}>
|
|
||||||
<ItemPreviewLoading />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
</TableLoading>
|
|
||||||
)}
|
|
||||||
{data?.map(({ id, name, indicator }) => (
|
{data?.map(({ id, name, indicator }) => (
|
||||||
<tr
|
<tr
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -93,7 +88,7 @@ const ApiResources = () => {
|
||||||
navigate(buildDetailsLink(id));
|
navigate(buildDetailsLink(id));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<td className={styles.apiResourceName}>
|
<td>
|
||||||
<ItemPreview title={name} icon={<ImagePlaceholder />} to={buildDetailsLink(id)} />
|
<ItemPreview title={name} icon={<ImagePlaceholder />} to={buildDetailsLink(id)} />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import CopyToClipboard from '@/components/CopyToClipboard';
|
||||||
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
||||||
import ItemPreview from '@/components/ItemPreview';
|
import ItemPreview from '@/components/ItemPreview';
|
||||||
import TableError from '@/components/Table/TableError';
|
import TableError from '@/components/Table/TableError';
|
||||||
import TableLoading, { ItemPreviewLoading } from '@/components/Table/TableLoading';
|
import TableLoading from '@/components/Table/TableLoading';
|
||||||
import { RequestError } from '@/hooks/use-api';
|
import { RequestError } from '@/hooks/use-api';
|
||||||
import * as modalStyles from '@/scss/modal.module.scss';
|
import * as modalStyles from '@/scss/modal.module.scss';
|
||||||
import { applicationTypeI18nKey } from '@/types/applications';
|
import { applicationTypeI18nKey } from '@/types/applications';
|
||||||
|
@ -60,9 +60,13 @@ const Applications = () => {
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
|
<colgroup>
|
||||||
|
<col className={styles.applicationName} />
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className={styles.applicationName}>{t('applications.application_name')}</th>
|
<th>{t('applications.application_name')}</th>
|
||||||
<th>{t('applications.client_id')}</th>
|
<th>{t('applications.client_id')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -73,16 +77,7 @@ const Applications = () => {
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isLoading && (
|
{isLoading && <TableLoading columns={2} />}
|
||||||
<TableLoading>
|
|
||||||
<td className={styles.applicationName}>
|
|
||||||
<ItemPreviewLoading />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
</TableLoading>
|
|
||||||
)}
|
|
||||||
{data?.map(({ id, name, type }) => (
|
{data?.map(({ id, name, type }) => (
|
||||||
<tr
|
<tr
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -91,7 +86,7 @@ const Applications = () => {
|
||||||
navigate(`/applications/${id}`);
|
navigate(`/applications/${id}`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<td className={styles.applicationName}>
|
<td>
|
||||||
<ItemPreview
|
<ItemPreview
|
||||||
title={name}
|
title={name}
|
||||||
subtitle={t(`${applicationTypeI18nKey[type]}.title`)}
|
subtitle={t(`${applicationTypeI18nKey[type]}.title`)}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { useTranslation } from 'react-i18next';
|
||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
import Status from '@/components/Status';
|
import Status from '@/components/Status';
|
||||||
|
|
||||||
import * as styles from '../index.module.scss';
|
|
||||||
import ConnectorName from './ConnectorName';
|
import ConnectorName from './ConnectorName';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -31,7 +30,7 @@ const ConnectorRow = ({ type, connector, onClickSetup }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td className={styles.connectorName}>
|
<td>
|
||||||
<ConnectorName connector={connector} titlePlaceholder={typeLabel} />
|
<ConnectorName connector={connector} titlePlaceholder={typeLabel} />
|
||||||
</td>
|
</td>
|
||||||
<td>{typeLabel}</td>
|
<td>{typeLabel}</td>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Card from '@/components/Card';
|
||||||
import CardTitle from '@/components/CardTitle';
|
import CardTitle from '@/components/CardTitle';
|
||||||
import TabNav, { TabNavLink } from '@/components/TabNav';
|
import TabNav, { TabNavLink } from '@/components/TabNav';
|
||||||
import TableError from '@/components/Table/TableError';
|
import TableError from '@/components/Table/TableError';
|
||||||
import TableLoading, { ItemPreviewLoading } from '@/components/Table/TableLoading';
|
import TableLoading from '@/components/Table/TableLoading';
|
||||||
import { RequestError } from '@/hooks/use-api';
|
import { RequestError } from '@/hooks/use-api';
|
||||||
|
|
||||||
import ConnectorRow from './components/ConnectorRow';
|
import ConnectorRow from './components/ConnectorRow';
|
||||||
|
@ -67,9 +67,14 @@ const Connectors = () => {
|
||||||
<TabNavLink href="/connectors/social">{t('connectors.tab_social')}</TabNavLink>
|
<TabNavLink href="/connectors/social">{t('connectors.tab_social')}</TabNavLink>
|
||||||
</TabNav>
|
</TabNav>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
|
<colgroup>
|
||||||
|
<col className={styles.connectorName} />
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className={styles.connectorName}>{t('connectors.connector_name')}</th>
|
<th>{t('connectors.connector_name')}</th>
|
||||||
<th>{t('connectors.connector_type')}</th>
|
<th>{t('connectors.connector_type')}</th>
|
||||||
<th>{t('connectors.connector_status')}</th>
|
<th>{t('connectors.connector_status')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -81,19 +86,7 @@ const Connectors = () => {
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isLoading && (
|
{isLoading && <TableLoading columns={3} />}
|
||||||
<TableLoading>
|
|
||||||
<td className={styles.connectorName}>
|
|
||||||
<ItemPreviewLoading />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
</TableLoading>
|
|
||||||
)}
|
|
||||||
{socialConnectors?.length === 0 && (
|
{socialConnectors?.length === 0 && (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={3}>
|
<td colSpan={3}>
|
||||||
|
|
|
@ -11,7 +11,7 @@ import CardTitle from '@/components/CardTitle';
|
||||||
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
import ImagePlaceholder from '@/components/ImagePlaceholder';
|
||||||
import ItemPreview from '@/components/ItemPreview';
|
import ItemPreview from '@/components/ItemPreview';
|
||||||
import TableError from '@/components/Table/TableError';
|
import TableError from '@/components/Table/TableError';
|
||||||
import TableLoading, { ItemPreviewLoading } from '@/components/Table/TableLoading';
|
import TableLoading from '@/components/Table/TableLoading';
|
||||||
import { RequestError } from '@/hooks/use-api';
|
import { RequestError } from '@/hooks/use-api';
|
||||||
import * as modalStyles from '@/scss/modal.module.scss';
|
import * as modalStyles from '@/scss/modal.module.scss';
|
||||||
|
|
||||||
|
@ -53,6 +53,11 @@ const Users = () => {
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
|
<colgroup>
|
||||||
|
<col className={styles.userName} />
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('users.user_name')}</th>
|
<th>{t('users.user_name')}</th>
|
||||||
|
@ -67,19 +72,7 @@ const Users = () => {
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isLoading && (
|
{isLoading && <TableLoading columns={3} />}
|
||||||
<TableLoading>
|
|
||||||
<td className={styles.userName}>
|
|
||||||
<ItemPreviewLoading />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div />
|
|
||||||
</td>
|
|
||||||
</TableLoading>
|
|
||||||
)}
|
|
||||||
{data?.map(({ id, name, username }) => (
|
{data?.map(({ id, name, username }) => (
|
||||||
<tr
|
<tr
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -88,7 +81,7 @@ const Users = () => {
|
||||||
navigate(`/users/${id}`);
|
navigate(`/users/${id}`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<td className={styles.userName}>
|
<td>
|
||||||
<ItemPreview
|
<ItemPreview
|
||||||
title={name ?? '-'}
|
title={name ?? '-'}
|
||||||
subtitle={username ?? '-'}
|
subtitle={username ?? '-'}
|
||||||
|
|
|
@ -22,16 +22,10 @@ table {
|
||||||
border: 1px solid var(--color-neutral-90);
|
border: 1px solid var(--color-neutral-90);
|
||||||
border-radius: _.unit(2);
|
border-radius: _.unit(2);
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody,
|
|
||||||
tr {
|
|
||||||
display: table;
|
|
||||||
width: 100%;
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead {
|
thead {
|
||||||
th {
|
th {
|
||||||
font: var(--font-subhead-2);
|
font: var(--font-subhead-2);
|
||||||
|
@ -48,11 +42,6 @@ table {
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody {
|
tbody {
|
||||||
display: block;
|
|
||||||
overflow: auto;
|
|
||||||
table-layout: fixed;
|
|
||||||
max-height: calc(100% - _.unit(40));
|
|
||||||
|
|
||||||
td {
|
td {
|
||||||
border-bottom: 1px solid var(--color-neutral-90);
|
border-bottom: 1px solid var(--color-neutral-90);
|
||||||
padding: _.unit(5) _.unit(4);
|
padding: _.unit(5) _.unit(4);
|
||||||
|
|
Loading…
Add table
Reference in a new issue