Mise en place d'un installeur pour la version bureau sans passer par Docker.
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Build & Push Images / build (brain) (push) Successful in 1m25s
Build & Push Images / build (core) (push) Successful in 2m55s
Build & Push Images / build (web) (push) Successful in 1m49s
Build & Push Images / build-switcher (push) Successful in 39s

Permet d'utiliser Loremind sans passer par Docker et sans lancer tous les conteneurs
Passage en v0.15.0
This commit is contained in:
2026-06-17 18:04:33 +02:00
parent f1c68634f7
commit 48baa08cfb
26 changed files with 1832 additions and 20 deletions

4
web/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "loremind-web",
"version": "0.14.0-beta",
"version": "0.15.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "loremind-web",
"version": "0.14.0-beta",
"version": "0.15.0",
"dependencies": {
"@angular/animations": "^21.2.16",
"@angular/common": "^21.2.16",

View File

@@ -1,6 +1,6 @@
{
"name": "loremind-web",
"version": "0.14.0-beta",
"version": "0.15.0",
"description": "LoreMind Frontend - Angular",
"scripts": {
"ng": "ng",

View File

@@ -1,6 +1,5 @@
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { LanguageService } from '../services/language.service';
import { STORAGE_KEY } from '../services/language.service';
/**
* Ajoute l'entête `X-User-Language` (langue choisie dans l'UI : `fr`/`en`) à
@@ -9,10 +8,27 @@ import { LanguageService } from '../services/language.service';
*
* NB : les appels SSE en `fetch()` (chat, imports, notebooks) ne passent PAS par
* les intercepteurs Angular — ils ajoutent l'entête manuellement de leur côté.
*
* IMPORTANT — on lit la langue directement depuis localStorage et NON via
* LanguageService/TranslateService. Injecter ces services ici créerait une
* dépendance circulaire fatale au démarrage : provideTranslateService charge la
* langue de repli (`fr.json`) PENDANT la construction de TranslateService ; cette
* requête passe par cet intercepteur ; si l'intercepteur injectait LanguageService
* (qui injecte TranslateService, en cours de construction) → cycle → la requête
* `fr.json` échoue → ngx-translate marque `fr` comme chargé-mais-vide → toutes les
* clés s'affichent brutes (l'anglais, n'étant pas la langue de repli, se chargeait
* après la construction et fonctionnait). localStorage est de toute façon la
* source de vérité (persistée par LanguageService.use()).
*/
export const languageInterceptor: HttpInterceptorFn = (req, next) => {
const language = inject(LanguageService);
return next(
req.clone({ setHeaders: { 'X-User-Language': language.current } })
);
let language = 'fr';
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
language = stored;
}
} catch {
// localStorage indisponible (mode privé strict) : on garde le défaut.
}
return next(req.clone({ setHeaders: { 'X-User-Language': language } }));
};

View File

@@ -22,7 +22,13 @@ export interface AppLanguage {
flag: string;
}
const STORAGE_KEY = 'loremind.lang';
/**
* Clé localStorage du choix de langue (par appareil). Exportée pour que le
* languageInterceptor lise la langue SANS injecter LanguageService/TranslateService
* (sinon dépendance circulaire au démarrage : le chargement initial de la langue
* de repli passe par l'intercepteur pendant la construction de TranslateService).
*/
export const STORAGE_KEY = 'loremind.lang';
@Injectable({ providedIn: 'root' })
export class LanguageService {