feat(frontend): gemeinsam am Server-Dokument arbeiten (?live=, Schritt 6)
Der Editor fuehrt ein Dokument des Backends: laden, nach 1,5 s Ruhe das Diff schicken, ueber einen offenen Abruf fremde Aenderungen einspielen — ohne Neuladen, mit mitwandernder Schreibmarke. Dazu CORS im Backend; ohne das blockiert der Browser jeden Aufruf. Zwei Fehler hat erst der Live-Test gegen das laufende Backend gefunden, beide an der Naht zwischen Modul und Verdrahtung (D54-Nachtrag 3): Der Konflikt entstand nie. Mit laufendem Feed zieht die Schattenkopie staendig nach, die eigene Basis ist also nie veraltet — der Server haette nie 409 geantwortet, und die fremde Zeile waere stillschweigend ueberschrieben worden. Der Client prueft die Ueberschneidung jetzt selbst gegen den ungesendeten Text; den kennt der Server nicht. Die Nummer begann nach jedem Neuladen wieder bei 1, waehrend die Kennung blieb — der Server hielt die erste echte Aenderung fuer eine Wiederholung und tat nichts. Beides liegt jetzt im sessionStorage: je Tab, ueberlebt Neuladen. Je Tab ist zugleich die richtige Aussage, zwei Tabs sind zwei Schreiber. Nachgemessen im Browser: fremde Aenderung erscheint ohne Neuladen, Getipptes erreicht den Server, beide Konflikt-Knoepfe tun was sie sagen, und die Schreibmarke steht nach zwei fremd eingefuegten Zeilen darueber unveraendert bei Zeile+2, Spalte 8. 518 Frontend-Tests, 135 im Backend. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5881be1a2c
commit
08965157a1
@@ -1544,3 +1544,27 @@
|
||||
.node:not(.folded) .fold{display:none!important}
|
||||
@page{margin:12mm}
|
||||
}
|
||||
|
||||
/* ---------- Konflikt beim gemeinsamen Bearbeiten (D76) ----------
|
||||
Band oben, wie der Update-Hinweis: Es unterbricht nicht die Arbeit, steht
|
||||
aber über allem, bis jemand entscheidet. In `--warn`, nicht in Petrol — es
|
||||
ist keine Einladung, sondern eine Sache, die geklärt werden muss. */
|
||||
.live-conflict{
|
||||
position: fixed; inset: 0 0 auto 0; z-index: 1200;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
gap: 16px; padding: 10px 16px;
|
||||
background: var(--warn, #B45309); color: #fff;
|
||||
font: 500 14px/1.4 'IBM Plex Sans', system-ui, sans-serif;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,.25);
|
||||
}
|
||||
.live-conflict-actions{ display: flex; gap: 8px; flex: 0 0 auto; }
|
||||
.live-conflict button{
|
||||
font: 500 13px/1 'IBM Plex Sans', system-ui, sans-serif;
|
||||
padding: 6px 10px; border-radius: 4px; cursor: pointer;
|
||||
border: 1px solid #fff; background: transparent; color: #fff;
|
||||
}
|
||||
/* „Eigene durchsetzen" ist die Antwort, die nichts von der eigenen Arbeit
|
||||
kostet - sie steht deshalb gefüllt da, ohne die andere zu verstecken. */
|
||||
.live-conflict button.mine{ background: #fff; color: var(--warn, #B45309); border-color: #fff; }
|
||||
.live-conflict button:focus-visible{ outline: 2px solid #fff; outline-offset: 2px; }
|
||||
@media print{ .live-conflict{ display: none; } }
|
||||
|
||||
Reference in New Issue
Block a user