Add drag & drop script variants and enhanced debugging tools

- Introduced multiple JavaScript scripts for handling drag & drop functionality:
  - `bridge_script.js`: Original implementation with popup prevention.
  - `bridge_script_debug.js`: Debug version with extensive logging for troubleshooting.
  - `bridge_script_v2.js`: Enhanced version extending DataTransfer for better integration.
  - `bridge_script_hybrid.js`: Hybrid approach allowing parallel native file drag.
  - `bridge_script_drop_intercept.js`: Intercepts drop events for custom handling.
  - `bridge_script_intercept.js`: Prevents browser drag for ALT+drag, using Qt for file drag.

- Added detailed documentation in `SCRIPT_VARIANTS.md` outlining usage, status, and recommended workflows for each script.
- Implemented logging features to capture drag events, DataTransfer modifications, and network requests for better debugging.
- Enhanced DataTransfer handling to support Windows-specific file formats and improve user experience during drag & drop operations.
This commit is contained in:
claudi 2026-02-17 19:19:14 +01:00
parent 88dc358894
commit dee02ad600
12 changed files with 2244 additions and 65 deletions

View file

@ -0,0 +1,268 @@
# Angular CDK Drag & Drop Analysis - GlobalDAM
## Framework Detection
**Web Application:** Agravity GlobalDAM
**Framework:** Angular 19.2.14
**Drag & Drop:** Angular CDK (Component Dev Kit)
**Styling:** TailwindCSS
## Technical Findings
### 1. Angular CDK Implementation
```html
<!-- Drag Group (oberste Ebene) -->
<div cdkdroplistgroup="" aydnd="" class="flex h-full flex-col">
<!-- Drop Zone (Collections) -->
<div cdkdroplist="" class="cdk-drop-list" id="collectioncsuaaDVNokl0...">
<!-- Draggable Element (Asset Card) -->
<li cdkdrag="" class="cdk-drag asset-list-item" draggable="false">
<img src="./GlobalDAM JRI_files/anPGZszKzgKaSz1SIx2HFgduy"
alt="weiss_ORIGINAL">
</li>
</div>
</div>
```
### 2. Key Observations
#### Native HTML5 Drag ist DEAKTIVIERT
```html
draggable="false"
```
**Bedeutung:**
- Kein Zugriff auf native `dragstart`, `drag`, `dragend` Events
- Kein `event.dataTransfer` API verfügbar
- Angular CDK simuliert Drag & Drop komplett in JavaScript
- Daten werden NICHT über natives Clipboard/DataTransfer übertragen
#### Angular CDK Direktiven
- `cdkdroplistgroup` - Gruppiert mehrere Drop-Zonen
- `cdkdroplist` - Markiert Drop-Bereiche (Collections, Clipboard)
- `cdkdrag` - Markiert draggbare Elemente (Assets)
- `cdkdroplistsortingdisabled` - Sortierung deaktiviert
#### Asset Identifikation
```html
<!-- Asset ID im Element-ID -->
<div id="anPGZszKzgKaSz1SIx2HFgduy">
<!-- Asset ID in der Bild-URL -->
<img src="./GlobalDAM JRI_files/anPGZszKzgKaSz1SIx2HFgduy">
<!-- Asset Name im alt-Attribut -->
<img alt="weiss_ORIGINAL">
```
## Impact on WebDrop Bridge
### ❌ Bisheriger Ansatz funktioniert NICHT
Unser aktueller Ansatz basiert auf:
1. Interception von nativen Drag-Events
2. Manipulation von `event.dataTransfer.effectAllowed` und `.dropEffect`
3. Setzen von URLs im DataTransfer
**Das funktioniert NICHT mit Angular CDK**, da:
- Angular CDK das native Drag & Drop komplett umgeht
- Keine nativen Events gefeuert werden
- DataTransfer API nicht verwendet wird
### ✅ Mögliche Lösungsansätze
#### Ansatz 1: JavaScript Injection zur Laufzeit
Injiziere JavaScript-Code, der Angular CDK Events abfängt:
```javascript
// Überwache Angular CDK Event-Handler
document.addEventListener('cdkDragStarted', (event) => {
const assetId = event.source.element.nativeElement.id;
const assetName = event.source.element.nativeElement.querySelector('img')?.alt;
// Sende an Qt WebChannel
bridge.handleDragStart(assetId, assetName);
});
document.addEventListener('cdkDragDropped', (event) => {
// Verhindere das Standard-Verhalten
event.preventDefault();
// Starte nativen Drag von Qt aus
bridge.initNativeDrag();
});
```
**Vorteile:**
- ✅ Direkter Zugriff auf Angular CDK Events
- ✅ Kann Asset-Informationen extrahieren
- ✅ Kann Drag-Operationen abfangen
**Nachteile:**
- ⚠️ Erfordert genaue Kenntnis der Angular CDK Internals
- ⚠️ Könnte bei Angular CDK Updates brechen
- ⚠️ Komplexer zu implementieren
#### Ansatz 2: DOM Mutation Observer
Überwache DOM-Änderungen während des Drags:
```javascript
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// Suche nach CDK Drag-Elementen mit bestimmten Klassen
const dragElement = document.querySelector('.cdk-drag-preview');
if (dragElement) {
const assetId = dragElement.querySelector('[id^="a"]')?.id;
bridge.handleDrag(assetId);
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class']
});
```
**Vorteile:**
- ✅ Robuster gegenüber Framework-Updates
- ✅ Funktioniert mit beliebigen Frameworks
**Nachteile:**
- ⚠️ Performance-Overhead
- ⚠️ Kann falsche Positive erzeugen
#### Ansatz 3: Qt WebChannel Bridge mit Custom Events
Nutze Qt WebChannel, um mit der Angular-Anwendung zu kommunizieren:
```python
# Python-Seite (Qt)
class DragBridge(QObject):
@Slot(str, str)
def onAssetDragStart(self, asset_id: str, asset_name: str):
"""Called from JavaScript when Angular CDK drag starts."""
logger.info(f"Asset drag started: {asset_id} ({asset_name})")
self.convert_and_drag(asset_id, asset_name)
```
```javascript
// JavaScript-Seite (injiziert via QWebEngineScript)
new QWebChannel(qt.webChannelTransport, (channel) => {
const dragBridge = channel.objects.dragBridge;
// Monkey-patch Angular CDK's DragRef
const originalStartDraggingSequence = CdkDrag.prototype._startDraggingSequence;
CdkDrag.prototype._startDraggingSequence = function(event) {
const assetElement = this.element.nativeElement;
const assetId = assetElement.id;
const assetName = assetElement.querySelector('img')?.alt;
// Benachrichtige Qt
dragBridge.onAssetDragStart(assetId, assetName);
// Rufe original Angular CDK Methode auf
return originalStartDraggingSequence.call(this, event);
};
});
```
**Vorteile:**
- ✅ Saubere Kommunikation zwischen Qt und Web
- ✅ Kann Asset-Informationen zuverlässig extrahieren
- ✅ Typensicher (Qt Signals/Slots)
**Nachteile:**
- ⚠️ Erfordert Monkey-Patching von Angular CDK
- ⚠️ Kann bei CDK Updates brechen
#### Ansatz 4: Browser DevTools Protocol (Chrome DevTools)
Nutze Chrome DevTools Protocol für tiefere Integration:
```python
from PySide6.QtWebEngineCore import QWebEngineProfile
profile = QWebEngineProfile.defaultProfile()
profile.setRequestInterceptor(...)
# Intercepte Netzwerk-Requests und injiziere Header
# Überwache JavaScript-Execution via CDP
```
**Vorteile:**
- ✅ Sehr mächtig, kann JavaScript-Execution überwachen
- ✅ Kann Events auf niedrigerer Ebene abfangen
**Nachteile:**
- ⚠️ Sehr komplex
- ⚠️ Erfordert Chrome DevTools Protocol Kenntnisse
- ⚠️ Performance-Overhead
## Empfohlener Ansatz
### **Ansatz 3: Qt WebChannel Bridge** (BEVORZUGT)
**Begründung:**
1. ✅ Saubere Architektur mit klarer Trennung
2. ✅ Typsicher durch Qt Signals/Slots
3. ✅ Kann Asset-IDs und -Namen zuverlässig extrahieren
4. ✅ Funktioniert auch wenn Angular CDK interne Änderungen hat
5. ✅ Ermöglicht bidirektionale Kommunikation
**Implementierungsschritte:**
### Phase 1: Asset-Informationen extrahieren
1. JavaScript via QWebEngineScript injizieren
2. Qt WebChannel setuppen
3. Angular CDK Events überwachen (ohne Monkey-Patching als Test)
4. Asset-IDs und Namen an Qt senden
### Phase 2: Native Drag initiieren
1. Bei CDK Drag-Start: Extrahiere Asset-Informationen
2. Sende Asset-ID an Backend/API
3. Erhalte lokalen Dateipfad oder Azure Blob URL
4. Konvertiere zu lokalem Pfad (wie aktuell)
5. Initiiere nativen Drag mit QDrag
### Phase 3: Drag-Feedback
1. Zeige Drag-Preview in Qt (optional)
2. Update Cursor während Drag
3. Cleanup nach Drag-Ende
## Asset-ID zu Dateipfad Mapping
Die Anwendung verwendet Asset-IDs in mehreren Formaten:
```javascript
// Asset-ID: anPGZszKzgKaSz1SIx2HFgduy
// Mögliche URL-Konstruktion:
const assetUrl = `https://dev.agravity.io/api/assets/${assetId}`;
const downloadUrl = `https://dev.agravity.io/api/assets/${assetId}/download`;
const blobUrl = `https://static.agravity.io/${workspaceId}/${assetId}/${filename}`;
```
**Für WebDrop Bridge:**
- Asset-ID aus DOM extrahieren
- Asset-Metadaten via API abrufen (falls verfügbar)
- Blob-URL konstruieren
- URL Converter nutzen (bereits implementiert!)
## Next Steps
1. **Proof of Concept**: Qt WebChannel mit einfachem Event-Logger
2. **Asset-ID Extraction**: JavaScript Injection testen
3. **API Research**: GlobalDAM API untersuchen (Asset-Metadaten)
4. **Integration**: Mit bestehendem URLConverter verbinden
5. **Testing**: Mit echten Assets testen
## Hinweise
- Angular CDK Version kann sich unterscheiden - Code muss robust sein
- Asset-IDs scheinen eindeutig zu sein (Base64-ähnlich)
- Die Anwendung nutzt Azure Blob Storage (basierend auf bisherigen URLs)
- Custom Components (`ay-*`) deuten auf eine eigene Component Library hin

View file

@ -0,0 +1,277 @@
# Drag & Drop Problem Analysis - File Drop + Web App Popup
## Das Kernproblem
**Ziel**: Bei ALT-Drag soll:
1. ✅ File gedroppt werden (Z:\ Laufwerk) → Native File-Drop
2. ✅ Web-App Popup erscheinen (Auschecken-Dialog) → Web-App Drop-Event
**Problem**: Diese beiden schließen sich gegenseitig aus:
- Native File-Drag (von Qt) → Web-App bekommt kein Drop-Event → Kein Popup
- Browser Text-Drag (von Web-App) → Kein File-Drop → Kein File
## Browser-Sicherheitsbeschränkungen
1. **DataTransfer.files ist read-only**
Wir können keine Files zu einem DataTransfer hinzufügen
2. **Nur EIN Drag zur Zeit möglich**
Wir können keinen parallelen Drag starten
3. **DataTransfer kann nicht erstellt werden**
Wir können kein synthetisches Drop-Event mit Files erzeugen
4. **Cross-Domain Sicherheit**
File-Zugriff ist stark eingeschränkt
## Getestete Ansätze
### ❌ Ansatz 1: DataTransfer erweitern
**Idee**: Web-App setzt URL, wir fügen Files hinzu
**Problem**: DataTransfer.files ist read-only
### ❌ Ansatz 2: Parallele Drags
**Idee**: Browser-Drag + Qt-Drag gleichzeitig
**Problem**: Nur ein Drag zur Zeit möglich
### ❌ Ansatz 3: Synthetisches Drop-Event
**Idee**: Original Drop abfangen, neues Event mit Files erzeugen
**Problem**: DataTransfer.files kann nicht gesetzt werden
### ⚠️ Ansatz 4: Native Drag + Event-Simulation
**Idee**: Qt Native Drag, dann Web-App Event manuell auslösen
**Problem**: Erfordert Kenntnis der exakten Web-App Event-Struktur (Angular CDK)
## 🎯 Praktikable Lösungen
### Lösung A: **Zwei-Phasen Ansatz** (EMPFOHLEN für Testing)
**Phase 1: File-Drop**
1. ALT-Drag startet
2. JavaScript erkennt convertible URL
3. Ruft Qt's `start_file_drag(url)` auf
4. `preventDefault()` verhindert Browser-Drag
5. Qt Native Drag läuft
6. File wird gedroppt ✅
**Phase 2: Popup manuell triggern**
7. Nach erfolgreichem Drop (via Qt Signal)
8. JavaScript simuliert den Event/API-Call der das Popup auslöst
9. Popup erscheint ✅
**Vorteile:**
- ✅ Funktioniert garantiert für File-Drop
- ✅ Kontrolle über beide Phasen
- ✅ Kann debugged werden
**Nachteile:**
- ⚠️ Erfordert Reverse-Engineering des Popup-Triggers
- ⚠️ Könnte bei Web-App Updates brechen
**Implementierung:**
```javascript
// Phase 1: Standard - File Drag
document.addEventListener('dragstart', function(e) {
if (!e.altKey) return;
// Extract URL from DataTransfer
var url = e.dataTransfer.getData('text/plain');
if (isConvertible(url)) {
e.preventDefault();
window.bridge.start_file_drag(url);
}
}, true);
// Phase 2: Popup Trigger (nach Drop-Erfolg)
// Qt ruft auf: window.trigger_checkout_popup(assetId)
window.trigger_checkout_popup = function(assetId) {
// Option 1: Klick auf Checkout-Button simulieren
// Option 2: API-Call direkt aufrufen
// Option 3: Angular-Event dispatchen
// Beispiel: Suche nach Angular-Component und rufe Methode auf
var angularComponent = findAngularComponent('ay-asset-card');
if (angularComponent) {
angularComponent.onCheckout(assetId);
}
};
```
**TODO für diese Lösung:**
1. ✅ File-Drag funktioniert bereits
2. ⏸️ Herausfinden wie Popup ausgelöst wird:
- Browser DevTools öffnen
- Network-Tab beobachten (API-Call?)
- Elements-Tab nutzen (Angular Component?)
- Event-Listeners ansehen
### Lösung B: **Gar nichts ändern beim Drag** (FALLBACK)
**Ansatz:**
1. ALT-Drag läuft normal durch (URL-Text wird gedroppt)
2. Popup erscheint ✅
3. Nach Popup-Bestätigung (Auschecken)
4. **DANN** konvertieren wir die URL und kopieren das File
**Vorteile:**
- ✅ Web-App funktioniert normal
- ✅ Kein Popup-Problem
- ✅ Einfach zu implementieren
**Nachteile:**
- ⚠️ Kein echter Drag & Drop (nur Copy)
- ⚠️ User muss zweimal handeln
### Lösung C: **File-Drop via Qt Window Overlay** (EXPERIMENTELL)
**Ansatz:**
1. Beim ALT-Drag: Start Normal Web-App Drag
2. Qt erstellt ein transparentes Overlay-Window über dem Browser
3. Overlay fängt das Drop-Event ab
4. Qt macht File-Drop
5. Qt leitet Drop-Koordinaten an Browser weiter
6. Browser bekommt synthetisches Event (ohne Files, nur Koordinaten)
7. Popup erscheint
**Vorteile:**
- ✅ Beide Funktionen potentiell möglich
- ✅ Keine DataTransfer-Manipulation nötig
**Nachteile:**
- ⚠️ Sehr komplex
- ⚠️ Plattform-spezifisch (Windows)
- ⚠️ Performance-Overhead
## 🔬 Nächste Schritte - Reverse Engineering
Um Lösung A zu implementieren, müssen wir herausfinden:
### 1. Wie wird das Popup ausgelöst?
**Debug-Schritte:**
```javascript
// In Browser Console ausführen während ALT-Drag+Drop
// Methode 1: Event-Listener finden
getEventListeners(document)
// Methode 2: Angular Component finden
var cards = document.querySelectorAll('ay-asset-card');
var component = ng.getComponent(cards[0]); // Angular DevTools
console.log(component);
// Methode 3: Network-Tab
// Schauen ob API-Call gemacht wird nach Drop
```
**Erwartete Möglichkeiten:**
- API-Call zu `/api/assets/{id}/checkout`
- Angular Event: `cdkDropListDropped`
- Component-Methode: `onAssetDropped()` oder ähnlich
- Modal-Service: `ModalService.show('checkout-dialog')`
### 2. Asset-ID extrahieren
Die Asset-ID wird benötigt für den Popup-Trigger:
```javascript
// Asset-ID ist wahrscheinlich in:
// - Element-ID: "anPGZszKzgKaSz1SIx2HFgduy"
// - Image-URL: "./GlobalDAM JRI_files/anPGZszKzgKaSz1SIx2HFgduy"
// - Data-Attribut: data-asset-id
function extractAssetId(element) {
// Aus Element-ID
if (element.id && element.id.match(/^a[A-Za-z0-9_-]+$/)) {
return element.id;
}
// Aus Bild-URL
var img = element.querySelector('img');
if (img && img.src) {
var match = img.src.match(/([A-Za-z0-9_-]{20,})/);
if (match) return match[1];
}
return null;
}
```
### 3. Popup programmatisch öffnen
Sobald wir wissen wie, implementieren wir:
```python
# Python (Qt)
class DragBridge(QObject):
@Slot(str)
def on_file_dropped_success(self, local_path: str):
"""Called after successful file drop."""
# Extrahiere Asset-ID aus Pfad oder URL-Mapping
asset_id = self.extract_asset_id(local_path)
# Trigger Popup via JavaScript
js_code = f"window.trigger_checkout_popup('{asset_id}')"
self.web_view.page().runJavaScript(js_code)
```
## ⚡ Quick Win: Debugging aktivieren
Fügen Sie zu **allen** JavaScript-Varianten umfangreiches Logging hinzu:
```javascript
// In bridge_script.js
// Log ALLE Events
['dragstart', 'drag', 'dragenter', 'dragover', 'drop', 'dragend'].forEach(function(eventName) {
document.addEventListener(eventName, function(e) {
console.log('[DEBUG]', eventName, {
target: e.target.tagName,
dataTransfer: {
types: e.dataTransfer.types,
effectAllowed: e.dataTransfer.effectAllowed,
dropEffect: e.dataTransfer.dropEffect
},
altKey: e.altKey,
coordinates: {x: e.clientX, y: e.clientY}
});
}, true);
});
// Log DataTransfer Zugriffe
Object.defineProperty(DataTransfer.prototype, 'types', {
get: function() {
var types = this._types || [];
console.log('[DEBUG] DataTransfer.types accessed:', types);
return types;
}
});
```
## 📝 Empfehlung
**Sofortige Maßnahmen:**
1. ✅ **Lösung A Phase 1 ist bereits implementiert** (File-Drop funktioniert)
2. 🔍 **Reverse-Engineering durchführen:**
- GlobalDAM JRI im Browser öffnen
- DevTools öffnen (F12)
- ALT-Drag+Drop durchführen
- Beobachten:
- Network-Tab → API-Calls?
- Console → Fehler/Logs?
- Angular DevTools → Component-Events?
3. 🛠️ **Popup-Trigger implementieren:**
- Sobald bekannt WIE Popup ausgelöst wird
- JavaScript-Funktion `trigger_checkout_popup()` erstellen
- Von Qt aus nach erfolgreichem Drop aufrufen
4. 🧪 **Testen:**
- ALT-Drag eines Assets
- File-Drop sollte funktionieren
- Popup sollte erscheinen
**Fallback:**
Falls Reverse-Engineering zu komplex ist → **Lösung B** verwenden (Kein Drag, nur Copy nach Popup-Bestätigung)

171
docs/SCRIPT_VARIANTS.md Normal file
View file

@ -0,0 +1,171 @@
# WebDrop Bridge - Drag & Drop Script Varianten
## Verfügbare JavaScript-Scripte
### 1. `bridge_script.js` (CURRENT - Original)
**Status:** Versucht Drag zu ersetzen, verhindert Popup
**Verwendung:** Testing, zeigt dass File-Drop prinzipiell funktioniert
**Problem:** Web-App Popup erscheint nicht
### 2. `bridge_script_debug.js` (DEBUG - **EMPFOHLEN ZUM START**)
**Status:** Umfangreiches Logging, keine Manipulation
**Verwendung:** Herausfinden wie Popup ausgelöst wird
**Funktionen:**
- Loggt ALLE Drag/Drop Events
- Überwacht DataTransfer.setData
- Überwacht Network-Requests (API-Calls)
- Erkennt Angular Components
- Erkennt Modal/Popup Öffnungen
- Bietet Helper-Funktionen in Console
**So verwenden:**
```python
# In main_window.py Zeile ~433 ändern:
script_path = Path(__file__).parent / "bridge_script_debug.js" # <-- DEBUG aktivieren
```
**Im Browser:**
1. F12 → Console öffnen
2. ALT-Drag+Drop durchführen
3. Logs analysieren:
- `[MODAL OPENED]` → Popup-Trigger gefunden!
- `[FETCH]` oder `[XHR]` → API-Call gefunden!
- `[EVENT]` → Drag-Flow verstehen
### 3. `bridge_script_v2.js` (EXTEND - Experimentell)
**Status:** Versuch DataTransfer zu erweitern
**Problem:** Browser-Sicherheit verhindert Files hinzufügen
### 4. `bridge_script_hybrid.js` (HYBRID - Experimentell)
**Status:** Versuch parallele Drags
**Problem:** Nur ein Drag zur Zeit möglich
### 5. `bridge_script_drop_intercept.js` (DROP - Experimentell)
**Status:** Drop-Event abfangen und manipulieren
**Problem:** DataTransfer kann nicht mit Files erstellt werden
## 🎯 Empfohlener Workflow
### Phase 1: Debugging (JETZT)
1. **Debug-Script aktivieren:**
```python
# main_window.py, _install_bridge_script()
script_path = Path(__file__).parent / "bridge_script_debug.js"
```
2. **Anwendung starten und testen:**
```powershell
python -m webdrop_bridge.main
```
3. **In Browser (F12 Console):**
- ALT-Drag+Drop durchführen
- Logs kopieren und analysieren
- Nach `[MODAL OPENED]` oder API-Calls suchen
4. **Herausfinden:**
- ✅ Wie wird Popup ausgelöst? (API-Call, Event, Component-Methode)
- ✅ Welche Asset-ID wird verwendet?
- ✅ Wo im DOM befindet sich die Popup-Logik?
### Phase 2: Implementation (DANACH)
Basierend auf Debug-Ergebnissen:
**Fall A: Popup wird durch API-Call ausgelöst**
```javascript
// In bridge_script.js nach erfolgreichem Drop:
fetch('/api/assets/' + assetId + '/checkout', {
method: 'POST',
headers: {'Content-Type': 'application/json'}
}).then(response => {
console.log('Checkout popup triggered');
});
```
**Fall B: Popup wird durch Angular-Event ausgelöst**
```javascript
// Trigger Angular CDK Event
var dropList = document.querySelector('[cdkdroplist]');
if (dropList && window.ng) {
var component = ng.getComponent(dropList);
component.onDrop({assetId: assetId});
}
```
**Fall C: Popup wird durch Component-Methode ausgelöst**
```javascript
// Direkter Methoden-Aufruf
var assetCard = document.getElementById(assetId);
if (assetCard && window.ng) {
var component = ng.getComponent(assetCard);
component.showCheckoutDialog();
}
```
### Phase 3: Testing (FINAL)
1. Implementation in `bridge_script.js` integrieren
2. Beide Funktionen testen:
- ✅ File wird gedroppt (Z:\ Laufwerk)
- ✅ Popup erscheint (Auschecken-Dialog)
## 🔧 Script-Wechsel in Code
```python
# src/webdrop_bridge/ui/main_window.py
# Zeile ~433 in _install_bridge_script()
# ORIGINAL (funktioniert, aber kein Popup):
script_path = Path(__file__).parent / "bridge_script.js"
# DEBUG (für Analyse):
script_path = Path(__file__).parent / "bridge_script_debug.js"
# Oder via Konfiguration:
script_name = self.config.bridge_script or "bridge_script.js"
script_path = Path(__file__).parent / script_name
```
## 📝 Debug-Checkliste
Beim Testen mit Debug-Script, notieren Sie:
- [ ] Wann erscheint das Popup? (Nach Drop, nach Verzögerung, sofort?)
- [ ] Gibt es API-Calls? (Welche URL, Parameter, Zeitpunkt?)
- [ ] Welche Angular-Events feuern? (CDK Events, Custom Events?)
- [ ] Wo wird Modal/Dialog erstellt? (DOM-Position, Klassen, Component)
- [ ] Welche Asset-Informationen werden benötigt? (ID, Name, URL?)
- [ ] Stack-Trace beim Modal-Öffnen? (console.trace Ausgabe)
## 🚀 Quick Commands
```powershell
# App mit Debug-Script starten
python -m webdrop_bridge.main
# In Browser Console (F12):
webdrop_debug.getEventCounts() # Event-Statistiken
webdrop_debug.resetCounters() # Zähler zurücksetzen
webdrop_debug.getListeners(element) # Event-Listener auflisten
webdrop_debug.getComponent(element) # Angular Component anzeigen
# Logs filtern:
# Console Filter: "[MODAL]" → Nur Popup-Logs
# Console Filter: "[EVENT]" → Nur Event-Logs
# Console Filter: "[FETCH]|[XHR]" → Nur Network-Logs
```
## ⚠️ Bekannte Limitationen
1. **Angular DevTools benötigt:** Für `ng.getComponent()` Installation nötig
2. **Chrome/Edge:** Einige Features funktionieren nur in Chromium-Browsern
3. **CSP:** Bei strengen Content-Security-Policies können Logs blockiert werden
4. **Performance:** Debug-Script hat deutlichen Performance-Overhead
## 📚 Weiterführende Dokumentation
- [ANGULAR_CDK_ANALYSIS.md](ANGULAR_CDK_ANALYSIS.md) - Angular Framework Details
- [DRAG_DROP_PROBLEM_ANALYSIS.md](DRAG_DROP_PROBLEM_ANALYSIS.md) - Problem-Analyse + Lösungen
- [ARCHITECTURE.md](ARCHITECTURE.md) - Gesamtarchitektur