Просмотр исходного кода

fix(admin-ui): Fix broken image re-ordering drag-drop

Fixes #982
Michael Bromley 4 лет назад
Родитель
Сommit
e052b25848

+ 7 - 12
packages/admin-ui/src/lib/catalog/src/components/product-assets/product-assets.component.html

@@ -44,22 +44,17 @@
 </ng-template>
 
 <ng-template #assetList>
-    <div class="all-assets" [class.compact]="compact" cdkDropListGroup #dlg>
+    <div class="all-assets" [class.compact]="compact" cdkDropListGroup>
         <div
+            *ngFor="let asset of assets; let index = index"
+            class="drop-list"
             cdkDropList
-            #dl
+            cdkDropListOrientation="horizontal"
+            [cdkDropListData]="index"
             [cdkDropListDisabled]="!(updatePermissions | hasPermission)"
-            [cdkDropListEnterPredicate]="dropListEnterPredicate"
-            (cdkDropListDropped)="dropListDropped()"
-        ></div>
-        <div
-            *ngFor="let asset of assets"
-            cdkDropList
-            [cdkDropListDisabled]="!(updatePermissions | hasPermission)"
-            [cdkDropListEnterPredicate]="dropListEnterPredicate"
-            (cdkDropListDropped)="dropListDropped()"
+            (cdkDropListDropped)="dropListDropped($event)"
         >
-            <vdr-dropdown cdkDrag (cdkDragMoved)="dragMoved($event)">
+            <vdr-dropdown cdkDrag>
                 <div
                     class="asset-thumb"
                     vdrDropdownTrigger

+ 11 - 25
packages/admin-ui/src/lib/catalog/src/components/product-assets/product-assets.component.scss

@@ -38,6 +38,10 @@
     display: flex;
     flex-wrap: wrap;
 
+    .drop-list {
+        min-width: 60px;
+    }
+
     .asset-thumb {
         margin: 3px;
         padding: 0;
@@ -54,6 +58,9 @@
     }
 
     &.compact {
+        .drop-list {
+            min-width: 54px;
+        }
         .asset-thumb {
             margin: 1px;
             border-width: 1px;
@@ -61,31 +68,6 @@
     }
 }
 
-.cdk-drag-preview {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    width: 50px;
-    background-color: var(--color-component-bg-100);
-    opacity: 0.9;
-    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
-    0 8px 10px 1px rgba(0, 0, 0, 0.14),
-    0 3px 14px 2px rgba(0, 0, 0, 0.12);
-}
-
-.cdk-drag-placeholder {
-    opacity: 0.8;
-    width: 60px;
-    height: 50px;
-    .asset-thumb {
-        background-color: var(--color-component-bg-300);
-        height: 100%;
-        width: 54px;
-    }
-    img {
-        display: none;
-    }
-}
 .all-assets.compact .cdk-drag-placeholder {
     width: 50px;
     .asset-thumb {
@@ -104,3 +86,7 @@
 .all-assets.cdk-drop-list-dragging vdr-dropdown:not(.cdk-drag-placeholder) {
     transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
 }
+
+.cdk-drop-list-dragging > *:not(.cdk-drag-placeholder) {
+  display: none;
+}

+ 6 - 130
packages/admin-ui/src/lib/catalog/src/components/product-assets/product-assets.component.ts

@@ -1,7 +1,6 @@
-import { CdkDrag, CdkDragMove, CdkDropList, CdkDropListGroup, moveItemInArray } from '@angular/cdk/drag-drop';
+import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
 import { ViewportRuler } from '@angular/cdk/overlay';
 import {
-    AfterViewInit,
     ChangeDetectionStrategy,
     ChangeDetectorRef,
     Component,
@@ -10,7 +9,6 @@ import {
     Input,
     Optional,
     Output,
-    ViewChild,
 } from '@angular/core';
 import {
     Asset,
@@ -41,25 +39,18 @@ export interface AssetChange {
     styleUrls: ['./product-assets.component.scss'],
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
-export class ProductAssetsComponent implements AfterViewInit {
+export class ProductAssetsComponent {
     @Input('assets') set assetsSetter(val: Asset[]) {
         // create a new non-readonly array of assets
         this.assets = val.slice();
     }
+
     @Input() featuredAsset: Asset | undefined;
     @HostBinding('class.compact')
     @Input()
     compact = false;
     @Output() change = new EventEmitter<AssetChange>();
-    @ViewChild('dlg', { static: false, read: CdkDropListGroup }) listGroup: CdkDropListGroup<CdkDropList>;
-    @ViewChild('dl', { static: false, read: CdkDropList }) placeholder: CdkDropList;
 
-    public target: CdkDropList | null;
-    public targetIndex: number;
-    public source: CdkDropList | null;
-    public sourceIndex: number;
-    public dragIndex: number;
-    public activeContainer;
     public assets: Asset[] = [];
 
     private readonly updateCollectionPermissions = [Permission.UpdateCatalog, Permission.UpdateCollection];
@@ -80,15 +71,6 @@ export class ProductAssetsComponent implements AfterViewInit {
         @Optional() private collectionDetailComponent?: CollectionDetailComponent,
     ) {}
 
-    ngAfterViewInit() {
-        const phElement = this.placeholder.element.nativeElement;
-
-        phElement.style.display = 'none';
-        if (phElement.parentElement) {
-            phElement.parentElement.removeChild(phElement);
-        }
-    }
-
     selectAssets() {
         this.modalService
             .fromComponent(AssetPickerDialogComponent, {
@@ -140,114 +122,8 @@ export class ProductAssetsComponent implements AfterViewInit {
         });
     }
 
-    dragMoved(e: CdkDragMove) {
-        const point = this.getPointerPositionOnPage(e.event);
-
-        this.listGroup._items.forEach(dropList => {
-            if (__isInsideDropListClientRect(dropList, point.x, point.y)) {
-                this.activeContainer = dropList;
-                return;
-            }
-        });
-    }
-
-    dropListDropped() {
-        if (!this.target || !this.source) {
-            return;
-        }
-
-        const phElement = this.placeholder.element.nativeElement;
-        // tslint:disable-next-line:no-non-null-assertion
-        const parent = phElement.parentElement!;
-
-        phElement.style.display = 'none';
-
-        parent.removeChild(phElement);
-        parent.appendChild(phElement);
-        parent.insertBefore(this.source.element.nativeElement, parent.children[this.sourceIndex]);
-
-        this.target = null;
-        this.source = null;
-
-        if (this.sourceIndex !== this.targetIndex) {
-            moveItemInArray(this.assets, this.sourceIndex, this.targetIndex);
-            this.emitChangeEvent(this.assets, this.featuredAsset);
-        }
-    }
-
-    dropListEnterPredicate = (drag: CdkDrag, drop: CdkDropList) => {
-        if (drop === this.placeholder) {
-            return true;
-        }
-        if (drop !== this.activeContainer) {
-            return false;
-        }
-
-        const phElement = this.placeholder.element.nativeElement;
-        const sourceElement = drag.dropContainer.element.nativeElement;
-        const dropElement = drop.element.nativeElement;
-        const children = dropElement.parentElement && dropElement.parentElement.children;
-
-        const dragIndex = __indexOf(children, this.source ? phElement : sourceElement);
-        const dropIndex = __indexOf(children, dropElement);
-
-        if (!this.source) {
-            this.sourceIndex = dragIndex;
-            this.source = drag.dropContainer;
-
-            phElement.style.width = sourceElement.clientWidth + 'px';
-            phElement.style.height = sourceElement.clientHeight + 'px';
-
-            if (sourceElement.parentElement) {
-                sourceElement.parentElement.removeChild(sourceElement);
-            }
-        }
-
-        this.targetIndex = dropIndex;
-        this.target = drop;
-
-        phElement.style.display = '';
-        if (dropElement.parentElement) {
-            dropElement.parentElement.insertBefore(
-                phElement,
-                dropIndex > dragIndex ? dropElement.nextSibling : dropElement,
-            );
-        }
-
-        this.placeholder._dropListRef.enter(
-            drag._dragRef,
-            drag.element.nativeElement.offsetLeft,
-            drag.element.nativeElement.offsetTop,
-        );
-        return false;
-    };
-
-    /** Determines the point of the page that was touched by the user. */
-    getPointerPositionOnPage(event: MouseEvent | TouchEvent) {
-        // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
-        const point = __isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] : event;
-        const scrollPosition = this.viewportRuler.getViewportScrollPosition();
-
-        return {
-            x: point.pageX - scrollPosition.left,
-            y: point.pageY - scrollPosition.top,
-        };
-    }
-}
-
-function __indexOf(collection: HTMLCollection | null, node: HTMLElement) {
-    if (!collection) {
-        return -1;
+    dropListDropped(event: CdkDragDrop<number>) {
+        moveItemInArray(this.assets, event.previousContainer.data, event.container.data);
+        this.emitChangeEvent(this.assets, this.featuredAsset);
     }
-    return Array.prototype.indexOf.call(collection, node);
-}
-
-/** Determines whether an event is a touch event. */
-function __isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
-    return event.type.startsWith('touch');
-}
-
-function __isInsideDropListClientRect(dropList: CdkDropList, x: number, y: number) {
-    const { top, bottom, left, right } = dropList.element.nativeElement.getBoundingClientRect();
-    return y >= top && y <= bottom && x >= left && x <= right;
 }