kavaa-kcge-ui-angular
v0.0.2
Published
UI Kit Angular standalone pour intégrer le Kavaa Committee Governance Engine dans une application front-end Angular.
Readme
kavaa-kcge-ui-angular
UI Kit Angular standalone pour intégrer le Kavaa Committee Governance Engine dans une application front-end Angular.
Le package expose des composants Angular Material et des tables Kendo Grid par défaut qui consomment les contrats de kavaa-kcge-viewmodels. Il ne contient pas d'appel backend direct, pas de HttpClient dans les composants visuels, pas de recalcul local du quorum, pas de recalcul de décision et pas d'inférence de droits depuis un rôle front. L'application hôte fournit les données via KCGE_WORKSPACE_CONTEXT, reçoit les intentions utilisateur, appelle ses APIs KCGE/KMME/DCE/KFE-L, puis recharge le workspace.
Sommaire
- Architecture
- Installation
- Configuration Angular
- Styles, Material et icônes
- Provider hôte
- Intégration rapide
- Composants publics
- Entrypoint de test
- Mapping API recommandé
- Développement dans ce monorepo
- Dépannage
- Checklist d'intégration
Architecture
Le kit est composé de trois couches.
| Couche | Responsabilité |
| --- | --- |
| kavaa-kcge-viewmodels | Types purs: comités, sessions, agenda, présence, vote, décision, PV, audit et contrats d'intention. |
| kavaa-kcge-ui-angular | Composants Angular standalone, rendu Material, formulaires, tableaux, badges, tri/pagination locale et émissions d'intentions. |
| Application hôte | Provider, appels HTTP, sécurité, droits, navigation, adaptation DTO, refresh et intégrations backend. |
Flux standard:
- Le host implémente
IKcgeWorkspaceContext. - Le host enregistre ce provider via
KCGE_WORKSPACE_CONTEXT. kavaa-committee-session-workspaceappellectx.load(...).- Le host retourne un
CommitteeSessionWorkspaceViewModel. - Les composants affichent le workspace.
- L'utilisateur déclenche une action.
- Le composant émet une intention ou appelle une méthode du provider.
- Le provider appelle l'API hôte correspondante.
- Le workspace est rechargé après mutation.
Règle d'or: le UI Kit affiche un contrat et émet des intentions; le host orchestre le métier.
Installation
Depuis le registre npm configuré
Le package dépend de kavaa-kcge-viewmodels et de peers Angular/Material.
npm install kavaa-kcge-viewmodels kavaa-kcge-ui-angular @angular/localize \
@progress/kendo-angular-grid @progress/kendo-data-query @progress/kendo-theme-defaultPeers attendus:
| Package | Version |
| --- | --- |
| @angular/core | ^20.3.0 |
| @angular/common | ^20.3.0 |
| @angular/forms | ^20.3.0 |
| @angular/localize | ^20.3.0 |
| @angular/cdk | ^20.2.0 |
| @angular/material | ^20.2.0 |
| kavaa-kcge-viewmodels | 0.0.2 |
| @progress/kendo-angular-grid | ^24.1.0 |
| @progress/kendo-data-query | ^1.7.3 |
| @progress/kendo-theme-default | ^14.1.0 |
| rxjs | ^7.8.0 |
Dépannage installation Azure Artifacts
Si npm install renvoie 401:
- le PAT est absent, expiré ou invalide;
- le PAT n'a pas la permission Packaging;
- le
.npmrcutilisateur n'a pas été généré; - l'utilisateur Azure DevOps n'a pas accès au feed.
Si npm install renvoie 404:
- l'URL du registry n'est pas celle de
Artifacts > Kavaa_Feed > Connect to feed > npm; - le package n'a pas encore été publié;
- l'utilisateur n'a pas le rôle requis sur le feed.
Après correction:
npm install kavaa-kcge-viewmodels kavaa-kcge-ui-angularDans ce monorepo Nx
Les imports locaux sont résolus par tsconfig.base.json:
{
"paths": {
"kavaa-kcge-viewmodels": ["./libs/kcge-viewmodels/src/index.ts"],
"kavaa-kcge-ui-angular": ["./libs/kcge-ui-angular/src/index.ts"],
"kavaa-kcge-ui-angular/testing": ["./libs/kcge-ui-angular/testing/src/index.ts"]
}
}Configuration Angular
Le package est standalone-first. Ne pas importer de module Angular KcgeUiAngularModule: il n'existe pas et ne doit pas être recréé. Importez les composants directement dans le tableau imports.
Configuration minimale recommandée:
import { provideHttpClient } from '@angular/common/http';
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideRouter } from '@angular/router';
import { KCGE_WORKSPACE_CONTEXT } from 'kavaa-kcge-ui-angular';
import { appRoutes } from './app.routes';
import { CdcKcgeWorkspaceProvider } from './providers/cdc-kcge-workspace-provider';
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideZoneChangeDetection({ eventCoalescing: true }),
provideAnimationsAsync(),
provideRouter(appRoutes),
provideHttpClient(),
CdcKcgeWorkspaceProvider,
{
provide: KCGE_WORKSPACE_CONTEXT,
useExisting: CdcKcgeWorkspaceProvider
}
]
};Exemple de page standalone:
import { Component } from '@angular/core';
import { CommitteeSessionWorkspaceComponent } from 'kavaa-kcge-ui-angular';
@Component({
selector: 'cdc-kcge-session-page',
standalone: true,
imports: [CommitteeSessionWorkspaceComponent],
templateUrl: './cdc-kcge-session-page.html'
})
export class CdcKcgeSessionPage {}Template:
<kavaa-committee-session-workspace
sessionId="SES-CDC-TN-001"
mode="voter"
[loading]="false"
[error]="null"
(intentEmitted)="handleKcgeIntent($event)"
(downloadRequested)="downloadMinutes($event.url)"
/>Styles, Material et icônes
Le kit publie ses tokens adaptatifs et ses styles globaux:
src/lib/tokens/kcge-tokens.css
src/styles/kcge-material-overrides.scssDans une application Angular, ajoutez un thème Kendo, puis les tokens et les overrides KCGE. Si l'application hôte charge déjà un thème Kendo compatible, ne chargez pas une deuxième fois le thème Default:
{
"styles": [
"node_modules/@progress/kendo-theme-default/scss/all.scss",
"node_modules/kavaa-kcge-ui-angular/src/lib/tokens/kcge-tokens.css",
"node_modules/kavaa-kcge-ui-angular/src/styles/kcge-material-overrides.scss",
"src/styles.scss"
]
}Dans ce monorepo, le chemin source peut être utilisé:
{
"styles": [
"libs/kcge-ui-angular/src/lib/tokens/kcge-tokens.css",
"libs/kcge-ui-angular/src/styles/kcge-material-overrides.scss",
"apps/cdc-kcge-test/src/styles.scss"
]
}Les composants lisent d'abord les variables de l'application hôte, puis utilisent les valeurs KCGE neutres comme fallback. Les familles reconnues incluent --app-*, --Kavaa-*, --CdcCarthage-*, --dce-* et les tokens Material --mat-sys-*. Les deux Kendo Grid remappent également les tokens --kendo-* à la charte résolue par KCGE.
Pour une surcharge directe ou un thème scoped, définissez les variables --kcge-* dans l'application hôte:
.theme-cdc {
--kcge-primary: var(--brand-primary);
--kcge-accent: var(--brand-accent);
--kcge-surface: var(--surface-card);
--kcge-text: var(--text-primary);
--kcge-border: var(--border-subtle);
}Le style KCGE est inspiré de SIFCOM:
| Token | Usage |
| --- | --- |
| --kcge-primary | Marque principale, proche #933835. |
| --kcge-accent | Accent secondaire, proche #0085c3. |
| --kcge-nav | Fonds de navigation et zones discrètes. |
| --kcge-page | Fond de page. |
| --kcge-surface | Surface de cartes, tableaux et panels. |
| --kcge-border | Bordures sobres. |
| --kcge-success-* | États favorables. |
| --kcge-warning-* | Alertes et états à surveiller. |
| --kcge-danger-* | Erreurs et blocages. |
Chargez Material Icons dans index.html:
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Round" rel="stylesheet" />Sans Material Icons, les composants mat-icon affichent les noms d'icônes sous forme de texte.
Provider hôte
Le composant composite kavaa-committee-session-workspace dépend de KCGE_WORKSPACE_CONTEXT.
Contrat
import { Observable } from 'rxjs';
import type {
AttendanceRequest,
CastVoteRequest,
CommitteeSessionWorkspaceViewModel,
DecisionResultViewModel,
KcgeActorRenderMode,
OverrideRequest
} from 'kavaa-kcge-viewmodels';
export type KcgeWorkspaceLoadParams =
| { sessionId: string; actorContext?: KcgeActorRenderMode }
| { committeeId: string; actorContext?: KcgeActorRenderMode };
export interface IKcgeWorkspaceContext {
load(params: KcgeWorkspaceLoadParams): Observable<CommitteeSessionWorkspaceViewModel>;
castVote(agendaItemId: string, req: CastVoteRequest): Observable<void>;
computeDecision(agendaItemId: string): Observable<DecisionResultViewModel>;
overrideDecision(agendaItemId: string, req: OverrideRequest): Observable<void>;
recordAttendance(memberId: string, req: AttendanceRequest): Observable<void>;
generateMinutes(sessionId: string): Observable<void>;
}Responsabilités du provider
Le provider hôte doit:
- appeler les APIs KCGE;
- adapter les DTO backend en
CommitteeSessionWorkspaceViewModel; - gérer les erreurs techniques et fonctionnelles;
- transmettre
actorContextuniquement comme contexte de rendu ou de chargement; - recharger le workspace après une mutation;
- garder les tokens, headers, droits, IAM et appels HTTP hors du UI Kit;
- ne pas recalculer quorum/décision côté composant.
Exemple connecté à une API
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs';
import type {
AttendanceRequest,
CastVoteRequest,
CommitteeSessionWorkspaceViewModel,
DecisionResultViewModel,
OverrideRequest
} from 'kavaa-kcge-viewmodels';
import type { IKcgeWorkspaceContext, KcgeWorkspaceLoadParams } from 'kavaa-kcge-ui-angular';
@Injectable()
export class CdcKcgeWorkspaceProvider implements IKcgeWorkspaceContext {
private readonly http = inject(HttpClient);
load(params: KcgeWorkspaceLoadParams): Observable<CommitteeSessionWorkspaceViewModel> {
if ('sessionId' in params) {
return this.http.get<CommitteeSessionWorkspaceViewModel>(
`/api/kcge/sessions/${params.sessionId}/workspace`,
{ params: { actorContext: params.actorContext ?? '' } }
);
}
return this.http.get<CommitteeSessionWorkspaceViewModel>(
`/api/kcge/committees/${params.committeeId}/workspace`,
{ params: { actorContext: params.actorContext ?? '' } }
);
}
castVote(agendaItemId: string, req: CastVoteRequest): Observable<void> {
return this.http.post<void>(`/api/kcge/agenda-items/${agendaItemId}/votes`, req);
}
computeDecision(agendaItemId: string): Observable<DecisionResultViewModel> {
return this.http.post<DecisionResultViewModel>(`/api/kcge/agenda-items/${agendaItemId}/decision`, {});
}
overrideDecision(agendaItemId: string, req: OverrideRequest): Observable<void> {
return this.http.post<void>(`/api/kcge/agenda-items/${agendaItemId}/override`, req);
}
recordAttendance(memberId: string, req: AttendanceRequest): Observable<void> {
return this.http.post<void>(`/api/kcge/members/${memberId}/attendance`, req);
}
generateMinutes(sessionId: string): Observable<void> {
return this.http.post<void>(`/api/kcge/sessions/${sessionId}/minutes`, {});
}
}Intégration rapide
Gestion des intentions du workspace
import { Router } from '@angular/router';
import type { KcgeIntent } from 'kavaa-kcge-viewmodels';
handleKcgeIntent(intent: KcgeIntent): void {
switch (intent.type) {
case 'openAgendaItemRequested':
this.router.navigate(['/cdc/agenda', intent.agendaItemId]);
break;
case 'addAgendaItemRequested':
this.router.navigate(['/cdc/sessions', intent.sessionId, 'agenda', 'new']);
break;
case 'sessionActionRequested':
this.auditUiAction(intent.sessionId, intent.action);
break;
case 'overrideDecisionRequested':
this.openKfelOverrideModal(intent.agendaItemId);
break;
default:
this.auditKcgeIntent(intent);
break;
}
}Composant table de comités
import { CommitteeListTableComponent } from 'kavaa-kcge-ui-angular';
import type { CommitteeListViewModel } from 'kavaa-kcge-viewmodels';
@Component({
standalone: true,
imports: [CommitteeListTableComponent],
template: `
<kavaa-committee-list-table
[committees]="committees"
[pageSize]="10"
[pageSizeOptions]="[5, 10, 20, 50]"
statusFilter="all"
(committeeSelected)="openCommittee($event.committeeId)"
(createSessionRequested)="createSession($event.committeeId)"
/>
`
})
export class CommitteeListPage {
committees: CommitteeListViewModel[] = [];
}Composants publics
Tous les composants publics sont standalone: true et utilisent ChangeDetectionStrategy.OnPush.
Exports publics
export * from './lib/composite/committee-session-workspace.component';
export * from './lib/animations/kcge-fuse-animations';
export * from './lib/components/kcge-components';
export * from './lib/providers/kcge-workspace-context.token';kavaa-committee-session-workspace
Composant composite principal. Il charge le workspace via KCGE_WORKSPACE_CONTEXT, affiche statut, logistique KMME, présence, agenda, revues, vote, décisions, PV et audit.
| Input | Type | Défaut | Description |
| --- | --- | --- | --- |
| sessionId | string | requis | Identifiant de session à charger. |
| mode | KcgeActorRenderMode | undefined | Mode de rendu: secretary, voter, observer, admin. |
| tableRenderer | 'kendo' \| 'material' | 'kendo' | Renderer de la table d'ordre du jour. |
| loading | boolean | false | État de chargement externe optionnel. |
| error | UiErrorState \| null | null | Erreur UI externe optionnelle. |
| Output | Payload | Usage host |
| --- | --- | --- |
| intentEmitted | KcgeIntent | Router, audit UI, workflow externe. |
| downloadRequested | { url: string } | Télécharger ou ouvrir le PV. |
Notes:
moden'autorise aucune action.- Les boutons sont pilotés par
allowedActions. - Le composant recharge le workspace après les actions provider.
kavaa-committee-list-table
Table Kendo Grid des comités par défaut, avec renderer Material de compatibilité, tri, pagination locale, filtre statut et état vide.
| Input | Type | Défaut |
| --- | --- | --- |
| committees | CommitteeListViewModel[] | [] |
| loading | boolean | false |
| pageSize | number | 10 |
| pageSizeOptions | number[] | [5, 10, 20, 50] |
| enablePagination | boolean | true |
| enableSort | boolean | true |
| statusFilter | string | all |
| tableRenderer | 'kendo' \| 'material' | 'kendo' |
| Output | Payload |
| --- | --- |
| committeeSelected | { committeeId: string } |
| createSessionRequested | { committeeId: string } |
kavaa-committee-header-summary
Résumé détaillé d'un comité.
| Input | Type |
| --- | --- |
| committee | CommitteeDetailViewModel |
| Output | Payload |
| --- | --- |
| actionRequested | string |
kavaa-session-status-banner
Bandeau de statut de session. Il filtre les actions visibles selon le cycle de vie: aucun bouton en Archived, génération PV uniquement en Closed.
| Input | Type | Défaut |
| --- | --- | --- |
| sessionStatus | SessionStatusInfo | requis |
| allowedActions | string[] | [] |
| Output | Payload |
| --- | --- |
| openRequested | void |
| closeRequested | void |
| actionRequested | string |
kavaa-agenda-item-table
Table Kendo Grid de l'ordre du jour par défaut, avec renderer Material de compatibilité, tri, pagination locale, action d'ajout et calcul de décision.
| Input | Type | Défaut |
| --- | --- | --- |
| agendaItems | AgendaItemViewModel[] | [] |
| agendaSummary | AgendaSummary | requis |
| allowedActions | KcgeAllowedAction[] | [] |
| pageSize | number | 10 |
| pageSizeOptions | number[] | [5, 10, 20, 50] |
| enablePagination | boolean | true |
| enableSort | boolean | true |
| tableRenderer | 'kendo' \| 'material' | 'kendo' |
| Output | Payload |
| --- | --- |
| itemSelected | { agendaItemId: string } |
| addItemRequested | void |
| computeDecisionRequested | { agendaItemId: string } |
kavaa-agenda-item-review-panel
Carte de revue d'un item d'agenda: dossier, readiness DCE, notes, règle de décision et votes.
| Input | Type |
| --- | --- |
| review | AgendaItemReviewViewModel |
| Output | Payload |
| --- | --- |
| actionRequested | string |
| voteRequested | { agendaItemId: string } |
| computeDecisionRequested | { agendaItemId: string } |
| overrideDecisionRequested | { agendaItemId: string } |
kavaa-attendance-panel
Panel de présence et quorum.
| Input | Type |
| --- | --- |
| attendance | AttendanceSummary |
| Output | Payload |
| --- | --- |
| attendanceRecorded | { memberId: string; req: AttendanceRequest } |
kavaa-vote-decision-panel
Panel de vote. Il génère une idempotencyKey UUID v4 et masque le formulaire si conflictOfInterestState.blocksVote = true.
| Input | Type |
| --- | --- |
| votePanel | VotePanelViewModel |
| Output | Payload |
| --- | --- |
| voteRequested | { agendaItemId: string; req: CastVoteRequest } |
kavaa-decision-result-panel
Carte de résultat de décision.
| Input | Type |
| --- | --- |
| decisionResult | DecisionResultViewModel |
| Output | Payload |
| --- | --- |
| overrideRequested | { agendaItemId: string } |
kavaa-decision-summary-panel
Liste de résultats de décision.
| Input | Type |
| --- | --- |
| decisionSummary | DecisionSummary |
| Output | Payload |
| --- | --- |
| overrideRequested | { agendaItemId: string } |
kavaa-minutes-generation-panel
Panel de génération et téléchargement du procès-verbal.
| Input | Type | Défaut |
| --- | --- | --- |
| minutesAvailability | MinutesAvailability | requis |
| allowedActions | string[] | [] |
| Output | Payload |
| --- | --- |
| generateRequested | void |
| downloadRequested | { url: string } |
kavaa-committee-audit-timeline
Timeline des événements d'audit.
| Input | Type |
| --- | --- |
| auditSummary | AuditSummary |
| sessionId | string |
Outputs: aucun.
kavaa-committee-read-only-panel
Vue lecture seule. Elle neutralise les actions d'écriture même si une décision contient allowedActions.
| Input | Type |
| --- | --- |
| readonly | CommitteeReadOnlyViewModel |
Outputs: aucun.
Entrypoint de test
Le package expose un entrypoint secondaire:
import {
MockKcgeWorkspaceContext,
buildDecisionStub,
buildWorkspaceStub
} from 'kavaa-kcge-ui-angular/testing';Utilisez-le pour:
- tests unitaires de pages hôtes;
- démos locales;
- stories Storybook;
- scénarios de non-régression.
Ne l'utilisez pas dans le code de production.
Exemple:
import { TestBed } from '@angular/core/testing';
import { KCGE_WORKSPACE_CONTEXT, CommitteeSessionWorkspaceComponent } from 'kavaa-kcge-ui-angular';
import { MockKcgeWorkspaceContext } from 'kavaa-kcge-ui-angular/testing';
it('affiche un workspace KCGE mocké', () => {
TestBed.configureTestingModule({
imports: [CommitteeSessionWorkspaceComponent],
providers: [{ provide: KCGE_WORKSPACE_CONTEXT, useValue: new MockKcgeWorkspaceContext() }]
});
const fixture = TestBed.createComponent(CommitteeSessionWorkspaceComponent);
fixture.componentRef.setInput('sessionId', 'SES-001');
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('Session de gouvernance');
});Mapping API recommandé
Les endpoints exacts dépendent du backend, mais le mapping des intentions doit rester stable.
| Action UI | Payload | API hôte typique | Après succès |
| --- | --- | --- | --- |
| load(params) | KcgeWorkspaceLoadParams | GET /workspace | Afficher le ViewModel. |
| attendanceRecorded | { memberId, req } | POST /attendance | Recharger le workspace. |
| voteRequested | { agendaItemId, req } | POST /agenda-items/{id}/votes | Recharger le workspace. |
| computeDecisionRequested | { agendaItemId } | POST /agenda-items/{id}/decision | Recharger le workspace. |
| overrideDecisionRequested | { agendaItemId, req? } | KFE-L modal puis POST /override | Recharger le workspace. |
| minutesRequested | { sessionId } | POST /sessions/{id}/minutes | Recharger le workspace. |
| downloadRequested | { url } | Ouverture blob/lien | Aucun recalcul UI. |
Développement dans ce monorepo
Structure principale:
libs/kcge-ui-angular/
package.json
ng-package.json
project.json
src/
index.ts
lib/
composite/
components/
providers/
sub-components/
animations/
styles/
testing/
src/
kcge-test-provider.mock.tsCommandes:
npm.cmd run build:ui
npm.cmd run test:cdc -- --runInBand --verbose
npm.cmd run build:cdc
npm.cmd run lint:architecture
npm.cmd run serve:cdcApplication de référence:
apps/cdc-kcge-test/Elle illustre:
- bootstrap standalone via
app.config.ts; - provider hôte mocké;
- pages séparées par fonctionnalité;
- imports directs des composants standalone;
- documentation d'intégration dans son propre
README.md; - tests de pagination, tri, read-only, conflit d'intérêt et absence de
HttpClient.
Publication
Build:
npm.cmd run build:uiSortie:
dist/libs/kcge-ui-angularLe package publié contient:
- l'entrypoint principal
kavaa-kcge-ui-angular; - l'entrypoint secondaire
kavaa-kcge-ui-angular/testing; - les assets de styles
src/styles.
Dépannage
NullInjectorError: No provider for KCGE_WORKSPACE_CONTEXT
Cause: le provider hôte n'est pas enregistré.
Correction:
providers: [
CdcKcgeWorkspaceProvider,
{ provide: KCGE_WORKSPACE_CONTEXT, useExisting: CdcKcgeWorkspaceProvider }
]Le workspace reste en chargement
Vérifier:
sessionIdest renseigné;KCGE_WORKSPACE_CONTEXTest fourni;load(...)retourne unObservable<CommitteeSessionWorkspaceViewModel>;- l'Observable émet puis se termine;
- aucune erreur HTTP n'est masquée côté provider.
Les icônes affichent du texte
Cause: Material Icons n'est pas chargé.
Correction: ajouter le lien Google Fonts Material Icons dans index.html.
Les actions ne s'affichent pas
Vérifier:
- l'action existe dans
allowedActions; - le statut de session permet l'action;
moden'est pas utilisé comme source d'autorisation;Archivedmasque toutes les actions du bandeau session;CommitteeReadOnlyPanelneutralise toujours les actions d'écriture.
Le formulaire de vote n'apparaît pas
Vérifier:
votePanel.allowedActionscontientcastVoteouchangeVote;votePanel.conflictOfInterestState.blocksVotevautfalse;votePanel.currentVoteestnullouchangeVoteest autorisé;votePanel.voteOptionscontient les options serveur.
Le statut ne change pas après une action
Cause probable: l'API a été appelée, mais le workspace n'a pas été rechargé.
Correction:
this.ctx.castVote(agendaItemId, req).pipe(
switchMap(() => this.ctx.load({ sessionId }))
);Erreur Azure Artifacts E401 ou E404
Voir Authentification Azure Artifacts.
TypeScript demande des extensions .js
Le workspace peut utiliser moduleResolution: nodenext. Dans ce cas, les imports relatifs de packages TypeScript peuvent nécessiter .js selon la configuration du projet consommateur.
Checklist d'intégration
kavaa-kcge-viewmodelsest installé.kavaa-kcge-ui-angularest installé.- Angular 20, Angular Material 20 et RxJS 7.8 sont disponibles.
- Le registry
@kavaapointe vers Azure Artifacts. - L'authentification Azure Artifacts fonctionne.
- Les styles
kcge-material-overrides.scsssont chargés. - Material Icons est chargé.
- Un provider implémente
IKcgeWorkspaceContext. KCGE_WORKSPACE_CONTEXTpointe vers ce provider.- Le provider convertit les DTO API en
CommitteeSessionWorkspaceViewModel. - Les actions utilisateur appellent les APIs du host, pas le UI Kit.
- Le workspace est rechargé après chaque mutation réussie.
- Les erreurs API sont transformées en erreurs UI affichables.
allowedActionspilote les boutons.modeetactorContextne servent jamais à autoriser une action.- Les scénarios
Closed,Archived, conflit d'intérêt et read-only sont testés. npm.cmd run build:uipasse.npm.cmd run test:cdc -- --runInBand --verbosepasse.
Règle d'or
Le KCGE UI Kit ne décide pas du métier. Il rend les ViewModels, collecte les intentions utilisateur et laisse l'application hôte appeler les APIs, appliquer les droits, tracer les actions et rafraîchir les données.
