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:
parent
88dc358894
commit
dee02ad600
12 changed files with 2244 additions and 65 deletions
268
docs/ANGULAR_CDK_ANALYSIS.md
Normal file
268
docs/ANGULAR_CDK_ANALYSIS.md
Normal 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
|
||||
277
docs/DRAG_DROP_PROBLEM_ANALYSIS.md
Normal file
277
docs/DRAG_DROP_PROBLEM_ANALYSIS.md
Normal 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
171
docs/SCRIPT_VARIANTS.md
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue