fix(marketing): restaurer visibilité 12 fonctions dans 'Comment ça marche'
L'abstraction en 4 catégories (commit 8a7650f) cachait les 13 modes
derrière des regroupements ; l'utilisateur ne VOYAIT plus les 6 boutons
features originaux et percevait que des fonctions avaient disparu.
Refonte v2 :
- Bottom tab bar : 6 boutons FEATURES originaux 1-6 (Trans/Diari/Lang/Exp/Users/Part) — visibles, cliquables
- Right panel : grid 3×4 = 12 boutons FEATURES 1-12 (IA mode 0 reste accessible via Brain card)
- Mobile pills : 12 features scrollables horizontalement
- Auto-cycle : 1→12 skip 0, 1100ms each (~13s cycle complet)
- Manual click : isManual 4500ms reset puis reprend auto
- SUPPRESSION : CATEGORIES array + activeCategory state + handleCategorySelect + sub-mode dots indicator
- AJOUT : featureGridLabel() pour labels compacts (Recording/Recherche IA/Résumés/Intégrations/Audit trail/Conformité)
Préservé : phone shell statique, palette brand stricte b1/b2/b3, IA Mistral
card inchangée, 13 templates de modes (0-12) intacts, eyebrow brand-navy noir,
WCAG aria-labels + aria-pressed, prefers-reduced-motion guard.
Test adapté : assert featureGridLabel + 12 fonctions + labels grid.
This commit is contained in:
@@ -480,8 +480,8 @@
|
||||
{# Stats row #}
|
||||
<div class="flex flex-wrap items-center justify-center gap-x-8 gap-y-3 text-brand-navy">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-2xl font-black grad-text">4</span>
|
||||
<span class="text-xs font-medium text-brand-navy/60 uppercase tracking-wider">catégories · 6 modules</span>
|
||||
<span class="text-2xl font-black grad-text">12</span>
|
||||
<span class="text-xs font-medium text-brand-navy/60 uppercase tracking-wider">fonctions · modules</span>
|
||||
</div>
|
||||
<div class="w-px h-6 bg-brand-navy/15 hidden sm:block" aria-hidden="true"></div>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -1200,34 +1200,27 @@
|
||||
|
||||
</div>
|
||||
|
||||
{# BOTTOM : 4 catégories tabs (Capture / IA / Distribution / Gouvernance) + sub-mode dots + Auto pill — hauteur fixe 90px #}
|
||||
<div class="relative flex flex-col items-center justify-center gap-1 z-10 flex-shrink-0"
|
||||
{# BOTTOM : 6 boutons feature originaux (Trans / Diari / Lang / Exp / Users / Part) + Auto pill — hauteur fixe 90px #}
|
||||
<div class="relative flex flex-col items-center justify-center gap-1.5 z-10 flex-shrink-0"
|
||||
style="height: 90px; border-top: 1px solid rgba(255,255,255,0.06); background: linear-gradient(180deg, transparent, rgba(0,0,0,0.32));">
|
||||
{# Sub-mode dots indicator (shows position within active category) #}
|
||||
<div class="flex items-center gap-1" style="height:6px;" aria-hidden="true">
|
||||
<template x-for="(sm, di) in CATEGORIES[activeCategory].submodes" :key="di">
|
||||
<span class="block rounded-full"
|
||||
:style="`width:${sm === selectedFeature ? '10px' : '4px'};height:4px;background:${sm === selectedFeature ? CATEGORIES[activeCategory].color : 'rgba(255,255,255,0.20)'};transition:width 0.2s, background 0.2s;`"></span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
{# 4 catégories tabs #}
|
||||
<div class="flex items-end gap-1">
|
||||
<template x-for="(cat, ci) in CATEGORIES" :key="ci">
|
||||
<button type="button" @click="handleCategorySelect(ci)"
|
||||
class="dictia-feat-btn dictia-cat-btn outline-none cursor-pointer focus-visible:ring-2 focus-visible:ring-white/40 flex flex-col items-center justify-end relative"
|
||||
style="width:54px;height:42px;border:none;padding:4px 0 6px;background:transparent;"
|
||||
:aria-pressed="activeCategory === ci ? 'true' : 'false'"
|
||||
:aria-label="`Catégorie : ${cat.title}`">
|
||||
<span :style="`color: ${activeCategory === ci ? cat.color : 'rgba(255,255,255,0.30)'}; transition: color 0.2s, transform 0.15s, filter 0.2s; filter: ${activeCategory === ci ? 'drop-shadow(0 0 6px ' + cat.color + 'CC)' : 'none'}; transform: scale(${activeCategory === ci ? 1.15 : 1}); display: inline-block;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;" aria-hidden="true" x-html="cat.iconPath"></svg>
|
||||
{# 6 boutons features originaux (FEATURES indexes 1-6) — visible bottom tab bar #}
|
||||
<div class="flex items-end gap-1.5 justify-center">
|
||||
<template x-for="i in [1,2,3,4,5,6]" :key="i">
|
||||
<button type="button" @click="handleManualSelect(i)"
|
||||
class="dictia-feat-btn outline-none cursor-pointer focus-visible:ring-2 focus-visible:ring-white/40 flex flex-col items-center justify-end relative"
|
||||
style="width:34px;height:42px;border:none;padding:4px 0 6px;background:transparent;"
|
||||
:aria-pressed="selectedFeature === i ? 'true' : 'false'"
|
||||
:aria-label="`Fonction : ${FEATURES[i].title}`">
|
||||
<span :style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(255,255,255,0.40)'}; transition: color 0.2s, transform 0.15s, filter 0.2s; filter: ${selectedFeature === i ? 'drop-shadow(0 0 6px ' + FEATURES[i].color + 'CC)' : 'none'}; transform: scale(${selectedFeature === i ? 1.15 : 1}); display: inline-block;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;" aria-hidden="true" x-html="featureIconPath(i)"></svg>
|
||||
</span>
|
||||
<span class="text-[9px] font-mono font-bold mt-0.5 leading-none uppercase tracking-wider"
|
||||
:style="`color: ${activeCategory === ci ? cat.color : 'rgba(255,255,255,0.40)'};`"
|
||||
x-text="cat.short"></span>
|
||||
:style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(255,255,255,0.55)'};`"
|
||||
x-text="featureShortLabel(i)"></span>
|
||||
{# Tab indicator bottom border 2px #}
|
||||
<span x-show="activeCategory === ci" class="absolute" aria-hidden="true"
|
||||
:style="`bottom: 0; left: 6px; right: 6px; height: 2px; background: ${cat.color}; border-radius: 1px; box-shadow: 0 0 8px ${cat.color};`"></span>
|
||||
<span x-show="selectedFeature === i" class="absolute" aria-hidden="true"
|
||||
:style="`bottom: 0; left: 4px; right: 4px; height: 2px; background: ${FEATURES[i].color}; border-radius: 1px; box-shadow: 0 0 8px ${FEATURES[i].color};`"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
@@ -1286,35 +1279,41 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Mobile : pills catégories horizontales scrollables #}
|
||||
{# Mobile : pills features horizontales scrollables (12 fonctions, indexes 1-12) #}
|
||||
<div class="lg:hidden w-full overflow-x-auto dictia-hide-scrollbar" style="scrollbar-width:none;">
|
||||
<div class="flex gap-2 px-1 pb-1" style="width:max-content;">
|
||||
<template x-for="(cat, ci) in CATEGORIES" :key="ci">
|
||||
<button type="button" @click="handleCategorySelect(ci)"
|
||||
<template x-for="i in [1,2,3,4,5,6,7,8,9,10,11,12]" :key="i">
|
||||
<button type="button" @click="handleManualSelect(i)"
|
||||
class="flex items-center gap-1.5 px-2.5 py-1.5 rounded-full shrink-0 transition-all focus-visible:ring-2 focus-visible:ring-brand-b1"
|
||||
:style="`border: 1px solid ${activeCategory === ci ? cat.color + '70' : 'rgba(0,0,0,0.10)'}; background-color: ${activeCategory === ci ? cat.color + '18' : 'rgba(0,0,0,0.04)'}; outline: none;`">
|
||||
<span :style="`color: ${activeCategory === ci ? cat.color : 'rgba(0,0,0,0.40)'}; transition: color 0.2s;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px;" aria-hidden="true" x-html="cat.iconPath"></svg>
|
||||
:style="`border: 1px solid ${selectedFeature === i ? FEATURES[i].color + '70' : 'rgba(0,0,0,0.10)'}; background-color: ${selectedFeature === i ? FEATURES[i].color + '18' : 'rgba(0,0,0,0.04)'}; outline: none;`"
|
||||
:aria-pressed="selectedFeature === i ? 'true' : 'false'"
|
||||
:aria-label="`Fonction : ${FEATURES[i].title}`">
|
||||
<span :style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(0,0,0,0.40)'}; transition: color 0.2s;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px;" aria-hidden="true" x-html="featureIconPath(i)"></svg>
|
||||
</span>
|
||||
<span class="text-[11px] font-bold whitespace-nowrap"
|
||||
:style="`color: ${activeCategory === ci ? cat.color : 'rgba(0,0,0,0.50)'};`"
|
||||
x-text="cat.title"></span>
|
||||
:style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(0,0,0,0.50)'};`"
|
||||
x-text="FEATURES[i].title"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ─────────── ZONE RIGHT : IA Mistral premium card + grid 6 features ─────────── #}
|
||||
{# ─────────── ZONE RIGHT : IA Mistral premium card + grid 12 features ─────────── #}
|
||||
<div class="flex flex-col gap-3 w-full lg:w-[320px] flex-shrink-0 relative z-10">
|
||||
|
||||
{# Eyebrow + title — alignés sur le système typo #}
|
||||
<div class="mb-1 flex items-center gap-2">
|
||||
<span class="block w-1 h-6 rounded-full" style="background:linear-gradient(180deg,#06b6d4,#c026d3);" aria-hidden="true"></span>
|
||||
<div>
|
||||
<p class="text-xs font-mono font-bold uppercase tracking-widest text-brand-b3">4 catégories · 12 sous-modes</p>
|
||||
<p class="font-bold text-lg leading-snug text-brand-navy">Le moteur IA local</p>
|
||||
<div class="mb-1 flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="block w-1 h-6 rounded-full" style="background:linear-gradient(180deg,#06b6d4,#c026d3);" aria-hidden="true"></span>
|
||||
<div>
|
||||
<p class="text-xs font-mono font-bold uppercase tracking-widest text-brand-b3">Fonctions clés</p>
|
||||
<p class="font-bold text-lg leading-snug text-brand-navy">Le moteur IA local</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-[10px] font-mono font-bold px-2 py-0.5 rounded-full text-brand-b3 whitespace-nowrap"
|
||||
style="background-color:rgba(192,38,211,0.10);border:1px solid rgba(192,38,211,0.25);">12 fonctions</span>
|
||||
</div>
|
||||
|
||||
{# IA Mistral 7B premium card — couleurs brand-b3 (fuchsia officiel) #}
|
||||
@@ -1410,32 +1409,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Category grid 2×2 — 4 catégories avec sous-modes affichés dessous (architecture lisible) #}
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<template x-for="(cat, ci) in CATEGORIES" :key="ci">
|
||||
<button type="button" @click="handleCategorySelect(ci)"
|
||||
class="flex flex-col items-start gap-2 rounded-xl py-3 px-3 outline-none transition-all focus-visible:ring-2 focus-visible:ring-white/40 text-left"
|
||||
:style="`border: 1px solid ${activeCategory === ci ? cat.color + '70' : 'rgba(255,255,255,0.10)'}; background-color: ${activeCategory === ci ? 'rgba(8,12,24,0.95)' : 'rgba(8,12,24,0.85)'}; box-shadow: ${activeCategory === ci ? '0 0 16px ' + cat.color + '40, inset 0 0 16px ' + cat.color + '20' : 'none'}; cursor: pointer;`"
|
||||
:aria-pressed="activeCategory === ci ? 'true' : 'false'"
|
||||
:aria-label="`Catégorie : ${cat.title}`">
|
||||
<div class="flex items-center gap-2 w-full">
|
||||
<span :style="`color: ${activeCategory === ci ? cat.color : 'rgba(255,255,255,0.55)'}; filter: ${activeCategory === ci ? 'drop-shadow(0 0 6px ' + cat.color + 'BB)' : 'none'}; transition: all 0.2s; display:inline-block;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;" aria-hidden="true" x-html="cat.iconPath"></svg>
|
||||
</span>
|
||||
<span class="text-[11px] font-bold leading-tight flex-1"
|
||||
:style="`color: ${activeCategory === ci ? 'rgba(255,255,255,0.98)' : 'rgba(255,255,255,0.85)'};`"
|
||||
x-text="cat.title"></span>
|
||||
</div>
|
||||
<p class="text-[10px] font-mono leading-snug w-full"
|
||||
:style="`color: ${activeCategory === ci ? cat.color + 'EE' : 'rgba(255,255,255,0.55)'};`"
|
||||
x-text="cat.subtitle"></p>
|
||||
{# Mini sous-modes dots dans la card #}
|
||||
<div class="flex items-center gap-0.5 mt-auto" aria-hidden="true">
|
||||
<template x-for="(sm, si) in cat.submodes" :key="si">
|
||||
<span class="block rounded-full"
|
||||
:style="`width:${activeCategory === ci && sm === selectedFeature ? '8px' : '3px'};height:3px;background:${activeCategory === ci ? (sm === selectedFeature ? cat.color : cat.color + '55') : 'rgba(255,255,255,0.15)'};transition:all 0.2s;`"></span>
|
||||
</template>
|
||||
</div>
|
||||
{# Feature grid 3×4 — 12 fonctions (FEATURES indexes 1-12, IA mode 0 accessible via Brain card ci-dessus) #}
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<template x-for="i in [1,2,3,4,5,6,7,8,9,10,11,12]" :key="i">
|
||||
<button type="button" @click="handleManualSelect(i)"
|
||||
class="flex flex-col items-center gap-1.5 rounded-xl py-2.5 px-2 outline-none transition-all focus-visible:ring-2 focus-visible:ring-white/40 text-center"
|
||||
:style="`border: 1px solid ${selectedFeature === i ? FEATURES[i].color + '70' : 'rgba(255,255,255,0.10)'}; background-color: ${selectedFeature === i ? 'rgba(8,12,24,0.95)' : 'rgba(8,12,24,0.85)'}; box-shadow: ${selectedFeature === i ? '0 0 16px ' + FEATURES[i].color + '40, inset 0 0 16px ' + FEATURES[i].color + '20' : 'none'}; cursor: pointer; min-height:64px;`"
|
||||
:aria-pressed="selectedFeature === i ? 'true' : 'false'"
|
||||
:aria-label="`Fonction : ${FEATURES[i].title}`">
|
||||
<span :style="`color: ${selectedFeature === i ? FEATURES[i].color : 'rgba(255,255,255,0.55)'}; filter: ${selectedFeature === i ? 'drop-shadow(0 0 6px ' + FEATURES[i].color + 'BB)' : 'none'}; transition: all 0.2s; transform: scale(${selectedFeature === i ? 1.15 : 1}); display:inline-block;`">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;" aria-hidden="true" x-html="featureIconPath(i)"></svg>
|
||||
</span>
|
||||
<span class="text-[10px] font-bold leading-tight w-full truncate"
|
||||
:style="`color: ${selectedFeature === i ? 'rgba(255,255,255,0.98)' : 'rgba(255,255,255,0.85)'};`"
|
||||
x-text="featureGridLabel(i)"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
@@ -1445,11 +1432,11 @@
|
||||
|
||||
</div>
|
||||
|
||||
{# Alpine logic — dictiaDashboard + 4 catégories × 12 sous-modes (refonte stratégique 2026-04-29) #}
|
||||
{# Alpine logic — dictiaDashboard : 12 fonctions visibles (1-12) + IA accessible via Brain card (refonte 2026-04-29) #}
|
||||
<script>
|
||||
function dictiaDashboard() {
|
||||
return {
|
||||
/* FEATURES indexes (0-12) — même structure que v1 (0=IA, 1-6=existants), nouveaux 7-12 ajoutés */
|
||||
/* FEATURES indexes (0-12) — IA mode 0 accessible via Brain card; 1-6 = originaux, 7-12 = nouveaux */
|
||||
FEATURES: [
|
||||
{ idx: 0, title: 'IA intégrée', subtitle: "Résumé, actions, Q&R", color: '#c026d3', badge: 'Mistral 7B' }, /* brand-b3 */
|
||||
{ idx: 1, title: 'Transcription', subtitle: 'Parole → texte en temps réel', color: '#06b6d4', badge: 'Whisper AI' }, /* brand-b2 */
|
||||
@@ -1466,43 +1453,7 @@
|
||||
{ idx: 11, title: 'Audit trail', subtitle: 'Traçabilité Loi 25 immutable', color: '#2563eb', badge: 'Loi 25' }, /* brand-b1 */
|
||||
{ idx: 12, title: 'Conformité', subtitle: '9 ordres pros · EFVP CAI', color: '#c026d3', badge: 'MCN' } /* brand-b3 */
|
||||
],
|
||||
/* CATEGORIES : 4 regroupements logiques. Chaque catégorie a ses sous-modes (ids des FEATURES). */
|
||||
CATEGORIES: [
|
||||
{
|
||||
title: 'Capture',
|
||||
short: 'Capture',
|
||||
subtitle: 'Audio in : upload, recording, recherche',
|
||||
color: '#06b6d4', /* brand-b2 cyan */
|
||||
submodes: [1, 7, 8], /* Transcription (upload), Recording live, Recherche sémantique */
|
||||
iconPath: '<rect x="9" y="2" width="6" height="12" rx="3"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/>'
|
||||
},
|
||||
{
|
||||
title: 'Transformation IA',
|
||||
short: 'IA',
|
||||
subtitle: 'Diarisation, langues, résumés, Q&R',
|
||||
color: '#2563eb', /* brand-b1 blue */
|
||||
submodes: [2, 3, 9, 0], /* Diarisation, Langues, Résumé+actions, Chat IA */
|
||||
iconPath: '<path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2Z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2Z"/>'
|
||||
},
|
||||
{
|
||||
title: 'Distribution',
|
||||
short: 'Distrib',
|
||||
subtitle: 'Exports, intégrations, partage',
|
||||
color: '#c026d3', /* brand-b3 fuchsia */
|
||||
submodes: [4, 10, 6, 5], /* Exports, Intégrations, Partage, Users */
|
||||
iconPath: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>'
|
||||
},
|
||||
{
|
||||
title: 'Gouvernance',
|
||||
short: 'Gouv',
|
||||
subtitle: 'Audit, Loi 25, AGPL, ordres pros',
|
||||
color: '#2563eb', /* brand-b1 blue (sobre, institutionnel) */
|
||||
submodes: [11, 12], /* Audit trail, Conformité Loi 25 */
|
||||
iconPath: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/>'
|
||||
}
|
||||
],
|
||||
selectedFeature: 1,
|
||||
activeCategory: 0,
|
||||
isManual: false,
|
||||
autoCycleTimer: null,
|
||||
manualResetTimer: null,
|
||||
@@ -1512,42 +1463,19 @@
|
||||
if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
this.startAutoCycle();
|
||||
},
|
||||
/* Auto-cycle logic : avance dans les sous-modes de la catégorie active toutes les 1100ms.
|
||||
Quand on atteint le dernier sous-mode → switch catégorie suivante (boucle 0→1→2→3→0). */
|
||||
/* Auto-cycle logic : avance 1→12 (skip 0=IA mode, accessible via Brain card), 1100ms each.
|
||||
Cycle complet : 12 features × 1100ms ≈ 13.2s puis recommence à 1. */
|
||||
startAutoCycle() {
|
||||
if (this.autoCycleTimer) clearInterval(this.autoCycleTimer);
|
||||
this.autoCycleTimer = setInterval(() => {
|
||||
const cat = this.CATEGORIES[this.activeCategory];
|
||||
const currentIdx = cat.submodes.indexOf(this.selectedFeature);
|
||||
if (currentIdx < cat.submodes.length - 1) {
|
||||
/* Avance dans la catégorie courante */
|
||||
this.selectedFeature = cat.submodes[currentIdx + 1];
|
||||
} else {
|
||||
/* Fin de catégorie → passe à la suivante */
|
||||
this.activeCategory = (this.activeCategory + 1) % this.CATEGORIES.length;
|
||||
this.selectedFeature = this.CATEGORIES[this.activeCategory].submodes[0];
|
||||
}
|
||||
/* Avance 1→2→...→12, puis retour à 1 (skip 0=IA) */
|
||||
this.selectedFeature = this.selectedFeature >= 12 ? 1 : this.selectedFeature + 1;
|
||||
if (this.selectedFeature === 0) this.selectedFeature = 1;
|
||||
}, 1100);
|
||||
},
|
||||
/* Click manuel sur un sous-mode (compatibilité 6 boutons originaux) */
|
||||
/* Click manuel sur un bouton feature : sélectionne ce mode + freeze auto 4500ms */
|
||||
handleManualSelect(i) {
|
||||
this.selectedFeature = i;
|
||||
/* Trouve la catégorie qui contient ce sous-mode */
|
||||
for (let ci = 0; ci < this.CATEGORIES.length; ci++) {
|
||||
if (this.CATEGORIES[ci].submodes.includes(i)) { this.activeCategory = ci; break; }
|
||||
}
|
||||
this.isManual = true;
|
||||
if (this.autoCycleTimer) { clearInterval(this.autoCycleTimer); this.autoCycleTimer = null; }
|
||||
if (this.manualResetTimer) clearTimeout(this.manualResetTimer);
|
||||
this.manualResetTimer = setTimeout(() => {
|
||||
this.isManual = false;
|
||||
this.startAutoCycle();
|
||||
}, 4500);
|
||||
},
|
||||
/* Click manuel sur une catégorie : sélectionne son premier sous-mode */
|
||||
handleCategorySelect(ci) {
|
||||
this.activeCategory = ci;
|
||||
this.selectedFeature = this.CATEGORIES[ci].submodes[0];
|
||||
this.isManual = true;
|
||||
if (this.autoCycleTimer) { clearInterval(this.autoCycleTimer); this.autoCycleTimer = null; }
|
||||
if (this.manualResetTimer) clearTimeout(this.manualResetTimer);
|
||||
@@ -1578,6 +1506,15 @@
|
||||
const labels = { 1: 'Trans', 2: 'Diari', 3: 'Lang', 4: 'Exp', 5: 'Users', 6: 'Part',
|
||||
7: 'Rec', 8: 'Search', 9: 'Résu', 10: 'Hub', 11: 'Audit', 12: 'Conf' };
|
||||
return labels[i] || '';
|
||||
},
|
||||
/* Labels compacts pour la grid 3×4 du right panel (raccourcis pour ne pas tronquer) */
|
||||
featureGridLabel(i) {
|
||||
const labels = {
|
||||
1: 'Transcription', 2: 'Diarisation', 3: '99+ langues', 4: 'Exports',
|
||||
5: 'Utilisateurs', 6: 'Partage', 7: 'Recording', 8: 'Recherche IA',
|
||||
9: 'Résumés', 10: 'Intégrations', 11: 'Audit trail', 12: 'Conformité'
|
||||
};
|
||||
return labels[i] || '';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -192,12 +192,13 @@ def test_fonctionnalites_how_it_works_reactor_section():
|
||||
assert 'handleManualSelect' in body, "Missing manual select handler"
|
||||
assert '1100' in body, "Missing 1100ms sub-mode cycle interval (refonte 2026-04-29)"
|
||||
assert '4500' in body, "Missing 4500ms manual reset timer"
|
||||
# Refonte 2026-04-29 : 4 catégories × 12 sous-modes
|
||||
assert 'CATEGORIES' in body, "Missing CATEGORIES array (refonte 4 catégories)"
|
||||
assert 'activeCategory' in body, "Missing activeCategory state"
|
||||
assert 'handleCategorySelect' in body, "Missing category click handler"
|
||||
for cat_title in ['Capture', 'Transformation IA', 'Distribution', 'Gouvernance']:
|
||||
assert cat_title in body, f"Missing category : {cat_title}"
|
||||
# Refonte 2026-04-29 (v2) : 12 fonctions visibles directement (1-12), IA mode 0 via Brain card.
|
||||
# Bottom tab bar = 6 boutons originaux (Trans/Diari/Lang/Exp/Users/Part) ; right panel grid = 12 features.
|
||||
assert 'featureGridLabel' in body, "Missing featureGridLabel (right grid 12 buttons)"
|
||||
assert '12 fonctions' in body, "Missing '12 fonctions' badge in right panel header"
|
||||
# Labels compacts grid right panel
|
||||
for grid_label in ['Recording', 'Recherche IA', 'Résumés', 'Intégrations', 'Audit trail', 'Conformité']:
|
||||
assert grid_label in body, f"Missing right grid label : {grid_label}"
|
||||
# Nouveaux modes 7-12
|
||||
assert 'recModeData' in body, "Missing Mode 7 (Recording live)"
|
||||
assert 'searchModeData' in body, "Missing Mode 8 (Recherche sémantique)"
|
||||
@@ -273,9 +274,9 @@ def test_fonctionnalites_how_it_works_reactor_section():
|
||||
assert 'dictia-bg-orbs' in body, "Missing floating orbs"
|
||||
assert 'dictia-connecting-line' in body, "Missing connecting line phone↔IA"
|
||||
|
||||
# Stats row in section header (refonte 2026-04-29 : 4 catégories · 6 modules)
|
||||
# Stats row in section header (refonte v2 2026-04-29 : 12 fonctions visibles)
|
||||
assert 'modules' in body, "Missing stats row 'modules'"
|
||||
assert 'catégories' in body, "Missing stats row 'catégories' (refonte)"
|
||||
assert 'fonctions' in body, "Missing stats row 'fonctions' (refonte v2)"
|
||||
assert 'cloud' in body, "Missing stats row 'cloud'"
|
||||
assert 'Voir une démo' in body, "Missing demo CTA link"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user