feat(monorepo): restructure web components and update configurations
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 27s
CI / web (push) Successful in 38s
CI / go (push) Successful in 2m36s
CI / bird2 (push) Successful in 15s
CI / release (push) Failing after 3m7s
CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 27s
CI / web (push) Successful in 38s
CI / go (push) Successful in 2m36s
CI / bird2 (push) Successful in 15s
CI / release (push) Failing after 3m7s
Refactored the project structure to support a monorepo setup, moving the web application to `apps/web/` and updating related configurations. Adjusted pre-commit hooks to use `pnpm` for linting and formatting. Updated CI workflows to reflect the new directory structure and dependencies. Removed legacy files and configurations from the previous `web/` directory, streamlining the project for better maintainability and clarity.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { page } from '$app/state';
|
||||
import { resolve } from '$app/paths';
|
||||
import * as Sidebar from '@evobgp/ui/components/sidebar/index.js';
|
||||
import * as Breadcrumb from '@evobgp/ui/components/breadcrumb/index.js';
|
||||
import { Separator } from '@evobgp/ui/components/separator/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
import { mainNav, bottomNav } from '$lib/ui/app/layout/nav.js';
|
||||
import ThemeMenu from '$lib/ui/app/layout/theme-menu.svelte';
|
||||
import AppVersion from '$lib/ui/app/layout/app-version.svelte';
|
||||
import AppMobileNav from '$lib/ui/app/layout/app-mobile-nav.svelte';
|
||||
|
||||
type Props = {
|
||||
children: Snippet;
|
||||
theme?: ThemePreference;
|
||||
};
|
||||
|
||||
let { children, theme = $bindable<ThemePreference>('system') }: Props = $props();
|
||||
|
||||
let mobileNavOpen = $state(false);
|
||||
|
||||
const routeLabels: Record<string, string> = {
|
||||
'/': 'Обзор',
|
||||
...Object.fromEntries(mainNav.map((i) => [i.href, i.label])),
|
||||
...Object.fromEntries(bottomNav.map((i) => [i.href, i.label]))
|
||||
};
|
||||
|
||||
const breadcrumbLabel = $derived(routeLabels[page.url.pathname] ?? 'EvoBGP');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const navHref = (href: string) => resolve(href as any);
|
||||
|
||||
function isActive(href: string) {
|
||||
const pathname = page.url.pathname;
|
||||
if (href === '/') return pathname === '/';
|
||||
return pathname === href || pathname.startsWith(href + '/');
|
||||
}
|
||||
</script>
|
||||
|
||||
<Sidebar.Provider>
|
||||
<Sidebar.Root>
|
||||
<Sidebar.Header class="border-b border-sidebar-border">
|
||||
<div class="flex items-center gap-2 px-2 py-1">
|
||||
<div class="flex min-w-0 flex-1 flex-col group-data-[collapsible=icon]:hidden">
|
||||
<a href={navHref('/')} class="truncate font-semibold tracking-tight">EvoBGP</a>
|
||||
<p class="truncate text-xs text-muted-foreground">Панель управления</p>
|
||||
</div>
|
||||
<ThemeMenu bind:theme />
|
||||
</div>
|
||||
</Sidebar.Header>
|
||||
<Sidebar.Content>
|
||||
<Sidebar.Group>
|
||||
<Sidebar.GroupLabel>Операции</Sidebar.GroupLabel>
|
||||
<Sidebar.GroupContent>
|
||||
<Sidebar.Menu>
|
||||
{#each mainNav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
<Sidebar.MenuItem>
|
||||
<Sidebar.MenuButton isActive={isActive(item.href)}>
|
||||
{#snippet child({ props })}
|
||||
<a href={navHref(item.href)} {...props}>
|
||||
<Icon class="size-4" />
|
||||
<span>{item.label}</span>
|
||||
</a>
|
||||
{/snippet}
|
||||
</Sidebar.MenuButton>
|
||||
</Sidebar.MenuItem>
|
||||
{/each}
|
||||
</Sidebar.Menu>
|
||||
</Sidebar.GroupContent>
|
||||
</Sidebar.Group>
|
||||
</Sidebar.Content>
|
||||
<Sidebar.Footer class="border-t border-sidebar-border">
|
||||
<Sidebar.Menu>
|
||||
{#each bottomNav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
<Sidebar.MenuItem>
|
||||
<Sidebar.MenuButton isActive={isActive(item.href)}>
|
||||
{#snippet child({ props })}
|
||||
<a href={navHref(item.href)} {...props}>
|
||||
<Icon class="size-4" />
|
||||
<span>{item.label}</span>
|
||||
</a>
|
||||
{/snippet}
|
||||
</Sidebar.MenuButton>
|
||||
</Sidebar.MenuItem>
|
||||
{/each}
|
||||
</Sidebar.Menu>
|
||||
<AppVersion />
|
||||
</Sidebar.Footer>
|
||||
<Sidebar.Rail />
|
||||
</Sidebar.Root>
|
||||
<Sidebar.Inset>
|
||||
<header
|
||||
class="sticky top-0 z-10 flex h-14 shrink-0 items-center gap-2 border-b bg-background/95 px-4 backdrop-blur supports-[backdrop-filter]:bg-background/60"
|
||||
>
|
||||
<div class="flex items-center gap-2 md:hidden">
|
||||
<AppMobileNav bind:open={mobileNavOpen} bind:theme />
|
||||
<span class="font-semibold tracking-tight">EvoBGP</span>
|
||||
</div>
|
||||
<Sidebar.Trigger class="-ms-1 hidden md:flex" />
|
||||
<Separator orientation="vertical" class="mx-2 hidden h-4 md:block" />
|
||||
<Breadcrumb.Root class="hidden min-w-0 md:flex">
|
||||
<Breadcrumb.List>
|
||||
<Breadcrumb.Item>
|
||||
<Breadcrumb.Page>{breadcrumbLabel}</Breadcrumb.Page>
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb.List>
|
||||
</Breadcrumb.Root>
|
||||
</header>
|
||||
<main class="flex flex-1 flex-col gap-4 p-4 md:gap-6 md:p-6">
|
||||
{@render children()}
|
||||
</main>
|
||||
</Sidebar.Inset>
|
||||
</Sidebar.Provider>
|
||||
Reference in New Issue
Block a user