diff options
author | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-04-14 11:59:32 +0000 |
---|---|---|
committer | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-04-14 11:59:32 +0000 |
commit | d68841d9f75636575cd778838a8ceea5fd5aada3 (patch) | |
tree | 778c84203ed9bfa4dc1c8234e4e2cf60da6ebd8c /src/app/modules/dashboard | |
parent | 42af09588f1f839b9ab36356f02f34c89559bcfa (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')
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 {} |