Browse Source

Merge pull request #7537 from vvlladd28/engix-ltd-drag_drop_actions_in_list

[3.4.2] UI: Let user to drag-n-drop widget actions in list.
pull/7569/head
Igor Kulikov 4 years ago
committed by GitHub
parent
commit
da6297dfe2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html
  2. 13
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss
  3. 23
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts

45
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html

@ -59,29 +59,49 @@
</div> </div>
</mat-toolbar> </mat-toolbar>
<div fxFlex class="table-container"> <div fxFlex class="table-container">
<table mat-table [dataSource]="dataSource" <table mat-table
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear> [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear
cdkDropList cdkDropListOrientation="vertical"
[cdkDropListData]="dataSource"
(cdkDropListDropped)="dropAction($event)"
[cdkDropListDisabled]="dragDisabled"
class="tb-drop-list">
<ng-container matColumnDef="actionSourceId">
<mat-header-cell *matHeaderCellDef style="width: 36px"></mat-header-cell>
<mat-cell *matCellDef="let action">
<div cdkDragHandle
class="tb-drag-handle"
style="min-width: 36px"
(mousedown)="dragDisabled = false"
(mouseup)="dragDisabled = true"
matTooltip="{{ 'action.drag' | translate }}"
matTooltipPosition="above">
<mat-icon>drag_handle</mat-icon>
</div>
</mat-cell>
</ng-container>
<ng-container matColumnDef="actionSourceName"> <ng-container matColumnDef="actionSourceName">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 20%"> {{ 'widget-config.action-source' | translate }} </mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header style="width: 20%"> {{ 'widget-config.action-source' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let action"> <mat-cell *matCellDef="let action" style="width: 20%">
{{ action.actionSourceName }} {{ action.actionSourceName }}
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="name"> <ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 30%"> {{ 'widget-config.action-name' | translate }} </mat-header-cell> <mat-header-cell *matHeaderCellDef style="width: 30%"> {{ 'widget-config.action-name' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let action"> <mat-cell *matCellDef="let action" style="width: 30%">
{{ action.name }} {{ action.name }}
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="icon"> <ng-container matColumnDef="icon">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 40px"> {{ 'widget-config.action-icon' | translate }} </mat-header-cell> <mat-header-cell *matHeaderCellDef style="width: 40px"> {{ 'widget-config.action-icon' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let action"> <mat-cell *matCellDef="let action" style="width: 40px">
<mat-icon>{{ action.icon }}</mat-icon> <mat-icon>{{ action.icon }}</mat-icon>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="typeName"> <ng-container matColumnDef="typeName">
<mat-header-cell *matHeaderCellDef mat-sort-header style="width: 50%"> {{ 'widget-config.action-type' | translate }} </mat-header-cell> <mat-header-cell *matHeaderCellDef style="width: 50%"> {{ 'widget-config.action-type' | translate }} </mat-header-cell>
<mat-cell *matCellDef="let action"> <mat-cell *matCellDef="let action" style="width: 50%">
{{ action.typeName }} {{ action.typeName }}
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -107,9 +127,10 @@
</div> </div>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row> <mat-header-row class="mat-row-select" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row [ngClass]="{'mat-row-select': true}" <mat-row class="mat-row-select tb-draggable"
*matRowDef="let action; columns: displayedColumns;"></mat-row> *matRowDef="let action; columns: displayedColumns;"
cdkDrag [cdkDragData]="action"></mat-row>
</table> </table>
<span [fxShow]="dataSource.isEmpty() | async" <span [fxShow]="dataSource.isEmpty() | async"
fxLayoutAlign="center center" fxLayoutAlign="center center"

13
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss

@ -41,4 +41,17 @@
.mat-sort-header-sorted .mat-sort-header-arrow { .mat-sort-header-sorted .mat-sort-header-arrow {
opacity: 1 !important; opacity: 1 !important;
} }
.tb-draggable {
&.cdk-drag-placeholder {
opacity: 0;
}
&.cdk-drag-preview {
box-sizing: border-box;
border-radius: 4px;
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);
}
}
} }

23
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts

@ -37,7 +37,7 @@ import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { fromEvent, merge } from 'rxjs'; import { fromEvent, merge } from 'rxjs';
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, first, tap } from 'rxjs/operators';
import { import {
toWidgetActionDescriptor, toWidgetActionDescriptor,
WidgetActionCallbacks, WidgetActionCallbacks,
@ -54,6 +54,7 @@ import {
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
import { ResizeObserver } from '@juggle/resize-observer'; import { ResizeObserver } from '@juggle/resize-observer';
import { hidePageSizePixelValue } from '@shared/models/constants'; import { hidePageSizePixelValue } from '@shared/models/constants';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({ @Component({
selector: 'tb-manage-widget-actions', selector: 'tb-manage-widget-actions',
@ -85,6 +86,7 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
viewsInited = false; viewsInited = false;
dirtyValue = false; dirtyValue = false;
dragDisabled = true;
private widgetResize$: ResizeObserver; private widgetResize$: ResizeObserver;
@ -106,7 +108,7 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
const sortOrder: SortOrder = { property: 'actionSourceName', direction: Direction.ASC }; const sortOrder: SortOrder = { property: 'actionSourceName', direction: Direction.ASC };
this.pageLink = new PageLink(10, 0, null, sortOrder); this.pageLink = new PageLink(10, 0, null, sortOrder);
this.dataSource = new WidgetActionsDatasource(this.translate, this.utils); this.dataSource = new WidgetActionsDatasource(this.translate, this.utils);
this.displayedColumns = ['actionSourceName', 'name', 'icon', 'typeName', 'actions']; this.displayedColumns = ['actionSourceId', 'actionSourceName', 'name', 'icon', 'typeName', 'actions'];
} }
ngOnInit(): void { ngOnInit(): void {
@ -163,6 +165,23 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
this.dataSource.loadActions(this.pageLink, reload); this.dataSource.loadActions(this.pageLink, reload);
} }
dropAction(event: CdkDragDrop<WidgetActionsDatasource>) {
this.dragDisabled = true;
const droppedAction: WidgetActionDescriptorInfo = event.item.data;
this.dataSource.pageData$.pipe(
first()
).subscribe((actions) => {
const action = actions.data;
let startActionSourceIndex = action.findIndex(element => element.actionSourceId === droppedAction.actionSourceId);
const targetActions = this.getOrCreateTargetActions(droppedAction.actionSourceId);
if (startActionSourceIndex === 0) {
startActionSourceIndex -= targetActions.findIndex(element => element.id === action[0].id);
}
moveItemInArray(targetActions, event.previousIndex - startActionSourceIndex, event.currentIndex - startActionSourceIndex);
this.onActionsUpdated();
});
}
addAction($event: Event) { addAction($event: Event) {
this.openWidgetActionDialog($event); this.openWidgetActionDialog($event);
} }

Loading…
Cancel
Save