feat: mirror v-can guard chains

This commit is contained in:
stanig2106
2025-11-14 19:23:18 +01:00
parent 2c4fe3f353
commit 7d823307fa
16 changed files with 573 additions and 138 deletions

View File

@@ -1,15 +1,26 @@
<template>
<main class="page">
<div v-can="can.baz.dskj">
foo.bar
</div>
<div v-cannot>
cannot
</div>
<section class="card">
<h1>`v-can` example</h1>
<div v-if="phase === 'draft'" v-can="can.foo.bar" class="block">
Draft branch
</div>
<div v-else-if="phase === 'pending'" class="block">
Pending branch
</div>
<div v-else class="block">
Fallback branch
</div>
<div v-cannot class="denied">
Missing `can.foo.bar` permission
</div>
</section>
</main>
</template>
<script setup lang="ts">
const phase = 'pending'
</script>
<style scoped>
@@ -18,66 +29,23 @@
font-family: system-ui, sans-serif;
}
header {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 1rem;
}
section {
margin-top: 1.5rem;
.card {
border: 1px solid #e2e8f0;
border-radius: 0.5rem;
padding: 1rem;
padding: 1.5rem;
background: #fff;
max-width: 32rem;
}
.card h2 {
margin-top: 0;
}
button {
margin-right: 0.75rem;
}
.ghost {
background: transparent;
border: 1px solid #cbd5f5;
padding: 0.35rem 0.75rem;
border-radius: 999px;
cursor: pointer;
}
.toggle {
display: inline-flex;
gap: 0.35rem;
align-items: center;
margin-top: 0.75rem;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
display: flex;
justify-content: space-between;
padding: 0.25rem 0;
border-bottom: 1px solid #edf2f7;
}
li:last-child {
border-bottom: 0;
}
.allowed {
color: #15803d;
.block {
border: 1px dashed #cbd5f5;
border-radius: 0.5rem;
padding: 0.75rem;
margin-block: 0.5rem;
}
.denied {
margin-top: 1rem;
color: #b91c1c;
}
</style>

View File

@@ -1,4 +1,4 @@
export function __can__(path: string[]) {
export function __can__(...path: string[]) {
const key = path.join('.')
const allowed = new Set([
'employee.view',
@@ -8,5 +8,5 @@ export function __can__(path: string[]) {
const granted = allowed.has(key)
console.log('Checking permission:', key, '->', granted)
return granted
return false
}