codex/permissions-refactoring #26
@@ -6,8 +6,6 @@
|
||||
"build": "vite build",
|
||||
"build:ssr": "vite build && vite build --ssr",
|
||||
"dev": "vite",
|
||||
"format": "prettier --write resources/",
|
||||
"format:check": "prettier --check resources/",
|
||||
"lint": "eslint . --fix",
|
||||
"lint:check": "eslint .",
|
||||
"types:check": "vue-tsc --noEmit"
|
||||
|
||||
@@ -71,7 +71,9 @@ const hasPermission = (actorId: number, permission: string) =>
|
||||
</div>
|
||||
|
||||
<div v-else class="overflow-x-auto">
|
||||
<table class="divide-border min-w-full divide-y text-sm">
|
||||
<table
|
||||
class="divide-border min-w-full divide-y text-sm"
|
||||
>
|
||||
<thead
|
||||
class="bg-muted/40 text-muted-foreground text-left"
|
||||
>
|
||||
@@ -95,7 +97,9 @@ const hasPermission = (actorId: number, permission: string) =>
|
||||
class="bg-background align-top"
|
||||
>
|
||||
<td class="px-4 py-4">
|
||||
<div class="text-foreground font-medium">
|
||||
<div
|
||||
class="text-foreground font-medium"
|
||||
>
|
||||
{{ user.name }}
|
||||
</div>
|
||||
</td>
|
||||
@@ -131,9 +135,11 @@ const hasPermission = (actorId: number, permission: string) =>
|
||||
</Badge>
|
||||
<span
|
||||
v-if="
|
||||
(directPermissions[
|
||||
user.id
|
||||
] ?? []).length === 0
|
||||
(
|
||||
directPermissions[
|
||||
user.id
|
||||
] ?? []
|
||||
).length === 0
|
||||
"
|
||||
class="text-muted-foreground"
|
||||
>
|
||||
@@ -154,9 +160,7 @@ const hasPermission = (actorId: number, permission: string) =>
|
||||
>
|
||||
<label
|
||||
v-for="option in permissionOptions"
|
||||
:key="
|
||||
`${user.id}-${option.value}`
|
||||
"
|
||||
:key="`${user.id}-${option.value}`"
|
||||
class="border-border inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm"
|
||||
>
|
||||
<input
|
||||
@@ -171,7 +175,9 @@ const hasPermission = (actorId: number, permission: string) =>
|
||||
"
|
||||
class="border-input text-primary focus:ring-ring size-4 rounded"
|
||||
/>
|
||||
<span>{{ option.label }}</span>
|
||||
<span>{{
|
||||
option.label
|
||||
}}</span>
|
||||
</label>
|
||||
|
||||
<div class="w-full sm:hidden" />
|
||||
|
||||
@@ -38,7 +38,10 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
description="Create and browse project spaces that will later host boards, backlog, and settings."
|
||||
/>
|
||||
|
||||
<Button v-if="$page.props.auth.permissions.projectCreate" as-child>
|
||||
<Button
|
||||
v-if="$page.props.auth.permissions.projectCreate"
|
||||
as-child
|
||||
>
|
||||
<Link :href="create()">
|
||||
<Plus class="size-4" />
|
||||
New project
|
||||
|
||||
@@ -22,10 +22,7 @@ import {
|
||||
metadata as metadataSettings,
|
||||
repositories as repositorySettings,
|
||||
} from '@/routes/projects/settings';
|
||||
import type {
|
||||
BreadcrumbItem,
|
||||
ProjectGeneralSettingsPageProps,
|
||||
} from '@/types';
|
||||
import type { BreadcrumbItem, ProjectGeneralSettingsPageProps } from '@/types';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps<ProjectGeneralSettingsPageProps>();
|
||||
@@ -124,24 +121,24 @@ const submitDelete = (): void => {
|
||||
</CardHeader>
|
||||
|
||||
<CardContent class="grid gap-4 md:grid-cols-2">
|
||||
<div class="rounded-xl border border-border/70 p-4">
|
||||
<div class="border-border/70 rounded-xl border p-4">
|
||||
<p
|
||||
class="text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground"
|
||||
class="text-muted-foreground text-xs font-semibold uppercase tracking-[0.18em]"
|
||||
>
|
||||
Project name
|
||||
</p>
|
||||
<p class="mt-2 text-sm font-semibold text-foreground">
|
||||
<p class="text-foreground mt-2 text-sm font-semibold">
|
||||
{{ project.name }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-border/70 p-4">
|
||||
<div class="border-border/70 rounded-xl border p-4">
|
||||
<p
|
||||
class="text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground"
|
||||
class="text-muted-foreground text-xs font-semibold uppercase tracking-[0.18em]"
|
||||
>
|
||||
Project key
|
||||
</p>
|
||||
<p class="mt-2 text-sm font-semibold text-foreground">
|
||||
<p class="text-foreground mt-2 text-sm font-semibold">
|
||||
{{ project.key }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -166,9 +163,9 @@ const submitDelete = (): void => {
|
||||
|
||||
<CardContent class="space-y-5">
|
||||
<div
|
||||
class="rounded-xl border border-red-200/80 bg-background/80 p-4 dark:border-red-900/60"
|
||||
class="bg-background/80 rounded-xl border border-red-200/80 p-4 dark:border-red-900/60"
|
||||
>
|
||||
<p class="text-sm font-medium text-foreground">
|
||||
<p class="text-foreground text-sm font-medium">
|
||||
Confirm by typing the exact project key:
|
||||
<span class="font-semibold">{{ project.key }}</span>
|
||||
</p>
|
||||
@@ -193,7 +190,7 @@ const submitDelete = (): void => {
|
||||
<div
|
||||
class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
|
||||
>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<p class="text-muted-foreground text-sm">
|
||||
This action cannot be undone.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -53,11 +53,7 @@ const permissionsForTeam = (teamId: number): Record<string, string[]> =>
|
||||
|
||||
<Badge variant="outline" class="gap-1.5 px-3 py-1">
|
||||
<Shield class="size-3.5" />
|
||||
{{
|
||||
canCreateTeams
|
||||
? 'Global admin'
|
||||
: 'Team-scoped access'
|
||||
}}
|
||||
{{ canCreateTeams ? 'Global admin' : 'Team-scoped access' }}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -254,9 +250,7 @@ const permissionsForTeam = (teamId: number): Record<string, string[]> =>
|
||||
option.value,
|
||||
)
|
||||
"
|
||||
:key="
|
||||
`${team.id}-${user.id}-${option.value}-badge`
|
||||
"
|
||||
:key="`${team.id}-${user.id}-${option.value}-badge`"
|
||||
variant="secondary"
|
||||
>
|
||||
{{ option.label }}
|
||||
@@ -266,8 +260,9 @@ const permissionsForTeam = (teamId: number): Record<string, string[]> =>
|
||||
(
|
||||
permissionsForTeam(
|
||||
team.id,
|
||||
)[user.id] ??
|
||||
[]
|
||||
)[
|
||||
user.id
|
||||
] ?? []
|
||||
).length === 0
|
||||
"
|
||||
class="text-muted-foreground"
|
||||
@@ -297,9 +292,7 @@ const permissionsForTeam = (teamId: number): Record<string, string[]> =>
|
||||
>
|
||||
<label
|
||||
v-for="option in permissionOptions"
|
||||
:key="
|
||||
`${team.id}-${user.id}-${option.value}`
|
||||
"
|
||||
:key="`${team.id}-${user.id}-${option.value}`"
|
||||
class="border-border inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm"
|
||||
>
|
||||
<input
|
||||
@@ -353,8 +346,7 @@ const permissionsForTeam = (teamId: number): Record<string, string[]> =>
|
||||
|
||||
<Card v-if="teams.length === 0">
|
||||
<CardContent class="text-muted-foreground p-6 text-sm">
|
||||
No teams are available for your current
|
||||
permissions.
|
||||
No teams are available for your current permissions.
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user