feat: onglets Réglages & Aide + icône Gitea

Réglages : préférences (langue, notifications push + test), gestion complète des tokens d'accès (liste/création/révocation, garde anti lock-out sur le dernier token), URL Gitea configurable, infos serveur en lecture seule (port/bind/origines/VAPID + flags CLI). Aide : documentation bilingue EN/FR de toutes les fonctionnalités, avec recherche. Icône Gitea (lien externe) dans la nav (sidebar + MoreSheet mobile).

Backend : routes /api/v1/auth/tokens (GET/POST/DELETE) + tokenId dans /me ; routes/settings.ts (GET/PATCH, allow-list stricte gitea_url, aucun secret exposé, URL validée http/https anti-XSS) ; AuthService.listTokens/revokeToken (transaction). Front : NavItem gère les liens externes, nav primaire/secondaire, store settings, vues SettingsView/HelpView.

236 tests verts (+15 nouveaux : auth-tokens, settings-routes).
This commit is contained in:
2026-06-18 14:16:53 +02:00
parent 5c1c2a8591
commit c9670ca309
23 changed files with 1469 additions and 24 deletions

View File

@@ -1,7 +1,12 @@
<template>
<RouterLink
:to="to"
:aria-current="active ? 'page' : undefined"
<!-- RouterLink pour une route interne ; <a target=_blank> pour un lien externe (ex. Gitea). -->
<component
:is="href ? 'a' : RouterLink"
:to="href ? undefined : to"
:href="href"
:target="href ? '_blank' : undefined"
:rel="href ? 'noopener noreferrer' : undefined"
:aria-current="!href && active ? 'page' : undefined"
:class="orientation === 'col' ? colClass : rowClass"
>
<span class="relative">
@@ -20,16 +25,19 @@
>
{{ badge }}
</span>
</RouterLink>
</component>
</template>
<script setup lang="ts">
import { computed, type Component } from 'vue';
import type { RouteLocationRaw } from 'vue-router';
import { RouterLink, type RouteLocationRaw } from 'vue-router';
const props = withDefaults(
defineProps<{
to: RouteLocationRaw;
// `| undefined` requis par exactOptionalPropertyTypes : les items de nav passent `to`/`href`
// potentiellement undefined (l'un ou l'autre selon route interne vs lien externe).
to?: RouteLocationRaw | undefined;
href?: string | undefined;
icon: Component;
label: string;
badge?: number;