diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts
index 7cfcf269de..c7ee635dae 100644
--- a/ui-ngx/src/app/modules/home/components/home-components.module.ts
+++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts
@@ -173,6 +173,7 @@ import { RateLimitsDetailsDialogComponent } from '@home/components/profile/tenan
import { AssetProfileComponent } from '@home/components/profile/asset-profile.component';
import { AssetProfileDialogComponent } from '@home/components/profile/asset-profile-dialog.component';
import { AssetProfileAutocompleteComponent } from '@home/components/profile/asset-profile-autocomplete.component';
+import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
declarations:
@@ -321,6 +322,7 @@ import { AssetProfileAutocompleteComponent } from '@home/components/profile/asse
imports: [
CommonModule,
SharedModule,
+ DragDropModule,
SharedHomeComponentsModule,
WidgetSettingsModule,
Lwm2mProfileComponentsModule,
@@ -453,7 +455,8 @@ import { AssetProfileAutocompleteComponent } from '@home/components/profile/asse
RateLimitsListComponent,
RateLimitsComponent,
RateLimitsTextComponent,
- RateLimitsDetailsDialogComponent
+ RateLimitsDetailsDialogComponent,
+ DragDropModule
],
providers: [
WidgetComponentService,
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html
index c3c51a5d76..81ccd42da0 100644
--- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html
@@ -60,7 +60,14 @@
+ matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()" matSortDisableClear
+ cdkDropList [cdkDropListData]="dataSource" (cdkDropListDropped)="dropAction($event)">
+
+ {{ 'widget-config.action-source-order' | translate }}
+
+ reorder
+
+
{{ 'widget-config.action-source' | translate }}
@@ -109,7 +116,8 @@
+ *matRowDef="let action; columns: displayedColumns;"
+ cdkDrag [cdkDragData]="action">
) {
+ const droppedAction = event.item.data;
+ this.dataSource.getAllActions().subscribe(
+ (actions) => {
+ moveItemInArray(actions, event.previousIndex, event.currentIndex);
+
+ const isBackward = event.currentIndex > event.previousIndex;
+ let nearestNeighbourAction: WidgetActionDescriptorInfo = null;
+ for (let i: number = isBackward ? actions.length - 1 : 0;
+ isBackward ? i >= 0 : i < actions.length; isBackward ? --i : ++i) {
+ if (actions[i].id === droppedAction.id) {
+ break;
+ }
+ if (actions[i].actionSourceId === droppedAction.actionSourceId) {
+ nearestNeighbourAction = actions[i];
+ }
+ }
+
+ const targetActions = this.getOrCreateTargetActions(droppedAction.actionSourceId);
+ let oldIndex: number = -1;
+ let newIndex: number = nearestNeighbourAction ? -1 : (isBackward ? targetActions.length - 1 : 0);
+
+ for (let i: number = isBackward ? targetActions.length - 1 : 0;
+ isBackward ? i >= 0 : i < targetActions.length; isBackward ? --i : ++i) {
+ if (targetActions[i].id === droppedAction.id) {
+ oldIndex = i;
+ }
+ if (nearestNeighbourAction && targetActions[i].id === nearestNeighbourAction.id) {
+ newIndex = isBackward ? i - 1 : i + 1;
+ }
+ if (oldIndex !== -1 && newIndex !== -1) {
+ moveItemInArray(targetActions, oldIndex, newIndex);
+ this.onActionsUpdated();
+ return;
+ }
+ }
+ }
+ );
+ }
+
addAction($event: Event) {
this.openWidgetActionDialog($event);
}
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json
index 061f042e44..878ee53d3b 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -3686,6 +3686,7 @@
"add-action": "Add action",
"search-actions": "Search actions",
"no-actions-text": "No actions found",
+ "action-source-order": "Order",
"action-source": "Action source",
"action-source-required": "Action source is required.",
"action-name": "Name",