Skip to content

Commit a3d2b52

Browse files
Copilotrenemadsen
andcommitted
Migrate from dragula to Angular CDK drag-drop
Co-authored-by: renemadsen <[email protected]>
1 parent 6657224 commit a3d2b52

File tree

14 files changed

+115
-145
lines changed

14 files changed

+115
-145
lines changed

eform-client/angular.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
],
2828
"tsConfig": "src/tsconfig.app.json",
2929
"allowedCommonJsDependencies": [
30-
"dragula",
3130
"file-saver"
3231
],
3332
"assets": [

eform-client/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,12 @@
9393
"date-fns": "4.1.0",
9494
"date-fns-tz": "3.2.0",
9595
"dom-to-image": "2.6.0",
96-
"dragula": "3.7.3",
9796
"file-saver": "2.0.5",
9897
"glob": "11.0.3",
9998
"hammerjs": "2.0.8",
10099
"luxon": "^3.7.2",
101100
"moment": "2.30.1",
102101
"ng-gallery": "^12.0.0",
103-
"ng2-dragula": "^6.0.0",
104102
"ng2-file-upload": "^9.0.0",
105103
"ng2-pdf-viewer": "^10.3.4",
106104
"ngx-auto-unsubscribe": "3.0.1",
@@ -136,7 +134,6 @@
136134
"@angular/language-service": "20.3.9",
137135
"@types/chai": "^5.2.2",
138136
"@types/d3": "^7.4.3",
139-
"@types/dragula": "^2.1.34",
140137
"@types/file-saver": "^2.0.7",
141138
"@types/jasmine": "^5.1.12",
142139
"@types/jest": "^30.0.0",

eform-client/src/app/app.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
55
import {GalleryModule} from 'ng-gallery';
66
import {TranslateModule} from '@ngx-translate/core';
77
import {LightboxModule} from 'ng-gallery/lightbox';
8-
import {DragulaModule} from 'ng2-dragula';
98
// TODO fix ngx-mask
109
//import {NgxMaskModule} from 'ngx-mask';
1110
import {ToastrModule} from 'ngx-toastr';
@@ -113,7 +112,6 @@ import {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';
113112
preventDuplicates: true,
114113
positionClass: 'toast-bottom-right',
115114
}),
116-
DragulaModule.forRoot(),
117115
// TODO fix ngx-mask
118116
// NgxMaskModule.forRoot(),
119117
GalleryModule,

eform-client/src/app/common/modules/eform-shared/eform-shared.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import {
2828
} from 'src/app/common/pipes';
2929
import {EformTableHeadersComponent} from './components';
3030
import {RouterModule} from '@angular/router';
31-
import {DragulaModule} from 'ng2-dragula';
3231
import {MatSortModule} from '@angular/material/sort';
3332
import {MatPaginatorIntl, MatPaginatorModule} from '@angular/material/paginator';
3433
import {MatButtonModule} from '@angular/material/button';
@@ -52,7 +51,6 @@ import {MatChip} from "@angular/material/chips";
5251
NgSelectModule,
5352
FormsModule,
5453
RouterModule,
55-
DragulaModule,
5654
MatSortModule,
5755
MatPaginatorModule,
5856
MatButtonModule,

eform-client/src/app/modules/advanced/advanced.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {NgModule} from '@angular/core';
22
import {CommonModule} from '@angular/common';
33
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
44
import {TranslateModule} from '@ngx-translate/core';
5-
import {DragulaModule} from 'ng2-dragula';
65
import {EformSharedModule} from '../../common/modules/eform-shared/eform-shared.module';
76
import {NgSelectModule} from '@ng-select/ng-select';
87
import {AdvancedRoutingModule} from './advanced.routing';
@@ -47,7 +46,6 @@ import {MatChipsModule} from '@angular/material/chips';
4746
EformSharedModule,
4847
NgSelectModule,
4948
FormsModule,
50-
DragulaModule,
5149
EformImportedModule,
5250
ReactiveFormsModule,
5351
EformSharedTagsModule,

eform-client/src/app/modules/advanced/modules/navigation-menu/components/navigation-menu-page/navigation-menu-page.component.html

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,17 @@
3131
</mat-expansion-panel-header>
3232
<div
3333
class="dragula-template"
34-
dragula="MENU_ITEMS"
34+
cdkDropList
35+
[cdkDropListData]="menuTemplate.items"
36+
[cdkDropListConnectedTo]="['actualMenuList']"
3537
id="mainMenu"
36-
[(dragulaModel)]="menuTemplate.items"
3738
>
3839
<app-navigation-menu-template-item
3940
*ngFor="
4041
let menuTemplateItem of menuTemplate.items;
4142
let itemIndex = index
4243
"
44+
cdkDrag
4345
[item]="menuTemplateItem"
4446
[itemIndex]="itemIndex"
4547
[templateIndex]="templateIndex"
@@ -56,20 +58,24 @@
5658
<mat-accordion
5759
multi="true"
5860
displayMode="flat"
59-
dragula="MENU_ITEMS"
60-
class="dragula-item"
61-
[dragulaModel]="navigationMenuModel.actualMenu"
62-
(dragulaModelChange)="menuItemModelChange($event)">
61+
cdkDropList
62+
id="actualMenuList"
63+
[cdkDropListData]="navigationMenuModel.actualMenu"
64+
[cdkDropListConnectedTo]="['mainMenu']"
65+
(cdkDropListDropped)="dropMenuItem($event)"
66+
class="dragula-item">
6367
<mat-expansion-panel *ngFor="
6468
let menuItem of navigationMenuModel.actualMenu;
6569
let firstLevelIndex = index"
6670
[hideToggle]="menuItem.type !== menuItemTypes.Dropdown"
71+
cdkDrag
6772
class="dragula-item"
6873
id="menuItems"
6974
>
7075
<mat-expansion-panel-header>
7176
<mat-panel-title>
7277
<mat-icon
78+
cdkDragHandle
7379
class="dragula-handle align-middle"
7480
style="cursor: all-scroll">
7581
menu
@@ -94,16 +100,19 @@
94100
<div
95101
id="dropdownBody"
96102
class="dragula-dropdown"
97-
dragula="MENU_ITEMS"
103+
cdkDropList
104+
[cdkDropListData]="menuItem.children"
105+
[cdkDropListConnectedTo]="['mainMenu']"
106+
(cdkDropListDropped)="dropMenuItemChild($event, firstLevelIndex)"
98107
*ngIf="menuItem.type === menuItemTypes.Dropdown"
99-
[(dragulaModel)]="menuItem.children"
100108
style="min-height: 50px;"
101109
>
102110
<ng-container
103111
*ngFor="let menuItemChild of menuItem.children;
104112
let secondLevelIndex = index"
105113
>
106114
<app-navigation-menu-item
115+
cdkDrag
107116
(itemDelete)="onItemDelete($event, firstLevelIndex, secondLevelIndex)"
108117
(itemEdit)="onItemEdit($event, firstLevelIndex, secondLevelIndex)"
109118
[item]="menuItemChild"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.cdk-drag-preview {
2+
box-sizing: border-box;
3+
border-radius: 4px;
4+
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
5+
0 8px 10px 1px rgba(0, 0, 0, 0.14),
6+
0 3px 14px 2px rgba(0, 0, 0, 0.12);
7+
}
8+
9+
.cdk-drag-animating {
10+
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
11+
}
12+
13+
.cdk-drop-list-dragging .cdk-drag:not(.cdk-drag-placeholder) {
14+
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
15+
}
16+
17+
.dragula-dropdown {
18+
min-height: 50px;
19+
}

eform-client/src/app/modules/advanced/modules/navigation-menu/components/navigation-menu-page/navigation-menu-page.component.ts

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
2-
import { DragulaService } from 'ng2-dragula';
2+
import { CdkDragDrop, moveItemInArray, copyArrayItem, transferArrayItem } from '@angular/cdk/drag-drop';
33
import {
44
NavigationMenuItemIndexedModel,
55
NavigationMenuItemModel,
@@ -36,7 +36,6 @@ import {loadAppMenu, selectCurrentUserLocale} from 'src/app/state';
3636
})
3737
export class NavigationMenuPageComponent implements OnInit, OnDestroy {
3838
private authStore = inject(Store);
39-
private dragulaService = inject(DragulaService);
4039
private navigationMenuService = inject(NavigationMenuService);
4140
private securityGroupsService = inject(SecurityGroupsService);
4241
private authStateService = inject(AuthStateService);
@@ -65,32 +64,6 @@ export class NavigationMenuPageComponent implements OnInit, OnDestroy {
6564
}
6665

6766
constructor() {
68-
const dragulaService = this.dragulaService;
69-
70-
dragulaService.createGroup('MENU_ITEMS', {
71-
moves: (el, container, handle) => {
72-
return handle.classList.contains('dragula-handle');
73-
},
74-
copy: (el, source) => {
75-
return source.id === 'mainMenu' || source.id === 'pluginMenu';
76-
},
77-
copyItem: (data: NavigationMenuItemModel) => {
78-
return { ...data, type: NavigationMenuItemTypeEnum.Link, isInternalLink: true, };
79-
},
80-
accepts: (el, target) => {
81-
// To avoid dragging from right to left container
82-
return (
83-
(target.classList.contains('dragula-item') ||
84-
(target.classList.contains('dragula-dropdown') &&
85-
!el.classList.contains('dragula-dropdown'))) &&
86-
target.id !== 'mainMenu' &&
87-
target.id !== 'pluginMenu'
88-
);
89-
},
90-
});
91-
this.dragulaService.drop('MENU_ITEMS').subscribe(({ name }) => {
92-
this.dragulaService.find(name).drake.cancel(true);
93-
});
9467
}
9568

9669
ngOnInit(): void {
@@ -133,8 +106,37 @@ export class NavigationMenuPageComponent implements OnInit, OnDestroy {
133106
];
134107
}
135108

109+
dropMenuItem(event: CdkDragDrop<NavigationMenuItemModel[]>) {
110+
if (event.previousContainer === event.container) {
111+
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
112+
} else {
113+
// Copy from template menu
114+
const item = {
115+
...event.previousContainer.data[event.previousIndex],
116+
type: NavigationMenuItemTypeEnum.Link,
117+
isInternalLink: true
118+
};
119+
this.navigationMenuModel.actualMenu.splice(event.currentIndex, 0, item);
120+
}
121+
this.navigationMenuModel.actualMenu = [...this.navigationMenuModel.actualMenu];
122+
}
123+
124+
dropMenuItemChild(event: CdkDragDrop<NavigationMenuItemModel[]>, parentIndex: number) {
125+
if (event.previousContainer === event.container) {
126+
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
127+
} else {
128+
// Copy from template menu
129+
const item = {
130+
...event.previousContainer.data[event.previousIndex],
131+
type: NavigationMenuItemTypeEnum.Link,
132+
isInternalLink: true
133+
};
134+
this.navigationMenuModel.actualMenu[parentIndex].children.splice(event.currentIndex, 0, item);
135+
}
136+
this.navigationMenuModel.actualMenu = [...this.navigationMenuModel.actualMenu];
137+
}
138+
136139
ngOnDestroy(): void {
137-
this.dragulaService.destroy('MENU_ITEMS');
138140
}
139141

140142
onItemDelete(
@@ -227,10 +229,6 @@ export class NavigationMenuPageComponent implements OnInit, OnDestroy {
227229
).name;
228230
}
229231

230-
menuItemModelChange($event: any[]) {
231-
this.navigationMenuModel.actualMenu = [...$event];
232-
}
233-
234232
getSecurityGroupNames(ids: number[]): string[] {
235233
return ids.map(id => {
236234
const group = this.securityGroups.find(g => g.id === id);

eform-client/src/app/modules/advanced/modules/navigation-menu/navigation-menu.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from './components';
1414
import { NavigationMenuRouting } from './navigation-menu.routing';
1515
import { TranslateModule } from '@ngx-translate/core';
16-
import { DragulaModule } from 'ng2-dragula';
16+
import { DragDropModule } from '@angular/cdk/drag-drop';
1717
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
1818
import { EformSharedModule } from 'src/app/common/modules/eform-shared/eform-shared.module';
1919
import {MatCheckboxModule} from '@angular/material/checkbox';
@@ -44,7 +44,7 @@ import {MatInputModule} from '@angular/material/input';
4444
CommonModule,
4545
NavigationMenuRouting,
4646
TranslateModule,
47-
DragulaModule,
47+
DragDropModule,
4848
FormsModule,
4949
EformSharedModule,
5050
ReactiveFormsModule,

eform-client/src/app/modules/eforms/eform-visual-editor/components/eform-visual-editor-page/eform-visual-editor-container/eform-visual-editor-container.component.html

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,19 @@
7474
[ngClass]="{'collapsed' : isItemsCollapsed}"
7575
>
7676
<div
77-
dragula="CHECK_LISTS"
77+
cdkDropList
7878
id="editorChecklists"
79-
(dragulaModelChange)="dragulaPositionChecklistChanged($event)"
80-
[dragulaModel]="visualEditorTemplateModel.checkLists"
79+
[cdkDropListData]="visualEditorTemplateModel.checkLists"
80+
(cdkDropListDropped)="dropChecklist($event)"
81+
class="cdk-drop-list"
8182
>
8283
<app-visual-editor-checklist
8384
*ngFor="
8485
let checklist of visualEditorTemplateModel.checkLists;
8586
let i = index
8687
"
88+
cdkDrag
89+
[cdkDragDisabled]="!checklist.collapsed"
8790
[checklist]="checklist"
8891
[checklistRecursionIndexes]="[i]"
8992
[checklistIndex]="i"
@@ -109,17 +112,18 @@
109112
!visualEditorTemplateModel.checkLists ||
110113
visualEditorTemplateModel.checkLists.length == 0
111114
"
112-
dragula="FIELDS"
115+
cdkDropList
113116
id="editorFields"
114-
class="editor-fields"
115-
(dragulaModelChange)="dragulaPositionFieldChanged($event)"
116-
[dragulaModel]="visualEditorTemplateModel.fields"
117+
class="editor-fields cdk-drop-list"
118+
[cdkDropListData]="visualEditorTemplateModel.fields"
119+
(cdkDropListDropped)="dropField($event)"
117120
>
118121
<app-visual-editor-field
119122
*ngFor="
120123
let field of visualEditorTemplateModel.fields;
121124
let i = index
122125
"
126+
cdkDrag
123127
[field]="field"
124128
[fieldIndex]="i"
125129
id="field_{{ i }}"

0 commit comments

Comments
 (0)