Migrate servers table to a tailwind-based Table component

This commit is contained in:
Alejandro Celaya 2025-04-02 09:01:33 +02:00
parent 06fac716d1
commit c9ada8f41d
3 changed files with 34 additions and 36 deletions

View File

@ -7,5 +7,5 @@ export type NoMenuLayoutProps = PropsWithChildren & {
};
export const NoMenuLayout: FC<NoMenuLayoutProps> = ({ children, className }) => (
<div className={clsx('no-menu-wrapper container-xl', className)}>{children}</div>
<div className={clsx('no-menu-wrapper tw:container tw:mx-auto', className)}>{children}</div>
);

View File

@ -1,7 +1,7 @@
import { faFileDownload as exportIcon, faPlus as plusIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import type { TimeoutToggle } from '@shlinkio/shlink-frontend-kit';
import { Button, Result, SearchInput, SimpleCard } from '@shlinkio/shlink-frontend-kit/tailwind';
import { Button, Result, SearchInput, SimpleCard, Table } from '@shlinkio/shlink-frontend-kit/tailwind';
import type { FC } from 'react';
import { useMemo, useState } from 'react';
import { NoMenuLayout } from '../common/NoMenuLayout';
@ -43,40 +43,37 @@ const ManageServers: FCWithDeps<ManageServersProps, ManageServersDeps> = ({ serv
const [errorImporting, setErrorImporting] = useTimeoutToggle(false, SHOW_IMPORT_MSG_TIME);
return (
<NoMenuLayout className="d-flex flex-column gap-3">
<NoMenuLayout className="tw:flex tw:flex-col tw:gap-y-4">
<SearchInput onChange={setSearchTerm} />
<div className="d-flex flex-column flex-md-row gap-2">
<div className="d-flex gap-2">
<ImportServersBtn className="flex-fill" onImportError={setErrorImporting}>Import servers</ImportServersBtn>
<div className="tw:flex tw:flex-col tw:md:flex-row tw:gap-2">
<div className="tw:flex tw:gap-2">
<ImportServersBtn className="tw:flex-grow" onImportError={setErrorImporting}>Import servers</ImportServersBtn>
{filteredServers.length > 0 && (
<Button variant="secondary" className="flex-fill" onClick={async () => serversExporter.exportServers()}>
<FontAwesomeIcon icon={exportIcon} fixedWidth /> Export servers
<Button variant="secondary" className="tw:flex-grow" onClick={async () => serversExporter.exportServers()}>
<FontAwesomeIcon icon={exportIcon} /> Export servers
</Button>
)}
</div>
<Button className="ms-md-auto" to="/server/create">
<FontAwesomeIcon icon={plusIcon} fixedWidth /> Add a server
<Button className="tw:md:ml-auto" to="/server/create">
<FontAwesomeIcon icon={plusIcon} /> Add a server
</Button>
</div>
<SimpleCard>
<table className="table table-hover responsive-table mb-0">
<thead className="responsive-table__header">
<tr>
{hasAutoConnect && <th style={{ width: '50px' }}><span className="sr-only">Auto-connect</span></th>}
<th>Name</th>
<th>Base URL</th>
<th><span className="sr-only">Options</span></th>
</tr>
</thead>
<tbody>
{!filteredServers.length && <tr className="text-center"><td colSpan={4}>No servers found.</td></tr>}
{filteredServers.map((server) => (
<ManageServersRow key={server.id} server={server} hasAutoConnect={hasAutoConnect} />
))}
</tbody>
</table>
<SimpleCard className="card">
<Table header={(
<Table.Row>
{hasAutoConnect && <Table.Cell style={{ width: '50px' }}><span className="sr-only">Auto-connect</span></Table.Cell>}
<Table.Cell>Name</Table.Cell>
<Table.Cell>Base URL</Table.Cell>
<Table.Cell><span className="sr-only">Options</span></Table.Cell>
</Table.Row>
)}>
{!filteredServers.length && <Table.Row className="text-center"><Table.Cell colSpan={4}>No servers found.</Table.Cell></Table.Row>}
{filteredServers.map((server) => (
<ManageServersRow key={server.id} server={server} hasAutoConnect={hasAutoConnect} />
))}
</Table>
</SimpleCard>
{errorImporting && (

View File

@ -1,5 +1,6 @@
import { faCheck as checkIcon } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Table } from '@shlinkio/shlink-frontend-kit/tailwind';
import type { FC } from 'react';
import { Link } from 'react-router';
import { UncontrolledTooltip } from 'reactstrap';
@ -21,9 +22,9 @@ const ManageServersRow: FCWithDeps<ManageServersRowProps, ManageServersRowDeps>
const { ManageServersRowDropdown } = useDependencies(ManageServersRow);
return (
<tr className="responsive-table__row">
<Table.Row className="tw:relative">
{hasAutoConnect && (
<td className="responsive-table__cell" data-th="Auto-connect">
<Table.Cell columnName="Auto-connect">
{server.autoConnect && (
<>
<FontAwesomeIcon icon={checkIcon} className="text-primary" id="autoConnectIcon" />
@ -32,16 +33,16 @@ const ManageServersRow: FCWithDeps<ManageServersRowProps, ManageServersRowDeps>
</UncontrolledTooltip>
</>
)}
</td>
</Table.Cell>
)}
<th className="responsive-table__cell" data-th="Name">
<Table.Cell className="tw:font-bold" columnName="Name">
<Link to={`/server/${server.id}`}>{server.name}</Link>
</th>
<td className="responsive-table__cell" data-th="Base URL">{server.url}</td>
<td className="responsive-table__cell text-end">
</Table.Cell>
<Table.Cell columnName="Base URL" className="tw:max-lg:border-b-0">{server.url}</Table.Cell>
<Table.Cell className="tw:text-right tw:max-lg:absolute tw:right-0 tw:-top-1 tw:mx-lg:pt-0">
<ManageServersRowDropdown server={server} />
</td>
</tr>
</Table.Cell>
</Table.Row>
);
};