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