Remplace la modale liste+menus deroulants du Scenario par un vrai graphe visuel
Build and deploy / test-python (push) Successful in 7m32s
Build and deploy / test-js (push) Successful in 49s
Build and deploy / lint-python (push) Successful in 5m21s
Build and deploy / lint-js (push) Failing after 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m53s
Build and deploy / test-python (push) Successful in 7m32s
Build and deploy / test-js (push) Successful in 49s
Build and deploy / lint-python (push) Successful in 5m21s
Build and deploy / lint-js (push) Failing after 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 3m53s
Retour utilisateur : "passons a un veritable graphe visuel". Chaque nœud gagne une position x/y (document_engine/labels/scenario_config.py : un x/y manquant/invalide retombe sur un quadrillage en cascade derive de l'index du nœud, jamais (0, 0) pour tous les nœuds qui les empilerait au meme endroit). Cote editeur (static/document/js/document-editor.js) : les nœuds sont des cartes deplacables a la souris sur un canevas (glisser-deposer reel, meme principe que le glisser des formes libres), les choix relies a une cible sont dessines comme des fleches SVG etiquetees par leur texte (jamais un menu deroulant). Editer le texte/les choix d'un nœud se fait dans un panneau inspecteur (colonne de droite) pour le nœud selectionne ; relier un choix se fait en cliquant "Relier" puis le nœud cible sur le graphe (mode connexion, Echap annule sans fermer la modale). La modale generique (.docModal*) est agrandie specifiquement pour ce graphe (jusqu'a 1180px) sans toucher sa taille par defaut. Verifie via simulation DOM reelle (jsdom) : rendu des nœuds/positions, glisser-deposer avec persistance au relachement, traces des fleches SVG + etiquettes, workflow complet du mode connexion, suppression d'un nœud avec reparation des references pendantes, et les 3 façons de fermer la modale (bouton/fond/Echap) y compris l'annulation du mode connexion sans fermer. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
7e504b7865
commit
d92f75a803
@@ -1469,6 +1469,220 @@ img.docImage {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ---- Scénario : éditeur d'arbre en GRAPHE VISUEL (retour utilisateur
|
||||
du 21/09/2026 : "passons à un véritable graphe visuel", remplace la
|
||||
première version en liste de nœuds + menus déroulants). Dialogue bien
|
||||
plus grand que la modale générique par défaut : un graphe a besoin de
|
||||
place pour être lisible. ---- */
|
||||
#docScenarioTreeModal .docModalDialog {
|
||||
width: min(1180px, 95vw);
|
||||
max-height: min(88vh, 820px);
|
||||
}
|
||||
|
||||
#docScenarioTreeModal .docModalBody {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.docScenarioGraphTitleRow {
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--doc-border);
|
||||
}
|
||||
|
||||
.docScenarioGraphTitleRow input {
|
||||
width: 100%;
|
||||
border: 1px solid var(--doc-border);
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--doc-text);
|
||||
background: var(--doc-bg-2);
|
||||
}
|
||||
|
||||
.docScenarioGraphToolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid var(--doc-border);
|
||||
}
|
||||
|
||||
.docScenarioGraphHint {
|
||||
font-size: 12.5px;
|
||||
color: var(--doc-muted);
|
||||
}
|
||||
|
||||
.docScenarioGraphHint.is-connecting {
|
||||
color: var(--doc-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.docScenarioGraphSplit {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.docScenarioGraphCanvas {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
background:
|
||||
radial-gradient(circle, var(--doc-border) 1px, transparent 1px) 0 0 / 24px 24px,
|
||||
var(--doc-bg-2);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.docScenarioGraphCanvas.is-connecting {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.docScenarioGraphCanvas.is-connecting .docScenarioGraphNode {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.docScenarioGraphInner {
|
||||
position: relative;
|
||||
width: 2200px;
|
||||
height: 1600px;
|
||||
}
|
||||
|
||||
.docScenarioGraphSvg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.docScenarioGraphEdge {
|
||||
fill: none;
|
||||
stroke: var(--doc-muted);
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.docScenarioGraphEdgeLabel {
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
background: var(--doc-bg-2);
|
||||
border: 1px solid var(--doc-border);
|
||||
border-radius: 6px;
|
||||
padding: 2px 7px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--doc-muted);
|
||||
white-space: nowrap;
|
||||
max-width: 140px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.docScenarioGraphNode {
|
||||
position: absolute;
|
||||
width: 180px;
|
||||
border: 1px solid var(--doc-border);
|
||||
border-radius: 10px;
|
||||
background: var(--doc-card);
|
||||
padding: 10px 12px;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
.docScenarioGraphNode:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.docScenarioGraphNode.is-root {
|
||||
border-color: var(--doc-accent);
|
||||
}
|
||||
|
||||
.docScenarioGraphNode.is-selected {
|
||||
border-color: var(--doc-accent);
|
||||
box-shadow: 0 0 0 2px var(--doc-accent);
|
||||
}
|
||||
|
||||
.docScenarioGraphNode.is-connect-target:hover {
|
||||
border-color: var(--doc-quiz-success-border);
|
||||
box-shadow: 0 0 0 2px var(--doc-quiz-success-border);
|
||||
}
|
||||
|
||||
.docScenarioGraphNodeLabel {
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.03em;
|
||||
text-transform: uppercase;
|
||||
color: var(--doc-accent);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.docScenarioGraphNodeText {
|
||||
font-size: 12.5px;
|
||||
line-height: 1.35;
|
||||
color: var(--doc-text);
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.docScenarioGraphInspector {
|
||||
flex: 0 0 300px;
|
||||
border-left: 1px solid var(--doc-border);
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.docScenarioGraphInspectorEmpty {
|
||||
font-size: 13px;
|
||||
color: var(--doc-muted);
|
||||
text-align: center;
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.docScenarioChoiceTargetRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.docScenarioChoiceTargetLabel {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
color: var(--doc-muted);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.docScenarioChoiceLinkBtn {
|
||||
border: 1px solid var(--doc-border);
|
||||
background: transparent;
|
||||
color: var(--doc-text);
|
||||
border-radius: 6px;
|
||||
padding: 3px 8px;
|
||||
font-size: 11.5px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.docScenarioChoiceLinkBtn:hover {
|
||||
border-color: var(--doc-accent);
|
||||
}
|
||||
|
||||
.docScenarioChoiceLinkBtn.is-active {
|
||||
border-color: var(--doc-accent);
|
||||
background: var(--doc-accent);
|
||||
color: #14100c;
|
||||
}
|
||||
|
||||
/* ===== RESPONSIVE (chrome de l'éditeur lui-même, <900px) ===== */
|
||||
@media (width <= 900px) {
|
||||
.docCrumbDim {
|
||||
|
||||
Reference in New Issue
Block a user