Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[dragAndDrop]="macro.macroActions"
[dragAndDropHandle]="dragAndDropHandle"
(dragAndDropChange)="macroActionReordered($event)">
<macro-item *ngFor="let macroAction of macro.macroActions; let macroActionIndex = index; trackBy:macroActionTrackByFn.bind(this)"
<macro-item *ngFor="let macroAction of macro.macroActions; let macroActionIndex = index; trackBy:macroActionTrackByFn"
[class.active]="selectedMacroActionId?.id === macroActionIndex"
[isMacroCommandSupported]="isMacroCommandSupported"
[macroAction]="macroAction"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export class MacroListComponent implements AfterViewChecked, OnDestroy {
readonly dragAndDropHandle = '.action--movable';
faPlus = faPlus;
scrollTopPosition: number;
isMacroReordering = false;

private scrollToBottomIntervalTimer: number;
private scrollToBottomSetTimeoutTimer: number;
Expand All @@ -89,10 +88,6 @@ export class MacroListComponent implements AfterViewChecked, OnDestroy {
window.scrollTo(window.scrollX, this.scrollTopPosition);
this.scrollTopPosition = undefined;
}

if (this.isMacroReordering) {
this.isMacroReordering = false;
}
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -168,20 +163,14 @@ export class MacroListComponent implements AfterViewChecked, OnDestroy {
}

macroActionReordered(macroActions: MacroAction[]): void {
this.isMacroReordering = true;
this.scrollTopPosition = window.scrollY;
this.reorder.emit({
macroId: this.macro.id,
macroActions
});
}

macroActionTrackByFn(index: number, macroAction: MacroAction): string {
if (this.isMacroReordering) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
return index.toString() + macroAction.toString();
}

macroActionTrackByFn(index: number): string {
return index.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class DragAndDropDirective implements OnDestroy {
private startX = 0;
private startY = 0;
private initialRect: DOMRect;
private initialOrder: HTMLElement[] = [];

private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);

Expand Down Expand Up @@ -68,6 +69,7 @@ export class DragAndDropDirective implements OnDestroy {
this.offsetX = event.clientX - rect.left;
this.offsetY = event.clientY - rect.top;
this.initialRect = rect;
this.initialOrder = Array.from(this.elementRef.nativeElement.children) as HTMLElement[];

window.addEventListener('pointermove', this.onPointerMove);
window.addEventListener('pointerup', this.onPointerUp);
Expand Down Expand Up @@ -110,13 +112,32 @@ export class DragAndDropDirective implements OnDestroy {
}

const reordered = this.dragging ? this.getReorderedModel() : undefined;
this.restoreDomOrder();
this.cleanup();

if (reordered) {
this.dragAndDropChange.emit(reordered);
}
};

/**
* Puts the list items back into their pre-drag DOM order.
*
* The reordering is shown live by moving the actual DOM nodes, but that leaves the DOM out of
* sync with the view order Angular tracks for the bound model. Restoring the original order
* before emitting lets Angular re-render the reordered model with its own, consistent view
* order instead of duplicating or misplacing items.
*/
private restoreDomOrder(): void {
const container = this.elementRef.nativeElement;

for (const child of this.initialOrder) {
container.appendChild(child);
}

this.initialOrder = [];
}

private beginDrag(): void {
this.dragging = true;
this.item.classList.add(TRANSIT_CLASS);
Expand Down Expand Up @@ -309,5 +330,6 @@ export class DragAndDropDirective implements OnDestroy {
this.mirror = undefined;
this.pointerId = -1;
this.initialRect = undefined;
this.initialOrder = [];
}
}
Loading