ui fix on plan view versions listing

This commit is contained in:
CITE\spapacharalampous 2024-09-05 16:04:32 +03:00
parent e7ce517c3d
commit f68a657b82
4 changed files with 82 additions and 79 deletions

View File

@ -20,10 +20,10 @@
<span class="col-auto" *ngIf="plan.status === planStatusEnum.Finalized && isPublic"><span class="material-icons icon-align">public</span>{{'TYPES.PLAN-VISIBILITY.PUBLIC' | translate}}</span> <span class="col-auto" *ngIf="plan.status === planStatusEnum.Finalized && isPublic"><span class="material-icons icon-align">public</span>{{'TYPES.PLAN-VISIBILITY.PUBLIC' | translate}}</span>
<span *ngIf="plan.status === planStatusEnum.Finalized && !isPublic; else draft" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span> <span *ngIf="plan.status === planStatusEnum.Finalized && !isPublic; else draft" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span>
<ng-template #draft> <ng-template #draft>
<span *ngIf="plan.status === planStatusEnum.Draft && canEditPlan(); else preview" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span> <span *ngIf="plan.status === planStatusEnum.Draft && canEditPlan; else preview" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span>
</ng-template> </ng-template>
<ng-template #preview> <ng-template #preview>
<span *ngIf="plan.status === planStatusEnum.Draft && !canEditPlan()" class=" col-auto draft"><span class="material-icons-outlined mr-1 icon-align">visibility</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span> <span *ngIf="plan.status === planStatusEnum.Draft && !canEditPlan" class=" col-auto draft"><span class="material-icons-outlined mr-1 icon-align">visibility</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span>
</ng-template> </ng-template>
<span>.</span> <span>.</span>
<span class="col-auto">{{'PLAN-LISTING.VERSION' | translate}} {{plan.version}}</span> <span class="col-auto">{{'PLAN-LISTING.VERSION' | translate}} {{plan.version}}</span>
@ -41,14 +41,14 @@
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="plan.descriptions?.length > 3" [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', plan.id]) : this.routerUtils.generateUrl(['/plans/overview/', plan.id])"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a> <a class="d-flex justify-content-center pb-3 show-more" *ngIf="plan.descriptions?.length > 3" [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', plan.id]) : this.routerUtils.generateUrl(['/plans/overview/', plan.id])"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
</a> </a>
<div class="plan-card-actions"> <div class="plan-card-actions">
<a class="col-auto border-right pointer" *ngIf="canExportPlan() && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'PLAN-LISTING.ACTIONS.EXPORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canExportPlan && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'PLAN-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftPlan(plan) && canEditPlan()" [routerLink]="this.routerUtils.generateUrl(['/plans/edit/', plan.id])" target="_blank"><span class="material-icons icon-align">add</span>{{'PLAN-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canEditPlan" [routerLink]="this.routerUtils.generateUrl(['/plans/edit/', plan.id])" target="_blank"><span class="material-icons icon-align">add</span>{{'PLAN-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers()" (click)="inviteToPlan()"><span class="material-icons icon-align pr-2">group_add</span>{{'PLAN-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers" (click)="inviteToPlan()"><span class="material-icons icon-align pr-2">group_add</span>{{'PLAN-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canClonePlan()" (click)="cloneClicked()"><span class="material-icons icon-align pr-2">filter_none</span>{{'PLAN-LISTING.ACTIONS.CLONE' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canClonePlan" (click)="cloneClicked()"><span class="material-icons icon-align pr-2">filter_none</span>{{'PLAN-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(plan)"><span class="material-icons icon-align pr-2">library_books</span>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="!isAuthenticated() && showAllVersionsAction" (click)="viewVersions(plan)"><span class="material-icons icon-align pr-2">library_books</span>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftPlan(plan) && canDeletePlan()" (click)="deleteClicked(plan.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}</a> <a class="col-auto border-right pointer" *ngIf="canDeletePlan" (click)="deleteClicked(plan.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}</a>
<a class="col-auto pointer" *ngIf="isAuthenticated()" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a> <a class="col-auto pointer" *ngIf="showActionsMenu" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div> </div>
<mat-menu #exportMenu="matMenu" xPosition="before"> <mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan)' (click)="fileTransformerService.exportPlan(plan.id, fileTransformer.repositoryId, fileTransformer.format, isPublic)"> <button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan)' (click)="fileTransformerService.exportPlan(plan.id, fileTransformer.repositoryId, fileTransformer.format, isPublic)">
@ -57,13 +57,13 @@
</button> </button>
</mat-menu> </mat-menu>
<mat-menu #actionsMenu="matMenu" xPosition="before"> <mat-menu #actionsMenu="matMenu" xPosition="before">
<button *ngIf="canCreateNewVersion()" mat-menu-item (click)="newVersionClicked()"> <button *ngIf="canCreateNewVersion" mat-menu-item (click)="newVersionClicked()">
<mat-icon>queue</mat-icon>{{'PLAN-LISTING.ACTIONS.NEW-VERSION' | translate}} <mat-icon>queue</mat-icon>{{'PLAN-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button> </button>
<a mat-menu-item [routerLink]="viewVersionsUrl(plan)" target="_blank"> <a *ngIf="showAllVersionsAction" mat-menu-item [routerLink]="viewVersionsUrl(plan)" target="_blank">
<mat-icon>library_books</mat-icon>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}} <mat-icon>library_books</mat-icon>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</a> </a>
<button mat-menu-item *ngIf="isDraftPlan(plan) && canDeletePlan()" (click)="deleteClicked(plan.id)" class="menu-item"> <button mat-menu-item *ngIf="canDeletePlan" (click)="deleteClicked(plan.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }} <mat-icon>delete</mat-icon>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,11 +1,9 @@
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { PlanAccessType } from '@app/core/common/enum/plan-access-type'; import { PlanAccessType } from '@app/core/common/enum/plan-access-type';
import { Plan } from '@app/core/model/plan/plan'; import { Plan } from '@app/core/model/plan/plan';
import { PlanBlueprintService } from '@app/core/services/plan/plan-blueprint.service';
import { PlanService } from '@app/core/services/plan/plan.service'; import { PlanService } from '@app/core/services/plan/plan.service';
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service'; import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
import { LockService } from '@app/core/services/lock/lock.service'; import { LockService } from '@app/core/services/lock/lock.service';
@ -13,7 +11,6 @@ import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/serv
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service'; import { ReferenceService } from '@app/core/services/reference/reference.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
@ -42,6 +39,7 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
@Input() plan: Plan; @Input() plan: Plan;
@Input() showDivider: boolean = true; @Input() showDivider: boolean = true;
@Input() showAllVersionsAction: boolean = true;
@Input() isPublic: boolean; @Input() isPublic: boolean;
@Input() tenants: Tenant[] = []; @Input() tenants: Tenant[] = [];
@Output() onClick: EventEmitter<Plan> = new EventEmitter(); @Output() onClick: EventEmitter<Plan> = new EventEmitter();
@ -52,6 +50,46 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
planStatusEnum = PlanStatusEnum; planStatusEnum = PlanStatusEnum;
fileTransformerEntityTypeEnum = FileTransformerEntityType; fileTransformerEntityTypeEnum = FileTransformerEntityType;
get canEditPlan(): boolean {
return (this.isDraft) && (this.plan.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
get canCreateNewVersion(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.plan.versionStatus === PlanVersionStatus.Current && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
get canDeletePlan(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false && this.isDraftPlan;
}
get canClonePlan(): boolean {
return this.plan.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan) || (this.authentication.hasPermission(AppPermission.PublicClonePlan) && this.isPublic);
}
get canFinalizePlan(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
get canExportPlan(): boolean {
return this.plan.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan);
}
get canInvitePlanUsers(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
get canAssignPlanUsers(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
get showActionsMenu(): boolean {
return this.isAuthenticated() && (this.canCreateNewVersion || this.showAllVersionsAction || this.canDeletePlan)
}
get isDraftPlan(): boolean {
return this.plan.status == PlanStatusEnum.Draft;
}
constructor( constructor(
public routerUtils: RouterUtilsService, public routerUtils: RouterUtilsService,
private router: Router, private router: Router,
@ -59,16 +97,13 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
private authentication: AuthService, private authentication: AuthService,
public enumUtils: EnumUtils, public enumUtils: EnumUtils,
private planService: PlanService, private planService: PlanService,
private planBlueprintService: PlanBlueprintService,
private language: TranslateService, private language: TranslateService,
private uiNotificationService: UiNotificationService, private uiNotificationService: UiNotificationService,
private lockService: LockService, private lockService: LockService,
private location: Location, private location: Location,
private httpClient: HttpClient,
public referenceService: ReferenceService, public referenceService: ReferenceService,
public referenceTypeService: ReferenceTypeService, public referenceTypeService: ReferenceTypeService,
public fileTransformerService: FileTransformerService, public fileTransformerService: FileTransformerService,
private fileUtils: FileUtils,
private analyticsService: AnalyticsService, private analyticsService: AnalyticsService,
private httpErrorHandlingService: HttpErrorHandlingService, private httpErrorHandlingService: HttpErrorHandlingService,
) { ) {
@ -226,10 +261,6 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
}); });
} }
isDraftPlan(activity: Plan) {
return activity.status == PlanStatusEnum.Draft;
}
reloadPage(): void { reloadPage(): void {
const path = this.location.path(); const path = this.location.path();
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => {
@ -245,36 +276,4 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
onDeleteCallbackError(error) { onDeleteCallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
} }
canEditPlan(): boolean {
return (this.isDraft) && (this.plan.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
canCreateNewVersion(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.plan.versionStatus === PlanVersionStatus.Current && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
canDeletePlan(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
canClonePlan(): boolean {
return this.plan.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan) || (this.authentication.hasPermission(AppPermission.PublicClonePlan) && this.isPublic);
}
canFinalizePlan(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
canExportPlan(): boolean {
return this.plan.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan);
}
canInvitePlanUsers(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
canAssignPlanUsers(): boolean {
return (this.plan.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && !this.isPublic && this.plan.belongsToCurrentTenant != false;
}
} }

View File

@ -50,35 +50,36 @@
<span *ngIf="!isPublic" class="center-content" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</span> <span *ngIf="!isPublic" class="center-content" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</span>
</div> </div>
<div class="col-12 col-xl-auto"> <div class="col-12 col-xl-auto">
<app-text-filter suffixIcon="search" floatLabel="never" placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" [(value)]=lookup.like (valueChange)="controlModified()" /> <app-text-filter suffixIcon="search" floatLabel="never" placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" [(value)]=lookup.like (valueChange)="controlModified()" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@if(!isLoading){ @if(!isLoading) {
<div class="col-md-12 col-sm-12 col-md-9"> <div class="col-md-12 col-sm-12 col-md-9">
<div *ngFor="let item of listingItems; let i = index"> <div *ngFor="let item of listingItems; let i = index">
<app-plan-listing-item-component <app-plan-listing-item-component
[showDivider]="i != (listingItems.length - 1)" [showAllVersionsAction]="!isVersionsListing"
[plan]="item" [showDivider]="i != (listingItems.length - 1)"
[isPublic]="isPublic" [plan]="item"
[tenants]="tenants" [isPublic]="isPublic"
></app-plan-listing-item-component> [tenants]="tenants"
</div> ></app-plan-listing-item-component>
<div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center"> </div>
<button type="button" mat-button class="rounded-btn load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button> <div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
</div> <button type="button" mat-button class="rounded-btn load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div> </div>
<div *ngIf="!hasListingItems && !hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4"> </div>
<span class="empty-list">{{'PLAN-LISTING.EMPTY-LIST' | translate}}</span> <div *ngIf="!hasListingItems && !hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4">
</div> <span class="empty-list">{{'PLAN-LISTING.EMPTY-LIST' | translate}}</span>
<div *ngIf="!hasListingItems && hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4"> </div>
<span class="empty-list">{{'PLAN-LISTING.FILTERS.NO-ITEMS-FOUND' | translate}}</span> <div *ngIf="!hasListingItems && hasFilters" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4">
</div> <span class="empty-list">{{'PLAN-LISTING.FILTERS.NO-ITEMS-FOUND' | translate}}</span>
} </div>
</div> }
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -69,6 +69,9 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
groupId: Guid | null = null; groupId: Guid | null = null;
mode; mode;
get isVersionsListing(): boolean {
return this.mode == 'versions-listing';
}
scrollbar: boolean; scrollbar: boolean;
@ -229,7 +232,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
let recentActivityOrder = this.isPublic ? this.toDescSortField(nameof<Description>(x => x.finalizedAt)) : this.toDescSortField(nameof<Description>(x => x.updatedAt)); let recentActivityOrder = this.isPublic ? this.toDescSortField(nameof<Description>(x => x.finalizedAt)) : this.toDescSortField(nameof<Description>(x => x.updatedAt));
lookup.order = { items: [recentActivityOrder] }; lookup.order = { items: [recentActivityOrder] };
if (this.mode && this.mode == 'versions-listing') { if (this.mode && this.isVersionsListing) {
this.groupId = Guid.parse(this.route.snapshot.paramMap.get('groupId')); this.groupId = Guid.parse(this.route.snapshot.paramMap.get('groupId'));
lookup.groupIds = [this.groupId]; lookup.groupIds = [this.groupId];