@atlashub/smartstack-cli 4.18.0 → 4.20.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/package.json +1 -1
- package/templates/agents/ba-reader.md +86 -80
- package/templates/agents/ba-writer.md +318 -415
- package/templates/agents/docs-context-reader.md +3 -3
- package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +133 -0
- package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +126 -0
- package/templates/skills/apex/SKILL.md +29 -16
- package/templates/skills/apex/_shared.md +62 -9
- package/templates/skills/apex/references/analysis-methods.md +8 -6
- package/templates/skills/apex/references/challenge-questions.md +5 -5
- package/templates/skills/apex/references/core-seed-data.md +68 -45
- package/templates/skills/apex/references/frontend-route-wiring-app-tsx.md +26 -21
- package/templates/skills/apex/references/parallel-execution.md +156 -0
- package/templates/skills/apex/references/person-extension-pattern.md +12 -12
- package/templates/skills/apex/references/post-checks.md +1748 -1726
- package/templates/skills/apex/references/smartstack-api.md +63 -57
- package/templates/skills/apex/references/smartstack-frontend-compliance.md +594 -0
- package/templates/skills/apex/references/smartstack-frontend.md +1246 -1842
- package/templates/skills/apex/references/smartstack-layers.md +98 -145
- package/templates/skills/apex/steps/step-00-init.md +30 -6
- package/templates/skills/apex/steps/step-01-analyze.md +27 -23
- package/templates/skills/apex/steps/step-02-plan.md +12 -12
- package/templates/skills/apex/steps/step-03-execute.md +198 -143
- package/templates/skills/apex/steps/step-04-examine.md +24 -93
- package/templates/skills/apex/steps/step-05-deep-review.md +16 -16
- package/templates/skills/apex/steps/step-06-resolve.md +9 -9
- package/templates/skills/apex/steps/step-07-tests.md +3 -1
- package/templates/skills/apex/steps/step-08-run-tests.md +1 -1
- package/templates/skills/business-analyse/SKILL.md +182 -301
- package/templates/skills/business-analyse/_shared.md +119 -336
- package/templates/skills/business-analyse/html/ba-interactive.html +706 -85
- package/templates/skills/business-analyse/html/build-html.js +41 -3
- package/templates/skills/business-analyse/html/src/partials/cadrage-context.html +34 -0
- package/templates/skills/business-analyse/html/src/partials/cadrage-risks.html +48 -0
- package/templates/skills/business-analyse/html/src/partials/cadrage-scope.html +49 -0
- package/templates/skills/business-analyse/html/src/partials/cadrage-stakeholders.html +55 -0
- package/templates/skills/business-analyse/html/src/partials/cadrage-success.html +34 -0
- package/templates/skills/business-analyse/html/src/partials/consol-datamodel.html +8 -0
- package/templates/skills/business-analyse/html/src/partials/consol-flows.html +29 -0
- package/templates/skills/business-analyse/html/src/partials/consol-interactions.html +8 -0
- package/templates/skills/business-analyse/html/src/partials/consol-permissions.html +8 -0
- package/templates/skills/business-analyse/html/src/partials/decomp-dependencies.html +38 -0
- package/templates/skills/business-analyse/html/src/partials/decomp-modules.html +51 -0
- package/templates/skills/business-analyse/html/src/partials/handoff-summary.html +24 -0
- package/templates/skills/business-analyse/html/src/partials/module-spec-container.html +4 -0
- package/templates/skills/business-analyse/html/src/scripts/01-data-init.js +17 -1
- package/templates/skills/business-analyse/html/src/scripts/02-navigation.js +32 -6
- package/templates/skills/business-analyse/html/src/scripts/05-render-specs.js +100 -63
- package/templates/skills/business-analyse/html/src/scripts/06-render-mockups.js +372 -0
- package/templates/skills/business-analyse/html/src/scripts/07-render-handoff.js +1 -1
- package/templates/skills/business-analyse/html/src/scripts/10-comments.js +41 -13
- package/templates/skills/business-analyse/html/src/styles/09-mockups-html.css +136 -0
- package/templates/skills/business-analyse/html/src/template.html +1 -1
- package/templates/skills/business-analyse/patterns/suggestion-catalog.md +7 -5
- package/templates/skills/business-analyse/questionnaire/01-context.md +11 -157
- package/templates/skills/business-analyse/questionnaire/02-stakeholders-scope.md +101 -0
- package/templates/skills/business-analyse/questionnaire/03-data-ui.md +92 -0
- package/templates/skills/business-analyse/questionnaire/04-risks-metrics.md +6 -0
- package/templates/skills/business-analyse/questionnaire/05-cross-module.md +69 -0
- package/templates/skills/business-analyse/questionnaire.md +22 -280
- package/templates/skills/business-analyse/react/application-viewer.md +2 -2
- package/templates/skills/business-analyse/react/components.md +4 -4
- package/templates/skills/business-analyse/react/i18n-template.md +1 -1
- package/templates/skills/business-analyse/react/schema.md +14 -14
- package/templates/skills/business-analyse/references/acceptance-criteria.md +21 -21
- package/templates/skills/business-analyse/references/analysis-semantic-checks.md +3 -3
- package/templates/skills/business-analyse/references/compilation-structure-cards.md +1 -1
- package/templates/skills/business-analyse/references/consolidation-structural-checks.md +5 -5
- package/templates/skills/business-analyse/references/deploy-data-build.md +12 -11
- package/templates/skills/business-analyse/references/deploy-modes.md +10 -10
- package/templates/skills/business-analyse/references/detection-strategies.md +6 -6
- package/templates/skills/business-analyse/references/html-data-mapping.md +15 -15
- package/templates/skills/business-analyse/references/naming-conventions.md +4 -4
- package/templates/skills/business-analyse/references/review-data-mapping.md +29 -29
- package/templates/skills/business-analyse/references/robustness-checks.md +36 -36
- package/templates/skills/business-analyse/references/spec-auto-inference.md +2 -2
- package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
- package/templates/skills/business-analyse/references/ui-resource-cards.md +1 -1
- package/templates/skills/business-analyse/references/validation-checklist.md +3 -3
- package/templates/skills/business-analyse/references/wireframe-svg-style-guide.md +2 -2
- package/templates/skills/business-analyse/schemas/application-schema.json +8 -8
- package/templates/skills/business-analyse/schemas/feature-schema.json +3 -3
- package/templates/skills/business-analyse/schemas/index-schema.json +47 -0
- package/templates/skills/business-analyse/schemas/project-schema.json +6 -6
- package/templates/skills/business-analyse/schemas/sections/analysis-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/sections/handoff-schema.json +5 -3
- package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +4 -4
- package/templates/skills/business-analyse/schemas/sections/specification-schema.json +1 -1
- package/templates/skills/business-analyse/schemas/shared/common-defs.json +4 -4
- package/templates/skills/business-analyse/steps/step-00-init.md +68 -77
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +50 -216
- package/templates/skills/business-analyse/steps/step-02-structure.md +175 -0
- package/templates/skills/business-analyse/steps/step-03-specify.md +198 -0
- package/templates/skills/business-analyse/steps/step-04-consolidate.md +478 -0
- package/templates/skills/business-analyse/steps/step-05-deploy.md +220 -0
- package/templates/skills/business-analyse/steps/step-06-review.md +51 -69
- package/templates/skills/business-analyse/templates/tpl-frd.md +1 -1
- package/templates/skills/business-analyse/templates/tpl-handoff.md +20 -17
- package/templates/skills/business-analyse/templates/tpl-launch-displays.md +2 -2
- package/templates/skills/business-analyse/templates-react.md +2 -2
- package/templates/skills/derive-prd/SKILL.md +92 -0
- package/templates/skills/derive-prd/references/acceptance-criteria.md +169 -0
- package/templates/skills/derive-prd/references/entity-domain-mapping.md +115 -0
- package/templates/skills/{business-analyse → derive-prd}/references/handoff-file-templates.md +131 -120
- package/templates/skills/{business-analyse → derive-prd}/references/handoff-mappings.md +95 -95
- package/templates/skills/{business-analyse → derive-prd}/references/handoff-seeddata-generation.md +312 -312
- package/templates/skills/{business-analyse → derive-prd}/references/prd-generation.md +262 -263
- package/templates/skills/derive-prd/references/readiness-scoring.md +104 -0
- package/templates/skills/derive-prd/schemas/handoff-schema.json +95 -0
- package/templates/skills/derive-prd/steps/step-00-validate.md +130 -0
- package/templates/skills/derive-prd/steps/step-01-transform.md +206 -0
- package/templates/skills/derive-prd/steps/step-02-export.md +181 -0
- package/templates/skills/{business-analyse → derive-prd}/templates/tpl-progress.md +172 -172
- package/templates/skills/documentation/SKILL.md +7 -0
- package/templates/skills/ralph-loop/SKILL.md +2 -1
- package/templates/skills/ralph-loop/references/init-resume-recovery.md +1 -1
- package/templates/skills/ralph-loop/steps/step-01-task.md +2 -2
- package/templates/skills/apex/references/agent-teams-protocol.md +0 -203
- package/templates/skills/business-analyse/_architecture.md +0 -124
- package/templates/skills/business-analyse/_elicitation.md +0 -206
- package/templates/skills/business-analyse/_module-loop.md +0 -115
- package/templates/skills/business-analyse/_rules.md +0 -142
- package/templates/skills/business-analyse/_suggestions.md +0 -34
- package/templates/skills/business-analyse/questionnaire/00-application.md +0 -160
- package/templates/skills/business-analyse/questionnaire/00b-project.md +0 -85
- package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +0 -189
- package/templates/skills/business-analyse/questionnaire/03-scope.md +0 -164
- package/templates/skills/business-analyse/questionnaire/04-data.md +0 -88
- package/templates/skills/business-analyse/questionnaire/05-integrations.md +0 -58
- package/templates/skills/business-analyse/questionnaire/06-security.md +0 -68
- package/templates/skills/business-analyse/questionnaire/07-ui.md +0 -76
- package/templates/skills/business-analyse/questionnaire/08-performance.md +0 -42
- package/templates/skills/business-analyse/questionnaire/09-constraints.md +0 -45
- package/templates/skills/business-analyse/questionnaire/10-documentation.md +0 -58
- package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +0 -59
- package/templates/skills/business-analyse/questionnaire/12-migration.md +0 -58
- package/templates/skills/business-analyse/questionnaire/13-cross-module.md +0 -69
- package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +0 -135
- package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +0 -136
- package/templates/skills/business-analyse/references/agent-module-prompt.md +0 -366
- package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +0 -557
- package/templates/skills/business-analyse/references/cache-warming-strategy.md +0 -566
- package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +0 -41
- package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +0 -74
- package/templates/skills/business-analyse/references/cadrage-pre-analysis.md +0 -115
- package/templates/skills/business-analyse/references/cadrage-shared-modules.md +0 -68
- package/templates/skills/business-analyse/references/cadrage-structure-cards.md +0 -85
- package/templates/skills/business-analyse/references/team-orchestration.md +0 -1093
- package/templates/skills/business-analyse/references/validate-incremental-html.md +0 -121
- package/templates/skills/business-analyse/steps/step-01b-applications.md +0 -419
- package/templates/skills/business-analyse/steps/step-02-decomposition.md +0 -387
- package/templates/skills/business-analyse/steps/step-03a-data.md +0 -16
- package/templates/skills/business-analyse/steps/step-03a1-setup.md +0 -486
- package/templates/skills/business-analyse/steps/step-03a2-analysis.md +0 -300
- package/templates/skills/business-analyse/steps/step-03b-ui.md +0 -405
- package/templates/skills/business-analyse/steps/step-03c-compile.md +0 -516
- package/templates/skills/business-analyse/steps/step-03d-validate.md +0 -691
- package/templates/skills/business-analyse/steps/step-04-consolidation.md +0 -17
- package/templates/skills/business-analyse/steps/step-04a-collect.md +0 -415
- package/templates/skills/business-analyse/steps/step-04b-analyze.md +0 -163
- package/templates/skills/business-analyse/steps/step-04c-decide.md +0 -186
- package/templates/skills/business-analyse/steps/step-05a-handoff.md +0 -937
- package/templates/skills/business-analyse/steps/step-05b-deploy.md +0 -522
- package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +0 -703
|
@@ -313,7 +313,10 @@ function renderEntity(code, ent, index) {
|
|
|
313
313
|
<tbody>
|
|
314
314
|
${ent.attributes.map(a => `<tr><td style="font-weight:500;color:var(--text-bright);">${a.name}</td><td>${a.description || ''}</td></tr>`).join('')}
|
|
315
315
|
</tbody>
|
|
316
|
-
</table
|
|
316
|
+
</table>
|
|
317
|
+
<div style="padding:0.3rem 0.75rem;">
|
|
318
|
+
<button class="add-btn" style="font-size:0.75rem;padding:0.4rem;" onclick="addEntityAttribute('${code}',${index})">+ Ajouter un attribut</button>
|
|
319
|
+
</div>` : ''}
|
|
317
320
|
${(ent.relationships || []).length > 0 ? `
|
|
318
321
|
<div style="padding:0.5rem 0.75rem;font-size:0.8rem;color:var(--text-muted);border-top:1px solid var(--border);">
|
|
319
322
|
Relations : ${ent.relationships.map(r => `<span style="color:var(--accent);">${r}</span>`).join(', ')}
|
|
@@ -355,6 +358,19 @@ function removeEntity(code, index) {
|
|
|
355
358
|
autoSave();
|
|
356
359
|
}
|
|
357
360
|
|
|
361
|
+
function addEntityAttribute(code, entityIndex) {
|
|
362
|
+
var attrName = prompt('Nom de l\'attribut :');
|
|
363
|
+
if (!attrName) return;
|
|
364
|
+
var attrDesc = prompt('Description (optionnel) :') || '';
|
|
365
|
+
if (!data.moduleSpecs[code]?.entities?.[entityIndex]) return;
|
|
366
|
+
if (!data.moduleSpecs[code].entities[entityIndex].attributes) {
|
|
367
|
+
data.moduleSpecs[code].entities[entityIndex].attributes = [];
|
|
368
|
+
}
|
|
369
|
+
data.moduleSpecs[code].entities[entityIndex].attributes.push({ name: attrName, description: attrDesc });
|
|
370
|
+
renderAllModuleSpecs();
|
|
371
|
+
autoSave();
|
|
372
|
+
}
|
|
373
|
+
|
|
358
374
|
function getSpecComment(code, type, index) {
|
|
359
375
|
const key = code + '.' + type + '.' + index;
|
|
360
376
|
return data.specComments[key] || '';
|
|
@@ -377,8 +393,25 @@ function updateWireframeComment(code, screen, value) {
|
|
|
377
393
|
}
|
|
378
394
|
|
|
379
395
|
function renderModuleMockups(code) {
|
|
380
|
-
|
|
396
|
+
var spec = data.moduleSpecs[code] || {};
|
|
397
|
+
var screens = spec.screens || [];
|
|
398
|
+
var wireframes = EMBEDDED_ARTIFACTS?.wireframes?.[code] || [];
|
|
399
|
+
|
|
400
|
+
// Priority 1: HTML mockups from screens[] specs
|
|
401
|
+
if (screens.length > 0) {
|
|
402
|
+
var html = '';
|
|
403
|
+
if (typeof renderScreenMockups === 'function') {
|
|
404
|
+
html = renderScreenMockups(code);
|
|
405
|
+
}
|
|
406
|
+
// Also show wireframes below if available
|
|
407
|
+
if (wireframes.length > 0) {
|
|
408
|
+
html += '<h3 style="color:var(--text-bright);font-size:1rem;margin:2rem 0 1rem;">Wireframes</h3>';
|
|
409
|
+
html += wireframes.map(function(wf, i) { return renderWireframeMockup(code, wf, i); }).join('');
|
|
410
|
+
}
|
|
411
|
+
return html;
|
|
412
|
+
}
|
|
381
413
|
|
|
414
|
+
// Priority 2: Wireframes from EMBEDDED_ARTIFACTS
|
|
382
415
|
if (wireframes.length === 0) {
|
|
383
416
|
return `
|
|
384
417
|
<div class="card" style="text-align:center;padding:2rem;color:var(--text-muted);">
|
|
@@ -387,69 +420,73 @@ function renderModuleMockups(code) {
|
|
|
387
420
|
</div>`;
|
|
388
421
|
}
|
|
389
422
|
|
|
390
|
-
return wireframes.map((wf, i)
|
|
391
|
-
|
|
392
|
-
const wireframeId = `wf-${code}-${i}`;
|
|
423
|
+
return wireframes.map(function(wf, i) { return renderWireframeMockup(code, wf, i); }).join('');
|
|
424
|
+
}
|
|
393
425
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
${
|
|
409
|
-
? `<div class="svg-wireframe wireframe-view active" data-view="svg">${wf.svgContent}</div>
|
|
410
|
-
<pre class="ascii-wireframe wireframe-view" data-view="ascii" style="display:none;">${wf.content || ''}</pre>`
|
|
411
|
-
: (wf.format === 'ascii'
|
|
412
|
-
? `<pre class="ascii-wireframe">${wf.content || ''}</pre>`
|
|
413
|
-
: `<div class="svg-wireframe">${wf.content || ''}</div>`)}
|
|
414
|
-
</div>
|
|
415
|
-
${wf.description ? `
|
|
416
|
-
<div class="wireframe-description">
|
|
417
|
-
<strong>Description:</strong> ${wf.description}
|
|
418
|
-
</div>` : ''}
|
|
419
|
-
${(wf.elements || []).length > 0 ? `
|
|
420
|
-
<div class="wireframe-metadata">
|
|
421
|
-
<div><strong>Elements:</strong> ${wf.elements.map(e => typeof e === 'string' ? e : (e.type || e.label || e.id || '')).filter(Boolean).join(', ')}</div>
|
|
426
|
+
function renderWireframeMockup(code, wf, i) {
|
|
427
|
+
const hasSvg = !!wf.svgContent;
|
|
428
|
+
const wireframeId = `wf-${code}-${i}`;
|
|
429
|
+
|
|
430
|
+
return `
|
|
431
|
+
<div class="mockup-frame" style="${i > 0 ? 'margin-top:1.5rem;' : ''}">
|
|
432
|
+
<div class="mockup-toolbar">
|
|
433
|
+
<div class="mockup-dot mockup-dot-red"></div>
|
|
434
|
+
<div class="mockup-dot mockup-dot-yellow"></div>
|
|
435
|
+
<div class="mockup-dot mockup-dot-green"></div>
|
|
436
|
+
<span class="mockup-title">${wf.screen || wf.section}</span>
|
|
437
|
+
${hasSvg ? `
|
|
438
|
+
<div class="wireframe-toggle">
|
|
439
|
+
<button class="wireframe-toggle-btn active" data-target="${wireframeId}" data-view="svg" onclick="toggleWireframeView('${wireframeId}', 'svg')">SVG</button>
|
|
440
|
+
<button class="wireframe-toggle-btn" data-target="${wireframeId}" data-view="ascii" onclick="toggleWireframeView('${wireframeId}', 'ascii')">ASCII</button>
|
|
422
441
|
</div>` : ''}
|
|
423
|
-
${(() => {
|
|
424
|
-
const cm = wf.componentMapping;
|
|
425
|
-
const mappings = Array.isArray(cm) ? cm
|
|
426
|
-
: (typeof cm === 'object' && cm !== null) ? Object.entries(cm).map(([k,v]) => ({wireframeElement: k, reactComponent: v}))
|
|
427
|
-
: [];
|
|
428
|
-
return mappings.length > 0 ? `
|
|
429
|
-
<details class="wireframe-details">
|
|
430
|
-
<summary>Mapping composants SmartStack</summary>
|
|
431
|
-
<table class="mapping-table">
|
|
432
|
-
<thead><tr><th>Element maquette</th><th>Composant React</th></tr></thead>
|
|
433
|
-
<tbody>
|
|
434
|
-
${mappings.map(m =>
|
|
435
|
-
'<tr><td>' + (m.wireframeElement || '') + '</td><td><code>' + (m.reactComponent || '') + '</code></td></tr>'
|
|
436
|
-
).join('')}
|
|
437
|
-
</tbody>
|
|
438
|
-
</table>
|
|
439
|
-
</details>` : '';
|
|
440
|
-
})()}
|
|
441
|
-
<div class="wireframe-comment">
|
|
442
|
-
<label style="font-size:0.8rem;color:var(--text-muted);display:block;margin-bottom:0.3rem;">Commentaire / Feedback :</label>
|
|
443
|
-
<textarea class="form-textarea"
|
|
444
|
-
data-module="${code}"
|
|
445
|
-
data-screen="${wf.screen}"
|
|
446
|
-
placeholder="Ajouter un commentaire sur cette maquette (ex: deplacer ce bouton, ajouter une colonne...)"
|
|
447
|
-
onblur="updateWireframeComment('${code}', '${wf.screen}', this.value)"
|
|
448
|
-
style="min-height:60px;font-size:0.85rem;resize:vertical;"
|
|
449
|
-
>${getWireframeComment(code, wf.screen)}</textarea>
|
|
450
|
-
</div>
|
|
451
442
|
</div>
|
|
452
|
-
|
|
443
|
+
<div class="mockup-content" id="${wireframeId}">
|
|
444
|
+
${hasSvg
|
|
445
|
+
? `<div class="svg-wireframe wireframe-view active" data-view="svg">${wf.svgContent}</div>
|
|
446
|
+
<pre class="ascii-wireframe wireframe-view" data-view="ascii" style="display:none;">${wf.content || ''}</pre>`
|
|
447
|
+
: (wf.format === 'ascii'
|
|
448
|
+
? `<pre class="ascii-wireframe">${wf.content || ''}</pre>`
|
|
449
|
+
: `<div class="svg-wireframe">${wf.content || ''}</div>`)}
|
|
450
|
+
</div>
|
|
451
|
+
${wf.description ? `
|
|
452
|
+
<div class="wireframe-description">
|
|
453
|
+
<strong>Description:</strong> ${wf.description}
|
|
454
|
+
</div>` : ''}
|
|
455
|
+
${(wf.elements || []).length > 0 ? `
|
|
456
|
+
<div class="wireframe-metadata">
|
|
457
|
+
<div><strong>Elements:</strong> ${wf.elements.map(e => typeof e === 'string' ? e : (e.type || e.label || e.id || '')).filter(Boolean).join(', ')}</div>
|
|
458
|
+
</div>` : ''}
|
|
459
|
+
${(() => {
|
|
460
|
+
const cm = wf.componentMapping;
|
|
461
|
+
const mappings = Array.isArray(cm) ? cm
|
|
462
|
+
: (typeof cm === 'object' && cm !== null) ? Object.entries(cm).map(([k,v]) => ({wireframeElement: k, reactComponent: v}))
|
|
463
|
+
: [];
|
|
464
|
+
return mappings.length > 0 ? `
|
|
465
|
+
<details class="wireframe-details">
|
|
466
|
+
<summary>Mapping composants SmartStack</summary>
|
|
467
|
+
<table class="mapping-table">
|
|
468
|
+
<thead><tr><th>Element maquette</th><th>Composant React</th></tr></thead>
|
|
469
|
+
<tbody>
|
|
470
|
+
${mappings.map(m =>
|
|
471
|
+
'<tr><td>' + (m.wireframeElement || '') + '</td><td><code>' + (m.reactComponent || '') + '</code></td></tr>'
|
|
472
|
+
).join('')}
|
|
473
|
+
</tbody>
|
|
474
|
+
</table>
|
|
475
|
+
</details>` : '';
|
|
476
|
+
})()}
|
|
477
|
+
<div class="wireframe-comment">
|
|
478
|
+
<label style="font-size:0.8rem;color:var(--text-muted);display:block;margin-bottom:0.3rem;">Commentaire / Feedback :</label>
|
|
479
|
+
<textarea class="form-textarea"
|
|
480
|
+
data-module="${code}"
|
|
481
|
+
data-screen="${wf.screen}"
|
|
482
|
+
placeholder="Ajouter un commentaire sur cette maquette (ex: deplacer ce bouton, ajouter une colonne...)"
|
|
483
|
+
onblur="updateWireframeComment('${code}', '${wf.screen}', this.value)"
|
|
484
|
+
style="min-height:60px;font-size:0.85rem;resize:vertical;"
|
|
485
|
+
>${getWireframeComment(code, wf.screen)}</textarea>
|
|
486
|
+
</div>
|
|
487
|
+
</div>
|
|
488
|
+
`;
|
|
489
|
+
}
|
|
453
490
|
}
|
|
454
491
|
|
|
455
492
|
function toggleWireframeView(wireframeId, view) {
|
|
@@ -473,7 +510,7 @@ function toggleWireframeView(wireframeId, view) {
|
|
|
473
510
|
}
|
|
474
511
|
|
|
475
512
|
function getPermRoles() {
|
|
476
|
-
// Extract roles from actual permission data (handles English role names from
|
|
513
|
+
// Extract roles from actual permission data (handles English role names from JSON data)
|
|
477
514
|
const rolesFromPerms = [];
|
|
478
515
|
const seen = new Set();
|
|
479
516
|
data.modules.forEach(m => {
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
HTML MOCKUP RENDERER
|
|
3
|
+
Generates realistic HTML mockups from screens[] specs
|
|
4
|
+
============================================ */
|
|
5
|
+
|
|
6
|
+
function renderScreenMockups(code) {
|
|
7
|
+
var spec = data.moduleSpecs[code] || {};
|
|
8
|
+
var screens = spec.screens || [];
|
|
9
|
+
|
|
10
|
+
if (screens.length === 0) return '';
|
|
11
|
+
|
|
12
|
+
return screens.map(function(screen, si) {
|
|
13
|
+
var resources = screen.resources || [];
|
|
14
|
+
return '<div class="screen-section" style="margin-bottom:2rem;">' +
|
|
15
|
+
'<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:1rem;">' +
|
|
16
|
+
'<span style="color:var(--accent);">▸</span> ' + (screen.sectionLabel || screen.sectionCode) +
|
|
17
|
+
'</h3>' +
|
|
18
|
+
resources.map(function(res, ri) {
|
|
19
|
+
return renderResourceMockup(code, screen.sectionCode, res, ri);
|
|
20
|
+
}).join('') +
|
|
21
|
+
'</div>';
|
|
22
|
+
}).join('');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function renderResourceMockup(code, sectionCode, res, index) {
|
|
26
|
+
var mockupId = 'mockup-' + code + '-' + sectionCode + '-' + index;
|
|
27
|
+
var html = '<div class="mockup-frame" style="margin-bottom:1.5rem;">';
|
|
28
|
+
|
|
29
|
+
// Browser chrome
|
|
30
|
+
html += '<div class="mockup-toolbar">';
|
|
31
|
+
html += '<div class="mockup-dot mockup-dot-red"></div>';
|
|
32
|
+
html += '<div class="mockup-dot mockup-dot-yellow"></div>';
|
|
33
|
+
html += '<div class="mockup-dot mockup-dot-green"></div>';
|
|
34
|
+
html += '<span class="mockup-title">' + (res.label || res.code) + ' (' + res.type + ')</span>';
|
|
35
|
+
if (res.permission) {
|
|
36
|
+
html += '<span style="margin-left:auto;font-size:0.65rem;color:var(--text-muted);background:var(--bg-dark);padding:0.15rem 0.5rem;border-radius:4px;">' + res.permission + '</span>';
|
|
37
|
+
}
|
|
38
|
+
html += '</div>';
|
|
39
|
+
|
|
40
|
+
// Mockup content
|
|
41
|
+
html += '<div class="mockup-content" id="' + mockupId + '">';
|
|
42
|
+
switch (res.type) {
|
|
43
|
+
case 'SmartTable':
|
|
44
|
+
html += renderSmartTableMockup(res);
|
|
45
|
+
break;
|
|
46
|
+
case 'SmartForm':
|
|
47
|
+
html += renderSmartFormMockup(res);
|
|
48
|
+
break;
|
|
49
|
+
case 'SmartCard':
|
|
50
|
+
html += renderSmartCardMockup(res);
|
|
51
|
+
break;
|
|
52
|
+
case 'SmartKanban':
|
|
53
|
+
html += renderSmartKanbanMockup(res);
|
|
54
|
+
break;
|
|
55
|
+
case 'SmartDashboard':
|
|
56
|
+
html += renderSmartDashboardMockup(res);
|
|
57
|
+
break;
|
|
58
|
+
case 'SmartFilter':
|
|
59
|
+
html += renderSmartFilterMockup(res);
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
html += '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Composant ' + res.type + ' - maquette non disponible</div>';
|
|
63
|
+
}
|
|
64
|
+
html += '</div>';
|
|
65
|
+
|
|
66
|
+
// Notes
|
|
67
|
+
if (res.notes) {
|
|
68
|
+
html += '<div style="padding:0.5rem 1rem;font-size:0.8rem;color:var(--text-muted);border-top:1px solid var(--border);background:var(--bg-input);">';
|
|
69
|
+
html += '<strong>Notes:</strong> ' + res.notes;
|
|
70
|
+
html += '</div>';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Comment area
|
|
74
|
+
html += '<div class="wireframe-comment">';
|
|
75
|
+
html += '<label style="font-size:0.8rem;color:var(--text-muted);display:block;margin-bottom:0.3rem;">Commentaire :</label>';
|
|
76
|
+
html += '<textarea class="form-textarea" placeholder="Commentaire sur cette maquette..."';
|
|
77
|
+
html += ' onblur="updateWireframeComment(\'' + code + '\', \'' + (res.code || sectionCode + '-' + index) + '\', this.value)"';
|
|
78
|
+
html += ' style="min-height:50px;font-size:0.85rem;resize:vertical;">';
|
|
79
|
+
html += getWireframeComment(code, res.code || sectionCode + '-' + index);
|
|
80
|
+
html += '</textarea>';
|
|
81
|
+
html += '</div>';
|
|
82
|
+
|
|
83
|
+
html += '</div>';
|
|
84
|
+
return html;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ---------- SmartTable ---------- */
|
|
88
|
+
function renderSmartTableMockup(res) {
|
|
89
|
+
var columns = res.columns || [];
|
|
90
|
+
if (columns.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Table sans colonnes definies</div>';
|
|
91
|
+
|
|
92
|
+
var html = '';
|
|
93
|
+
|
|
94
|
+
// Header with actions
|
|
95
|
+
html += '<div class="mock-header">';
|
|
96
|
+
html += '<span class="mock-title">' + (res.label || 'Liste') + '</span>';
|
|
97
|
+
html += '<div style="display:flex;gap:0.4rem;">';
|
|
98
|
+
(res.actions || []).forEach(function(action) {
|
|
99
|
+
var isPrimary = action === 'create' || action === 'export';
|
|
100
|
+
html += '<span class="mock-btn' + (isPrimary ? '' : '" style="background:var(--bg-hover);color:var(--text)') + '">' + formatActionLabel(action) + '</span>';
|
|
101
|
+
});
|
|
102
|
+
html += '</div></div>';
|
|
103
|
+
|
|
104
|
+
// Filters
|
|
105
|
+
if (res.filters && res.filters.length > 0) {
|
|
106
|
+
html += '<div style="display:flex;gap:0.5rem;margin-bottom:1rem;">';
|
|
107
|
+
res.filters.forEach(function(f) {
|
|
108
|
+
html += '<span class="mock-input" style="width:auto;min-width:120px;font-size:0.8rem;color:var(--text-muted);">' + f + ' ▾</span>';
|
|
109
|
+
});
|
|
110
|
+
html += '<span class="mock-input" style="width:auto;min-width:200px;font-size:0.8rem;color:var(--text-muted);">Rechercher...</span>';
|
|
111
|
+
html += '</div>';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Table
|
|
115
|
+
html += '<table class="mock-table">';
|
|
116
|
+
html += '<thead><tr>';
|
|
117
|
+
columns.forEach(function(col) {
|
|
118
|
+
html += '<th>' + (col.label || col.field);
|
|
119
|
+
if (col.sortable) html += ' <span style="font-size:0.6rem;color:var(--text-muted);">▲▼</span>';
|
|
120
|
+
html += '</th>';
|
|
121
|
+
});
|
|
122
|
+
html += '<th style="width:80px;">Actions</th>';
|
|
123
|
+
html += '</tr></thead>';
|
|
124
|
+
|
|
125
|
+
// Sample rows
|
|
126
|
+
html += '<tbody>';
|
|
127
|
+
var sampleData = generateSampleRows(columns, 4);
|
|
128
|
+
sampleData.forEach(function(row) {
|
|
129
|
+
html += '<tr>';
|
|
130
|
+
columns.forEach(function(col) {
|
|
131
|
+
var val = row[col.field] || '';
|
|
132
|
+
if (col.type === 'badge') {
|
|
133
|
+
html += '<td><span class="mock-status mock-status-active">' + val + '</span></td>';
|
|
134
|
+
} else if (col.type === 'lookup') {
|
|
135
|
+
html += '<td style="color:var(--accent);">' + val + '</td>';
|
|
136
|
+
} else {
|
|
137
|
+
html += '<td>' + val + '</td>';
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
html += '<td style="text-align:center;"><span style="cursor:pointer;color:var(--text-muted);">✎ 🗑</span></td>';
|
|
141
|
+
html += '</tr>';
|
|
142
|
+
});
|
|
143
|
+
html += '</tbody></table>';
|
|
144
|
+
|
|
145
|
+
// Pagination
|
|
146
|
+
html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:0.75rem 0;font-size:0.8rem;color:var(--text-muted);">';
|
|
147
|
+
html += '<span>1-4 sur 24 resultats</span>';
|
|
148
|
+
html += '<div style="display:flex;gap:0.3rem;">';
|
|
149
|
+
html += '<span class="mock-btn" style="background:var(--primary);font-size:0.75rem;padding:0.2rem 0.5rem;">1</span>';
|
|
150
|
+
html += '<span class="mock-btn" style="background:var(--bg-hover);font-size:0.75rem;padding:0.2rem 0.5rem;">2</span>';
|
|
151
|
+
html += '<span class="mock-btn" style="background:var(--bg-hover);font-size:0.75rem;padding:0.2rem 0.5rem;">3</span>';
|
|
152
|
+
html += '</div></div>';
|
|
153
|
+
|
|
154
|
+
return html;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* ---------- SmartForm ---------- */
|
|
158
|
+
function renderSmartFormMockup(res) {
|
|
159
|
+
var tabs = res.tabs || [];
|
|
160
|
+
if (tabs.length === 0 && res.fields) {
|
|
161
|
+
tabs = [{ label: 'Informations', fields: res.fields }];
|
|
162
|
+
}
|
|
163
|
+
if (tabs.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Formulaire sans champs definis</div>';
|
|
164
|
+
|
|
165
|
+
var html = '';
|
|
166
|
+
|
|
167
|
+
// Header
|
|
168
|
+
html += '<div class="mock-header">';
|
|
169
|
+
html += '<span class="mock-title">' + (res.label || 'Formulaire') + '</span>';
|
|
170
|
+
html += '<div style="display:flex;gap:0.4rem;">';
|
|
171
|
+
(res.actions || ['save', 'cancel']).forEach(function(action) {
|
|
172
|
+
var isPrimary = action === 'save';
|
|
173
|
+
html += '<span class="mock-btn' + (isPrimary ? '' : '" style="background:var(--bg-hover);color:var(--text)') + '">' + formatActionLabel(action) + '</span>';
|
|
174
|
+
});
|
|
175
|
+
html += '</div></div>';
|
|
176
|
+
|
|
177
|
+
// Tabs
|
|
178
|
+
if (tabs.length > 1) {
|
|
179
|
+
html += '<div style="display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:1.5rem;">';
|
|
180
|
+
tabs.forEach(function(tab, i) {
|
|
181
|
+
html += '<span style="padding:0.5rem 1rem;font-size:0.85rem;cursor:pointer;border-bottom:2px solid ' + (i === 0 ? 'var(--primary)' : 'transparent') + ';color:' + (i === 0 ? 'var(--primary-light)' : 'var(--text-muted)') + ';">' + tab.label + '</span>';
|
|
182
|
+
});
|
|
183
|
+
html += '</div>';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Fields (first tab only)
|
|
187
|
+
var fields = tabs[0].fields || [];
|
|
188
|
+
var rows = [];
|
|
189
|
+
for (var i = 0; i < fields.length; i += 2) {
|
|
190
|
+
rows.push(fields.slice(i, i + 2));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
rows.forEach(function(row) {
|
|
194
|
+
if (row.length === 1 && row[0].type === 'subtable') {
|
|
195
|
+
html += renderSubtableMockup(row[0]);
|
|
196
|
+
} else {
|
|
197
|
+
html += '<div class="mock-form-row">';
|
|
198
|
+
row.forEach(function(field) {
|
|
199
|
+
html += '<div class="mock-form-group">';
|
|
200
|
+
html += '<label class="mock-label">' + (field.label || field.field);
|
|
201
|
+
if (field.required) html += ' <span style="color:var(--error);">*</span>';
|
|
202
|
+
html += '</label>';
|
|
203
|
+
html += renderFormFieldMockup(field);
|
|
204
|
+
html += '</div>';
|
|
205
|
+
});
|
|
206
|
+
html += '</div>';
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
return html;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function renderFormFieldMockup(field) {
|
|
214
|
+
var val = generateSampleValue(field);
|
|
215
|
+
switch (field.type) {
|
|
216
|
+
case 'select':
|
|
217
|
+
return '<span class="mock-input" style="display:block;">' + val + ' ▾</span>';
|
|
218
|
+
case 'lookup':
|
|
219
|
+
return '<span class="mock-input" style="display:block;color:var(--accent);">' + val + ' 🔍</span>';
|
|
220
|
+
case 'date':
|
|
221
|
+
return '<span class="mock-input" style="display:block;">' + val + ' 📅</span>';
|
|
222
|
+
case 'textarea':
|
|
223
|
+
return '<span class="mock-input" style="display:block;min-height:60px;">' + val + '</span>';
|
|
224
|
+
case 'checkbox':
|
|
225
|
+
return '<div style="display:flex;align-items:center;gap:0.5rem;"><input type="checkbox" checked disabled style="width:16px;height:16px;"><span style="font-size:0.85rem;color:var(--text);">' + val + '</span></div>';
|
|
226
|
+
default:
|
|
227
|
+
return '<span class="mock-input" style="display:block;' + (field.readonly ? 'opacity:0.6;' : '') + '">' + val + '</span>';
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function renderSubtableMockup(field) {
|
|
232
|
+
var cols = field.columns || [];
|
|
233
|
+
var entity = field.entity || 'Element';
|
|
234
|
+
var html = '<div style="margin:1rem 0;border:1px solid var(--border);border-radius:8px;overflow:hidden;">';
|
|
235
|
+
html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:0.5rem 0.75rem;background:var(--bg-hover);">';
|
|
236
|
+
html += '<span style="font-weight:500;color:var(--text-bright);font-size:0.85rem;">' + entity + '</span>';
|
|
237
|
+
html += '<span class="mock-btn" style="font-size:0.75rem;padding:0.2rem 0.5rem;">+ Ajouter</span>';
|
|
238
|
+
html += '</div>';
|
|
239
|
+
html += '<table class="mock-table"><thead><tr>';
|
|
240
|
+
cols.forEach(function(c) { html += '<th>' + c + '</th>'; });
|
|
241
|
+
html += '</tr></thead><tbody>';
|
|
242
|
+
html += '<tr>' + cols.map(function() { return '<td style="color:var(--text-muted);font-style:italic;">...</td>'; }).join('') + '</tr>';
|
|
243
|
+
html += '</tbody></table></div>';
|
|
244
|
+
return html;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* ---------- SmartCard ---------- */
|
|
248
|
+
function renderSmartCardMockup(res) {
|
|
249
|
+
var columns = res.columns || res.fields || [];
|
|
250
|
+
var html = '<div class="mock-header"><span class="mock-title">' + (res.label || 'Cartes') + '</span></div>';
|
|
251
|
+
html += '<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:1rem;">';
|
|
252
|
+
|
|
253
|
+
for (var i = 0; i < 4; i++) {
|
|
254
|
+
html += '<div style="background:var(--bg-hover);border:1px solid var(--border);border-radius:8px;padding:1rem;">';
|
|
255
|
+
columns.forEach(function(col, ci) {
|
|
256
|
+
var label = col.label || col.field || col;
|
|
257
|
+
if (ci === 0) {
|
|
258
|
+
html += '<div style="font-weight:600;color:var(--text-bright);margin-bottom:0.5rem;">' + label + ' #' + (i + 1) + '</div>';
|
|
259
|
+
} else {
|
|
260
|
+
html += '<div style="font-size:0.8rem;color:var(--text-muted);margin-bottom:0.25rem;">' + label + ': <span style="color:var(--text);">valeur</span></div>';
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
html += '</div>';
|
|
264
|
+
}
|
|
265
|
+
html += '</div>';
|
|
266
|
+
return html;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* ---------- SmartKanban ---------- */
|
|
270
|
+
function renderSmartKanbanMockup(res) {
|
|
271
|
+
var options = res.options || res.columns || ['A faire', 'En cours', 'Termine'];
|
|
272
|
+
var html = '<div class="mock-header"><span class="mock-title">' + (res.label || 'Kanban') + '</span></div>';
|
|
273
|
+
html += '<div style="display:flex;gap:1rem;overflow-x:auto;padding-bottom:0.5rem;">';
|
|
274
|
+
|
|
275
|
+
options.forEach(function(col, ci) {
|
|
276
|
+
var colLabel = typeof col === 'string' ? col : (col.label || col.field || 'Colonne');
|
|
277
|
+
html += '<div style="min-width:200px;flex:1;background:var(--bg-hover);border-radius:8px;padding:0.75rem;">';
|
|
278
|
+
html += '<div style="font-weight:600;font-size:0.85rem;color:var(--text-bright);margin-bottom:0.75rem;display:flex;justify-content:space-between;">';
|
|
279
|
+
html += colLabel + ' <span style="font-size:0.7rem;background:var(--bg-card);padding:0.1rem 0.4rem;border-radius:4px;color:var(--text-muted);">' + (3 - ci) + '</span>';
|
|
280
|
+
html += '</div>';
|
|
281
|
+
for (var j = 0; j < Math.max(1, 3 - ci); j++) {
|
|
282
|
+
html += '<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:0.5rem;margin-bottom:0.5rem;font-size:0.8rem;">';
|
|
283
|
+
html += '<div style="color:var(--text-bright);font-weight:500;">Element ' + (j + 1) + '</div>';
|
|
284
|
+
html += '<div style="color:var(--text-muted);font-size:0.7rem;margin-top:0.25rem;">Description...</div>';
|
|
285
|
+
html += '</div>';
|
|
286
|
+
}
|
|
287
|
+
html += '</div>';
|
|
288
|
+
});
|
|
289
|
+
html += '</div>';
|
|
290
|
+
return html;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* ---------- SmartDashboard ---------- */
|
|
294
|
+
function renderSmartDashboardMockup(res) {
|
|
295
|
+
var html = '<div class="mock-header"><span class="mock-title">' + (res.label || 'Tableau de bord') + '</span></div>';
|
|
296
|
+
|
|
297
|
+
// KPI cards
|
|
298
|
+
html += '<div class="mock-kpi-grid">';
|
|
299
|
+
var kpis = res.kpis || [
|
|
300
|
+
{ label: 'Total', value: '1,234' },
|
|
301
|
+
{ label: 'Actifs', value: '987' },
|
|
302
|
+
{ label: 'En attente', value: '156' },
|
|
303
|
+
{ label: 'Taux', value: '80%' }
|
|
304
|
+
];
|
|
305
|
+
kpis.forEach(function(kpi) {
|
|
306
|
+
html += '<div class="mock-kpi"><div class="mock-kpi-value">' + (kpi.value || '0') + '</div><div class="mock-kpi-label">' + (kpi.label || '') + '</div></div>';
|
|
307
|
+
});
|
|
308
|
+
html += '</div>';
|
|
309
|
+
|
|
310
|
+
// Chart placeholder
|
|
311
|
+
html += '<div class="mock-chart-placeholder">Graphique</div>';
|
|
312
|
+
|
|
313
|
+
return html;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* ---------- SmartFilter ---------- */
|
|
317
|
+
function renderSmartFilterMockup(res) {
|
|
318
|
+
var options = res.options || [];
|
|
319
|
+
var html = '<div style="display:flex;gap:0.4rem;flex-wrap:wrap;padding:0.5rem 0;">';
|
|
320
|
+
html += '<span style="padding:0.3rem 0.7rem;border-radius:16px;font-size:0.8rem;background:var(--primary);color:#fff;cursor:pointer;">Tous</span>';
|
|
321
|
+
options.forEach(function(opt) {
|
|
322
|
+
html += '<span style="padding:0.3rem 0.7rem;border-radius:16px;font-size:0.8rem;background:var(--bg-hover);color:var(--text);border:1px solid var(--border);cursor:pointer;">' + opt + '</span>';
|
|
323
|
+
});
|
|
324
|
+
html += '</div>';
|
|
325
|
+
return html;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* ---------- Helpers ---------- */
|
|
329
|
+
function formatActionLabel(action) {
|
|
330
|
+
var labels = {
|
|
331
|
+
create: 'Nouveau', edit: 'Modifier', delete: 'Supprimer',
|
|
332
|
+
export: 'Exporter', save: 'Enregistrer', cancel: 'Annuler',
|
|
333
|
+
validate: 'Valider', archive: 'Archiver', print: 'Imprimer'
|
|
334
|
+
};
|
|
335
|
+
return labels[action] || action;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function generateSampleRows(columns, count) {
|
|
339
|
+
var rows = [];
|
|
340
|
+
for (var i = 0; i < count; i++) {
|
|
341
|
+
var row = {};
|
|
342
|
+
columns.forEach(function(col) {
|
|
343
|
+
row[col.field] = generateSampleValue(col, i);
|
|
344
|
+
});
|
|
345
|
+
rows.push(row);
|
|
346
|
+
}
|
|
347
|
+
return rows;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function generateSampleValue(field, index) {
|
|
351
|
+
var idx = (index || 0) + 1;
|
|
352
|
+
var t = field.type || 'text';
|
|
353
|
+
var f = field.field || '';
|
|
354
|
+
|
|
355
|
+
if (field.options && field.options.length > 0) {
|
|
356
|
+
return field.options[idx % field.options.length];
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (t === 'date') return '0' + idx + '/03/2026';
|
|
360
|
+
if (t === 'badge' || t === 'select') return 'Actif';
|
|
361
|
+
if (t === 'lookup') return f.replace(/Id$/, '') + ' #' + idx;
|
|
362
|
+
if (t === 'number') return String(idx * 100);
|
|
363
|
+
if (t === 'checkbox') return idx % 2 === 0 ? 'Oui' : 'Non';
|
|
364
|
+
|
|
365
|
+
if (f.toLowerCase().includes('code')) return 'CODE-' + String(idx).padStart(3, '0');
|
|
366
|
+
if (f.toLowerCase().includes('name') || f.toLowerCase().includes('nom')) return 'Nom ' + idx;
|
|
367
|
+
if (f.toLowerCase().includes('email')) return 'user' + idx + '@example.com';
|
|
368
|
+
if (f.toLowerCase().includes('date')) return '0' + idx + '/03/2026';
|
|
369
|
+
if (f.toLowerCase().includes('status') || f.toLowerCase().includes('statut')) return 'Actif';
|
|
370
|
+
|
|
371
|
+
return f + ' ' + idx;
|
|
372
|
+
}
|
|
@@ -24,7 +24,7 @@ function renderHandoffStats() {
|
|
|
24
24
|
<div class="stat-card"><div class="stat-value">${totalStakeholders}</div><div class="stat-label">Profils utilisateurs</div></div>
|
|
25
25
|
<div class="stat-card"><div class="stat-value">${data.dependencies.length}</div><div class="stat-label">Dependances</div></div>
|
|
26
26
|
<div class="stat-card"><div class="stat-value">${data.consolidation.e2eFlows.length}</div><div class="stat-label">Parcours bout en bout</div></div>
|
|
27
|
-
|
|
27
|
+
${isVibeCoding ? '' : `<div class="stat-card"><div class="stat-value">${data.cadrage.risks.length}</div><div class="stat-label">Risques identifies</div></div>`}
|
|
28
28
|
`;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -13,20 +13,48 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
function initInlineComments() {
|
|
16
|
-
//
|
|
17
|
-
document.querySelectorAll('.section').forEach(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
// Cadrage sections: direct card children
|
|
17
|
+
document.querySelectorAll('.section > .card, .section > .stakeholder-card, .section > .uc-item, .section > .risk-item').forEach(function(card) {
|
|
18
|
+
if (card.dataset.commentInitialized) return;
|
|
19
|
+
card.dataset.commentInitialized = 'true';
|
|
20
|
+
var section = card.closest('.section');
|
|
21
|
+
var sectionId = section ? section.id : 'unknown';
|
|
22
|
+
var siblings = Array.from(section.querySelectorAll(':scope > .card, :scope > .stakeholder-card, :scope > .uc-item, :scope > .risk-item'));
|
|
23
|
+
var index = siblings.indexOf(card);
|
|
24
|
+
card.appendChild(createCommentUI(sectionId, index));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Module spec lists: nested items in ucList, brList, entList containers
|
|
28
|
+
document.querySelectorAll('[id^="ucList-"] > .uc-item, [id^="brList-"] > div, [id^="entList-"] > .entity-block').forEach(function(item) {
|
|
29
|
+
if (item.dataset.commentInitialized) return;
|
|
30
|
+
item.dataset.commentInitialized = 'true';
|
|
31
|
+
var list = item.parentElement;
|
|
32
|
+
var listId = list.id;
|
|
33
|
+
var siblings = Array.from(list.children);
|
|
34
|
+
var index = siblings.indexOf(item);
|
|
35
|
+
item.appendChild(createCommentUI(listId, index));
|
|
23
36
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
|
|
38
|
+
// Stakeholder cards in grid
|
|
39
|
+
document.querySelectorAll('.stakeholder-grid > .stakeholder-card').forEach(function(card) {
|
|
40
|
+
if (card.dataset.commentInitialized) return;
|
|
41
|
+
card.dataset.commentInitialized = 'true';
|
|
42
|
+
var grid = card.parentElement;
|
|
43
|
+
var section = card.closest('.section');
|
|
44
|
+
var sectionId = section ? section.id : 'stakeholders';
|
|
45
|
+
var siblings = Array.from(grid.children);
|
|
46
|
+
var index = siblings.indexOf(card);
|
|
47
|
+
card.appendChild(createCommentUI(sectionId, index));
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Scope items
|
|
51
|
+
['scopeVital', 'scopeImportant', 'scopeOptional', 'scopeExcluded'].forEach(function(containerId) {
|
|
52
|
+
var container = document.getElementById(containerId);
|
|
53
|
+
if (!container) return;
|
|
54
|
+
container.querySelectorAll('.uc-item').forEach(function(item, index) {
|
|
55
|
+
if (item.dataset.commentInitialized) return;
|
|
56
|
+
item.dataset.commentInitialized = 'true';
|
|
57
|
+
item.appendChild(createCommentUI(containerId, index));
|
|
30
58
|
});
|
|
31
59
|
});
|
|
32
60
|
}
|