@atlashub/smartstack-cli 4.41.0 → 4.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.documentation/apex.html +2 -2
- package/.documentation/business-analyse.html +26 -27
- package/.documentation/commands.html +6 -6
- package/dist/index.js +24 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/templates/agents/ba-reader.md +2 -2
- package/templates/agents/ba-writer.md +44 -9
- package/templates/hooks/stop-hook.sh +6 -6
- package/templates/ralph/README.md +1 -1
- package/templates/scripts/setup-ralph-loop.sh +2 -2
- package/templates/skills/_resources/context-digest-template.md +1 -1
- package/templates/skills/_shared.md +13 -13
- package/templates/skills/apex/SKILL.md +14 -7
- package/templates/skills/apex/_shared.md +1 -1
- package/templates/skills/apex/references/challenge-questions.md +46 -13
- package/templates/skills/apex/references/core-seed-data.md +4 -4
- package/templates/skills/apex/references/error-classification.md +3 -3
- package/templates/skills/apex/references/smartstack-api.md +1 -1
- package/templates/skills/apex/references/smartstack-layers.md +1 -1
- package/templates/skills/apex/steps/step-00-init.md +46 -8
- package/templates/skills/apex/steps/step-01-analyze.md +1 -1
- package/templates/skills/apex/steps/step-02-plan.md +1 -1
- package/templates/skills/apex/steps/step-03-execute.md +1 -1
- package/templates/skills/business-analyse/SKILL.md +83 -22
- package/templates/skills/business-analyse/_shared.md +12 -9
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +13 -0
- package/templates/skills/business-analyse/questionnaire/03-data-ui.md +33 -0
- package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +1 -1
- package/templates/skills/business-analyse/react/components.md +1 -1
- package/templates/skills/business-analyse/react/schema.md +1 -1
- package/templates/skills/business-analyse/references/acceptance-criteria.md +3 -3
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +1 -1
- package/templates/skills/business-analyse/references/detection-strategies.md +2 -2
- package/templates/skills/business-analyse/references/entity-architecture-decision.md +1 -1
- package/templates/skills/business-analyse/references/naming-conventions.md +6 -6
- package/templates/skills/business-analyse/references/robustness-checks.md +4 -4
- package/templates/skills/business-analyse/references/spec-auto-inference.md +2 -2
- package/templates/skills/business-analyse/references/validation-checklist.md +3 -3
- package/templates/skills/business-analyse/schemas/feature-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +2 -2
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +3 -2
- package/templates/skills/business-analyse/steps/step-00-init.md +15 -5
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +14 -5
- package/templates/skills/business-analyse/steps/step-02-structure.md +17 -1
- package/templates/skills/business-analyse/steps/step-03-specify.md +136 -26
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +44 -8
- package/templates/skills/business-analyse/templates/tpl-handoff.md +5 -5
- package/templates/skills/business-analyse/templates/tpl-launch-displays.md +4 -4
- package/templates/skills/business-analyse/templates-frd.md +4 -4
- package/templates/skills/{ba-design-ui → business-analyse-design}/SKILL.md +9 -9
- package/templates/skills/{ba-design-ui → business-analyse-design}/steps/step-01-screens.md +9 -0
- package/templates/skills/{ba-design-ui → business-analyse-design}/steps/step-03-navigation.md +9 -2
- package/templates/skills/business-analyse-develop/SKILL.md +248 -0
- package/templates/skills/{ralph-loop → business-analyse-develop}/references/category-completeness.md +1 -1
- package/templates/skills/{ralph-loop → business-analyse-develop}/references/init-resume-recovery.md +8 -8
- package/templates/skills/{ralph-loop → business-analyse-develop}/references/multi-module-queue.md +1 -1
- package/templates/skills/business-analyse-develop/references/quality-gates.md +70 -0
- package/templates/skills/{ralph-loop → business-analyse-develop}/references/task-transform-legacy.md +1 -1
- package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-00-init.md +20 -4
- package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-01-task.md +3 -2
- package/templates/skills/business-analyse-develop/steps/step-01-v4-execute.md +131 -0
- package/templates/skills/business-analyse-develop/steps/step-02-v4-verify.md +156 -0
- package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-04-check.md +1 -1
- package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-05-report.md +1 -1
- package/templates/skills/{derive-prd → business-analyse-handoff}/SKILL.md +7 -7
- package/templates/skills/{derive-prd → business-analyse-handoff}/references/acceptance-criteria.md +5 -5
- package/templates/skills/{derive-prd → business-analyse-handoff}/references/handoff-file-templates.md +1 -1
- package/templates/skills/{derive-prd → business-analyse-handoff}/references/handoff-mappings.md +1 -1
- package/templates/skills/{derive-prd → business-analyse-handoff}/references/handoff-seeddata-generation.md +2 -2
- package/templates/skills/{derive-prd → business-analyse-handoff}/references/prd-generation.md +14 -14
- package/templates/skills/{derive-prd → business-analyse-handoff}/schemas/handoff-schema.json +2 -2
- package/templates/skills/{derive-prd → business-analyse-handoff}/steps/step-00-validate.md +6 -6
- package/templates/skills/{derive-prd → business-analyse-handoff}/steps/step-01-transform.md +46 -7
- package/templates/skills/{derive-prd → business-analyse-handoff}/steps/step-02-export.md +34 -14
- package/templates/skills/{ba-generate-html → business-analyse-html}/SKILL.md +4 -4
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/ba-interactive.html +709 -277
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/build-html.js +25 -3
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/01-data-init.js +54 -0
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/02-navigation.js +97 -3
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/03-render-cadrage.js +8 -7
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/04-render-modules.js +7 -7
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/05-render-specs.js +188 -85
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/06-render-consolidation.js +15 -14
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/06-render-mockups.js +19 -19
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/07-render-handoff.js +24 -4
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/08-editing.js +6 -2
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/09-export.js +27 -57
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/10-comments.js +67 -45
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/11-review-panel.js +15 -13
- package/templates/skills/business-analyse-html/html/src/styles/02-layout.css +216 -0
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/05-modules.css +36 -0
- package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/template.html +22 -12
- package/templates/skills/{ba-generate-html → business-analyse-html}/references/data-build.md +1 -1
- package/templates/skills/{ba-generate-html → business-analyse-html}/references/data-mapping.md +5 -1
- package/templates/skills/{ba-generate-html → business-analyse-html}/references/output-modes.md +7 -7
- package/templates/skills/{ba-generate-html → business-analyse-html}/steps/step-01-collect.md +25 -1
- package/templates/skills/{ba-generate-html → business-analyse-html}/steps/step-02-build-data.md +33 -5
- package/templates/skills/{ba-generate-html → business-analyse-html}/steps/step-03-render.md +2 -2
- package/templates/skills/{ba-generate-html → business-analyse-html}/steps/step-04-verify.md +2 -2
- package/templates/skills/{ba-review → business-analyse-review}/SKILL.md +11 -10
- package/templates/skills/{ba-review → business-analyse-review}/references/review-data-mapping.md +2 -2
- package/templates/skills/business-analyse-review/steps/step-00-init.md +107 -0
- package/templates/skills/{ba-review → business-analyse-review}/steps/step-01-apply.md +19 -11
- package/templates/skills/business-analyse-status/SKILL.md +118 -0
- package/templates/skills/documentation/SKILL.md +2 -2
- package/templates/skills/sketch/SKILL.md +172 -0
- package/templates/skills/sketch/references/domain-heuristics.md +116 -0
- package/templates/skills/ba-generate-html/html/src/styles/02-layout.css +0 -101
- package/templates/skills/ralph-loop/SKILL.md +0 -240
- /package/templates/skills/{ba-design-ui → business-analyse-design}/steps/step-02-wireframes.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/category-rules.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/compact-loop.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/module-transition.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/parallel-execution.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/section-splitting.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/references/team-orchestration.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-02-execute.md +0 -0
- /package/templates/skills/{ralph-loop → business-analyse-develop}/steps/step-03-commit.md +0 -0
- /package/templates/skills/{derive-prd → business-analyse-handoff}/references/entity-domain-mapping.md +0 -0
- /package/templates/skills/{derive-prd → business-analyse-handoff}/references/readiness-scoring.md +0 -0
- /package/templates/skills/{derive-prd → business-analyse-handoff}/templates/tpl-progress.md +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/cadrage-context.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/cadrage-scope.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/cadrage-stakeholders.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/cadrage-success.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/consol-datamodel.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/consol-flows.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/consol-interactions.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/consol-permissions.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/decomp-dependencies.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/decomp-modules.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/handoff-summary.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/partials/module-spec-container.html +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/01-variables.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/03-navigation.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/04-cards.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/06-wireframes.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/07-comments.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/08-review-panel.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/styles/09-mockups-html.css +0 -0
- /package/templates/skills/{ba-generate-html → business-analyse-html}/references/wireframe-svg-style-guide.md +0 -0
|
@@ -60,8 +60,28 @@ function resolvePartials(template) {
|
|
|
60
60
|
return resolved;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
function minifyCss(css) {
|
|
64
|
+
return css
|
|
65
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // remove comments
|
|
66
|
+
.replace(/\s*([{}:;,>~+])\s*/g, '$1') // remove whitespace around symbols
|
|
67
|
+
.replace(/\s+/g, ' ') // collapse whitespace
|
|
68
|
+
.replace(/;\s*}/g, '}') // remove trailing semicolons
|
|
69
|
+
.trim();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function minifyJs(js) {
|
|
73
|
+
// Light minification — remove comments and collapse whitespace (no AST transform)
|
|
74
|
+
return js
|
|
75
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // remove block comments
|
|
76
|
+
.replace(/\/\/.*$/gm, '') // remove line comments
|
|
77
|
+
.replace(/^\s*\n/gm, '') // remove empty lines
|
|
78
|
+
.replace(/\n\s+/g, '\n') // reduce leading whitespace
|
|
79
|
+
.trim();
|
|
80
|
+
}
|
|
81
|
+
|
|
63
82
|
function build() {
|
|
64
|
-
|
|
83
|
+
const doMinify = process.argv.includes('--minify');
|
|
84
|
+
console.log('[build-html] Starting build...' + (doMinify ? ' (minified)' : ''));
|
|
65
85
|
|
|
66
86
|
// Read template
|
|
67
87
|
if (!fs.existsSync(TEMPLATE_FILE)) {
|
|
@@ -80,12 +100,14 @@ function build() {
|
|
|
80
100
|
// Read and concatenate CSS files
|
|
81
101
|
const cssFiles = readSortedFiles(STYLES_DIR, '.css');
|
|
82
102
|
console.log(`[build-html] CSS files: ${cssFiles.map(f => f.name).join(', ')}`);
|
|
83
|
-
|
|
103
|
+
let css = cssFiles.map(f => `/* --- ${f.name} --- */\n${f.content}`).join('\n\n');
|
|
104
|
+
if (doMinify) css = minifyCss(css);
|
|
84
105
|
|
|
85
106
|
// Read and concatenate JS files
|
|
86
107
|
const jsFiles = readSortedFiles(SCRIPTS_DIR, '.js');
|
|
87
108
|
console.log(`[build-html] JS files: ${jsFiles.map(f => f.name).join(', ')}`);
|
|
88
|
-
|
|
109
|
+
let js = jsFiles.map(f => `/* --- ${f.name} --- */\n${f.content}`).join('\n\n');
|
|
110
|
+
if (doMinify) js = minifyJs(js);
|
|
89
111
|
|
|
90
112
|
// Inject into template
|
|
91
113
|
template = template.replace('<!-- CSS_PLACEHOLDER -->', css);
|
package/templates/skills/{ba-generate-html → business-analyse-html}/html/src/scripts/01-data-init.js
RENAMED
|
@@ -73,8 +73,23 @@ data.moduleSpecs = data.moduleSpecs || {};
|
|
|
73
73
|
if (!data.moduleSpecs[m.code].screens) {
|
|
74
74
|
data.moduleSpecs[m.code].screens = [];
|
|
75
75
|
}
|
|
76
|
+
// Ensure sections have initialized arrays for hierarchical data
|
|
77
|
+
m.anticipatedSections.forEach(function(section) {
|
|
78
|
+
section.useCases = section.useCases || [];
|
|
79
|
+
section.businessRules = section.businessRules || [];
|
|
80
|
+
section.resources = section.resources || [];
|
|
81
|
+
section.permission = section.permission || '';
|
|
82
|
+
section.route = section.route || '';
|
|
83
|
+
});
|
|
76
84
|
});
|
|
77
85
|
|
|
86
|
+
// Detect if modules use section-level specs (hierarchical mode)
|
|
87
|
+
function hasHierarchicalSpecs(mod) {
|
|
88
|
+
return (mod.anticipatedSections || []).some(function(s) {
|
|
89
|
+
return (s.useCases && s.useCases.length > 0) || (s.businessRules && s.businessRules.length > 0);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
78
93
|
// Defensive: normalize stakeholder tasks (string → array)
|
|
79
94
|
(data.cadrage.stakeholders || []).forEach(function(s) {
|
|
80
95
|
if (typeof s.tasks === 'string') {
|
|
@@ -146,6 +161,45 @@ function formatModuleType(t) {
|
|
|
146
161
|
return { 'data-centric': 'Données', 'workflow': 'Processus', 'reporting': 'Rapports', 'integration': 'Intégration', 'full-module': 'Complet' }[t] || t;
|
|
147
162
|
}
|
|
148
163
|
|
|
164
|
+
function escapeHtml(s) {
|
|
165
|
+
if (s == null) return '';
|
|
166
|
+
var d = document.createElement('div');
|
|
167
|
+
d.textContent = String(s);
|
|
168
|
+
return d.innerHTML;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function computeProgress() {
|
|
172
|
+
var totalModules = data.modules.length;
|
|
173
|
+
var modulesWithUC = 0, modulesWithBR = 0, modulesWithEntities = 0, modulesWithWireframes = 0;
|
|
174
|
+
var totalUCs = 0, totalBRs = 0, totalEntities = 0;
|
|
175
|
+
|
|
176
|
+
data.modules.forEach(function(m) {
|
|
177
|
+
var spec = data.moduleSpecs[m.code] || {};
|
|
178
|
+
var ucs = (spec.useCases || []).length;
|
|
179
|
+
var brs = (spec.businessRules || []).length;
|
|
180
|
+
var ents = (spec.entities || []).length;
|
|
181
|
+
var wfs = (EMBEDDED_ARTIFACTS?.wireframes?.[m.code] || []).length + (spec.screens || []).length;
|
|
182
|
+
totalUCs += ucs; totalBRs += brs; totalEntities += ents;
|
|
183
|
+
if (ucs > 0) modulesWithUC++;
|
|
184
|
+
if (brs > 0) modulesWithBR++;
|
|
185
|
+
if (ents > 0) modulesWithEntities++;
|
|
186
|
+
if (wfs > 0) modulesWithWireframes++;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
var checks = [];
|
|
190
|
+
if (totalModules > 0) checks.push({ done: true, label: 'Modules définis (' + totalModules + ')' });
|
|
191
|
+
checks.push({ done: modulesWithUC === totalModules && totalModules > 0, label: 'Cas d\'utilisation (' + modulesWithUC + '/' + totalModules + ' modules)' });
|
|
192
|
+
checks.push({ done: modulesWithBR === totalModules && totalModules > 0, label: 'Règles métier (' + modulesWithBR + '/' + totalModules + ' modules)' });
|
|
193
|
+
checks.push({ done: modulesWithEntities === totalModules && totalModules > 0, label: 'Données (' + modulesWithEntities + '/' + totalModules + ' modules)' });
|
|
194
|
+
checks.push({ done: modulesWithWireframes === totalModules && totalModules > 0, label: 'Maquettes (' + modulesWithWireframes + '/' + totalModules + ' modules)' });
|
|
195
|
+
checks.push({ done: data.cadrage.stakeholders.length > 0, label: 'Parties prenantes (' + data.cadrage.stakeholders.length + ')' });
|
|
196
|
+
checks.push({ done: (data.cadrage.scope.inscope || []).length > 0, label: 'Périmètre défini' });
|
|
197
|
+
|
|
198
|
+
var doneCount = checks.filter(function(c) { return c.done; }).length;
|
|
199
|
+
var pct = checks.length > 0 ? Math.round(doneCount / checks.length * 100) : 0;
|
|
200
|
+
return { checks: checks, doneCount: doneCount, total: checks.length, pct: pct, totalUCs: totalUCs, totalBRs: totalBRs, totalEntities: totalEntities };
|
|
201
|
+
}
|
|
202
|
+
|
|
149
203
|
/* ============================================
|
|
150
204
|
INITIALIZATION
|
|
151
205
|
============================================ */
|
|
@@ -174,17 +174,20 @@ function renderModuleNavItem(mod) {
|
|
|
174
174
|
if (sections.length > 0) {
|
|
175
175
|
sections.forEach(function(section) {
|
|
176
176
|
var resources = section.resources || [];
|
|
177
|
+
var sectionUCs = (section.useCases || []).length;
|
|
178
|
+
var sectionBRs = (section.businessRules || []).length;
|
|
179
|
+
var contentCount = sectionUCs + sectionBRs + resources.length;
|
|
177
180
|
html += '<div class="nav-section-item">';
|
|
178
181
|
html += '<a class="nav-item nav-section-link" onclick="showSection(\'module-spec-' + code + '\');switchTab(\'' + code + '\',\'struct\')" data-section="module-struct-' + code + '-' + section.code + '">';
|
|
179
|
-
html += '<span class="nav-icon nav-icon-section">▷</span> ' + section.code;
|
|
180
|
-
if (
|
|
182
|
+
html += '<span class="nav-icon nav-icon-section">▷</span> ' + escapeHtml(section.code || section.name || '');
|
|
183
|
+
if (contentCount > 0) html += ' <span class="nav-badge">' + contentCount + '</span>';
|
|
181
184
|
html += '</a>';
|
|
182
185
|
if (resources.length > 0) {
|
|
183
186
|
html += '<div class="nav-children nav-resources">';
|
|
184
187
|
resources.forEach(function(res) {
|
|
185
188
|
var resName = typeof res === 'string' ? res : (res.code || res.name || '');
|
|
186
189
|
html += '<a class="nav-item nav-resource-link">';
|
|
187
|
-
html += '<span class="nav-icon nav-icon-resource">•</span> ' + resName;
|
|
190
|
+
html += '<span class="nav-icon nav-icon-resource">•</span> ' + escapeHtml(resName);
|
|
188
191
|
html += '</a>';
|
|
189
192
|
});
|
|
190
193
|
html += '</div>';
|
|
@@ -250,3 +253,94 @@ function highlightActiveNavItem() {
|
|
|
250
253
|
var navItem = document.querySelector('#sidebarNav [data-section="' + currentSectionId + '"]');
|
|
251
254
|
if (navItem) navItem.classList.add('active');
|
|
252
255
|
}
|
|
256
|
+
|
|
257
|
+
/* ---------- Mobile Sidebar ---------- */
|
|
258
|
+
|
|
259
|
+
function toggleMobileSidebar() {
|
|
260
|
+
var sidebar = document.getElementById('sidebarAside');
|
|
261
|
+
var overlay = document.getElementById('sidebarOverlay');
|
|
262
|
+
if (!sidebar) return;
|
|
263
|
+
var isOpen = sidebar.classList.contains('mobile-open');
|
|
264
|
+
sidebar.classList.toggle('mobile-open', !isOpen);
|
|
265
|
+
if (overlay) overlay.classList.toggle('visible', !isOpen);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* ---------- Search / Filter ---------- */
|
|
269
|
+
|
|
270
|
+
var _searchTimer;
|
|
271
|
+
function filterNavItems(query) {
|
|
272
|
+
clearTimeout(_searchTimer);
|
|
273
|
+
_searchTimer = setTimeout(function() { doFilterNavItems(query); }, 200);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function doFilterNavItems(query) {
|
|
277
|
+
var q = (query || '').toLowerCase().trim();
|
|
278
|
+
var nav = document.getElementById('sidebarNav');
|
|
279
|
+
if (!nav) return;
|
|
280
|
+
|
|
281
|
+
// Clear previous highlights
|
|
282
|
+
nav.querySelectorAll('.search-highlight').forEach(function(el) {
|
|
283
|
+
el.outerHTML = el.textContent;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
if (!q) {
|
|
287
|
+
// Show all items
|
|
288
|
+
nav.querySelectorAll('.nav-item, .nav-group, .nav-module, .nav-section-item').forEach(function(el) {
|
|
289
|
+
el.classList.remove('search-hidden');
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Filter nav items
|
|
295
|
+
var allItems = nav.querySelectorAll('.nav-item');
|
|
296
|
+
var visibleSections = new Set();
|
|
297
|
+
|
|
298
|
+
allItems.forEach(function(item) {
|
|
299
|
+
var text = item.textContent.toLowerCase();
|
|
300
|
+
if (text.includes(q)) {
|
|
301
|
+
item.classList.remove('search-hidden');
|
|
302
|
+
// Show parent groups
|
|
303
|
+
var parent = item.parentElement;
|
|
304
|
+
while (parent && parent.id !== 'sidebarNav') {
|
|
305
|
+
parent.classList.remove('search-hidden');
|
|
306
|
+
if (parent.querySelector(':scope > .nav-children')) {
|
|
307
|
+
var children = parent.querySelector(':scope > .nav-children');
|
|
308
|
+
if (children) children.style.display = '';
|
|
309
|
+
}
|
|
310
|
+
parent = parent.parentElement;
|
|
311
|
+
}
|
|
312
|
+
// Track section for content search
|
|
313
|
+
var sectionId = item.dataset.section;
|
|
314
|
+
if (sectionId) visibleSections.add(sectionId);
|
|
315
|
+
} else {
|
|
316
|
+
item.classList.add('search-hidden');
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Hide groups that have no visible children
|
|
321
|
+
nav.querySelectorAll('.nav-group, .nav-module').forEach(function(group) {
|
|
322
|
+
var visibleChildren = group.querySelectorAll('.nav-item:not(.search-hidden)');
|
|
323
|
+
if (visibleChildren.length === 0) {
|
|
324
|
+
group.classList.add('search-hidden');
|
|
325
|
+
} else {
|
|
326
|
+
group.classList.remove('search-hidden');
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// Also search in section content and show matching sections
|
|
331
|
+
document.querySelectorAll('.section').forEach(function(section) {
|
|
332
|
+
var text = section.textContent.toLowerCase();
|
|
333
|
+
if (text.includes(q) && !visibleSections.has(section.id)) {
|
|
334
|
+
// Unhide corresponding nav item
|
|
335
|
+
var navItem = nav.querySelector('[data-section="' + section.id + '"]');
|
|
336
|
+
if (navItem) {
|
|
337
|
+
navItem.classList.remove('search-hidden');
|
|
338
|
+
var parent = navItem.parentElement;
|
|
339
|
+
while (parent && parent.id !== 'sidebarNav') {
|
|
340
|
+
parent.classList.remove('search-hidden');
|
|
341
|
+
parent = parent.parentElement;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}
|
|
@@ -42,23 +42,24 @@ function renderStakeholders() {
|
|
|
42
42
|
grid.innerHTML = data.cadrage.stakeholders.map((s, i) => `
|
|
43
43
|
<div class="stakeholder-card">
|
|
44
44
|
<div style="display:flex;justify-content:space-between;align-items:start;">
|
|
45
|
-
<div class="stakeholder-role">${s.role}</div>
|
|
45
|
+
<div class="stakeholder-role">${escapeHtml(s.role)}</div>
|
|
46
46
|
<button class="btn btn-sm" onclick="removeStakeholder(${i})" style="opacity:0.5;font-size:0.7rem;">Supprimer</button>
|
|
47
47
|
</div>
|
|
48
|
-
<div class="stakeholder-function">${s.function || ''}</div>
|
|
48
|
+
<div class="stakeholder-function">${escapeHtml(s.function || '')}</div>
|
|
49
49
|
<ul class="stakeholder-tasks">
|
|
50
|
-
${(Array.isArray(s.tasks) ? s.tasks : typeof s.tasks === 'string' ? s.tasks.split(',').map(t => t.trim()).filter(Boolean) : []).map(t => '<li>' + t + '</li>').join('')}
|
|
50
|
+
${(Array.isArray(s.tasks) ? s.tasks : typeof s.tasks === 'string' ? s.tasks.split(',').map(t => t.trim()).filter(Boolean) : []).map(t => '<li>' + escapeHtml(t) + '</li>').join('')}
|
|
51
51
|
</ul>
|
|
52
52
|
<div class="stakeholder-meta">
|
|
53
53
|
<span>${formatFrequency(s.frequency)}</span>
|
|
54
54
|
<span>${formatAccess(s.access)}</span>
|
|
55
55
|
</div>
|
|
56
|
-
${s.frustrations ? '<div style="font-size:0.8rem;color:var(--warning);margin-top:0.5rem;font-style:italic;">' + s.frustrations + '</div>' : ''}
|
|
56
|
+
${s.frustrations ? '<div style="font-size:0.8rem;color:var(--warning);margin-top:0.5rem;font-style:italic;">' + escapeHtml(s.frustrations) + '</div>' : ''}
|
|
57
57
|
</div>
|
|
58
58
|
`).join('');
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function removeStakeholder(index) {
|
|
62
|
+
if (!confirm('Supprimer ce profil utilisateur ?')) return;
|
|
62
63
|
data.cadrage.stakeholders.splice(index, 1);
|
|
63
64
|
renderStakeholders();
|
|
64
65
|
updateCounts();
|
|
@@ -89,12 +90,12 @@ function renderScope() {
|
|
|
89
90
|
<div class="uc-item">
|
|
90
91
|
<div class="uc-header">
|
|
91
92
|
<span class="priority priority-${p}">${formatPriority(p)}</span>
|
|
92
|
-
<span class="uc-title">${item.name}</span>
|
|
93
|
+
<span class="uc-title">${escapeHtml(item.name)}</span>
|
|
93
94
|
<div class="uc-actions">
|
|
94
95
|
<button class="btn btn-sm" onclick="removeScopeItem('${p}',${i})">Supprimer</button>
|
|
95
96
|
</div>
|
|
96
97
|
</div>
|
|
97
|
-
${item.description ? '<div class="uc-detail">' + item.description + '</div>' : ''}
|
|
98
|
+
${item.description ? '<div class="uc-detail">' + escapeHtml(item.description) + '</div>' : ''}
|
|
98
99
|
</div>
|
|
99
100
|
`).join('');
|
|
100
101
|
});
|
|
@@ -139,7 +140,7 @@ function renderCriteria() {
|
|
|
139
140
|
container.innerHTML = criteria.map((c, i) => `
|
|
140
141
|
<div class="uc-item" style="display:flex;align-items:center;gap:0.75rem;">
|
|
141
142
|
<input type="checkbox" ${c.validated ? 'checked' : ''} onchange="toggleCriterion(${i})" style="cursor:pointer;width:18px;height:18px;flex-shrink:0;">
|
|
142
|
-
<span style="flex:1;${c.validated ? 'text-decoration:line-through;color:var(--text-muted);' : ''}">${c.text}</span>
|
|
143
|
+
<span style="flex:1;${c.validated ? 'text-decoration:line-through;color:var(--text-muted);' : ''}">${escapeHtml(c.text)}</span>
|
|
143
144
|
<button class="btn btn-sm" onclick="removeCriterion(${i})" style="opacity:0.5;flex-shrink:0;">✕</button>
|
|
144
145
|
</div>
|
|
145
146
|
`).join('');
|
|
@@ -55,10 +55,10 @@ function renderModules() {
|
|
|
55
55
|
<div class="module-card" onclick="showSection('module-spec-${m.code}')">
|
|
56
56
|
<button class="module-card-remove" onclick="event.stopPropagation();removeModule(${i})">✕</button>
|
|
57
57
|
<div class="module-card-header">
|
|
58
|
-
<span class="module-card-code">${m.name}</span>
|
|
58
|
+
<span class="module-card-code">${escapeHtml(m.name)}</span>
|
|
59
59
|
<span class="module-card-type">${formatModuleType(m.featureType)}</span>
|
|
60
60
|
</div>
|
|
61
|
-
<div class="module-card-desc">${m.description || ''}</div>
|
|
61
|
+
<div class="module-card-desc">${escapeHtml(m.description || '')}</div>
|
|
62
62
|
<div class="module-card-meta">
|
|
63
63
|
<span>${(m.entities || []).length} données</span>
|
|
64
64
|
<span>${(data.moduleSpecs[m.code]?.useCases || []).length} cas d'utilisation</span>
|
|
@@ -115,10 +115,10 @@ function renderDependencies() {
|
|
|
115
115
|
const toName = data.modules.find(m => m.code === d.to)?.name || d.to;
|
|
116
116
|
return `
|
|
117
117
|
<div class="interaction-item">
|
|
118
|
-
<span style="font-weight:600;color:var(--text-bright);">${fromName}</span>
|
|
118
|
+
<span style="font-weight:600;color:var(--text-bright);">${escapeHtml(fromName)}</span>
|
|
119
119
|
<span class="interaction-arrow">→</span>
|
|
120
|
-
<span style="font-weight:600;color:var(--text-bright);">${toName}</span>
|
|
121
|
-
<span style="flex:1;font-size:0.8rem;color:var(--text-muted);">${d.description || ''}</span>
|
|
120
|
+
<span style="font-weight:600;color:var(--text-bright);">${escapeHtml(toName)}</span>
|
|
121
|
+
<span style="flex:1;font-size:0.8rem;color:var(--text-muted);">${escapeHtml(d.description || '')}</span>
|
|
122
122
|
<button class="btn btn-sm" onclick="removeDependency(${i})" style="opacity:0.5;">Supprimer</button>
|
|
123
123
|
</div>
|
|
124
124
|
`;
|
|
@@ -147,7 +147,7 @@ function renderDepGraph() {
|
|
|
147
147
|
<div class="dep-layer-modules">
|
|
148
148
|
${layer.map(code => {
|
|
149
149
|
const m = data.modules.find(mod => mod.code === code);
|
|
150
|
-
return `<div class="dep-module">${m ? (m.name || m.code) : code}</div>`;
|
|
150
|
+
return `<div class="dep-module">${escapeHtml(m ? (m.name || m.code) : code)}</div>`;
|
|
151
151
|
}).join('')}
|
|
152
152
|
</div>
|
|
153
153
|
</div>
|
|
@@ -195,7 +195,7 @@ function renderProcessingOrder() {
|
|
|
195
195
|
return `
|
|
196
196
|
<div class="process-step">
|
|
197
197
|
<div class="process-step-number">Étape ${i + 1}</div>
|
|
198
|
-
<div class="process-step-label">${m ? (m.name || m.code) : code}</div>
|
|
198
|
+
<div class="process-step-label">${escapeHtml(m ? (m.name || m.code) : code)}</div>
|
|
199
199
|
</div>
|
|
200
200
|
${i < order.length - 1 ? '<div class="process-arrow">→</div>' : ''}
|
|
201
201
|
`;
|