feat: improve UI contrast, dark mode, dialog sizing, color coherence, and add table sorting
- Fix dialog scrollability (flex layout + max-h-[90dvh]) and increase L4 dialog to lg width - Add styled enable card to L4 dialog matching proxy host pattern - Unify section colors across proxy host and L4 dialogs (cyan=LB, emerald=DNS, violet=upstream DNS, rose=geo, amber=mTLS) - Improve light mode contrast: muted-foreground oklch 0.552→0.502, remove opacity modifiers on secondary text - Improve dark mode: boost muted-foreground to 0.85, increase border opacity 10%→16%, input 15%→20% - Add bg-card to DataTable wrapper and bg-muted/40 to table headers for surface hierarchy - Add semantic badge variants (success, warning, info, muted) and StatusChip dark mode fix - Add server-side sortable columns to Proxy Hosts and L4 Proxy Hosts (name, upstream, status, protocol, listen) - Add sortKey to DataTable Column type with clickable sort headers (ArrowUp/Down indicators, URL param driven) - Fix E2E test selectors for shadcn UI (label associations, combobox roles, dropdown menus, mobile drawer) - Add htmlFor/id to proxy host form fields and aria-labels to select triggers for accessibility - Add sorting E2E tests for both proxy host pages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import db, { nowIso, toIso } from "../db";
|
||||
import { applyCaddyConfig } from "../caddy";
|
||||
import { logAuditEvent } from "../audit";
|
||||
import { proxyHosts } from "../db/schema";
|
||||
import { desc, eq, count, like, or } from "drizzle-orm";
|
||||
import { asc, desc, eq, count, like, or } from "drizzle-orm";
|
||||
import { type GeoBlockSettings } from "../settings";
|
||||
import { normalizeProxyHostDomains } from "../proxy-host-domains";
|
||||
|
||||
@@ -1462,7 +1462,22 @@ export async function countProxyHosts(search?: string): Promise<number> {
|
||||
return row?.value ?? 0;
|
||||
}
|
||||
|
||||
export async function listProxyHostsPaginated(limit: number, offset: number, search?: string): Promise<ProxyHost[]> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const PROXY_HOST_SORT_COLUMNS: Record<string, any> = {
|
||||
name: proxyHosts.name,
|
||||
domains: proxyHosts.domains,
|
||||
upstreams: proxyHosts.upstreams,
|
||||
enabled: proxyHosts.enabled,
|
||||
created_at: proxyHosts.createdAt,
|
||||
};
|
||||
|
||||
export async function listProxyHostsPaginated(
|
||||
limit: number,
|
||||
offset: number,
|
||||
search?: string,
|
||||
sortBy?: string,
|
||||
sortDir?: "asc" | "desc"
|
||||
): Promise<ProxyHost[]> {
|
||||
const where = search
|
||||
? or(
|
||||
like(proxyHosts.name, `%${search}%`),
|
||||
@@ -1470,11 +1485,13 @@ export async function listProxyHostsPaginated(limit: number, offset: number, sea
|
||||
like(proxyHosts.upstreams, `%${search}%`)
|
||||
)
|
||||
: undefined;
|
||||
const col = (sortBy && PROXY_HOST_SORT_COLUMNS[sortBy]) || proxyHosts.createdAt;
|
||||
const dir = sortDir === "asc" ? asc : desc;
|
||||
const hosts = await db
|
||||
.select()
|
||||
.from(proxyHosts)
|
||||
.where(where)
|
||||
.orderBy(desc(proxyHosts.createdAt))
|
||||
.orderBy(dir(col))
|
||||
.limit(limit)
|
||||
.offset(offset);
|
||||
return hosts.map(parseProxyHost);
|
||||
|
||||
Reference in New Issue
Block a user