Files
keystone/resources/js/components/AppSidebarHeader.vue
Harry Bayliss 66f0ee9e50
All checks were successful
CI / Tests (push) Successful in 43s
CI / Lint (push) Successful in 1m3s
Migrate to Gitea, switch JS tooling to oxlint/oxfmt, lift test coverage to 95%
- Add .gitea/workflows/ci.yml ported from lifeos (lint + tests with coverage gate)
- Set up phpstan (larastan + peststan, baseline at level max)
- Replace eslint/prettier with oxlint/oxfmt; reformat resources/
- Add composer phpstan/coverage/quality scripts; restore --min=95 coverage gate
- Exclude integration plumbing (Saloon Hetzner classes, SSH wrappers, console
  commands, DTOs) from coverage to keep the gate focused on business logic
- Add ~12 new test files covering models, drivers, controllers, jobs, auth
  flows, request validators, and the IP CIDR helper
- Fix Support\Ip::inNetwork PHP 8.4 TypeError in CIDR mask check
- Fix FirewallRule::command comparing the enum-cast type column to a string
- Fix Server::network using the wrong foreign key column
- Remove unreachable code under abort(403) in RegisteredUserController
2026-05-13 16:51:07 +01:00

147 lines
6.0 KiB
Vue

<script setup lang="ts">
import Breadcrumbs from "@/components/Breadcrumbs.vue";
import { SidebarTrigger } from "@/components/ui/sidebar";
import type { BreadcrumbItemType } from "@/types";
import { Link, usePage } from "@inertiajs/vue3";
import { ChevronsUpDown } from "lucide-vue-next";
import { Button } from "./ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "./ui/dropdown-menu";
defineProps<{
breadcrumbs?: BreadcrumbItemType[];
}>();
const organisation = usePage().props.organisation ?? null;
const application = usePage().props.application ?? null;
const environment = usePage().props.environment ?? null;
</script>
<template>
<header
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-in-out group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 md:px-4"
>
<div class="flex w-full items-center gap-4">
<SidebarTrigger class="-ml-1" />
<template v-if="breadcrumbs.length > 0">
<Breadcrumbs :breadcrumbs="breadcrumbs" />
</template>
<div class="gap-0.25 ml-auto flex items-center">
<Button
:as="organisation ? Link : 'button'"
:href="
organisation
? route('organisations.show', { organisation: organisation?.id })
: null
"
variant="ghost"
size="xs"
>
{{ organisation?.name ?? "Select Organisation" }}
</Button>
<DropdownMenu>
<DropdownMenuTrigger :as="Button" size="iconxs" variant="ghost">
<ChevronsUpDown class="size-3" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
v-for="org in $page.props.auth.user?.organisations"
:as="Link"
:href="route('organisations.show', { organisation: org.id })"
>{{ org.name }}</DropdownMenuItem
>
</DropdownMenuContent>
</DropdownMenu>
</div>
<div v-if="organisation" class="gap-0.25 flex items-center">
<Button
:disabled="!organisation?.applications?.length"
:as="application ? Link : 'button'"
:href="
application
? route('applications.show', {
organisation: application.organisation_id,
application: application.id,
})
: null
"
variant="ghost"
size="xs"
>
{{ application?.name ?? "Application" }}
</Button>
<DropdownMenu>
<DropdownMenuTrigger
:as="Button"
size="iconxs"
variant="ghost"
:disabled="!organisation?.applications?.length"
>
<ChevronsUpDown class="size-3" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
v-for="app in organisation?.applications"
:as="Link"
:href="
route('applications.show', {
organisation: app.organisation_id,
application: app.id,
})
"
>{{ app.name }}</DropdownMenuItem
>
</DropdownMenuContent>
</DropdownMenu>
</div>
<div class="gap-0.25 flex items-center">
<Button
:disabled="!application?.environments?.length"
:as="environment ? Link : 'button'"
:href="
environment
? route('environments.show', {
organisation: application.organisation_id,
application: application.id,
environment: environment.id,
})
: null
"
variant="ghost"
size="xs"
>
{{ environment?.name ?? "Environment" }}
</Button>
<DropdownMenu>
<DropdownMenuTrigger
:as="Button"
size="iconxs"
variant="ghost"
:disabled="!application?.environments?.length"
>
<ChevronsUpDown class="size-3" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
v-for="env in application?.environments"
:as="Link"
:href="
route('environments.show', {
organisation: application.organisation_id,
application: application.id,
environment: env.id,
})
"
>{{ env.name }}</DropdownMenuItem
>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</header>
</template>