aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/modules/dashboard
diff options
context:
space:
mode:
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-04-14 11:59:32 +0000
committerFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-04-14 11:59:32 +0000
commitd68841d9f75636575cd778838a8ceea5fd5aada3 (patch)
tree778c84203ed9bfa4dc1c8234e4e2cf60da6ebd8c /src/app/modules/dashboard
parent42af09588f1f839b9ab36356f02f34c89559bcfa (diff)
Upload ui
Issue-ID: PORTAL-1084 Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de> Change-Id: Id0c94859a775094e67b0bb9c91ca5e776a08c068
Diffstat (limited to 'src/app/modules/dashboard')
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.css19
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.html63
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.ts40
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.css23
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.html105
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.ts35
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.css19
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.html33
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.ts39
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.css27
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.html85
-rw-r--r--src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.ts145
-rw-r--r--src/app/modules/dashboard/dashboard-routing.module.ts31
-rw-r--r--src/app/modules/dashboard/dashboard.component.css34
-rw-r--r--src/app/modules/dashboard/dashboard.component.html77
-rw-r--r--src/app/modules/dashboard/dashboard.component.ts88
-rw-r--r--src/app/modules/dashboard/dashboard.module.ts41
17 files changed, 904 insertions, 0 deletions
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.css b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.css
new file mode 100644
index 0000000..b7b5110
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.css
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.html b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.html
new file mode 100644
index 0000000..2c35f19
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.html
@@ -0,0 +1,63 @@
+<!--
+ ~ Copyright (c) 2022. Deutsche Telekom AG
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ -->
+
+
+<ng-container *ngIf="action">
+ <button
+ *ngIf="action.type | in: REPEAT_ACTIONS"
+ class="btn btn-invisible p-0 qa_repeat_action"
+ (click)="onButtonClick(action)"
+ [attr.aria-label]="'dashboard.apps.userLastAction.tooltip.repeatAction' | translate"
+ [ngbTooltip]="repeatActionTooltipContent"
+ container="body"
+ >
+ <i class="bi bi-arrow-clockwise pointer" aria-hidden="true"></i>
+ </button>
+ <button
+ *ngIf="action.type | in: VIEW_ACTIONS"
+ class="btn btn-invisible p-0 qa_view_action"
+ (click)="onButtonClick(action)"
+ [attr.aria-label]="'dashboard.apps.userLastAction.tooltip.viewAction' | translate"
+ [ngbTooltip]="viewActionTooltipContent"
+ container="body"
+ >
+ <i class="bi bi-eyeglasses" aria-hidden="true"></i>
+ </button>
+
+ <ng-template #repeatActionTooltipContent>
+ <span
+ >{{ 'dashboard.apps.userLastAction.actionType.' + action.type | translate }}
+ {{ 'dashboard.apps.userLastAction.tooltip.again' | translate }}
+ {{ 'dashboard.apps.userLastAction.entityType.' + action.entity | translate }}
+ {{ message }}</span
+ >
+ </ng-template>
+ <ng-template #viewActionTooltipContent>
+ <span
+ >{{ 'dashboard.apps.userLastAction.actionType.' + ActionType.VIEW | translate }}
+ <span *ngIf="action.type === ActionType.DEPLOY">
+ {{ 'dashboard.apps.userLastAction.tooltip.statusOf' | translate }}
+ </span>
+ {{ 'dashboard.apps.userLastAction.entityType.' + action.entity | translate }}
+ <span *ngIf="action.type === ActionType.DEPLOY">
+ {{ 'dashboard.apps.userLastAction.tooltip.deployment' | translate }}
+ </span>
+ {{ message }}</span
+ >
+ </ng-template>
+</ng-container>
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.ts b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.ts
new file mode 100644
index 0000000..b30a35e
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-button/action-button.component.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { ActionModel, ActionRowModel, ActionType, EntityTypeModel } from '../../../../../model/user-last-action.model';
+
+@Component({
+ selector: 'app-action-button',
+ templateUrl: './action-button.component.html',
+ styleUrls: ['./action-button.component.css'],
+})
+export class ActionButtonComponent {
+ public readonly VIEW_ACTIONS = [ActionType.ACK, ActionType.UNACK, ActionType.CLEAR, ActionType.DEPLOY];
+ public readonly REPEAT_ACTIONS = [ActionType.SEARCH, ActionType.VIEW, ActionType.EDIT];
+ ActionType = ActionType;
+
+ @Input() action: ActionRowModel<EntityTypeModel> | undefined;
+ @Input() message: string | undefined;
+ @Output() btnClick = new EventEmitter<ActionModel>();
+
+ public onButtonClick(action: ActionModel): void {
+ this.btnClick.emit(action);
+ }
+}
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.css b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.css
new file mode 100644
index 0000000..c6f52a8
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.css
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+img {
+ height: 20px;
+ width: 20px;
+}
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.html b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.html
new file mode 100644
index 0000000..62cf722
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.html
@@ -0,0 +1,105 @@
+<!--
+ ~ Copyright (c) 2022. Deutsche Telekom AG
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ -->
+
+
+<ng-container *ngIf="action">
+ <div class="row py-2 border-bottom">
+ <div class="col-3">
+ <div class="d-flex justify-content-between">
+ <span
+ class="qa_action_created_at"
+ container="body"
+ [ngbTooltip]="action.actionCreatedAt | date: FULL_DATE_FORMAT"
+ >{{
+ (action.actionCreatedAt | isToday)
+ ? (action.actionCreatedAt | date: TIME_FORMAT)
+ : (action.actionCreatedAt | date: DATE_FORMAT)
+ }}</span
+ >
+ <ng-container [ngSwitch]="action.type">
+ <ng-template [ngSwitchCase]="ActionType.CREATE">
+ <img
+ class="qa_create_icon"
+ src='../../../../../../assets/images/icons/install_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.CREATE' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.DELETE">
+ <img
+ class="qa_delete_icon"
+ src='../../../../../../assets/images/icons/eraser_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.DELETE' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.SEARCH">
+ <img
+ class="qa_search_icon"
+ src='../../../../../../assets/images/icons/search_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.SEARCH' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.VIEW">
+ <img
+ class="qa_view_icon"
+ src='../../../../../../assets/images/icons/visible_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.VIEW' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.EDIT">
+ <img
+ class="qa_edit_icon"
+ src='../../../../../../assets/images/icons/edit_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.EDIT' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.CLEAR">
+ <img
+ class="qa_clear_icon"
+ src='../../../../../../assets/images/icons/brush_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.CLEAR' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.ACK">
+ <img
+ class="qa_ack_icon"
+ src='../../../../../../assets/images/icons/thumbs-up_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.ACK' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.UNACK">
+ <img
+ class="qa_unack_icon"
+ src='../../../../../../assets/images/icons/thumbs-down_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.UNACK' | translate"
+ />
+ </ng-template>
+ <ng-template [ngSwitchCase]="ActionType.DEPLOY">
+ <img
+ class="qa_deployment_icon"
+ src='../../../../../../assets/images/icons/crane_graphical.svg'
+ [attr.alt]="'dashboard.apps.userLastAction.actionType.DEPLOY' | translate"
+ />
+ </ng-template>
+ </ng-container>
+ </div>
+ </div>
+ <div class="col-9">
+ <ng-content></ng-content>
+ </div>
+ </div>
+</ng-container>
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.ts b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.ts
new file mode 100644
index 0000000..89e7950
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/action-row/action-row.component.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { Component, Input } from '@angular/core';
+import { ActionModel, ActionType, EntityType } from '../../../../../model/user-last-action.model';
+
+@Component({
+ selector: 'app-action-row',
+ templateUrl: './action-row.component.html',
+ styleUrls: ['./action-row.component.css'],
+})
+export class ActionRowComponent {
+ readonly FULL_DATE_FORMAT = 'E, d MMM Y HH:mm';
+ readonly TIME_FORMAT = 'HH:mm';
+ readonly DATE_FORMAT = 'd MMM';
+ ActionType = ActionType;
+ EntityType = EntityType;
+ @Input() action: ActionModel | undefined;
+}
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.css b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.css
new file mode 100644
index 0000000..b7b5110
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.css
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.html b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.html
new file mode 100644
index 0000000..54f71c6
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.html
@@ -0,0 +1,33 @@
+<!--
+ ~ Copyright (c) 2022. Deutsche Telekom AG
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ -->
+
+
+<div class="d-flex justify-content-between" *ngIf='action'>
+ <span class="d-inline-block text-truncate w-100"
+ >{{ 'dashboard.apps.userLastAction.actionType.' + action.type | translate }}
+ {{ 'dashboard.apps.userLastAction.entityType.' + action.entity | translate | colon }}
+ {{ action.entityParams.userName }}
+ </span>
+
+ <app-action-button
+ *ngIf="action.type === ActionType.EDIT"
+ [message]="action.entityParams.userName"
+ [action]="action"
+ (btnClick)="repeatAction(action)"
+ ></app-action-button>
+</div>
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.ts b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.ts
new file mode 100644
index 0000000..b55ad17
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { Component, Input } from '@angular/core';
+import { ActionRowModel, ActionType, EntityUserHistoryActionModel } from '../../../../../model/user-last-action.model';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-entity-user-administration-row',
+ templateUrl: './entity-user-administration-row.component.html',
+ styleUrls: ['./entity-user-administration-row.component.css'],
+})
+export class EntityUserAdministrationRowComponent {
+ ActionType = ActionType;
+ @Input()
+ action: ActionRowModel<EntityUserHistoryActionModel> | undefined;
+
+ constructor(private router: Router) {}
+
+ public repeatAction(action: ActionRowModel<EntityUserHistoryActionModel>): void {
+ this.router.navigate(['user-administration', action.entityParams.userId, 'edit']);
+ }
+}
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.css b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.css
new file mode 100644
index 0000000..60842fa
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.css
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+img {
+ height: 20px;
+ width: 20px;
+}
+
+.bg-color-inherit {
+ background-color: inherit;
+}
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.html b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.html
new file mode 100644
index 0000000..d696728
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.html
@@ -0,0 +1,85 @@
+<!--
+ ~ Copyright (c) 2022. Deutsche Telekom AG
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ -->
+
+<ng-template #template>
+ <ng-container *ngIf="actions$ | async as actions">
+ <div class="col-xl-4 col-lg-6 col-sm-12 my-2 qa_USER_LAST_ACTION_TILE" cdkDrag>
+ <div class="shadow card" style="height: 334.867px">
+ <div class="card-header pl-3">
+ <div class="d-flex" *ngIf="actionFilterType$ | async as selectedFilter">
+ <div class="d-flex align-items-center">
+ <i
+ class="bi bi-arrows-move text-primary draggable text-primary pr-2"
+ cdkDragHandle
+ aria-hidden="true"
+ ></i>
+ <label class="d-none" for="filterSelect"
+ >{{ 'dashboard.apps.userLastAction.filter.label' | translate
+ }}{{ 'dashboard.apps.userLastAction.filter.type.' + selectedFilter | translate }}</label
+ >
+ <select
+ id="filterSelect"
+ [ngModel]="selectedFilter"
+ (ngModelChange)="changeFilterType.next($event)"
+ class="form-select-sm font-weight-bolder bg-color-inherit"
+ >
+ <option *ngFor="let filter of actionsFilter" [ngValue]="filter" class="font-weight-normal">
+ {{ 'dashboard.apps.userLastAction.filter.type.' + filter | translate }}
+ </option>
+ </select>
+ </div>
+ <div class="d-flex" *ngIf="actionIntervalType$ | async as selectedInterval">
+ <label class="d-none" for="intervalSelect"
+ >{{ 'dashboard.apps.userLastAction.filter.label' | translate
+ }}{{ 'dashboard.apps.userLastAction.filter.interval.' + selectedInterval | translate }}</label
+ >
+ <select
+ id="intervalSelect"
+ [ngModel]="selectedInterval"
+ (ngModelChange)="changeIntervalType.next($event)"
+ class="form-select-sm font-weight-bold bg-color-inherit"
+ >
+ <option *ngFor="let interval of intervals" [ngValue]="interval" class="font-weight-normal">
+ {{ 'dashboard.apps.userLastAction.filter.interval.' + interval | translate }}
+ </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="card-body overflow-auto">
+ <ng-container *ngIf="actions.length > 0; else noData">
+ <div *ngFor="let action of actions">
+ <app-action-row [action]="action">
+ <app-entity-user-administration-row
+ *ngIf="action.entity === EntityType.USERADMINISTRATION"
+ [action]="$any(action)"
+ ></app-entity-user-administration-row>
+ </app-action-row>
+ </div>
+ </ng-container>
+ </div>
+ <div class="card-footer"></div>
+ </div>
+ </div>
+ </ng-container>
+</ng-template>
+<ng-template #noData>
+ <div class="d-flex justify-content-center qa_class_no_data">
+ {{ 'common.filters.noResults' | translate }}
+ </div>
+</ng-template>
diff --git a/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.ts b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.ts
new file mode 100644
index 0000000..c03016f
--- /dev/null
+++ b/src/app/modules/dashboard/apps/user-last-action-tile/user-last-action-tile.component.ts
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { Component, OnInit, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
+import {
+ ActionFilter,
+ ActionInterval,
+ ActionModel,
+ ActionType,
+ EntityType,
+} from '../../../../model/user-last-action.model';
+import { ActionsListResponse } from '../../../../../../openapi/output';
+import { combineLatest, merge, Subject } from 'rxjs';
+import { map, scan, shareReplay, switchMap } from 'rxjs/operators';
+import { UnsubscribeService } from '../../../../services/unsubscribe/unsubscribe.service';
+import { selectDistinctState, UserSettingsService } from '../../../../services/user-settings.service';
+import { LastUserActionSettings, STATE_KEYS } from '../../../../model/user-preferences.model';
+import { HistoryService } from '../../../../services/history.service';
+
+@Component({
+ selector: 'app-user-last-action-tile',
+ templateUrl: './user-last-action-tile.component.html',
+ styleUrls: ['./user-last-action-tile.component.css'],
+ providers: [UnsubscribeService],
+})
+export class UserLastActionTileComponent implements OnInit {
+ public readonly actionsFilter: ActionFilter[] = Object.values(ActionFilter);
+ public readonly intervals: ActionInterval[] = Object.values(ActionInterval);
+ public readonly ActionType = ActionType;
+ public readonly EntityType = EntityType;
+ public changeFilterType: Subject<ActionFilter> = new Subject<ActionFilter>();
+ public changeIntervalType: Subject<ActionInterval> = new Subject<ActionInterval>();
+
+ @ViewChild('template', { static: true }) template!: TemplateRef<unknown>;
+
+ constructor(
+ private viewContainerRef: ViewContainerRef,
+ private historyService: HistoryService,
+ private unsubscribeService: UnsubscribeService,
+ private userSettingsService: UserSettingsService,
+ ) {}
+
+ private userActionsSettings$ = this.userSettingsService
+ .selectLastUserAction()
+ .pipe(shareReplay({ refCount: true, bufferSize: 1 }));
+
+ public actionFilterType$ = this.userActionsSettings$.pipe(
+ selectDistinctState<LastUserActionSettings, ActionFilter>(STATE_KEYS.FILTER_TYPE),
+ shareReplay({ refCount: true, bufferSize: 1 }),
+ );
+
+ public actionIntervalType$ = this.userActionsSettings$.pipe(
+ selectDistinctState<LastUserActionSettings, ActionInterval>(STATE_KEYS.INTERVAL),
+ shareReplay({ refCount: true, bufferSize: 1 }),
+ );
+
+ public actions$ = combineLatest([this.actionFilterType$, this.actionIntervalType$]).pipe(
+ switchMap(([filter, interval]) => {
+ const mappedInterval = UserLastActionTileComponent.mapActionInterval(interval);
+ return this.historyService.getUserActions(mappedInterval).pipe(
+ map(actions => UserLastActionTileComponent.mapActionsFromResponse(actions)),
+ map(actions => this.filterBySelectedFilterType(filter, actions)),
+ );
+ }),
+ );
+
+ private commands$ = merge(
+ this.changeIntervalType.pipe(map(interval => ({ interval: interval }))),
+ this.changeFilterType.pipe(map(filterType => ({ filterType: filterType }))),
+ );
+
+ private settings$ = this.userActionsSettings$.pipe(
+ switchMap(data => this.commands$.pipe(scan((settings, change) => ({ ...settings, ...change }), data))),
+ );
+
+ ngOnInit(): void {
+ this.viewContainerRef.createEmbeddedView(this.template);
+
+ this.settings$
+ .pipe(
+ switchMap(lastUserAction =>
+ this.userSettingsService.updatePreferences({
+ dashboard: {
+ apps: {
+ lastUserAction,
+ },
+ },
+ }),
+ ),
+ )
+ .subscribe();
+ }
+
+ private static mapActionsFromResponse(actions: ActionsListResponse): ActionModel[] {
+ return actions.items.map((action: any) => {
+ return {
+ actionCreatedAt: action.actionCreatedAt,
+ type: action.action.type,
+ entity: action.action.entity,
+ entityParams: {
+ ...action.action.entityParams,
+ },
+ };
+ });
+ }
+
+ private static mapActionInterval(interval: ActionInterval): number | undefined {
+ switch (interval) {
+ case ActionInterval.ALL:
+ return undefined;
+ case ActionInterval.LAST1D:
+ return 24;
+ case ActionInterval.LAST1H:
+ return 1;
+ case ActionInterval.LAST4H:
+ return 4;
+ }
+ }
+
+ private filterBySelectedFilterType(filter: ActionFilter, actions: ActionModel[]): ActionModel[] {
+ if (filter === ActionFilter.ALL) {
+ return actions;
+ } else if (filter === ActionFilter.SEARCH) {
+ return actions.filter(action => action.type === ActionType.SEARCH);
+ } else {
+ return actions.filter(action => action.type !== ActionType.SEARCH);
+ }
+ }
+}
diff --git a/src/app/modules/dashboard/dashboard-routing.module.ts b/src/app/modules/dashboard/dashboard-routing.module.ts
new file mode 100644
index 0000000..68833ba
--- /dev/null
+++ b/src/app/modules/dashboard/dashboard-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import { AuthGuard } from '../../guards/auth.guard';
+import { DashboardComponent } from './dashboard.component';
+
+const routes: Routes = [{ path: '', component: DashboardComponent, canActivate: [AuthGuard] }];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule],
+})
+export class DashboardRoutingModule {}
diff --git a/src/app/modules/dashboard/dashboard.component.css b/src/app/modules/dashboard/dashboard.component.css
new file mode 100644
index 0000000..bdf57d6
--- /dev/null
+++ b/src/app/modules/dashboard/dashboard.component.css
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+p {
+ margin-bottom: 0 !important;
+}
+li {
+ list-style-type: none;
+}
+
+.row > * {
+ flex-shrink: 0;
+ width: initial;
+ max-width: initial;
+ padding-right: initial;
+ padding-left: initial;
+ margin-top: initial;
+}
diff --git a/src/app/modules/dashboard/dashboard.component.html b/src/app/modules/dashboard/dashboard.component.html
new file mode 100644
index 0000000..76a8e96
--- /dev/null
+++ b/src/app/modules/dashboard/dashboard.component.html
@@ -0,0 +1,77 @@
+<!--
+ ~ Copyright (c) 2022. Deutsche Telekom AG
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ SPDX-License-Identifier: Apache-2.0
+ -->
+
+
+<app-breadcrumb>
+ <app-breadcrumb-item>
+ <span aria-current="page">{{ 'layout.menu.items.dashboard' | translate }}</span>
+ </app-breadcrumb-item>
+</app-breadcrumb>
+<ng-container *ngIf="tiles$ | async as apps">
+ <div class="w-100 d-flex justify-content-between">
+ <h2 class="qa_title">{{ 'layout.menu.items.dashboard' | translate }}</h2>
+ <ul>
+ <li
+ #settingsDrop="ngbDropdown"
+ [ngbTooltip]="'dashboard.tooltips.settings' | translate"
+ class="qa_alarm_auto_settings"
+ ngbDropdown
+ >
+ <button
+ [attr.aria-label]="'dashboard.showSettings' | translate"
+ class="btn btn-outline-secondary no-border qa_dashboard_show_and_hide_settings_btn"
+ id="dropdownColumnSettings"
+ ngbDropdownToggle
+ >
+ <i aria-hidden="true" class="bi bi-gear-fill text-muted"></i>
+ </button>
+ <div aria-labelledby="dropdownColumnSettings" ngbDropdownMenu style="min-width: 250px">
+ <p class="px-4 small text-muted mb-1">{{ 'dashboard.selectApplications' | translate }}</p>
+ <form class="px-4 py-3 d-flex flex-column align-items-start">
+ <div
+ [appHasPermissions]="'dashboard.tile.' + app.type"
+ *ngFor="let app of apps"
+ class="d-flex justify-content-center"
+ >
+ <ng-container *ngIf="'dashboard.tile.' + app.type | hasPermission | async">
+ <input
+ type="checkbox"
+ [(ngModel)]="app.displayed"
+ (ngModelChange)="updateAction.next(app)"
+ [ngModelOptions]="{ standalone: true }"
+ [ngClass]="'qa_dashboard_show_app_' + app.type"
+ />
+ <p class="ml-2">{{ 'dashboard.apps.' + app.type | translate }}</p>
+ </ng-container>
+ </div>
+ </form>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <hr />
+ <div class="row" cdkDropList (cdkDropListDropped)="dropAction.next($event)">
+ <ng-container *ngFor="let app of apps | map: filterDisplayedTiles">
+ <ng-container *ngIf="'dashboard.tile.' + app.type | hasPermission | async">
+ <ng-container *ngIf="app.type === DashboardApplications.USER_LAST_ACTION_TILE">
+ <app-user-last-action-tile></app-user-last-action-tile>
+ </ng-container>
+ </ng-container>
+ </ng-container>
+ </div>
+</ng-container>
diff --git a/src/app/modules/dashboard/dashboard.component.ts b/src/app/modules/dashboard/dashboard.component.ts
new file mode 100644
index 0000000..043ab6b
--- /dev/null
+++ b/src/app/modules/dashboard/dashboard.component.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { Component, OnInit } from '@angular/core';
+import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
+import { UserSettingsService } from '../../services/user-settings.service';
+import { DashboardApplications, DashboardTileSettings } from '../../model/dashboard.model';
+import { UnsubscribeService } from '../../services/unsubscribe/unsubscribe.service';
+import { map, shareReplay, switchMap, takeUntil } from 'rxjs/operators';
+import { merge, Observable, Subject } from 'rxjs';
+
+@Component({
+ selector: 'app-dashboard',
+ templateUrl: './dashboard.component.html',
+ styleUrls: ['./dashboard.component.css'],
+ providers: [UnsubscribeService],
+})
+export class DashboardComponent implements OnInit {
+ DashboardApplications = DashboardApplications;
+
+ public dropAction = new Subject<CdkDragDrop<string[]>>();
+ public updateAction = new Subject<DashboardTileSettings>();
+
+ constructor(private unsubscribeService: UnsubscribeService, private userSettingsService: UserSettingsService) {}
+
+ public tiles$: Observable<DashboardTileSettings[]> = this.userSettingsService
+ .selectDashboardAvailableTiles()
+ .pipe(shareReplay({ refCount: true, bufferSize: 1 }));
+
+ filterDisplayedTiles(tiles: DashboardTileSettings[]): DashboardTileSettings[] {
+ return tiles.filter(tile => tile.displayed);
+ }
+
+ public visibleTiles$: Observable<DashboardTileSettings[]> = this.tiles$.pipe(
+ switchMap(tiles =>
+ this.updateAction.pipe(
+ map(updatedTile => {
+ const index = tiles.findIndex(tile => tile.type === updatedTile.type);
+ tiles[index].displayed = updatedTile.displayed;
+ return [...tiles];
+ }),
+ ),
+ ),
+ );
+
+ public movedTiles$: Observable<DashboardTileSettings[]> = this.tiles$.pipe(
+ switchMap(tiles =>
+ this.dropAction.pipe(
+ map(event => {
+ moveItemInArray(tiles, event.previousIndex, event.currentIndex);
+ return tiles;
+ }),
+ ),
+ ),
+ );
+ ngOnInit() {
+ merge(this.visibleTiles$, this.movedTiles$)
+ .pipe(
+ takeUntil(this.unsubscribeService.unsubscribe$),
+ switchMap(availableTiles =>
+ this.userSettingsService.updatePreferences({
+ dashboard: {
+ apps: {
+ availableTiles,
+ },
+ },
+ }),
+ ),
+ )
+ .subscribe();
+ }
+}
diff --git a/src/app/modules/dashboard/dashboard.module.ts b/src/app/modules/dashboard/dashboard.module.ts
new file mode 100644
index 0000000..8d63307
--- /dev/null
+++ b/src/app/modules/dashboard/dashboard.module.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { NgModule } from '@angular/core';
+import { DashboardRoutingModule } from './dashboard-routing.module';
+import { SharedModule } from '../../shared.module';
+import {
+ EntityUserAdministrationRowComponent,
+} from './apps/user-last-action-tile/entity-user-administration-row/entity-user-administration-row.component';
+import { ActionButtonComponent } from './apps/user-last-action-tile/action-button/action-button.component';
+import { ActionRowComponent } from './apps/user-last-action-tile/action-row/action-row.component';
+import { UserLastActionTileComponent } from './apps/user-last-action-tile/user-last-action-tile.component';
+import { DashboardComponent } from './dashboard.component';
+import { DragDropModule } from '@angular/cdk/drag-drop';
+
+@NgModule({
+ declarations: [
+ DashboardComponent,
+ UserLastActionTileComponent,
+ ActionRowComponent,
+ ActionButtonComponent,
+ EntityUserAdministrationRowComponent,
+ ],
+ imports: [DashboardRoutingModule, SharedModule, DragDropModule],
+})
+export class DashboardModule {}