# Drag & Drop Problem Analysis - File Drop + Web App Popup

**Status**: Phase 1 (File Drop) ✅ Implemented | Phase 2 (Popup Trigger) ⏸️ Planned  
**Last Updated**: March 3, 2026

## Overview

### Current Implementation Status

✅ **Phase 1 - File Drop (IMPLEMENTED)**
- JavaScript in `bridge_script_intercept.js` intercepts drag events
- Calls `window.bridge.start_file_drag(url)` via QWebChannel to Qt
- Validates path against whitelist via `PathValidator`
- Converts Azure Storage URLs to local paths via `URLConverter`
- Creates and executes native Qt file drag operation
- Target application (InDesign, Word, etc.) successfully receives file

⏸️ **Phase 2 - Programmatic Popup Trigger (PLANNED)**
- Would require reverse-engineering the web app's popup trigger mechanism
- Could be implemented by calling JavaScript function after successful drop
- Currently: Applications handle popups manually or separately from file drops

---

## Das Kernproblem
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

### Current Status (as of March 2026)

✅ **Phase 1 Complete:**
- File-drop via native Qt drag operations is fully functional
- JavaScript bridge (`bridge_script_intercept.js`) successfully intercepts and converts drags
- Path validation and Azure URL mapping working
- Tested with real applications (InDesign, Word, etc.)

### For Future Enhancement (Phase 2 - Popup Trigger)

**If popup trigger integration is needed:**

1. 🔍 **Reverse-Engineering the Target Web App:**
   - Identify how popups are triggered (API call, component method, event, etc.)
   - Use browser DevTools:
     - Network tab → Monitor API calls
     - Console → Check for JavaScript errors/logs
     - Elements → Inspect component structure
     - Angular/Vue DevTools if applicable

2. 🛠️ **Implement Popup Trigger:**
   - Create JavaScript hook function (e.g., `window.trigger_popup(assetId)`)
   - Connect to drop success signal from Qt
   - Call popup trigger after successful file drop

3. 🧪 **Test Integration:**
   - Verify file drops successfully
   - Verify popup appears after drop
   - Test with real assets/files

**Alternative Approaches:**

- **Lösung B (Manual)**: Keep file drop and popup as separate user actions
- **Lösung C (Complex)**: Use overlay window approach (more involved)

Current implementation uses **Phase 1 of Lösung A** and is production-ready.
