lint fix and formatted
This commit is contained in:
+10
-4
@@ -26,11 +26,17 @@ const eslintConfig = [
|
||||
{
|
||||
ignores: [
|
||||
'**/dist/**',
|
||||
'vite/**',
|
||||
'public/**',
|
||||
'node_modules/**',
|
||||
|
||||
// aus vorheriger .prettierignore
|
||||
'.github/**',
|
||||
'**/*.yml',
|
||||
'**/*.yaml',
|
||||
'docker-compose.yml',
|
||||
'docker/**',
|
||||
'vendor/**',
|
||||
'storage/**',
|
||||
'bootstrap/cache/**',
|
||||
'public/build/**',
|
||||
'public/hot',
|
||||
'resources/js/components/ui/**',
|
||||
'resources/views/mail/**',
|
||||
],
|
||||
|
||||
@@ -77,7 +77,7 @@ const rightNavItems: NavItem[] = [
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="border-b border-sidebar-border/80">
|
||||
<div class="border-sidebar-border/80 border-b">
|
||||
<div class="mx-auto flex h-16 items-center px-4 md:max-w-7xl">
|
||||
<!-- Mobile Menu -->
|
||||
<div class="lg:hidden">
|
||||
@@ -108,7 +108,7 @@ const rightNavItems: NavItem[] = [
|
||||
v-for="item in mainNavItems"
|
||||
:key="item.title"
|
||||
:href="item.href"
|
||||
class="flex items-center gap-x-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-accent"
|
||||
class="hover:bg-accent flex items-center gap-x-3 rounded-lg px-3 py-2 text-sm font-medium"
|
||||
:class="
|
||||
whenCurrentUrl(
|
||||
item.href,
|
||||
@@ -243,7 +243,7 @@ const rightNavItems: NavItem[] = [
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class="relative size-10 w-auto rounded-full p-1 focus-within:ring-2 focus-within:ring-primary"
|
||||
class="focus-within:ring-primary relative size-10 w-auto rounded-full p-1 focus-within:ring-2"
|
||||
>
|
||||
<Avatar
|
||||
class="size-8 overflow-hidden rounded-full"
|
||||
@@ -271,7 +271,7 @@ const rightNavItems: NavItem[] = [
|
||||
|
||||
<div
|
||||
v-if="props.breadcrumbs.length > 1"
|
||||
class="flex w-full border-b border-sidebar-border/70"
|
||||
class="border-sidebar-border/70 flex w-full border-b"
|
||||
>
|
||||
<div
|
||||
class="mx-auto flex h-12 w-full items-center justify-start px-4 text-neutral-500 md:max-w-7xl"
|
||||
|
||||
@@ -4,12 +4,12 @@ import AppLogoIcon from '@/components/AppLogoIcon.vue';
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex aspect-square size-8 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground"
|
||||
class="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-md"
|
||||
>
|
||||
<AppLogoIcon class="size-5 fill-current text-white dark:text-black" />
|
||||
</div>
|
||||
<div class="ml-1 grid flex-1 text-left text-sm">
|
||||
<span class="mb-0.5 truncate leading-tight font-semibold"
|
||||
<span class="mb-0.5 truncate font-semibold leading-tight"
|
||||
>Laravel Starter Kit</span
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@ withDefaults(
|
||||
|
||||
<template>
|
||||
<header
|
||||
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4"
|
||||
class="border-sidebar-border/70 group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 flex h-16 shrink-0 items-center gap-2 border-b px-6 transition-[width,height] ease-linear md:px-4"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<SidebarTrigger class="-ml-1" />
|
||||
|
||||
@@ -22,7 +22,7 @@ const tabs = [
|
||||
:class="[
|
||||
'flex items-center rounded-md px-3.5 py-1.5 transition-colors',
|
||||
appearance === value
|
||||
? 'bg-white shadow-xs dark:bg-neutral-700 dark:text-neutral-100'
|
||||
? 'shadow-xs bg-white dark:bg-neutral-700 dark:text-neutral-100'
|
||||
: 'text-neutral-500 hover:bg-neutral-200/60 hover:text-black dark:text-neutral-400 dark:hover:bg-neutral-700/60',
|
||||
]"
|
||||
>
|
||||
|
||||
@@ -21,7 +21,7 @@ withDefaults(defineProps<Props>(), {
|
||||
>
|
||||
{{ title }}
|
||||
</h2>
|
||||
<p v-if="description" class="text-sm text-muted-foreground">
|
||||
<p v-if="description" class="text-muted-foreground text-sm">
|
||||
{{ description }}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@@ -33,7 +33,7 @@ defineExpose({
|
||||
@click="showPassword = !showPassword"
|
||||
:class="
|
||||
cn(
|
||||
'absolute inset-y-0 right-0 flex items-center rounded-r-md px-3 text-muted-foreground hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring focus-visible:outline-none',
|
||||
'text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute inset-y-0 right-0 flex items-center rounded-r-md px-3 focus-visible:outline-none focus-visible:ring-[3px]',
|
||||
)
|
||||
"
|
||||
:aria-label="showPassword ? 'Hide password' : 'Show password'"
|
||||
|
||||
@@ -18,7 +18,7 @@ defineProps<Props>();
|
||||
:tabindex="tabindex"
|
||||
:method="method"
|
||||
:as="as"
|
||||
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
|
||||
class="text-foreground hover:decoration-current! underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out dark:decoration-neutral-500"
|
||||
>
|
||||
<slot />
|
||||
</Link>
|
||||
|
||||
@@ -13,7 +13,7 @@ defineProps<{
|
||||
<template>
|
||||
<ul class="space-y-3">
|
||||
<li v-for="node in nodes" :key="node.id">
|
||||
<div class="rounded-xl border border-border px-4 py-4">
|
||||
<div class="border-border rounded-xl border px-4 py-4">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Link
|
||||
:href="
|
||||
@@ -22,7 +22,7 @@ defineProps<{
|
||||
ticket: node.id,
|
||||
})
|
||||
"
|
||||
class="font-medium text-foreground transition hover:text-primary"
|
||||
class="text-foreground hover:text-primary font-medium transition"
|
||||
>
|
||||
{{ node.ticket_key }}
|
||||
</Link>
|
||||
@@ -32,14 +32,14 @@ defineProps<{
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div class="mt-2 text-sm text-foreground">
|
||||
<div class="text-foreground mt-2 text-sm">
|
||||
{{ node.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="node.children.length > 0"
|
||||
class="mt-3 border-l border-border pl-4"
|
||||
class="border-border mt-3 border-l pl-4"
|
||||
>
|
||||
<TicketTreeList
|
||||
:nodes="node.children"
|
||||
|
||||
@@ -51,7 +51,7 @@ onMounted(async () => {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div
|
||||
class="flex flex-col gap-3 select-none sm:flex-row sm:items-center sm:justify-between"
|
||||
class="flex select-none flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
|
||||
>
|
||||
<Button @click="toggleRecoveryCodesVisibility" class="w-fit">
|
||||
<component
|
||||
@@ -93,13 +93,13 @@ onMounted(async () => {
|
||||
<div v-else class="mt-3 space-y-3">
|
||||
<div
|
||||
ref="recoveryCodeSectionRef"
|
||||
class="grid gap-1 rounded-lg bg-muted p-4 font-mono text-sm"
|
||||
class="bg-muted grid gap-1 rounded-lg p-4 font-mono text-sm"
|
||||
>
|
||||
<div v-if="!recoveryCodesList.length" class="space-y-2">
|
||||
<div
|
||||
v-for="n in 8"
|
||||
:key="n"
|
||||
class="h-4 animate-pulse rounded bg-muted-foreground/20"
|
||||
class="bg-muted-foreground/20 h-4 animate-pulse rounded"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
@@ -110,7 +110,7 @@ onMounted(async () => {
|
||||
{{ code }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground select-none">
|
||||
<p class="text-muted-foreground select-none text-xs">
|
||||
Each recovery code can be used once to access your
|
||||
account and will be removed after use. If you need more,
|
||||
click
|
||||
|
||||
@@ -114,10 +114,10 @@ watch(
|
||||
<DialogContent class="sm:max-w-md">
|
||||
<DialogHeader class="flex items-center justify-center">
|
||||
<div
|
||||
class="mb-3 w-auto rounded-full border border-border bg-card p-0.5 shadow-sm"
|
||||
class="border-border bg-card mb-3 w-auto rounded-full border p-0.5 shadow-sm"
|
||||
>
|
||||
<div
|
||||
class="relative overflow-hidden rounded-full border border-border bg-muted p-2.5"
|
||||
class="border-border bg-muted relative overflow-hidden rounded-full border p-2.5"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 grid grid-cols-5 opacity-50"
|
||||
@@ -125,7 +125,7 @@ watch(
|
||||
<div
|
||||
v-for="i in 5"
|
||||
:key="`col-${i}`"
|
||||
class="border-r border-border last:border-r-0"
|
||||
class="border-border border-r last:border-r-0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
@@ -134,11 +134,11 @@ watch(
|
||||
<div
|
||||
v-for="i in 5"
|
||||
:key="`row-${i}`"
|
||||
class="border-b border-border last:border-b-0"
|
||||
class="border-border border-b last:border-b-0"
|
||||
/>
|
||||
</div>
|
||||
<ScanLine
|
||||
class="relative z-20 size-6 text-foreground"
|
||||
class="text-foreground relative z-20 size-6"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -158,11 +158,11 @@ watch(
|
||||
class="relative mx-auto flex max-w-md items-center overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border border-border"
|
||||
class="border-border relative mx-auto aspect-square w-64 overflow-hidden rounded-lg border"
|
||||
>
|
||||
<div
|
||||
v-if="!qrCodeSvg"
|
||||
class="absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center bg-background"
|
||||
class="bg-background absolute inset-0 z-10 flex aspect-square h-auto w-full animate-pulse items-center justify-center"
|
||||
>
|
||||
<Spinner class="size-6" />
|
||||
</div>
|
||||
@@ -194,9 +194,9 @@ watch(
|
||||
class="relative flex w-full items-center justify-center"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 top-1/2 h-px w-full bg-border"
|
||||
class="bg-border absolute inset-0 top-1/2 h-px w-full"
|
||||
/>
|
||||
<span class="relative bg-card px-2 py-1"
|
||||
<span class="bg-card relative px-2 py-1"
|
||||
>or, enter the code manually</span
|
||||
>
|
||||
</div>
|
||||
@@ -205,11 +205,11 @@ watch(
|
||||
class="flex w-full items-center justify-center space-x-2"
|
||||
>
|
||||
<div
|
||||
class="flex w-full items-stretch overflow-hidden rounded-xl border border-border"
|
||||
class="border-border flex w-full items-stretch overflow-hidden rounded-xl border"
|
||||
>
|
||||
<div
|
||||
v-if="!manualSetupKey"
|
||||
class="flex h-full w-full items-center justify-center bg-muted p-3"
|
||||
class="bg-muted flex h-full w-full items-center justify-center p-3"
|
||||
>
|
||||
<Spinner />
|
||||
</div>
|
||||
@@ -218,11 +218,11 @@ watch(
|
||||
type="text"
|
||||
readonly
|
||||
:value="manualSetupKey"
|
||||
class="h-full w-full bg-background p-3 text-foreground"
|
||||
class="bg-background text-foreground h-full w-full p-3"
|
||||
/>
|
||||
<button
|
||||
@click="copy(manualSetupKey || '')"
|
||||
class="relative block h-auto border-l border-border px-3 hover:bg-muted"
|
||||
class="border-border hover:bg-muted relative block h-auto border-l px-3"
|
||||
>
|
||||
<Check
|
||||
v-if="copied"
|
||||
|
||||
@@ -31,7 +31,7 @@ const showAvatar = computed(
|
||||
|
||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||
<span class="truncate font-medium">{{ user.name }}</span>
|
||||
<span v-if="showEmail" class="truncate text-xs text-muted-foreground">{{
|
||||
<span v-if="showEmail" class="text-muted-foreground truncate text-xs">{{
|
||||
user.email
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex min-h-svh flex-col items-center justify-center gap-6 bg-muted p-6 md:p-10"
|
||||
class="bg-muted flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10"
|
||||
>
|
||||
<div class="flex w-full max-w-md flex-col gap-6">
|
||||
<Link
|
||||
@@ -34,7 +34,7 @@ defineProps<{
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<Card class="rounded-xl">
|
||||
<CardHeader class="px-10 pt-8 pb-0 text-center">
|
||||
<CardHeader class="px-10 pb-0 pt-8 text-center">
|
||||
<CardTitle class="text-xl">{{ title }}</CardTitle>
|
||||
<CardDescription>
|
||||
{{ description }}
|
||||
|
||||
@@ -11,7 +11,7 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex min-h-svh flex-col items-center justify-center gap-6 bg-background p-6 md:p-10"
|
||||
class="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10"
|
||||
>
|
||||
<div class="w-full max-w-sm">
|
||||
<div class="flex flex-col gap-8">
|
||||
@@ -31,7 +31,7 @@ defineProps<{
|
||||
</Link>
|
||||
<div class="space-y-2 text-center">
|
||||
<h1 class="text-xl font-medium">{{ title }}</h1>
|
||||
<p class="text-center text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-center text-sm">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@ defineProps<{
|
||||
class="relative grid h-dvh flex-col items-center justify-center px-8 sm:px-0 lg:max-w-none lg:grid-cols-2 lg:px-0"
|
||||
>
|
||||
<div
|
||||
class="relative hidden h-full flex-col bg-muted p-10 text-white lg:flex dark:border-r"
|
||||
class="bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-r"
|
||||
>
|
||||
<div class="absolute inset-0 bg-zinc-900" />
|
||||
<Link
|
||||
@@ -36,7 +36,7 @@ defineProps<{
|
||||
<h1 class="text-xl font-medium tracking-tight" v-if="title">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<p class="text-sm text-muted-foreground" v-if="description">
|
||||
<p class="text-muted-foreground text-sm" v-if="description">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ const { isCurrentOrParentUrl } = useCurrentUrl();
|
||||
<div class="flex flex-col lg:flex-row lg:space-x-12">
|
||||
<aside class="w-full max-w-xl lg:w-48">
|
||||
<nav
|
||||
class="flex flex-col space-y-1 space-x-0"
|
||||
class="flex flex-col space-x-0 space-y-1"
|
||||
aria-label="Settings"
|
||||
>
|
||||
<Button
|
||||
|
||||
@@ -22,23 +22,23 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
>
|
||||
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border"
|
||||
class="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border"
|
||||
>
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border"
|
||||
class="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border"
|
||||
>
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
<div
|
||||
class="relative aspect-video overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border"
|
||||
class="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border"
|
||||
>
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="relative min-h-[100vh] flex-1 rounded-xl border border-sidebar-border/70 md:min-h-min dark:border-sidebar-border"
|
||||
class="border-sidebar-border/70 dark:border-sidebar-border relative min-h-[100vh] flex-1 rounded-xl border md:min-h-min"
|
||||
>
|
||||
<PlaceholderPattern />
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@ withDefaults(
|
||||
class="flex min-h-screen flex-col items-center bg-[#FDFDFC] p-6 text-[#1b1b18] lg:justify-center lg:p-8 dark:bg-[#0a0a0a]"
|
||||
>
|
||||
<header
|
||||
class="mb-6 w-full max-w-[335px] text-sm not-has-[nav]:hidden lg:max-w-4xl"
|
||||
class="not-has-[nav]:hidden mb-6 w-full max-w-[335px] text-sm lg:max-w-4xl"
|
||||
>
|
||||
<nav class="flex items-center justify-end gap-4">
|
||||
<Link
|
||||
@@ -49,13 +49,13 @@ withDefaults(
|
||||
</nav>
|
||||
</header>
|
||||
<div
|
||||
class="flex w-full items-center justify-center opacity-100 transition-opacity duration-750 lg:grow starting:opacity-0"
|
||||
class="duration-750 starting:opacity-0 flex w-full items-center justify-center opacity-100 transition-opacity lg:grow"
|
||||
>
|
||||
<main
|
||||
class="flex w-full max-w-[335px] flex-col-reverse overflow-hidden rounded-lg lg:max-w-4xl lg:flex-row"
|
||||
>
|
||||
<div
|
||||
class="flex-1 rounded-br-lg rounded-bl-lg bg-white p-6 pb-12 text-[13px] leading-[20px] shadow-[inset_0px_0px_0px_1px_rgba(26,26,0,0.16)] lg:rounded-tl-lg lg:rounded-br-none lg:p-20 dark:bg-[#161615] dark:text-[#EDEDEC] dark:shadow-[inset_0px_0px_0px_1px_#fffaed2d]"
|
||||
class="flex-1 rounded-bl-lg rounded-br-lg bg-white p-6 pb-12 text-[13px] leading-[20px] shadow-[inset_0px_0px_0px_1px_rgba(26,26,0,0.16)] lg:rounded-br-none lg:rounded-tl-lg lg:p-20 dark:bg-[#161615] dark:text-[#EDEDEC] dark:shadow-[inset_0px_0px_0px_1px_#fffaed2d]"
|
||||
>
|
||||
<h1 class="mb-1 font-medium">Let's get started</h1>
|
||||
<p class="mb-2 text-[#706f6c] dark:text-[#A1A09A]">
|
||||
@@ -64,7 +64,7 @@ withDefaults(
|
||||
</p>
|
||||
<ul class="mb-4 flex flex-col lg:mb-6">
|
||||
<li
|
||||
class="relative flex items-center gap-4 py-2 before:absolute before:top-1/2 before:bottom-0 before:left-[0.4rem] before:border-l before:border-[#e3e3e0] dark:before:border-[#3E3E3A]"
|
||||
class="relative flex items-center gap-4 py-2 before:absolute before:bottom-0 before:left-[0.4rem] before:top-1/2 before:border-l before:border-[#e3e3e0] dark:before:border-[#3E3E3A]"
|
||||
>
|
||||
<span
|
||||
class="relative bg-white py-1 dark:bg-[#161615]"
|
||||
@@ -103,7 +103,7 @@ withDefaults(
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="relative flex items-center gap-4 py-2 before:absolute before:top-0 before:bottom-1/2 before:left-[0.4rem] before:border-l before:border-[#e3e3e0] dark:before:border-[#3E3E3A]"
|
||||
class="relative flex items-center gap-4 py-2 before:absolute before:bottom-1/2 before:left-[0.4rem] before:top-0 before:border-l before:border-[#e3e3e0] dark:before:border-[#3E3E3A]"
|
||||
>
|
||||
<span
|
||||
class="relative bg-white py-1 dark:bg-[#161615]"
|
||||
@@ -155,11 +155,11 @@ withDefaults(
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="relative -mb-px aspect-[335/364] w-full shrink-0 overflow-hidden rounded-t-lg bg-[#fff2f2] lg:mb-0 lg:-ml-px lg:aspect-auto lg:w-[438px] lg:rounded-t-none lg:rounded-r-lg dark:bg-[#1D0002]"
|
||||
class="relative -mb-px aspect-[335/364] w-full shrink-0 overflow-hidden rounded-t-lg bg-[#fff2f2] lg:-ml-px lg:mb-0 lg:aspect-auto lg:w-[438px] lg:rounded-r-lg lg:rounded-t-none dark:bg-[#1D0002]"
|
||||
>
|
||||
<!-- Laravel Logo -->
|
||||
<svg
|
||||
class="w-full max-w-none translate-y-0 text-[#F53003] opacity-100 transition-all duration-750 dark:text-[#F61500] starting:opacity-0 motion-safe:starting:translate-y-6"
|
||||
class="duration-750 starting:opacity-0 motion-safe:starting:translate-y-6 w-full max-w-none translate-y-0 text-[#F53003] opacity-100 transition-all dark:text-[#F61500]"
|
||||
viewBox="0 0 438 104"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -196,13 +196,13 @@ withDefaults(
|
||||
|
||||
<!-- 13 -->
|
||||
<svg
|
||||
class="relative -mt-[6.6rem] -ml-8 w-[438px] max-w-none [--stroke-color:#1B1B18] lg:ml-0 dark:[--stroke-color:#FF750F]"
|
||||
class="relative -ml-8 -mt-[6.6rem] w-[438px] max-w-none [--stroke-color:#1B1B18] lg:ml-0 dark:[--stroke-color:#FF750F]"
|
||||
viewBox="0 0 440 392"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
class="text-[#1B1B18] opacity-100 mix-blend-darken transition-all delay-300 duration-750 dark:text-black dark:mix-blend-normal starting:opacity-0"
|
||||
class="duration-750 starting:opacity-0 text-[#1B1B18] opacity-100 mix-blend-darken transition-all delay-300 dark:text-black dark:mix-blend-normal"
|
||||
>
|
||||
<mask
|
||||
id="path-1-mask"
|
||||
@@ -250,7 +250,7 @@ withDefaults(
|
||||
</g>
|
||||
|
||||
<g
|
||||
class="text-[#F3BEC7] opacity-100 transition-all delay-400 duration-750 dark:text-[#4B0600] starting:opacity-0 motion-safe:starting:-translate-x-[26px]"
|
||||
class="delay-400 duration-750 starting:opacity-0 motion-safe:starting:-translate-x-[26px] text-[#F3BEC7] opacity-100 transition-all dark:text-[#4B0600]"
|
||||
>
|
||||
<mask
|
||||
id="path-2-mask"
|
||||
@@ -298,7 +298,7 @@ withDefaults(
|
||||
</g>
|
||||
|
||||
<g
|
||||
class="text-[#F8B803] opacity-100 mix-blend-color transition-all delay-400 duration-750 dark:text-[#391800] dark:mix-blend-hard-light starting:opacity-0 motion-safe:starting:-translate-x-[51px]"
|
||||
class="delay-400 duration-750 starting:opacity-0 motion-safe:starting:-translate-x-[51px] text-[#F8B803] opacity-100 mix-blend-color transition-all dark:text-[#391800] dark:mix-blend-hard-light"
|
||||
>
|
||||
<mask
|
||||
id="path-3-mask"
|
||||
@@ -346,7 +346,7 @@ withDefaults(
|
||||
</g>
|
||||
|
||||
<g
|
||||
class="text-[#F3BEC7] opacity-100 mix-blend-multiply transition-all delay-400 duration-750 dark:text-[#733000] dark:mix-blend-normal starting:opacity-0 motion-safe:starting:-translate-x-[78px]"
|
||||
class="delay-400 duration-750 starting:opacity-0 motion-safe:starting:-translate-x-[78px] text-[#F3BEC7] opacity-100 mix-blend-multiply transition-all dark:text-[#733000] dark:mix-blend-normal"
|
||||
>
|
||||
<mask
|
||||
id="path-4-mask"
|
||||
@@ -394,7 +394,7 @@ withDefaults(
|
||||
</g>
|
||||
|
||||
<g
|
||||
class="text-[#F3BEC7] opacity-100 mix-blend-hard-light transition-all delay-400 duration-750 dark:text-[#4B0600] starting:opacity-0 motion-safe:starting:-translate-x-[102px]"
|
||||
class="delay-400 duration-750 starting:opacity-0 motion-safe:starting:-translate-x-[102px] text-[#F3BEC7] opacity-100 mix-blend-hard-light transition-all dark:text-[#4B0600]"
|
||||
>
|
||||
<mask
|
||||
id="path-5-mask"
|
||||
@@ -442,11 +442,11 @@ withDefaults(
|
||||
</g>
|
||||
</svg>
|
||||
<div
|
||||
class="absolute inset-0 rounded-t-lg shadow-[inset_0px_0px_0px_1px_rgba(26,26,0,0.16)] lg:rounded-t-none lg:rounded-r-lg dark:shadow-[inset_0px_0px_0px_1px_#fffaed2d]"
|
||||
class="absolute inset-0 rounded-t-lg shadow-[inset_0px_0px_0px_1px_rgba(26,26,0,0.16)] lg:rounded-r-lg lg:rounded-t-none dark:shadow-[inset_0px_0px_0px_1px_#fffaed2d]"
|
||||
></div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<div class="hidden h-14.5 lg:block"></div>
|
||||
<div class="h-14.5 hidden lg:block"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -62,17 +62,17 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<CardContent class="p-0">
|
||||
<div
|
||||
v-if="users.length === 0"
|
||||
class="p-6 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground p-6 text-sm"
|
||||
>
|
||||
No users exist yet.
|
||||
</div>
|
||||
|
||||
<div v-else class="overflow-x-auto">
|
||||
<table
|
||||
class="min-w-full divide-y divide-border text-sm"
|
||||
class="divide-border min-w-full divide-y text-sm"
|
||||
>
|
||||
<thead
|
||||
class="bg-muted/40 text-left text-muted-foreground"
|
||||
class="bg-muted/40 text-muted-foreground text-left"
|
||||
>
|
||||
<tr>
|
||||
<th class="px-4 py-3 font-medium">User</th>
|
||||
@@ -85,7 +85,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border">
|
||||
<tbody class="divide-border divide-y">
|
||||
<tr
|
||||
v-for="user in users"
|
||||
:key="user.id"
|
||||
@@ -93,12 +93,12 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
>
|
||||
<td class="px-4 py-4">
|
||||
<div
|
||||
class="font-medium text-foreground"
|
||||
class="text-foreground font-medium"
|
||||
>
|
||||
{{ user.name }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 text-muted-foreground">
|
||||
<td class="text-muted-foreground px-4 py-4">
|
||||
{{ user.email }}
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
|
||||
@@ -56,7 +56,7 @@ defineProps<{
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
<div class="space-x-1 text-center text-sm text-muted-foreground">
|
||||
<div class="text-muted-foreground space-x-1 text-center text-sm">
|
||||
<span>Or, return to</span>
|
||||
<TextLink :href="login()">log in</TextLink>
|
||||
</div>
|
||||
|
||||
@@ -99,7 +99,7 @@ defineProps<{
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="text-center text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-center text-sm"
|
||||
v-if="canRegister"
|
||||
>
|
||||
Don't have an account?
|
||||
|
||||
@@ -93,7 +93,7 @@ import { store } from '@/routes/register';
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-sm text-muted-foreground">
|
||||
<div class="text-muted-foreground text-center text-sm">
|
||||
Already have an account?
|
||||
<TextLink
|
||||
:href="login()"
|
||||
|
||||
@@ -84,11 +84,11 @@ const code = ref<string>('');
|
||||
<Button type="submit" class="w-full" :disabled="processing"
|
||||
>Continue</Button
|
||||
>
|
||||
<div class="text-center text-sm text-muted-foreground">
|
||||
<div class="text-muted-foreground text-center text-sm">
|
||||
<span>or you can </span>
|
||||
<button
|
||||
type="button"
|
||||
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
|
||||
class="text-foreground hover:decoration-current! underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out dark:decoration-neutral-500"
|
||||
@click="() => toggleRecoveryMode(clearErrors)"
|
||||
>
|
||||
{{ authConfigContent.buttonText }}
|
||||
@@ -116,11 +116,11 @@ const code = ref<string>('');
|
||||
>Continue</Button
|
||||
>
|
||||
|
||||
<div class="text-center text-sm text-muted-foreground">
|
||||
<div class="text-muted-foreground text-center text-sm">
|
||||
<span>or you can </span>
|
||||
<button
|
||||
type="button"
|
||||
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
|
||||
class="text-foreground hover:decoration-current! underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out dark:decoration-neutral-500"
|
||||
@click="() => toggleRecoveryMode(clearErrors)"
|
||||
>
|
||||
{{ authConfigContent.buttonText }}
|
||||
|
||||
@@ -81,10 +81,10 @@ const hasPermission = (
|
||||
<CardContent class="p-0">
|
||||
<div class="overflow-x-auto">
|
||||
<table
|
||||
class="min-w-full divide-y divide-border text-sm"
|
||||
class="divide-border min-w-full divide-y text-sm"
|
||||
>
|
||||
<thead
|
||||
class="bg-muted/40 text-left text-muted-foreground"
|
||||
class="bg-muted/40 text-muted-foreground text-left"
|
||||
>
|
||||
<tr>
|
||||
<th class="px-4 py-3 font-medium">User</th>
|
||||
@@ -99,18 +99,18 @@ const hasPermission = (
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border">
|
||||
<tbody class="divide-border divide-y">
|
||||
<tr
|
||||
v-for="user in users"
|
||||
:key="user.id"
|
||||
class="bg-background align-top"
|
||||
>
|
||||
<td
|
||||
class="px-4 py-4 font-medium text-foreground"
|
||||
class="text-foreground px-4 py-4 font-medium"
|
||||
>
|
||||
{{ user.name }}
|
||||
</td>
|
||||
<td class="px-4 py-4 text-muted-foreground">
|
||||
<td class="text-muted-foreground px-4 py-4">
|
||||
{{ user.email }}
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
@@ -126,7 +126,7 @@ const hasPermission = (
|
||||
<label
|
||||
v-for="option in permissionOptions"
|
||||
:key="`${user.id}-${option.value}`"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-sm"
|
||||
class="border-border inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -139,7 +139,7 @@ const hasPermission = (
|
||||
option.value,
|
||||
)
|
||||
"
|
||||
class="size-4 rounded border-input text-primary focus:ring-ring"
|
||||
class="border-input text-primary focus:ring-ring size-4 rounded"
|
||||
/>
|
||||
<span>{{ option.label }}</span>
|
||||
</label>
|
||||
@@ -157,7 +157,7 @@ const hasPermission = (
|
||||
</Form>
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-4 text-right text-muted-foreground"
|
||||
class="text-muted-foreground px-4 py-4 text-right"
|
||||
>
|
||||
Direct
|
||||
</td>
|
||||
@@ -180,7 +180,7 @@ const hasPermission = (
|
||||
<CardContent class="p-0">
|
||||
<div
|
||||
v-if="teams.length === 0"
|
||||
class="p-6 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground p-6 text-sm"
|
||||
>
|
||||
No teams exist yet. Create teams first to assign
|
||||
inherited permissions.
|
||||
@@ -188,10 +188,10 @@ const hasPermission = (
|
||||
|
||||
<div v-else class="overflow-x-auto">
|
||||
<table
|
||||
class="min-w-full divide-y divide-border text-sm"
|
||||
class="divide-border min-w-full divide-y text-sm"
|
||||
>
|
||||
<thead
|
||||
class="bg-muted/40 text-left text-muted-foreground"
|
||||
class="bg-muted/40 text-muted-foreground text-left"
|
||||
>
|
||||
<tr>
|
||||
<th class="px-4 py-3 font-medium">Team</th>
|
||||
@@ -208,14 +208,14 @@ const hasPermission = (
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border">
|
||||
<tbody class="divide-border divide-y">
|
||||
<tr
|
||||
v-for="team in teams"
|
||||
:key="team.id"
|
||||
class="bg-background align-top"
|
||||
>
|
||||
<td
|
||||
class="px-4 py-4 font-medium text-foreground"
|
||||
class="text-foreground px-4 py-4 font-medium"
|
||||
>
|
||||
{{ team.name }}
|
||||
</td>
|
||||
@@ -249,7 +249,7 @@ const hasPermission = (
|
||||
<label
|
||||
v-for="option in permissionOptions"
|
||||
:key="`${team.id}-${option.value}`"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-sm"
|
||||
class="border-border inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -262,7 +262,7 @@ const hasPermission = (
|
||||
option.value,
|
||||
)
|
||||
"
|
||||
class="size-4 rounded border-input text-primary focus:ring-ring"
|
||||
class="border-input text-primary focus:ring-ring size-4 rounded"
|
||||
/>
|
||||
<span>{{ option.label }}</span>
|
||||
</label>
|
||||
@@ -280,7 +280,7 @@ const hasPermission = (
|
||||
</Form>
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-4 text-right text-muted-foreground"
|
||||
class="text-muted-foreground px-4 py-4 text-right"
|
||||
>
|
||||
Inherited
|
||||
</td>
|
||||
|
||||
@@ -113,7 +113,7 @@ const hasTicketMetadata =
|
||||
<select
|
||||
id="ticket_type_id"
|
||||
name="ticket_type_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="ticketType in ticketTypes"
|
||||
@@ -133,7 +133,7 @@ const hasTicketMetadata =
|
||||
<select
|
||||
id="ticket_priority_id"
|
||||
name="ticket_priority_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="ticketPriority in ticketPriorities"
|
||||
@@ -155,7 +155,7 @@ const hasTicketMetadata =
|
||||
id="description"
|
||||
name="description"
|
||||
rows="4"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
placeholder="Describe the expected behavior and relevant context."
|
||||
/>
|
||||
<InputError :message="errors.description" />
|
||||
@@ -169,7 +169,7 @@ const hasTicketMetadata =
|
||||
id="acceptance_criteria"
|
||||
name="acceptance_criteria"
|
||||
rows="4"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
placeholder="List the conditions that must be true before this ticket is done."
|
||||
/>
|
||||
<InputError :message="errors.acceptance_criteria" />
|
||||
@@ -212,17 +212,17 @@ const hasTicketMetadata =
|
||||
<CardContent class="p-0">
|
||||
<div
|
||||
v-if="tickets.length === 0"
|
||||
class="p-6 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground p-6 text-sm"
|
||||
>
|
||||
No backlog tickets exist yet.
|
||||
</div>
|
||||
|
||||
<div v-else class="overflow-x-auto">
|
||||
<table
|
||||
class="min-w-full divide-y divide-border text-sm"
|
||||
class="divide-border min-w-full divide-y text-sm"
|
||||
>
|
||||
<thead
|
||||
class="bg-muted/40 text-left text-muted-foreground"
|
||||
class="bg-muted/40 text-muted-foreground text-left"
|
||||
>
|
||||
<tr>
|
||||
<th class="px-4 py-3 font-medium">Key</th>
|
||||
@@ -239,7 +239,7 @@ const hasTicketMetadata =
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border">
|
||||
<tbody class="divide-border divide-y">
|
||||
<tr
|
||||
v-for="ticket in tickets"
|
||||
:key="ticket.id"
|
||||
@@ -267,21 +267,21 @@ const hasTicketMetadata =
|
||||
ticket: ticket.id,
|
||||
})
|
||||
"
|
||||
class="font-medium text-foreground transition hover:text-primary"
|
||||
class="text-foreground hover:text-primary font-medium transition"
|
||||
>
|
||||
{{ ticket.title }}
|
||||
</Link>
|
||||
<div
|
||||
v-if="ticket.description"
|
||||
class="mt-1 line-clamp-2 text-muted-foreground"
|
||||
class="text-muted-foreground mt-1 line-clamp-2"
|
||||
>
|
||||
{{ ticket.description }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 text-muted-foreground">
|
||||
<td class="text-muted-foreground px-4 py-4">
|
||||
{{ ticket.ticket_type.name }}
|
||||
</td>
|
||||
<td class="px-4 py-4 text-muted-foreground">
|
||||
<td class="text-muted-foreground px-4 py-4">
|
||||
{{ ticket.ticket_priority.name }}
|
||||
</td>
|
||||
<td v-if="canEditTickets" class="px-4 py-4">
|
||||
@@ -305,7 +305,7 @@ const hasTicketMetadata =
|
||||
/>
|
||||
<select
|
||||
name="board_column_id"
|
||||
class="min-w-44 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 min-w-44 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="boardColumn in boardColumns"
|
||||
@@ -326,7 +326,7 @@ const hasTicketMetadata =
|
||||
|
||||
<span
|
||||
v-else
|
||||
class="text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
Add board columns first.
|
||||
</span>
|
||||
|
||||
@@ -108,7 +108,7 @@ const statusOptions = [
|
||||
:key="boardColumn.id"
|
||||
class="flex h-full flex-col gap-0 overflow-hidden"
|
||||
>
|
||||
<CardHeader class="border-b bg-muted/20">
|
||||
<CardHeader class="bg-muted/20 border-b">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<CardTitle>{{ boardColumn.name }}</CardTitle>
|
||||
@@ -127,7 +127,7 @@ const statusOptions = [
|
||||
<CardContent class="flex flex-1 flex-col gap-4 p-4">
|
||||
<div
|
||||
v-if="(boardColumn.tickets?.length ?? 0) === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No tickets are currently in this column.
|
||||
</div>
|
||||
@@ -169,7 +169,7 @@ const statusOptions = [
|
||||
ticket: ticket.id,
|
||||
})
|
||||
"
|
||||
class="transition hover:text-primary"
|
||||
class="hover:text-primary transition"
|
||||
>
|
||||
{{ ticket.title }}
|
||||
</Link>
|
||||
@@ -181,7 +181,10 @@ const statusOptions = [
|
||||
{{ ticket.description }}
|
||||
</CardDescription>
|
||||
<CardDescription
|
||||
v-if="ticket.is_blocked && ticket.blocked_comment"
|
||||
v-if="
|
||||
ticket.is_blocked &&
|
||||
ticket.blocked_comment
|
||||
"
|
||||
class="mt-2 text-amber-900 dark:text-amber-200"
|
||||
>
|
||||
{{ ticket.blocked_comment }}
|
||||
@@ -206,7 +209,7 @@ const statusOptions = [
|
||||
/>
|
||||
<label
|
||||
:for="`ticket-status-${ticket.id}`"
|
||||
class="text-xs font-medium tracking-wide text-muted-foreground uppercase"
|
||||
class="text-muted-foreground text-xs font-medium uppercase tracking-wide"
|
||||
>
|
||||
Move ticket
|
||||
</label>
|
||||
@@ -219,7 +222,7 @@ const statusOptions = [
|
||||
:value="
|
||||
ticket.board_column_id ?? ''
|
||||
"
|
||||
class="min-w-44 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 min-w-44 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="statusOption in statusOptions"
|
||||
|
||||
@@ -76,9 +76,9 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
placeholder="CORE"
|
||||
class="uppercase"
|
||||
/>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Example ticket keys will look like
|
||||
<span class="font-medium text-foreground"
|
||||
<span class="text-foreground font-medium"
|
||||
>CORE-1</span
|
||||
>.
|
||||
</p>
|
||||
|
||||
@@ -48,7 +48,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
|
||||
<div
|
||||
v-if="projects.length === 0"
|
||||
class="rounded-xl border border-dashed px-6 py-10 text-center text-sm text-muted-foreground"
|
||||
class="text-muted-foreground rounded-xl border border-dashed px-6 py-10 text-center text-sm"
|
||||
>
|
||||
No projects exist yet. Create the first one to start building
|
||||
out board, backlog, and settings areas.
|
||||
@@ -62,7 +62,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
class="group block"
|
||||
>
|
||||
<Card
|
||||
class="h-full border-border/80 transition-colors group-hover:border-primary/40"
|
||||
class="border-border/80 group-hover:border-primary/40 h-full transition-colors"
|
||||
>
|
||||
<CardHeader class="gap-3">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
@@ -80,7 +80,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
</CardHeader>
|
||||
|
||||
<CardContent
|
||||
class="flex items-center gap-2 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground flex items-center gap-2 text-sm"
|
||||
>
|
||||
<Folder class="size-4" />
|
||||
Open board, backlog, and settings hub
|
||||
|
||||
@@ -130,7 +130,7 @@ const projectAreas = [
|
||||
>
|
||||
<CardHeader>
|
||||
<div
|
||||
class="mb-3 flex size-10 items-center justify-center rounded-full bg-muted text-foreground"
|
||||
class="bg-muted text-foreground mb-3 flex size-10 items-center justify-center rounded-full"
|
||||
>
|
||||
<component :is="area.icon" class="size-5" />
|
||||
</div>
|
||||
@@ -139,7 +139,7 @@ const projectAreas = [
|
||||
area.description
|
||||
}}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="text-sm text-muted-foreground">
|
||||
<CardContent class="text-muted-foreground text-sm">
|
||||
Use the project shortcuts above to open this area.
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -141,7 +141,8 @@ const selectedBranchRepositoryConnection = computed(
|
||||
);
|
||||
|
||||
const selectedBranchRepositoryHasPersonalAccess = computed(
|
||||
() => selectedBranchRepositoryConnection.value?.has_personal_access ?? false,
|
||||
() =>
|
||||
selectedBranchRepositoryConnection.value?.has_personal_access ?? false,
|
||||
);
|
||||
|
||||
const initializeBranchCreationForm = (): void => {
|
||||
@@ -174,7 +175,11 @@ watch(
|
||||
() => branchCreationForm.repository_connection_id,
|
||||
() => branchCreationForm.branch_name,
|
||||
],
|
||||
([isOpen, repositoryConnectionId, branchName], _previousValues, onCleanup) => {
|
||||
(
|
||||
[isOpen, repositoryConnectionId, branchName],
|
||||
_previousValues,
|
||||
onCleanup,
|
||||
) => {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
@@ -412,7 +417,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<option
|
||||
v-for="ticketType in ticketTypes"
|
||||
@@ -437,7 +442,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<option
|
||||
v-for="ticketPriority in ticketPriorities"
|
||||
@@ -465,7 +470,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<option value="">No parent ticket</option>
|
||||
<option
|
||||
@@ -492,7 +497,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
/>
|
||||
<InputError
|
||||
:message="form.errors.description"
|
||||
@@ -510,14 +515,16 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
/>
|
||||
<InputError
|
||||
:message="form.errors.acceptance_criteria"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-3 rounded-xl border border-border p-4">
|
||||
<div
|
||||
class="border-border grid gap-3 rounded-xl border p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<input
|
||||
id="is_blocked"
|
||||
@@ -526,7 +533,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="size-4 rounded border-input text-primary focus:ring-ring"
|
||||
class="border-input text-primary focus:ring-ring size-4 rounded"
|
||||
/>
|
||||
<Label for="is_blocked">
|
||||
Mark ticket as blocked
|
||||
@@ -544,7 +551,7 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
placeholder="Describe what currently blocks progress on this ticket."
|
||||
/>
|
||||
<InputError
|
||||
@@ -558,7 +565,7 @@ const formatDateTime = (value: string): string => {
|
||||
<h3 class="text-sm font-semibold">
|
||||
Custom fields
|
||||
</h3>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Project-configured fields can be tracked
|
||||
directly on the ticket.
|
||||
</p>
|
||||
@@ -566,7 +573,7 @@ const formatDateTime = (value: string): string => {
|
||||
|
||||
<div
|
||||
v-if="ticketFieldDefinitions.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No custom fields are configured for this
|
||||
project yet.
|
||||
@@ -600,7 +607,7 @@ const formatDateTime = (value: string): string => {
|
||||
!canEditTicket ||
|
||||
form.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<option value="">Unassigned</option>
|
||||
<option
|
||||
@@ -664,9 +671,9 @@ const formatDateTime = (value: string): string => {
|
||||
<div class="space-y-1.5">
|
||||
<CardTitle>Branches</CardTitle>
|
||||
<CardDescription>
|
||||
Matching branches are discovered from
|
||||
linked repositories when the branch name
|
||||
starts with this ticket key.
|
||||
Matching branches are discovered from linked
|
||||
repositories when the branch name starts
|
||||
with this ticket key.
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
@@ -699,7 +706,9 @@ const formatDateTime = (value: string): string => {
|
||||
@submit.prevent="submitBranchCreation"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
<Label for="repository_connection_id">
|
||||
<Label
|
||||
for="repository_connection_id"
|
||||
>
|
||||
Repository
|
||||
</Label>
|
||||
<select
|
||||
@@ -710,11 +719,13 @@ const formatDateTime = (value: string): string => {
|
||||
:disabled="
|
||||
branchCreationForm.processing
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<option
|
||||
v-for="repositoryConnection in linkedRepositoryConnections"
|
||||
:key="repositoryConnection.id"
|
||||
:key="
|
||||
repositoryConnection.id
|
||||
"
|
||||
:value="
|
||||
String(
|
||||
repositoryConnection.id,
|
||||
@@ -764,9 +775,7 @@ const formatDateTime = (value: string): string => {
|
||||
: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900/70 dark:bg-amber-950/40 dark:text-amber-100'
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="flex items-start gap-3"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<CheckCircle2
|
||||
v-if="
|
||||
branchNameValidation?.is_valid
|
||||
@@ -784,8 +793,8 @@ const formatDateTime = (value: string): string => {
|
||||
{{
|
||||
isCheckingBranchName
|
||||
? 'Checking whether this branch name is valid and still available...'
|
||||
: branchNameValidation?.message ??
|
||||
'Select a linked repository to validate the branch name.'
|
||||
: (branchNameValidation?.message ??
|
||||
'Select a linked repository to validate the branch name.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
@@ -797,10 +806,10 @@ const formatDateTime = (value: string): string => {
|
||||
selectedBranchRepositoryConnection !==
|
||||
null
|
||||
"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-4"
|
||||
class="border-border rounded-xl border border-dashed px-4 py-4"
|
||||
>
|
||||
<p
|
||||
class="text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
You can only create branches in
|
||||
repositories that match one of
|
||||
@@ -814,9 +823,7 @@ const formatDateTime = (value: string): string => {
|
||||
class="mt-3"
|
||||
>
|
||||
<Link
|
||||
:href="
|
||||
editGitConnections()
|
||||
"
|
||||
:href="editGitConnections()"
|
||||
>
|
||||
Open Git connections
|
||||
</Link>
|
||||
@@ -828,8 +835,7 @@ const formatDateTime = (value: string): string => {
|
||||
type="button"
|
||||
variant="secondary"
|
||||
@click="
|
||||
isCreateBranchDialogOpen =
|
||||
false
|
||||
isCreateBranchDialogOpen = false
|
||||
"
|
||||
>
|
||||
Cancel
|
||||
@@ -855,7 +861,7 @@ const formatDateTime = (value: string): string => {
|
||||
<CardContent class="space-y-4">
|
||||
<div
|
||||
v-if="visibleRepositoryBranches.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No matching branches were found across the
|
||||
linked repositories you can access.
|
||||
@@ -865,9 +871,10 @@ const formatDateTime = (value: string): string => {
|
||||
<div
|
||||
v-for="repositoryBranch in visibleRepositoryBranches"
|
||||
:key="
|
||||
repositoryBranch.repository_connection.id
|
||||
repositoryBranch.repository_connection
|
||||
.id
|
||||
"
|
||||
class="rounded-xl border border-border px-4 py-4"
|
||||
class="border-border rounded-xl border px-4 py-4"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
@@ -889,7 +896,7 @@ const formatDateTime = (value: string): string => {
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="mt-2 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground mt-2 text-sm"
|
||||
>
|
||||
{{
|
||||
repositoryBranch
|
||||
@@ -906,14 +913,18 @@ const formatDateTime = (value: string): string => {
|
||||
class="mt-3 space-y-3"
|
||||
>
|
||||
<p
|
||||
class="text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
Connect a matching Git account in
|
||||
your user settings to inspect
|
||||
branches for this repository.
|
||||
</p>
|
||||
|
||||
<Button as-child variant="outline" size="sm">
|
||||
<Button
|
||||
as-child
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
<Link :href="editGitConnections()">
|
||||
Open Git connections
|
||||
</Link>
|
||||
@@ -927,7 +938,10 @@ const formatDateTime = (value: string): string => {
|
||||
{{ repositoryBranch.error }}
|
||||
</div>
|
||||
|
||||
<div v-else class="mt-3 flex flex-wrap gap-2">
|
||||
<div
|
||||
v-else
|
||||
class="mt-3 flex flex-wrap gap-2"
|
||||
>
|
||||
<Badge
|
||||
v-for="branch in repositoryBranch.branches"
|
||||
:key="branch.name"
|
||||
@@ -964,7 +978,7 @@ const formatDateTime = (value: string): string => {
|
||||
ticket: ticket.id,
|
||||
})
|
||||
"
|
||||
class="grid gap-4 rounded-xl border border-dashed border-border p-4"
|
||||
class="border-border grid gap-4 rounded-xl border border-dashed p-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
@@ -974,7 +988,7 @@ const formatDateTime = (value: string): string => {
|
||||
<select
|
||||
id="ticket_link_type_id"
|
||||
name="ticket_link_type_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="ticketLinkType in ticketLinkTypes"
|
||||
@@ -996,7 +1010,7 @@ const formatDateTime = (value: string): string => {
|
||||
<select
|
||||
id="linked_ticket_id"
|
||||
name="linked_ticket_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="ticketLinkOption in ticketLinkOptions"
|
||||
@@ -1013,17 +1027,14 @@ const formatDateTime = (value: string): string => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
:disabled="processing"
|
||||
>
|
||||
<Button type="submit" :disabled="processing">
|
||||
Save link
|
||||
</Button>
|
||||
</Form>
|
||||
|
||||
<div
|
||||
v-if="linkedTickets.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No ticket links are configured for this ticket
|
||||
yet.
|
||||
@@ -1033,9 +1044,11 @@ const formatDateTime = (value: string): string => {
|
||||
<div
|
||||
v-for="linkedTicket in linkedTickets"
|
||||
:key="linkedTicket.id"
|
||||
class="rounded-xl border border-border px-4 py-4"
|
||||
class="border-border rounded-xl border px-4 py-4"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Badge variant="secondary">
|
||||
{{
|
||||
linkedTicket.ticket_link_type
|
||||
@@ -1050,7 +1063,7 @@ const formatDateTime = (value: string): string => {
|
||||
.linked_ticket.id,
|
||||
})
|
||||
"
|
||||
class="font-medium text-foreground transition hover:text-primary"
|
||||
class="text-foreground hover:text-primary font-medium transition"
|
||||
>
|
||||
{{
|
||||
linkedTicket.linked_ticket
|
||||
@@ -1058,7 +1071,9 @@ const formatDateTime = (value: string): string => {
|
||||
}}
|
||||
</Link>
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-muted-foreground">
|
||||
<p
|
||||
class="text-muted-foreground mt-2 text-sm"
|
||||
>
|
||||
{{ linkedTicket.linked_ticket.title }}
|
||||
</p>
|
||||
|
||||
@@ -1069,8 +1084,7 @@ const formatDateTime = (value: string): string => {
|
||||
{
|
||||
project: project.id,
|
||||
ticket: ticket.id,
|
||||
ticketLink:
|
||||
linkedTicket.id,
|
||||
ticketLink: linkedTicket.id,
|
||||
},
|
||||
)
|
||||
"
|
||||
@@ -1106,7 +1120,7 @@ const formatDateTime = (value: string): string => {
|
||||
v-if="
|
||||
visibleRepositoryPullRequests.length === 0
|
||||
"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No matching pull requests were found across the
|
||||
linked repositories you can access.
|
||||
@@ -1119,7 +1133,7 @@ const formatDateTime = (value: string): string => {
|
||||
repositoryPullRequest
|
||||
.repository_connection.id
|
||||
"
|
||||
class="rounded-xl border border-border px-4 py-4"
|
||||
class="border-border rounded-xl border px-4 py-4"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
@@ -1141,7 +1155,7 @@ const formatDateTime = (value: string): string => {
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="mt-2 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground mt-2 text-sm"
|
||||
>
|
||||
{{
|
||||
repositoryPullRequest
|
||||
@@ -1158,14 +1172,18 @@ const formatDateTime = (value: string): string => {
|
||||
class="mt-3 space-y-3"
|
||||
>
|
||||
<p
|
||||
class="text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
Connect a matching Git account in
|
||||
your user settings to inspect pull
|
||||
requests for this repository.
|
||||
</p>
|
||||
|
||||
<Button as-child variant="outline" size="sm">
|
||||
<Button
|
||||
as-child
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
<Link :href="editGitConnections()">
|
||||
Open Git connections
|
||||
</Link>
|
||||
@@ -1183,7 +1201,7 @@ const formatDateTime = (value: string): string => {
|
||||
<div
|
||||
v-for="pullRequest in repositoryPullRequest.pull_requests"
|
||||
:key="pullRequest.html_url"
|
||||
class="rounded-xl border border-border/70 px-4 py-3"
|
||||
class="border-border/70 rounded-xl border px-4 py-3"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
@@ -1192,26 +1210,22 @@ const formatDateTime = (value: string): string => {
|
||||
#{{ pullRequest.number }}
|
||||
</Badge>
|
||||
<Badge variant="secondary">
|
||||
{{
|
||||
pullRequest.status
|
||||
}}
|
||||
{{ pullRequest.status }}
|
||||
</Badge>
|
||||
<a
|
||||
:href="pullRequest.html_url"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
class="font-medium text-foreground transition hover:text-primary"
|
||||
class="text-foreground hover:text-primary font-medium transition"
|
||||
>
|
||||
{{ pullRequest.title }}
|
||||
</a>
|
||||
</div>
|
||||
<p
|
||||
class="mt-2 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground mt-2 text-sm"
|
||||
>
|
||||
Source branch:
|
||||
{{
|
||||
pullRequest.source_branch
|
||||
}}
|
||||
{{ pullRequest.source_branch }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1232,7 +1246,7 @@ const formatDateTime = (value: string): string => {
|
||||
<CardContent>
|
||||
<div
|
||||
v-if="childTicketTree.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No child tickets are assigned to this ticket
|
||||
yet.
|
||||
@@ -1260,7 +1274,7 @@ const formatDateTime = (value: string): string => {
|
||||
v-if="
|
||||
(ticket.worklog_entries?.length ?? 0) === 0
|
||||
"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No worklog entries exist for this ticket yet.
|
||||
</div>
|
||||
@@ -1269,7 +1283,7 @@ const formatDateTime = (value: string): string => {
|
||||
<div
|
||||
v-for="worklogEntry in ticket.worklog_entries"
|
||||
:key="worklogEntry.id"
|
||||
class="rounded-xl border border-border px-4 py-4"
|
||||
class="border-border rounded-xl border px-4 py-4"
|
||||
>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
@@ -1278,7 +1292,7 @@ const formatDateTime = (value: string): string => {
|
||||
{{ worklogEntry.entry_type }}
|
||||
</Badge>
|
||||
<span
|
||||
class="text-sm font-medium text-foreground"
|
||||
class="text-foreground text-sm font-medium"
|
||||
>
|
||||
{{
|
||||
worklogEntry.actor?.name ??
|
||||
@@ -1286,11 +1300,11 @@ const formatDateTime = (value: string): string => {
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<p class="mt-3 text-sm text-foreground">
|
||||
<p class="text-foreground mt-3 text-sm">
|
||||
{{ worklogEntry.summary }}
|
||||
</p>
|
||||
<p
|
||||
class="mt-2 text-xs text-muted-foreground"
|
||||
class="text-muted-foreground mt-2 text-xs"
|
||||
>
|
||||
{{
|
||||
formatDateTime(
|
||||
|
||||
@@ -89,7 +89,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
|
||||
<CardContent class="flex flex-wrap gap-3">
|
||||
<Badge class="px-3 py-1">Backlog</Badge>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Tickets will later be valid only in backlog or in one of
|
||||
the ordered columns below.
|
||||
</p>
|
||||
@@ -148,7 +148,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<CardContent class="space-y-4 p-6">
|
||||
<div
|
||||
v-if="boardColumns.length === 0"
|
||||
class="text-sm text-muted-foreground"
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
No board columns exist yet.
|
||||
</div>
|
||||
@@ -156,7 +156,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="column in boardColumns"
|
||||
:key="column.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<Form
|
||||
v-bind="
|
||||
|
||||
@@ -105,7 +105,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
project.id,
|
||||
)
|
||||
"
|
||||
class="space-y-4 rounded-xl border border-dashed border-border p-4"
|
||||
class="border-border space-y-4 rounded-xl border border-dashed p-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
@@ -127,7 +127,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="ticketType in ticketTypes"
|
||||
:key="ticketType.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<Form
|
||||
v-bind="
|
||||
@@ -155,7 +155,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
}}
|
||||
</Badge>
|
||||
<p
|
||||
class="text-xs tracking-wide text-muted-foreground uppercase"
|
||||
class="text-muted-foreground text-xs uppercase tracking-wide"
|
||||
>
|
||||
Position {{ ticketType.position }}
|
||||
</p>
|
||||
@@ -243,7 +243,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
project.id,
|
||||
)
|
||||
"
|
||||
class="space-y-4 rounded-xl border border-dashed border-border p-4"
|
||||
class="border-border space-y-4 rounded-xl border border-dashed p-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
@@ -267,7 +267,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="ticketPriority in ticketPriorities"
|
||||
:key="ticketPriority.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<Form
|
||||
v-bind="
|
||||
@@ -361,7 +361,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
project.id,
|
||||
)
|
||||
"
|
||||
class="space-y-4 rounded-xl border border-dashed border-border p-4"
|
||||
class="border-border space-y-4 rounded-xl border border-dashed p-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
@@ -380,7 +380,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<select
|
||||
id="field-type"
|
||||
name="field_type"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="option in fieldTypeOptions"
|
||||
@@ -401,7 +401,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="fieldDefinition in ticketFieldDefinitions"
|
||||
:key="fieldDefinition.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<Form
|
||||
v-bind="
|
||||
@@ -436,7 +436,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<select
|
||||
:id="`field-type-${fieldDefinition.id}`"
|
||||
name="field_type"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="option in fieldTypeOptions"
|
||||
@@ -465,7 +465,9 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
type="number"
|
||||
min="1"
|
||||
:max="ticketFieldDefinitions.length"
|
||||
:default-value="fieldDefinition.position"
|
||||
:default-value="
|
||||
fieldDefinition.position
|
||||
"
|
||||
required
|
||||
/>
|
||||
<InputError :message="errors.position" />
|
||||
@@ -521,7 +523,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
project.id,
|
||||
)
|
||||
"
|
||||
class="space-y-4 rounded-xl border border-dashed border-border p-4"
|
||||
class="border-border space-y-4 rounded-xl border border-dashed p-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
@@ -545,7 +547,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="ticketLinkType in ticketLinkTypes"
|
||||
:key="ticketLinkType.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<Form
|
||||
v-bind="
|
||||
|
||||
@@ -47,7 +47,9 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
];
|
||||
|
||||
const selectableRepositorySources = computed(() =>
|
||||
props.availableRepositorySources.filter((source) => source.repositories.length > 0),
|
||||
props.availableRepositorySources.filter(
|
||||
(source) => source.repositories.length > 0,
|
||||
),
|
||||
);
|
||||
|
||||
const repositoryConnectionById = computed(
|
||||
@@ -271,7 +273,7 @@ const submitUpdate = (): void => {
|
||||
Open Git connections
|
||||
</Link>
|
||||
</Button>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Without a matching personal connection, KanbanGit only
|
||||
shows the repository name and links you to your user
|
||||
settings.
|
||||
@@ -293,7 +295,7 @@ const submitUpdate = (): void => {
|
||||
<CardContent>
|
||||
<div
|
||||
v-if="selectableRepositorySources.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
Add a personal Git connection first, or fix an
|
||||
existing connection that currently cannot load
|
||||
@@ -311,13 +313,17 @@ const submitUpdate = (): void => {
|
||||
</Label>
|
||||
<select
|
||||
id="create-user-git-connection"
|
||||
v-model="createForm.user_git_connection_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
v-model="
|
||||
createForm.user_git_connection_id
|
||||
"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="source in selectableRepositorySources"
|
||||
:key="source.user_git_connection_id"
|
||||
:value="source.user_git_connection_id"
|
||||
:value="
|
||||
source.user_git_connection_id
|
||||
"
|
||||
>
|
||||
{{
|
||||
`${source.provider_label} · ${source.account_login} @ ${source.base_url}`
|
||||
@@ -326,7 +332,8 @@ const submitUpdate = (): void => {
|
||||
</select>
|
||||
<InputError
|
||||
:message="
|
||||
createForm.errors.user_git_connection_id
|
||||
createForm.errors
|
||||
.user_git_connection_id
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@@ -340,7 +347,7 @@ const submitUpdate = (): void => {
|
||||
v-model="
|
||||
createForm.provider_repository_id
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="repository in createRepositories"
|
||||
@@ -358,7 +365,8 @@ const submitUpdate = (): void => {
|
||||
</select>
|
||||
<InputError
|
||||
:message="
|
||||
createForm.errors.provider_repository_id
|
||||
createForm.errors
|
||||
.provider_repository_id
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@@ -382,9 +390,9 @@ const submitUpdate = (): void => {
|
||||
<CardHeader>
|
||||
<CardTitle>Relink repository</CardTitle>
|
||||
<CardDescription>
|
||||
Update an existing project repository
|
||||
connection by choosing a different repository
|
||||
from one of your personal Git connections.
|
||||
Update an existing project repository connection
|
||||
by choosing a different repository from one of
|
||||
your personal Git connections.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
@@ -402,7 +410,7 @@ const submitUpdate = (): void => {
|
||||
v-model="
|
||||
updateForm.repository_connection_id
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="repositoryConnection in repositoryConnections"
|
||||
@@ -422,13 +430,17 @@ const submitUpdate = (): void => {
|
||||
</Label>
|
||||
<select
|
||||
id="update-user-git-connection"
|
||||
v-model="updateForm.user_git_connection_id"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
v-model="
|
||||
updateForm.user_git_connection_id
|
||||
"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="source in selectableRepositorySources"
|
||||
:key="source.user_git_connection_id"
|
||||
:value="source.user_git_connection_id"
|
||||
:value="
|
||||
source.user_git_connection_id
|
||||
"
|
||||
>
|
||||
{{
|
||||
`${source.provider_label} · ${source.account_login} @ ${source.base_url}`
|
||||
@@ -437,7 +449,8 @@ const submitUpdate = (): void => {
|
||||
</select>
|
||||
<InputError
|
||||
:message="
|
||||
updateForm.errors.user_git_connection_id
|
||||
updateForm.errors
|
||||
.user_git_connection_id
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@@ -451,7 +464,7 @@ const submitUpdate = (): void => {
|
||||
v-model="
|
||||
updateForm.provider_repository_id
|
||||
"
|
||||
class="rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="repository in updateRepositories"
|
||||
@@ -469,7 +482,8 @@ const submitUpdate = (): void => {
|
||||
</select>
|
||||
<InputError
|
||||
:message="
|
||||
updateForm.errors.provider_repository_id
|
||||
updateForm.errors
|
||||
.provider_repository_id
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@@ -500,7 +514,7 @@ const submitUpdate = (): void => {
|
||||
<CardContent class="space-y-4 p-6">
|
||||
<div
|
||||
v-if="repositoryConnections.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No repositories are linked to this project yet.
|
||||
</div>
|
||||
@@ -508,20 +522,24 @@ const submitUpdate = (): void => {
|
||||
<div
|
||||
v-for="repositoryConnection in repositoryConnections"
|
||||
:key="repositoryConnection.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"
|
||||
>
|
||||
<div class="space-y-2">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
>
|
||||
<Badge>
|
||||
{{
|
||||
repositoryConnection.provider_label
|
||||
}}
|
||||
</Badge>
|
||||
<Badge variant="secondary">
|
||||
{{ repositoryConnection.base_url }}
|
||||
{{
|
||||
repositoryConnection.base_url
|
||||
}}
|
||||
</Badge>
|
||||
</div>
|
||||
<div>
|
||||
@@ -530,7 +548,9 @@ const submitUpdate = (): void => {
|
||||
repositoryConnection.repository_full_name
|
||||
}}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
{{
|
||||
repositoryConnection.repository_name
|
||||
}}
|
||||
@@ -574,8 +594,10 @@ const submitUpdate = (): void => {
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="!repositoryConnection.has_personal_access"
|
||||
class="mt-3 text-sm text-muted-foreground"
|
||||
v-if="
|
||||
!repositoryConnection.has_personal_access
|
||||
"
|
||||
class="text-muted-foreground mt-3 text-sm"
|
||||
>
|
||||
This project link is visible, but you need a
|
||||
matching Git connection in your user
|
||||
@@ -625,14 +647,14 @@ const submitUpdate = (): void => {
|
||||
<div
|
||||
v-for="source in availableRepositorySources"
|
||||
:key="source.user_git_connection_id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Badge>{{ source.provider_label }}</Badge>
|
||||
<span class="text-sm font-medium">
|
||||
{{ source.account_login }}
|
||||
</span>
|
||||
<span class="text-xs text-muted-foreground">
|
||||
<span class="text-muted-foreground text-xs">
|
||||
{{ source.base_url }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -646,10 +668,11 @@ const submitUpdate = (): void => {
|
||||
|
||||
<p
|
||||
v-else
|
||||
class="mt-3 text-sm text-muted-foreground"
|
||||
class="text-muted-foreground mt-3 text-sm"
|
||||
>
|
||||
{{ source.repositories.length }} repositories
|
||||
available through this connection.
|
||||
{{ source.repositories.length }}
|
||||
repositories available through this
|
||||
connection.
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
@@ -41,7 +41,7 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
title="Git connections"
|
||||
description="Add your personal Git provider credentials here. Project repository links will use these connections to fetch repositories, branches, and pull requests you can access."
|
||||
/>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Each user needs their own application key. Without a
|
||||
matching personal connection, KanbanGit can only show
|
||||
repository names and will link you back to this page.
|
||||
@@ -71,7 +71,11 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
class="space-y-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<input name="provider" type="hidden" value="gitea" />
|
||||
<input
|
||||
name="provider"
|
||||
type="hidden"
|
||||
value="gitea"
|
||||
/>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="base_url">Gitea base URL</Label>
|
||||
@@ -87,7 +91,9 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="api_token">Application token</Label>
|
||||
<Label for="api_token"
|
||||
>Application token</Label
|
||||
>
|
||||
<Input
|
||||
id="api_token"
|
||||
name="api_token"
|
||||
@@ -117,7 +123,7 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
<CardContent class="space-y-4 p-6">
|
||||
<div
|
||||
v-if="gitConnections.length === 0"
|
||||
class="rounded-xl border border-dashed border-border px-4 py-6 text-sm text-muted-foreground"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No Git connections have been added yet.
|
||||
</div>
|
||||
@@ -125,30 +131,40 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
<div
|
||||
v-for="gitConnection in gitConnections"
|
||||
:key="gitConnection.id"
|
||||
class="rounded-xl border border-border p-4"
|
||||
class="border-border rounded-xl border p-4"
|
||||
>
|
||||
<div
|
||||
class="mb-4 flex flex-wrap items-start justify-between gap-3"
|
||||
>
|
||||
<div class="space-y-1">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Badge>{{ gitConnection.provider_label }}</Badge>
|
||||
<div
|
||||
class="flex flex-wrap items-center gap-2"
|
||||
>
|
||||
<Badge>{{
|
||||
gitConnection.provider_label
|
||||
}}</Badge>
|
||||
<span class="text-sm font-medium">
|
||||
{{ gitConnection.account_login }}
|
||||
{{
|
||||
gitConnection.account_login
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p
|
||||
class="text-muted-foreground text-sm"
|
||||
>
|
||||
{{
|
||||
gitConnection.account_name ??
|
||||
'Unnamed remote account'
|
||||
}}
|
||||
</p>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
<p
|
||||
class="text-muted-foreground text-xs"
|
||||
>
|
||||
{{ gitConnection.base_url }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p class="text-xs text-muted-foreground">
|
||||
<p class="text-muted-foreground text-xs">
|
||||
Remote user ID:
|
||||
{{ gitConnection.provider_user_id }}
|
||||
</p>
|
||||
@@ -170,21 +186,29 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
/>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label :for="`base-url-${gitConnection.id}`">
|
||||
<Label
|
||||
:for="`base-url-${gitConnection.id}`"
|
||||
>
|
||||
Gitea base URL
|
||||
</Label>
|
||||
<Input
|
||||
:id="`base-url-${gitConnection.id}`"
|
||||
name="base_url"
|
||||
type="url"
|
||||
:default-value="gitConnection.base_url"
|
||||
:default-value="
|
||||
gitConnection.base_url
|
||||
"
|
||||
required
|
||||
/>
|
||||
<InputError :message="errors.base_url" />
|
||||
<InputError
|
||||
:message="errors.base_url"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label :for="`token-${gitConnection.id}`">
|
||||
<Label
|
||||
:for="`token-${gitConnection.id}`"
|
||||
>
|
||||
New application token
|
||||
</Label>
|
||||
<Input
|
||||
@@ -194,10 +218,14 @@ const breadcrumbItems: BreadcrumbItem[] = [
|
||||
required
|
||||
placeholder="Paste a new token to verify and save"
|
||||
/>
|
||||
<InputError :message="errors.api_token" />
|
||||
<InputError
|
||||
:message="errors.api_token"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap justify-between gap-3">
|
||||
<div
|
||||
class="flex flex-wrap justify-between gap-3"
|
||||
>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="outline"
|
||||
|
||||
@@ -81,12 +81,12 @@ const user = computed(() => page.props.auth.user);
|
||||
</div>
|
||||
|
||||
<div v-if="mustVerifyEmail && !user.email_verified_at">
|
||||
<p class="-mt-4 text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground -mt-4 text-sm">
|
||||
Your email address is unverified.
|
||||
<Link
|
||||
:href="send()"
|
||||
as="button"
|
||||
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
|
||||
class="text-foreground hover:decoration-current! underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out dark:decoration-neutral-500"
|
||||
>
|
||||
Click here to resend the verification email.
|
||||
</Link>
|
||||
|
||||
@@ -144,7 +144,7 @@ onUnmounted(() => clearTwoFactorAuthData());
|
||||
v-if="!twoFactorEnabled"
|
||||
class="flex flex-col items-start justify-start space-y-4"
|
||||
>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
When you enable two-factor authentication, you will be
|
||||
prompted for a secure pin during login. This pin can be
|
||||
retrieved from a TOTP-supported application on your
|
||||
@@ -175,7 +175,7 @@ onUnmounted(() => clearTwoFactorAuthData());
|
||||
v-else
|
||||
class="flex flex-col items-start justify-start space-y-4"
|
||||
>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
You will be prompted for a secure, random pin during
|
||||
login, which you can retrieve from the TOTP-supported
|
||||
application on your phone.
|
||||
|
||||
@@ -137,7 +137,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
:id="`team-members-${team.id}`"
|
||||
name="user_ids[]"
|
||||
multiple
|
||||
class="min-h-44 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 min-h-44 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px]"
|
||||
>
|
||||
<option
|
||||
v-for="user in users"
|
||||
@@ -150,7 +150,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
{{ user.name }} ({{ user.email }})
|
||||
</option>
|
||||
</select>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
Hold Cmd or Ctrl to select multiple
|
||||
users.
|
||||
</p>
|
||||
@@ -168,7 +168,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
</Card>
|
||||
|
||||
<Card v-if="teams.length === 0">
|
||||
<CardContent class="p-6 text-sm text-muted-foreground">
|
||||
<CardContent class="text-muted-foreground p-6 text-sm">
|
||||
No teams exist yet.
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Vendored
+2
@@ -1,4 +1,6 @@
|
||||
import type { Auth } from '@/types/auth';
|
||||
import type { Page, Router } from '@inertiajs/core';
|
||||
import { createHeadManager } from '@inertiajs/vue3';
|
||||
|
||||
// Extend ImportMeta interface for Vite...
|
||||
declare module 'vite/client' {
|
||||
|
||||
Reference in New Issue
Block a user