# 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)