Refactor Settings UI (#20392)

* refactor with sidebar and mobile page

* sidebar spacing and color tweaks

* layout tweaks

* move camera switch button to header

* improve mobile

* remove back button on mobile page header

* mobile fixes

* remove debug

* don't use mobilepage

* more mobile tweaks

* use mobile page for components

* add optional actions to mobile page header for top right buttons

* fix alignment

* use page toggle

* tweaks

* sidebar inset tweaks

* move triggers to notifications sub menu

* consistency

* fix padding

* more padding fixes

* navigate history
This commit is contained in:
Josh Hawkins
2025-10-08 14:59:21 -05:00
committed by GitHub
parent 3c7e36fb16
commit 6df950bb78
14 changed files with 431 additions and 174 deletions

View File

@@ -405,9 +405,9 @@ export default function AuthenticationView({
// Users section
const UsersSection = (
<>
<div className="mb-5 flex flex-row items-center justify-between gap-2">
<div className="mb-5 flex flex-row items-center justify-between gap-2 md:pr-2">
<div className="flex flex-col items-start">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("users.management.title")}
</Heading>
<p className="text-sm text-muted-foreground">
@@ -425,7 +425,7 @@ export default function AuthenticationView({
</Button>
</div>
<div className="mb-6 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div className="scrollbar-container flex-1 overflow-hidden rounded-lg border border-border bg-background_alt">
<div className="scrollbar-container flex-1 overflow-hidden rounded-lg border border-border bg-background_alt md:mr-2">
<div className="h-full overflow-auto">
<Table>
<TableHeader className="sticky top-0 bg-muted/50">
@@ -594,9 +594,9 @@ export default function AuthenticationView({
// Roles section
const RolesSection = (
<>
<div className="mb-5 flex flex-row items-center justify-between gap-2">
<div className="mb-5 flex flex-row items-center justify-between gap-2 md:pr-2">
<div className="flex flex-col items-start">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("roles.management.title")}
</Heading>
<p className="text-sm text-muted-foreground">
@@ -614,7 +614,7 @@ export default function AuthenticationView({
</Button>
</div>
<div className="mb-6 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div className="scrollbar-container flex-1 overflow-hidden rounded-lg border border-border bg-background_alt">
<div className="scrollbar-container flex-1 overflow-hidden rounded-lg border border-border bg-background_alt md:mr-2">
<div className="h-full overflow-auto">
<Table>
<TableHeader className="sticky top-0 bg-muted/50">
@@ -784,7 +784,7 @@ export default function AuthenticationView({
return (
<div className="flex size-full flex-col">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none md:mr-2 md:mt-0">
{section === "users" && UsersSection}
{section === "roles" && RolesSection}
{!section && (

View File

@@ -313,10 +313,10 @@ export default function CameraSettingsView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
{viewMode === "settings" ? (
<>
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("camera.title")}
</Heading>
<div className="mb-4 flex flex-col gap-4">

View File

@@ -244,8 +244,8 @@ export default function EnrichmentsSettingsView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<Heading as="h3" className="my-2">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("enrichments.title")}
</Heading>
<Separator className="my-2 flex bg-secondary" />

View File

@@ -211,8 +211,8 @@ export default function FrigatePlusSettingsView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<Heading as="h3" className="my-2">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("frigatePlus.title")}
</Heading>

View File

@@ -433,7 +433,7 @@ export default function MasksAndZonesView({
{cameraConfig && editingPolygons && (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-2 md:mt-0 md:w-3/12">
{editPane == "zone" && (
<ZoneEditPane
polygons={editingPolygons}
@@ -482,7 +482,7 @@ export default function MasksAndZonesView({
)}
{editPane === undefined && (
<>
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("menu.masksAndZones")}
</Heading>
<div className="flex w-full flex-col">

View File

@@ -191,8 +191,8 @@ export default function MotionTunerView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
<Heading as="h3" className="my-2">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mr-2 md:mt-0 md:w-3/12">
<Heading as="h4" className="mb-2">
{t("motionDetectionTuner.title")}
</Heading>
<div className="my-3 space-y-3 text-sm text-muted-foreground">

View File

@@ -331,10 +331,10 @@ export default function NotificationView({
if (!("Notification" in window) || !window.isSecureContext) {
return (
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<div className="grid w-full grid-cols-1 gap-4 md:grid-cols-2">
<div className="col-span-1">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("notification.notificationSettings.title")}
</Heading>
<div className="max-w-6xl">
@@ -385,14 +385,14 @@ export default function NotificationView({
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto p-2 md:order-none">
<div
className={cn(
isAdmin && "grid w-full grid-cols-1 gap-4 md:grid-cols-2",
)}
>
<div className="col-span-1">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("notification.notificationSettings.title")}
</Heading>

View File

@@ -164,8 +164,8 @@ export default function ObjectSettingsView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
<Heading as="h3" className="my-2">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:w-3/12">
<Heading as="h4" className="mb-2">
{t("debug.title")}
</Heading>
<div className="mb-5 space-y-3 text-sm text-muted-foreground">

View File

@@ -414,11 +414,11 @@ export default function TriggerView({
return (
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
{!isSemanticSearchEnabled ? (
<div className="mb-5 flex flex-row items-center justify-between gap-2">
<div className="flex flex-col items-start">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("triggers.management.title")}
</Heading>
<p className="mb-5 text-sm text-muted-foreground">
@@ -452,7 +452,7 @@ export default function TriggerView({
<>
<div className="mb-5 flex flex-row items-center justify-between gap-2">
<div className="flex flex-col items-start">
<Heading as="h3" className="my-2">
<Heading as="h4" className="mb-2">
{t("triggers.management.title")}
</Heading>
<p className="text-sm text-muted-foreground">

View File

@@ -100,8 +100,8 @@ export default function UiSettingsView() {
<>
<div className="flex size-full flex-col md:flex-row">
<Toaster position="top-center" closeButton={true} />
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0">
<Heading as="h3" className="my-2">
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto pb-2 md:order-none">
<Heading as="h4" className="mb-2">
{t("general.title")}
</Heading>