feat: refactor all dashboard routes

This commit is contained in:
Aarnav Tale 2024-12-08 13:52:02 -05:00
parent 50e43bc0c3
commit 6cf343d623
No known key found for this signature in database
39 changed files with 48 additions and 66 deletions

View File

@ -3,8 +3,8 @@ import { index, layout, prefix, route } from '@remix-run/route-config'
export default [ export default [
// Utility Routes // Utility Routes
index('routes/_index.tsx'), index('routes/util/redirect.ts'),
route('/healthz', 'routes/healthz.tsx'), route('/healthz', 'routes/util/healthz.ts'),
// Authentication Routes // Authentication Routes
route('/login', 'routes/auth/login.tsx'), route('/login', 'routes/auth/login.tsx'),
@ -14,21 +14,17 @@ export default [
// All the main logged-in dashboard routes // All the main logged-in dashboard routes
layout('layouts/dashboard.tsx', [ layout('layouts/dashboard.tsx', [
...prefix('/machines', [ ...prefix('/machines', [
index('routes/_data.machines._index/route.tsx'), index('routes/machines/overview.tsx'),
route('/:id', 'routes/_data.machines.$id/route.tsx'), route('/:id', 'routes/machines/machine.tsx'),
]),
...prefix('/users', [
index('routes/_data.users._index/route.tsx'),
]),
...prefix('/dns', [
index('routes/_data.dns._index/route.tsx'),
]),
...prefix('/acls', [
index('routes/_data.acls._index/route.tsx'),
]), ]),
route('/users', 'routes/users/overview.tsx'),
route('/acls', 'routes/acls/editor.tsx'),
route('/dns', 'routes/dns/overview.tsx'),
...prefix('/settings', [ ...prefix('/settings', [
index('routes/_data.settings._index/route.tsx'), index('routes/settings/overview.tsx'),
route('/auth-keys', 'routes/_data.settings.auth-keys._index/route.tsx'), route('/auth-keys', 'routes/settings/auth-keys.tsx'),
]), ]),
]) ])
] ]

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { BeakerIcon, EyeIcon, IssueDraftIcon, PencilIcon } from '@primer/octicons-react' import { BeakerIcon, EyeIcon, IssueDraftIcon, PencilIcon } from '@primer/octicons-react'
import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node' import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
import { useLoaderData, useRevalidator } from '@remix-run/react' import { useLoaderData, useRevalidator } from '@remix-run/react'
@ -21,9 +20,9 @@ import { getSession } from '~/utils/sessions'
import { send } from '~/utils/res' import { send } from '~/utils/res'
import log from '~/utils/log' import log from '~/utils/log'
import { Editor, Differ } from './cm.client' import { Editor, Differ } from './components/cm.client'
import { Unavailable } from './unavailable' import { Unavailable } from './components/unavailable'
import { ErrorView } from './error' import { ErrorView } from './components/error'
export async function loader({ request }: LoaderFunctionArgs) { export async function loader({ request }: LoaderFunctionArgs) {
const session = await getSession(request.headers.get('Cookie')) const session = await getSession(request.headers.get('Cookie'))

View File

@ -6,7 +6,7 @@ import Link from '~/components/Link'
import TableList from '~/components/TableList' import TableList from '~/components/TableList'
import { cn } from '~/utils/cn' import { cn } from '~/utils/cn'
import AddDNS from './dialogs/dns' import AddDNS from '../dialogs/dns'
interface Props { interface Props {
records: { name: string, type: 'A', value: string }[] records: { name: string, type: 'A', value: string }[]

View File

@ -16,7 +16,7 @@ import {
} from '@dnd-kit/sortable' } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities' import { CSS } from '@dnd-kit/utilities'
import { LockIcon, ThreeBarsIcon } from '@primer/octicons-react' import { LockIcon, ThreeBarsIcon } from '@primer/octicons-react'
import { type FetcherWithComponents, useFetcher } from '@remix-run/react' import { FetcherWithComponents, useFetcher } from '@remix-run/react'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Button, Input } from 'react-aria-components' import { Button, Input } from 'react-aria-components'

View File

@ -5,7 +5,6 @@ import Spinner from '~/components/Spinner'
type Properties = { type Properties = {
readonly isEnabled: boolean; readonly isEnabled: boolean;
// eslint-disable-next-line react/boolean-prop-naming
readonly disabled?: boolean; readonly disabled?: boolean;
} }

View File

@ -7,7 +7,7 @@ import Switch from '~/components/Switch'
import TableList from '~/components/TableList' import TableList from '~/components/TableList'
import { cn } from '~/utils/cn' import { cn } from '~/utils/cn'
import AddNameserver from './dialogs/nameserver' import AddNameserver from '../dialogs/nameserver'
interface Props { interface Props {
nameservers: Record<string, string[]> nameservers: Record<string, string[]>

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable unicorn/no-keyword-prefix */
import { useFetcher } from '@remix-run/react' import { useFetcher } from '@remix-run/react'
import { useState } from 'react' import { useState } from 'react'
import { Input } from 'react-aria-components' import { Input } from 'react-aria-components'
@ -12,7 +10,6 @@ import { cn } from '~/utils/cn'
type Properties = { type Properties = {
readonly name: string; readonly name: string;
// eslint-disable-next-line react/boolean-prop-naming
readonly disabled?: boolean; readonly disabled?: boolean;
} }

View File

@ -1,4 +1,4 @@
import { type ActionFunctionArgs } from '@remix-run/node' import { ActionFunctionArgs } from '@remix-run/node'
import { json, useLoaderData } from '@remix-run/react' import { json, useLoaderData } from '@remix-run/react'
import Code from '~/components/Code' import Code from '~/components/Code'
@ -8,11 +8,11 @@ import { loadConfig, patchConfig } from '~/utils/config/headscale'
import { getSession } from '~/utils/sessions' import { getSession } from '~/utils/sessions'
import { useLiveData } from '~/utils/useLiveData' import { useLiveData } from '~/utils/useLiveData'
import DNS from './dns' import DNS from './components/dns'
import Domains from './domains' import Domains from './components/domains'
import MagicModal from './magic' import MagicModal from './components/magic'
import Nameservers from './nameservers' import Nameservers from './components/nameservers'
import RenameModal from './rename' import RenameModal from './components/rename'
// We do not want to expose every config value // We do not want to expose every config value
export async function loader() { export async function loader() {

View File

@ -5,12 +5,12 @@ import MenuComponent from '~/components/Menu'
import { Machine, Route, User } from '~/types' import { Machine, Route, User } from '~/types'
import { cn } from '~/utils/cn' import { cn } from '~/utils/cn'
import Delete from './dialogs/delete' import Delete from '../dialogs/delete'
import Expire from './dialogs/expire' import Expire from '../dialogs/expire'
import Move from './dialogs/move' import Move from '../dialogs/move'
import Rename from './dialogs/rename' import Rename from '../dialogs/rename'
import Routes from './dialogs/routes' import Routes from '../dialogs/routes'
import Tags from './dialogs/tags' import Tags from '../dialogs/tags'
interface MenuProps { interface MenuProps {
machine: Machine machine: Machine

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node' import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
import { Link as RemixLink, useLoaderData } from '@remix-run/react' import { Link as RemixLink, useLoaderData } from '@remix-run/react'
import { InfoIcon, GearIcon, CheckCircleIcon, SkipIcon, PersonIcon } from '@primer/octicons-react' import { InfoIcon, GearIcon, CheckCircleIcon, SkipIcon, PersonIcon } from '@primer/octicons-react'
@ -19,9 +18,9 @@ import { getSession } from '~/utils/sessions'
import { useLiveData } from '~/utils/useLiveData' import { useLiveData } from '~/utils/useLiveData'
import Link from '~/components/Link' import Link from '~/components/Link'
import { menuAction } from '../_data.machines._index/action' import { menuAction } from './action'
import MenuOptions from '../_data.machines._index/menu' import MenuOptions from './components/menu'
import Routes from '../_data.machines._index/dialogs/routes' import Routes from './dialogs/routes'
export async function loader({ request, params }: LoaderFunctionArgs) { export async function loader({ request, params }: LoaderFunctionArgs) {
const session = await getSession(request.headers.get('Cookie')) const session = await getSession(request.headers.get('Cookie'))

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { InfoIcon } from '@primer/octicons-react' import { InfoIcon } from '@primer/octicons-react'
import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node' import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react' import { useLoaderData } from '@remix-run/react'
@ -15,7 +14,7 @@ import { useLiveData } from '~/utils/useLiveData'
import type { Machine, Route, User } from '~/types' import type { Machine, Route, User } from '~/types'
import { menuAction } from './action' import { menuAction } from './action'
import MachineRow from './machine' import MachineRow from './components/machine'
import NewMachine from './dialogs/new' import NewMachine from './dialogs/new'
export async function loader({ request }: LoaderFunctionArgs) { export async function loader({ request }: LoaderFunctionArgs) {

View File

@ -15,7 +15,7 @@ import Select from '~/components/Select'
import Switch from '~/components/Switch' import Switch from '~/components/Switch'
import AddPreAuthKey from './dialogs/new' import AddPreAuthKey from './dialogs/new'
import AuthKeyRow from './key' import AuthKeyRow from './components/key'
export async function action({ request }: ActionFunctionArgs) { export async function action({ request }: ActionFunctionArgs) {
const session = await getSession(request.headers.get('Cookie')) const session = await getSession(request.headers.get('Cookie'))

View File

@ -4,7 +4,7 @@ import { toast } from '~/components/Toaster'
import Code from '~/components/Code' import Code from '~/components/Code'
import Button from '~/components/Button' import Button from '~/components/Button'
import Attribute from '~/components/Attribute' import Attribute from '~/components/Attribute'
import ExpireKey from './dialogs/expire' import ExpireKey from '../dialogs/expire'
interface Props { interface Props {
authKey: PreAuthKey authKey: PreAuthKey

View File

@ -3,7 +3,7 @@ import { HomeIcon, PasskeyFillIcon } from '@primer/octicons-react'
import Card from '~/components/Card' import Card from '~/components/Card'
import Link from '~/components/Link' import Link from '~/components/Link'
import Add from './add' import Add from '../dialogs/add'
interface Props { interface Props {
readonly magic: string | undefined readonly magic: string | undefined

View File

@ -4,7 +4,7 @@ import Card from '~/components/Card'
import Link from '~/components/Link' import Link from '~/components/Link'
import { HeadplaneContext } from '~/utils/config/headplane' import { HeadplaneContext } from '~/utils/config/headplane'
import Add from './add' import Add from '../dialogs/add'
interface Props { interface Props {
readonly oidc: NonNullable<HeadplaneContext['oidc']> readonly oidc: NonNullable<HeadplaneContext['oidc']>

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { DataRef, DndContext, useDraggable, useDroppable } from '@dnd-kit/core' import { DataRef, DndContext, useDraggable, useDroppable } from '@dnd-kit/core'
import { PersonIcon } from '@primer/octicons-react' import { PersonIcon } from '@primer/octicons-react'
import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node' import { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
@ -19,10 +18,10 @@ import { getSession } from '~/utils/sessions'
import { useLiveData } from '~/utils/useLiveData' import { useLiveData } from '~/utils/useLiveData'
import { send } from '~/utils/res' import { send } from '~/utils/res'
import Auth from './auth' import Auth from './components/auth'
import Oidc from './oidc' import Oidc from './components/oidc'
import Remove from './remove' import Remove from './dialogs/remove'
import Rename from './rename' import Rename from './dialogs/rename'
export async function loader({ request }: LoaderFunctionArgs) { export async function loader({ request }: LoaderFunctionArgs) {
const session = await getSession(request.headers.get('Cookie')) const session = await getSession(request.headers.get('Cookie'))

View File

@ -1,5 +1,6 @@
import { loadContext } from '~/utils/config/headplane' import { loadContext } from '~/utils/config/headplane'
import { HeadscaleError, pull } from '~/utils/headscale' import { HeadscaleError, pull } from '~/utils/headscale'
import { data } from '@remix-run/node'
import log from '~/utils/log' import log from '~/utils/log'
export async function loader() { export async function loader() {
@ -11,19 +12,12 @@ export async function loader() {
} catch (e) { } catch (e) {
if (!(e instanceof HeadscaleError)) { if (!(e instanceof HeadscaleError)) {
log.debug('Healthz', 'Headscale is not reachable') log.debug('Healthz', 'Headscale is not reachable')
return new Response('Headscale is not reachable', { return data({
status: 500, status: 'NOT OK',
headers: { error: e.message
'Content-Type': 'text/plain', }, { status: 500 })
},
})
} }
} }
return new Response('OK', { return { status: 'OK' }
status: 200,
headers: {
'Content-Type': 'text/plain',
},
})
} }

View File

@ -1,5 +1,5 @@
import { redirect } from '@remix-run/node' import { redirect } from '@remix-run/node'
export function loader() { export async function loader() {
return redirect('/machines') return redirect('/machines')
} }