feat: roles SPA foundations

This commit is contained in:
Florian Sylvain committed 2026-10-27 22:21:12 +01:00
1 parent 80f7037d3a
commit 907949aa12
180 files changed
+4308 -835

No files matched your search

+15 -44
View File
@@ -8,6 +8,7 @@ import AuthorStack from '@/components/AuthorStack.vue'
import { authorsSummary } from '@/lib/articleMeta'
import { formatRelativeDate } from '@/lib/relativeDate'
import type { Article } from '@/composables/useArticles'
import { useArticleMenu } from '@/composables/useArticleMenu'
import { seoChipOf } from '@/lib/articleSeoStatus'
const props = withDefaults(
@@ -45,50 +46,14 @@ function pendingFor(article: Article) {
return article.is_online ? ('unpublish' as const) : ('publish' as const)
}
function actionsFor(article: Article) {
return [
[
{
get label() {
return t('Edit')
},
icon: 'i-lucide-pencil',
onSelect: () => router.push(editPath(article)),
},
{
get label() {
return article.is_online ? t('Unpublish') : t('Publish')
},
icon: article.is_online ? 'i-lucide-globe-lock' : 'i-lucide-globe',
disabled: isBusy(article),
onSelect: () => {
if (article.is_online) {
emit('unpublish', article.id)
} else {
emit('publish', article.id)
}
},
},
{
get label() {
return t('Copy API URL')
},
icon: 'i-lucide-link',
onSelect: () => emit('copy-url', article.id),
},
],
[
{
get label() {
return t('Delete…')
},
icon: 'i-lucide-trash-2',
color: 'error' as const,
onSelect: () => emit('delete', article),
},
],
]
}
const { actionsFor, publishHint } = useArticleMenu({
isBusy,
edit: (article) => router.push(editPath(article)),
publish: (id) => emit('publish', id),
unpublish: (id) => emit('unpublish', id),
copyUrl: (id) => emit('copy-url', id),
remove: (article) => emit('delete', article),
})
function onRowClick(article: Article, event: MouseEvent) {
if ((event.target as HTMLElement).closest('[data-row-menu]')) {
@@ -139,6 +104,12 @@ function onRowClick(article: Article, event: MouseEvent) {
size="sm"
:pending="pendingFor(article)"
/>
<span
v-if="publishHint(article)"
class="sr-only"
data-testid="publish-hint"
>{{ publishHint(article) }}</span
>
<SeoStatusChip
v-if="seoChipOf(article)"
:chip="seoChipOf(article)!"