add description status model, listing, editor, rename enum descriptionStatus to descriptionStatusEnum, small changes to plan status
This commit is contained in:
parent
318e269b95
commit
0cd47ede1a
|
@ -406,7 +406,22 @@ const appRoutes: Routes = [
|
|||
breadcrumb: true,
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'GENERAL.TITLES.PLAN-STATUSES'
|
||||
})
|
||||
}),
|
||||
title: 'GENERAL.TITLES.PLAN-STATUSES'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'description-statuses',
|
||||
loadChildren: () => import('./ui/admin/description-status/description-status.module').then(m => m.DescriptionStatusModule),
|
||||
data: {
|
||||
authContext: {
|
||||
permissions: [AppPermission.ViewDescriptionStatusPage]
|
||||
},
|
||||
breadcrumb: true,
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-STATUSES'
|
||||
}),
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-STATUSES'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export enum DescriptionStatus {
|
||||
export enum DescriptionStatusEnum {
|
||||
Draft = 0,
|
||||
Finalized = 1,
|
||||
Canceled = 2
|
||||
|
|
|
@ -90,6 +90,10 @@ export enum AppPermission {
|
|||
EditPlanStatus = "EditPlanStatus",
|
||||
DeletePlanStatus = "DeletePlanStatus",
|
||||
|
||||
//DescriptionStatus
|
||||
EditDescriptionStatus = "EditDescriptionStatus",
|
||||
DeleteDescriptionStatus = "DeleteDescriptionStatus",
|
||||
|
||||
//PlanBlueprint
|
||||
BrowsePlanBlueprint = "BrowsePlanBlueprint",
|
||||
EditPlanBlueprint = "EditPlanBlueprint",
|
||||
|
@ -239,6 +243,7 @@ export enum AppPermission {
|
|||
ViewTenantConfigurationPage = "ViewTenantConfigurationPage",
|
||||
ViewStatusPage = "ViewStatusPage",
|
||||
ViewUsageLimitPage = "ViewUsageLimitPage",
|
||||
ViewPlanStatusPage = "ViewPlanStatusPage"
|
||||
ViewPlanStatusPage = "ViewPlanStatusPage",
|
||||
ViewDescriptionStatusPage = "ViewDescriptionStatusPage",
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ import { TenantHandlingService } from './services/tenant/tenant-handling.service
|
|||
import { RouterUtilsService } from './services/router/router-utils.service';
|
||||
import { UsageLimitService } from './services/usage-limit/usage.service';
|
||||
import { PlanStatusService } from './services/plan/plan-status.service';
|
||||
import { DescriptionStatusService } from './services/description-status/description-status.service';
|
||||
//
|
||||
//
|
||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||
|
@ -117,7 +118,8 @@ export class CoreServiceModule {
|
|||
TenantHandlingService,
|
||||
RouterUtilsService,
|
||||
UsageLimitService,
|
||||
PlanStatusService
|
||||
PlanStatusService,
|
||||
DescriptionStatusService
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { DescriptionStatusEnum } from "@app/core/common/enum/description-status";
|
||||
import { BaseEntityPersist } from "@common/base/base-entity.model";
|
||||
import { DescriptionStatusDefinition } from "./description-status";
|
||||
|
||||
export interface DescriptionStatusPersist extends BaseEntityPersist {
|
||||
name: string;
|
||||
description: string;
|
||||
internalStatus: DescriptionStatusEnum;
|
||||
definition: DescriptionStatusDefinition;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import { AppRole } from "@app/core/common/enum/app-role";
|
||||
import { DescriptionStatusEnum } from "@app/core/common/enum/description-status";
|
||||
import { PlanUserRole } from "@app/core/common/enum/plan-user-role";
|
||||
import { BaseEntity } from "@common/base/base-entity.model";
|
||||
|
||||
export interface DescriptionStatus extends BaseEntity{
|
||||
name: string;
|
||||
description: string;
|
||||
internalStatus: DescriptionStatusEnum;
|
||||
definition: DescriptionStatusDefinition;
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinition {
|
||||
authorization: DescriptionStatusDefinitionAuthorization
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinitionAuthorization {
|
||||
edit: DescriptionStatusDefinitionAuthorizationItem;
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinitionAuthorizationItem{
|
||||
roles: AppRole[],
|
||||
planRoles: PlanUserRole[],
|
||||
allowAuthenticated: boolean;
|
||||
allowAnonymous: boolean
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { DescriptionStatus } from "@app/core/common/enum/description-status";
|
||||
import { DescriptionStatusEnum } from "@app/core/common/enum/description-status";
|
||||
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { DescriptionTemplate } from "../description-template/description-template";
|
||||
|
@ -76,7 +76,7 @@ export interface DescriptionPersist extends BaseEntityPersist {
|
|||
planId: Guid;
|
||||
planDescriptionTemplateId: Guid;
|
||||
descriptionTemplateId: Guid;
|
||||
status: DescriptionStatus;
|
||||
status: DescriptionStatusEnum;
|
||||
description: string;
|
||||
properties: DescriptionPropertyDefinitionPersist;
|
||||
tags: string[];
|
||||
|
@ -120,7 +120,7 @@ export interface DescriptionReferencePersist {
|
|||
|
||||
export interface DescriptionStatusPersist {
|
||||
id: Guid;
|
||||
status: DescriptionStatus;
|
||||
status: DescriptionStatusEnum;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ export interface DescriptionStatusPersist {
|
|||
|
||||
export interface PublicDescription extends BaseDescription {
|
||||
label?: string;
|
||||
status?: DescriptionStatus;
|
||||
status?: DescriptionStatusEnum;
|
||||
description?: string;
|
||||
finalizedAt?: Date;
|
||||
descriptionTemplate?: PublicDescriptionTemplate;
|
||||
|
@ -161,5 +161,5 @@ export interface UpdateDescriptionTemplatePersist {
|
|||
|
||||
export interface BaseDescription extends BaseEntity {
|
||||
tenantId?: Guid;
|
||||
status?: DescriptionStatus;
|
||||
status?: DescriptionStatusEnum;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { Lookup } from "@common/model/lookup";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { IsActive } from "../common/enum/is-active.enum";
|
||||
|
||||
export class DescriptionStatusLookup extends Lookup implements DescriptionStatusFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface DescriptionStatusFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { Lookup } from '@common/model/lookup';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { IsActive } from '../common/enum/is-active.enum';
|
||||
import { DescriptionStatus } from '../common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '../common/enum/description-status';
|
||||
import { PlanLookup } from './plan.lookup';
|
||||
import { DescriptionReferenceLookup } from './reference.lookup';
|
||||
import { DescriptionTagLookup } from './tag.lookup';
|
||||
|
@ -17,7 +17,7 @@ export class DescriptionLookup extends Lookup implements DescriptionFilter {
|
|||
finalizedAfter: Date;
|
||||
finalizedBefore: Date;
|
||||
isActive: IsActive[];
|
||||
statuses: DescriptionStatus[];
|
||||
statuses: DescriptionStatusEnum[];
|
||||
|
||||
planSubQuery: PlanLookup;
|
||||
tenantSubQuery: TenantLookup;
|
||||
|
@ -39,7 +39,7 @@ export interface DescriptionFilter {
|
|||
finalizedAfter: Date;
|
||||
finalizedBefore: Date;
|
||||
isActive: IsActive[];
|
||||
statuses: DescriptionStatus[];
|
||||
statuses: DescriptionStatusEnum[];
|
||||
|
||||
planSubQuery: PlanLookup;
|
||||
descriptionTemplateSubQuery: DescriptionTemplateLookup;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { HttpHeaders } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { BaseHttpV2Service } from "../http/base-http-v2.service";
|
||||
import { ConfigurationService } from "../configuration/configuration.service";
|
||||
import { QueryResult } from "@common/model/query-result";
|
||||
import { catchError, Observable, throwError } from "rxjs";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { DescriptionStatusLookup } from "@app/core/query/description-status.lookup";
|
||||
import { DescriptionStatus } from "@app/core/model/description-status/description-status";
|
||||
import { DescriptionStatusPersist } from "@app/core/model/description/description";
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionStatusService {
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(
|
||||
private http: BaseHttpV2Service,
|
||||
private configurationService: ConfigurationService,
|
||||
) {
|
||||
}
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}description-status`; }
|
||||
|
||||
query(q: DescriptionStatusLookup): Observable<QueryResult<DescriptionStatus>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<DescriptionStatus>>(url, q).pipe(catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
|
||||
getSingle(id: Guid, reqFields: string[] = []): Observable<DescriptionStatus> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<DescriptionStatus>(url, options).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
|
||||
persist(item: DescriptionStatusPersist): Observable<DescriptionStatus> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http
|
||||
.post<DescriptionStatus>(url, item).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<DescriptionStatus> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<DescriptionStatus>(url).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
}
|
|
@ -47,6 +47,8 @@ export class AnalyticsService {
|
|||
public static NotificationTempplateEditor: string = 'Admin: Notification Tempplates';
|
||||
public static PlanStatusListing: string = 'Plan Status Listing';
|
||||
public static PlanStatusEditor: string = 'Plan Status Editor';
|
||||
public static DescriptionStatusListing: string = 'Description Status Listing';
|
||||
public static DescriptionStatusEditor: string = 'Description Status Editor';
|
||||
//#endregion
|
||||
|
||||
//#region trackDownload
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { AnnotationProtectionType } from '@app/core/common/enum/annotation-protection-type.enum';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionTemplateExternalSelectAuthType } from '@app/core/common/enum/description-template-external-select-auth-type';
|
||||
import { DescriptionTemplateExternalSelectHttpMethodType } from '@app/core/common/enum/description-template-external-select-http-method-type';
|
||||
import { DescriptionTemplateFieldDataExternalDatasetType } from '@app/core/common/enum/description-template-field-data-external-dataset-type';
|
||||
|
@ -210,11 +210,11 @@ export class EnumUtils {
|
|||
}
|
||||
}
|
||||
|
||||
toDescriptionStatusString(status: DescriptionStatus): string {
|
||||
toDescriptionStatusString(status: DescriptionStatusEnum): string {
|
||||
switch (status) {
|
||||
case DescriptionStatus.Draft: return this.language.instant('TYPES.DESCRIPTION-STATUS.DRAFT');
|
||||
case DescriptionStatus.Finalized: return this.language.instant('TYPES.DESCRIPTION-STATUS.FINALIZED');
|
||||
case DescriptionStatus.Canceled: return this.language.instant('TYPES.DESCRIPTION-STATUS.CANCELED');
|
||||
case DescriptionStatusEnum.Draft: return this.language.instant('TYPES.DESCRIPTION-STATUS.DRAFT');
|
||||
case DescriptionStatusEnum.Finalized: return this.language.instant('TYPES.DESCRIPTION-STATUS.FINALIZED');
|
||||
case DescriptionStatusEnum.Canceled: return this.language.instant('TYPES.DESCRIPTION-STATUS.CANCELED');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import { NgModule } from "@angular/core";
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { CommonFormattingModule } from "@common/formatting/common-formatting.module";
|
||||
import { ConfirmationDialogModule } from "@common/modules/confirmation-dialog/confirmation-dialog.module";
|
||||
import { HybridListingModule } from "@common/modules/hybrid-listing/hybrid-listing.module";
|
||||
import { UserSettingsModule } from "@common/modules/user-settings/user-settings.module";
|
||||
import { TextFilterModule } from "@common/modules/text-filter/text-filter.module";
|
||||
import { RichTextEditorModule } from "@app/library/rich-text-editor/rich-text-editor.module";
|
||||
import { DescriptionStatusRoutingModule } from "./description-status.routing";
|
||||
import { DescriptionStatusListingComponent } from "./listing/description-status-listing/description-status-listing.component";
|
||||
import { DescriptionStatusEditorComponent } from "./editor/description-status-editor/description-status-editor.component";
|
||||
import { DescriptionStatusListingFiltersComponent } from "./listing/description-status-listing-filters/description-status-listing-filters.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
DescriptionStatusRoutingModule,
|
||||
ConfirmationDialogModule,
|
||||
HybridListingModule,
|
||||
UserSettingsModule,
|
||||
CommonFormattingModule,
|
||||
TextFilterModule,
|
||||
RichTextEditorModule
|
||||
],
|
||||
declarations: [
|
||||
DescriptionStatusListingComponent,
|
||||
DescriptionStatusListingFiltersComponent,
|
||||
DescriptionStatusEditorComponent,
|
||||
]
|
||||
})
|
||||
export class DescriptionStatusModule { }
|
|
@ -0,0 +1,64 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
|
||||
import { DescriptionStatusEditorComponent } from './editor/description-status-editor/description-status-editor.component';
|
||||
import { DescriptionStatusListingComponent } from './listing/description-status-listing/description-status-listing.component';
|
||||
import { DescriptionStatusEditorResolver } from './editor/description-status-editor/description-status-editor.resolver';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DescriptionStatusListingComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
breadcrumb: true,
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
hideNavigationItem: true
|
||||
}),
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'new',
|
||||
canActivate: [AuthGuard],
|
||||
component: DescriptionStatusEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
data: {
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescriptionStatus]
|
||||
},
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.NEW-LANGUAGE'
|
||||
}),
|
||||
getFromTitleService: true,
|
||||
usePrefix: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
canActivate: [AuthGuard],
|
||||
component: DescriptionStatusEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionStatusEditorResolver
|
||||
},
|
||||
data: {
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescriptionStatus]
|
||||
},
|
||||
getFromTitleService: true,
|
||||
usePrefix: false
|
||||
}
|
||||
|
||||
},
|
||||
{ path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
providers: [DescriptionStatusEditorResolver]
|
||||
})
|
||||
export class DescriptionStatusRoutingModule { }
|
|
@ -0,0 +1,109 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-10 offset-md-1 colums-gapped">
|
||||
<div class="row align-items-center mt-4 mb-4" *ngIf="formGroup">
|
||||
<div class="col-md col-12">
|
||||
<app-navigation-breadcrumb />
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-button class="action-btn cancel-btn" (click)="cancel()" type="button">{{'PLAN-STATUS-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canDelete">
|
||||
<button mat-button class="action-btn delete-btn" type="button" (click)="delete()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canSave">
|
||||
<button mat-button class="action-btn save-btn" (click)="formSubmit()">
|
||||
<mat-icon>save</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()">
|
||||
<mat-card class="pt-3 pb-3" appearance="outlined">
|
||||
<mat-card-content>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-STATUS-EDITOR.FIELDS.NAME' | translate}}</mat-label>
|
||||
<input matInput type="text" name="name" [formControl]="formGroup.controls.name" required>
|
||||
<mat-error *ngIf="formGroup.controls.name.hasError('backendError')">{{formGroup.controls.name.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.controls.name.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-STATUS-EDITOR.FIELDS.INTERNAL-STATUS' | translate}}*</mat-label>
|
||||
<mat-select [formControl]="formGroup.controls.internalStatus">
|
||||
<mat-option *ngFor="let internalStatus of internalStatusEnum" [value]="internalStatus">{{enumUtils.toDescriptionStatusString(internalStatus)}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="formGroup.controls.internalStatus.hasError('backendError')">{{formGroup.controls.internalStatus.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.controls.internalStatus.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<h3>{{'PLAN-STATUS-EDITOR.FIELDS.DESCRIPTION' | translate}}</h3>
|
||||
<div class="col-12">
|
||||
<rich-text-editor-component
|
||||
[form]="formGroup.controls.description"
|
||||
[placeholder]="'PLAN-STATUS-EDITOR.FIELDS.DESCRIPTION'"
|
||||
[editable]="!formGroup.controls.description.disabled"
|
||||
[wrapperClasses]="(formGroup.controls.description.touched && formGroup.controls.description.hasError('backendError')) ? 'required' : ''"
|
||||
/>
|
||||
@if(formGroup.controls.description.hasError('backendError')){
|
||||
<div class="mat-form-field formGroup-field-subscript-wrapper">
|
||||
<mat-error>{{formGroup.controls.description.getError('backendError').message}}</mat-error>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<h3>
|
||||
{{'PLAN-STATUS-EDITOR.FIELDS.AUTHORIZATION' | translate}}
|
||||
</h3>
|
||||
<div id="Edit">
|
||||
<mat-card-title class="pb-2">{{'PLAN-STATUS-EDITOR.FIELDS.EDIT' | translate}}</mat-card-title>
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-STATUS-EDITOR.FIELDS.ROLES' | translate}}*</mat-label>
|
||||
<mat-select [formControl]="editAuthenticationForm.controls.roles" [multiple]="true">
|
||||
<mat-option *ngFor="let userRole of userRolesEnum" [value]="userRole">{{enumUtils.toAppRoleString(userRole)}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.roles.hasError('backendError')">{{"editAuthenticationForm.controls.roles.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.roles.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-STATUS-EDITOR.FIELDS.PLAN-ROLES' | translate}}*</mat-label>
|
||||
<mat-select [formControl]="editAuthenticationForm.controls.planRoles" [multiple]="true">
|
||||
<mat-option *ngFor="let planRole of planRolesEnum" [value]="planRole">{{enumUtils.toPlanUserRoleString(planRole)}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.planRoles.hasError('backendError')">{{"editAuthenticationForm.controls.planRoles.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.planRoles.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="d-flex" style="gap: 0.5rem">
|
||||
<div>
|
||||
<mat-checkbox [formControl]="editAuthenticationForm.controls.allowAuthenticated">{{'PLAN-STATUS-EDITOR.FIELDS.ALLOW-AUTHENTICATED' | translate}}</mat-checkbox>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.allowAuthenticated.hasError('backendError')">{{editAuthenticationForm.controls.allowAuthenticated.getError('backendError').message}}</mat-error>
|
||||
</div>
|
||||
<div>
|
||||
<mat-checkbox [formControl]="editAuthenticationForm.controls.allowAnonymous">{{'PLAN-STATUS-EDITOR.FIELDS.ALLOW-ANONYMOUS' | translate}}</mat-checkbox>
|
||||
<mat-error *ngIf="editAuthenticationForm.controls.allowAnonymous.hasError('backendError')">{{editAuthenticationForm.controls.allowAnonymous.getError('backendError').message}}</mat-error>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
::ng-deep label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
border-radius: 30px;
|
||||
background-color: var(--secondary-color);
|
||||
border: 1px solid transparent;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
box-shadow: 0px 3px 6px #1E202029;
|
||||
|
||||
transition-property: background-color, color;
|
||||
transition-duration: 200ms;
|
||||
transition-delay: 50ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
&:disabled{
|
||||
background-color: #CBCBCB;
|
||||
color: #FFF;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
border: 1px solid #b5b5b5;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background: #ffffff;
|
||||
color: #ba2c2c;
|
||||
border: 1px solid #ba2c2c;
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { AppRole } from '@app/core/common/enum/app-role';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionStatus } from '@app/core/model/description-status/description-status';
|
||||
import { DescriptionStatusPersist } from '@app/core/model/description/description';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { DescriptionStatusService } from '@app/core/services/description-status/description-status.service';
|
||||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
|
||||
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { IsActive } from '@notification-service/core/enum/is-active.enum';
|
||||
import { map, takeUntil } from 'rxjs';
|
||||
import { DescriptionStatusForm, DescriptionStatusDefinitionAuthorizationItemForm, DescriptionStatusEditorModel } from './description-status-editor.model';
|
||||
import { DescriptionStatusEditorResolver } from './description-status-editor.resolver';
|
||||
import { BaseEditor } from '@common/base/base-editor';
|
||||
import { PlanUserRole } from '@app/core/common/enum/plan-user-role';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-status-editor',
|
||||
templateUrl: './description-status-editor.component.html',
|
||||
styleUrl: './description-status-editor.component.scss'
|
||||
})
|
||||
export class DescriptionStatusEditorComponent extends BaseEditor<DescriptionStatusEditorModel, DescriptionStatus> implements OnInit{
|
||||
protected internalStatusEnum = this.enumUtils.getEnumValues<DescriptionStatusEnum>(DescriptionStatusEnum);
|
||||
protected userRolesEnum = this.enumUtils.getEnumValues<AppRole>(AppRole);
|
||||
protected planRolesEnum = this.enumUtils.getEnumValues<PlanUserRole>(PlanUserRole);
|
||||
protected belongsToCurrentTenant: boolean;
|
||||
|
||||
constructor(
|
||||
protected enumUtils: EnumUtils,
|
||||
protected dialog: MatDialog,
|
||||
protected language: TranslateService,
|
||||
protected formService: FormService,
|
||||
protected router: Router,
|
||||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected filterService: FilterService,
|
||||
protected route: ActivatedRoute,
|
||||
protected queryParamsService: QueryParamsService,
|
||||
protected lockService: LockService,
|
||||
protected authService: AuthService,
|
||||
protected configurationService: ConfigurationService,
|
||||
private analyticsService: AnalyticsService,
|
||||
private descriptionStatusService: DescriptionStatusService,
|
||||
private logger: LoggingService,
|
||||
private routerUtils: RouterUtilsService,
|
||||
){
|
||||
super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, route, queryParamsService, lockService, authService, configurationService);
|
||||
}
|
||||
|
||||
formGroup: FormGroup<DescriptionStatusForm>;
|
||||
|
||||
ngOnInit(){
|
||||
this.analyticsService.trackPageView(AnalyticsService.DescriptionStatusEditor);
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
get editAuthenticationForm(): FormGroup<DescriptionStatusDefinitionAuthorizationItemForm> {
|
||||
return this.formGroup?.controls?.definition?.controls?.authorization?.controls?.edit;
|
||||
}
|
||||
|
||||
getItem(itemId: Guid, successFunction: (item: DescriptionStatus) => void): void {
|
||||
this.descriptionStatusService.getSingle(itemId, DescriptionStatusEditorResolver.lookupFields())
|
||||
.pipe(map(data => data as DescriptionStatus), takeUntil(this._destroyed))
|
||||
.subscribe({
|
||||
next: (data) => successFunction(data),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
|
||||
prepareForm(data: DescriptionStatus): void {
|
||||
try {
|
||||
this.editorModel = data ? new DescriptionStatusEditorModel().fromModel(data) : new DescriptionStatusEditorModel();
|
||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||
this.belongsToCurrentTenant = data?.belongsToCurrentTenant;
|
||||
this.buildForm();
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse descriptionStatus item: ' + data + error);
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
buildForm(): void {
|
||||
this.formGroup = this.editorModel.buildForm({disabled: !this.belongsToCurrentTenant || this.isDeleted || !this.authService.hasPermission(AppPermission.EditDescriptionStatus)});
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.formService.removeAllBackEndErrors(this.formGroup);
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.isFormValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.persistEntity();
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
const value = this.formGroup.value;
|
||||
if (value.id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionStatusService.delete(value.id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe({
|
||||
complete: () => this.onCallbackDeleteSuccess(),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
refreshData(): void {
|
||||
this.getItem(this.editorModel.id, (data: DescriptionStatus) => this.prepareForm(data));
|
||||
}
|
||||
|
||||
refreshOnNavigateToData(id?: Guid): void {
|
||||
this.formGroup.markAsPristine();
|
||||
if (this.isNew) {
|
||||
let route = [];
|
||||
route.push(this.routerUtils.generateUrl('/description-statuses/' + id));
|
||||
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
||||
} else {
|
||||
this.refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
persistEntity(onSuccess?: (response) => void): void {
|
||||
const formData = this.formGroup.value as DescriptionStatusPersist;
|
||||
|
||||
this.descriptionStatusService.persist(formData)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe({
|
||||
next: (complete) => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
|
||||
protected get canSave(): boolean {
|
||||
const editDescriptionStatus = this.authService.permissionEnum.EditDescriptionStatus;
|
||||
return (this.isNew || (this.belongsToCurrentTenant && !this.isDeleted)) && this.authService.hasPermission(editDescriptionStatus);
|
||||
}
|
||||
|
||||
protected get canDelete(): boolean {
|
||||
const deletedDescriptionStatus = this.authService.permissionEnum.DeleteDescriptionStatus;
|
||||
return this.belongsToCurrentTenant && !this.isNew && !this.isDeleted && this.authService.hasPermission(deletedDescriptionStatus);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import { AppRole } from "@app/core/common/enum/app-role";
|
||||
import { DescriptionStatusEnum } from "@app/core/common/enum/description-status";
|
||||
import { PlanUserRole } from "@app/core/common/enum/plan-user-role";
|
||||
import { DescriptionStatus, DescriptionStatusDefinition, DescriptionStatusDefinitionAuthorizationItem } from "@app/core/model/description-status/description-status";
|
||||
import { DescriptionStatusPersist } from "@app/core/model/description-status/description-status-persist";
|
||||
import { BaseEditorModel } from "@common/base/base-form-editor-model";
|
||||
import { BackendErrorValidator } from "@common/forms/validation/custom-validator";
|
||||
import { Validation, ValidationContext } from "@common/forms/validation/validation-context";
|
||||
import { Guid } from "@common/types/guid";
|
||||
|
||||
export class DescriptionStatusEditorModel extends BaseEditorModel implements DescriptionStatusPersist {
|
||||
name: string;
|
||||
description: string;
|
||||
internalStatus: DescriptionStatusEnum;
|
||||
definition: DescriptionStatusDefinition;
|
||||
|
||||
public fromModel(item: DescriptionStatus): DescriptionStatusEditorModel {
|
||||
if (item) {
|
||||
super.fromModel(item);
|
||||
this.name = item?.name;
|
||||
this.description = item?.description;
|
||||
this.internalStatus = item?.internalStatus;
|
||||
this.definition = item?.definition;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(params: {context?: ValidationContext, disabled?: boolean}): FormGroup<DescriptionStatusForm> {
|
||||
const {context = this.createValidationContext(), disabled = false} = params;
|
||||
|
||||
return this.formBuilder.group({
|
||||
id: [{ value: this.id, disabled }, context.getValidation('id').validators],
|
||||
name: [{value: this.name, disabled}, context.getValidation('name').validators],
|
||||
description: [{value: this.description, disabled}, context.getValidation('description').validators],
|
||||
internalStatus: [{value: this.internalStatus, disabled}, context.getValidation('internalStatus').validators],
|
||||
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators],
|
||||
definition: this.buildDefinitionForm({context, disabled}),
|
||||
});
|
||||
}
|
||||
|
||||
buildDefinitionForm(params: {context: ValidationContext, disabled: boolean}): FormGroup<DescriptionStatusDefinitionForm> {
|
||||
const {context = this.createValidationContext(), disabled} = params;
|
||||
const definitionForm = new FormGroup<DescriptionStatusDefinitionForm>({
|
||||
authorization: new FormGroup<DescriptionStatusDefinitionAuthorizationForm>({
|
||||
edit: this.buildDefinitionAuthorizationItemForm({item: this.definition?.authorization?.edit, rootPath: 'edit', disabled})
|
||||
})
|
||||
});
|
||||
definitionForm.controls.authorization.addValidators(context.getValidation('authorization').validators);
|
||||
definitionForm.addValidators(context.getValidation('definition').validators);
|
||||
return definitionForm;
|
||||
}
|
||||
|
||||
buildDefinitionAuthorizationItemForm(params: {item: DescriptionStatusDefinitionAuthorizationItem, rootPath: string, disabled: boolean}): FormGroup<DescriptionStatusDefinitionAuthorizationItemForm>{
|
||||
const {item, rootPath, disabled} = params;
|
||||
const context = this.createAuthorizationItemContext(rootPath);
|
||||
return new FormGroup<DescriptionStatusDefinitionAuthorizationItemForm>({
|
||||
allowAnonymous: new FormControl({value: item?.allowAnonymous ?? false, disabled}, context.getValidation('allowAnonymous').validators),
|
||||
allowAuthenticated: new FormControl({value: item?.allowAuthenticated ?? false, disabled}, context.getValidation('allowAuthenticated').validators),
|
||||
roles: new FormControl({value: item?.roles ?? [], disabled}, context.getValidation('roles').validators),
|
||||
planRoles: new FormControl({value: item?.planRoles ?? [], disabled}, context.getValidation('planRoles').validators),
|
||||
})
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] });
|
||||
baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] });
|
||||
baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] });
|
||||
baseValidationArray.push({ key: 'internalStatus', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'internalStatus')] });
|
||||
baseValidationArray.push({ key: 'hash', validators: [] });
|
||||
baseValidationArray.push({ key: 'definition', validators: [BackendErrorValidator(this.validationErrorModel, 'definition')] });
|
||||
baseValidationArray.push({ key: 'authorization', validators: [BackendErrorValidator(this.validationErrorModel, 'definition.authorization')] });
|
||||
baseValidationArray.push({ key: 'edit', validators: [BackendErrorValidator(this.validationErrorModel, 'definition.authorization.edit')] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
}
|
||||
|
||||
createAuthorizationItemContext(rootPath?: string): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'allowAnonymous', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}allowAnonymous`)] });
|
||||
baseValidationArray.push({ key: 'allowAuthenticated', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}allowAuthenticated`)] });
|
||||
baseValidationArray.push({ key: 'planRoles', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}planRoles`)] });
|
||||
baseValidationArray.push({ key: 'roles', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}roles`)] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface DescriptionStatusForm {
|
||||
id: FormControl<Guid>;
|
||||
name: FormControl<string>;
|
||||
description: FormControl<string>;
|
||||
internalStatus: FormControl<DescriptionStatusEnum>;
|
||||
definition: FormGroup<DescriptionStatusDefinitionForm>;
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinitionForm {
|
||||
authorization: FormGroup<DescriptionStatusDefinitionAuthorizationForm>
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinitionAuthorizationForm {
|
||||
edit: FormGroup<DescriptionStatusDefinitionAuthorizationItemForm>;
|
||||
}
|
||||
|
||||
export interface DescriptionStatusDefinitionAuthorizationItemForm {
|
||||
roles: FormControl<AppRole[]>;
|
||||
planRoles: FormControl<PlanUserRole[]>;
|
||||
allowAuthenticated: FormControl<boolean>;
|
||||
allowAnonymous: FormControl<boolean>;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { Injectable } from "@angular/core";
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router";
|
||||
import { DescriptionStatus, DescriptionStatusDefinition, DescriptionStatusDefinitionAuthorization, DescriptionStatusDefinitionAuthorizationItem } from "@app/core/model/description-status/description-status";
|
||||
import { DescriptionStatusService } from "@app/core/services/description-status/description-status.service";
|
||||
import { BreadcrumbService } from "@app/ui/misc/breadcrumb/breadcrumb.service";
|
||||
import { BaseEditorResolver } from "@common/base/base-editor.resolver";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { takeUntil, tap } from "rxjs";
|
||||
import { nameof } from "ts-simple-nameof";
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionStatusEditorResolver extends BaseEditorResolver{
|
||||
|
||||
constructor(private descriptionStatusService: DescriptionStatusService, private breadcrumbService: BreadcrumbService) {
|
||||
super();
|
||||
}
|
||||
|
||||
public static lookupFields(): string[] {
|
||||
return [
|
||||
nameof<DescriptionStatus>(x => x.id),
|
||||
nameof<DescriptionStatus>(x => x.name),
|
||||
nameof<DescriptionStatus>(x => x.description),
|
||||
nameof<DescriptionStatus>(x => x.internalStatus),
|
||||
nameof<DescriptionStatus>(x => x.definition),
|
||||
[nameof<DescriptionStatus>(x => x.definition), nameof<DescriptionStatusDefinition>(x => x.authorization)].join('.'),
|
||||
[nameof<DescriptionStatus>(x => x.definition), nameof<DescriptionStatusDefinition>(x => x.authorization), nameof<DescriptionStatusDefinitionAuthorization>(x => x.edit), nameof<DescriptionStatusDefinitionAuthorizationItem>(x => x.roles)].join('.'),
|
||||
[nameof<DescriptionStatus>(x => x.definition), nameof<DescriptionStatusDefinition>(x => x.authorization), nameof<DescriptionStatusDefinitionAuthorization>(x => x.edit), nameof<DescriptionStatusDefinitionAuthorizationItem>(x => x.planRoles)].join('.'),
|
||||
[nameof<DescriptionStatus>(x => x.definition), nameof<DescriptionStatusDefinition>(x => x.authorization), nameof<DescriptionStatusDefinitionAuthorization>(x => x.edit), nameof<DescriptionStatusDefinitionAuthorizationItem>(x => x.allowAnonymous)].join('.'),
|
||||
[nameof<DescriptionStatus>(x => x.definition), nameof<DescriptionStatusDefinition>(x => x.authorization), nameof<DescriptionStatusDefinitionAuthorization>(x => x.edit), nameof<DescriptionStatusDefinitionAuthorizationItem>(x => x.allowAuthenticated)].join('.'),
|
||||
|
||||
nameof<DescriptionStatus>(x => x.updatedAt),
|
||||
nameof<DescriptionStatus>(x => x.createdAt),
|
||||
nameof<DescriptionStatus>(x => x.hash),
|
||||
nameof<DescriptionStatus>(x => x.isActive),
|
||||
nameof<DescriptionStatus>(x => x.belongsToCurrentTenant),
|
||||
]
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
const fields = [
|
||||
...DescriptionStatusEditorResolver.lookupFields()
|
||||
];
|
||||
const id = route.paramMap.get('id');
|
||||
if (id != null) {
|
||||
return this.descriptionStatusService.getSingle(Guid.parse(id), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.name)), takeUntil(this._destroyed));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<div class="d-flex align-items-center gap-1-rem">
|
||||
|
||||
<button mat-flat-button [matMenuTriggerFor]="filterMenu" #filterMenuTrigger="matMenuTrigger" (click)="updateFilters()" class="filter-button">
|
||||
<mat-icon aria-hidden="false" [matBadgeHidden]="!appliedFilterCount" [matBadge]="appliedFilterCount" matBadgeColor="warn" matBadgeSize="small">filter_alt</mat-icon>
|
||||
{{'COMMONS.LISTING-COMPONENT.SEARCH-FILTER-BTN' | translate}}
|
||||
</button>
|
||||
|
||||
|
||||
<mat-menu #filterMenu>
|
||||
<div class="container-fluid" (click)="$event?.stopPropagation?.()">
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-auto mt-2">
|
||||
<h4>{{'PLAN-BLUEPRINT-LISTING.FILTER.TITLE' | translate}}</h4>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button color="accent" mat-button (click)="clearFilters()">
|
||||
{{'COMMONS.LISTING-COMPONENT.CLEAR-ALL-FILTERS' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<section class="w-100">
|
||||
<mat-slide-toggle [(ngModel)]="internalFilters.isActive" labelPosition="before">
|
||||
{{'PLAN-BLUEPRINT-LISTING.FILTER.IS-ACTIVE' | translate}}</mat-slide-toggle>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row justify-content-end align-items-center mt-4 mb-1 gap-1-rem">
|
||||
<div class="col-auto">
|
||||
<button class="normal-btn-light-sm" (click)="filterMenuTrigger?.closeMenu()">
|
||||
{{'PLAN-BLUEPRINT-LISTING.FILTER.CANCEL' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button class="normal-btn-sm" (click)="filterMenuTrigger.closeMenu(); applyFilters();">
|
||||
{{'PLAN-BLUEPRINT-LISTING.FILTER.APPLY-FILTERS' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
||||
<app-expandable-search-field [(value)]=internalFilters.like (valueChange)="onSearchTermChange($event)" />
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
//Maybe move these to global listing filter styles?
|
||||
|
||||
::ng-deep.mat-mdc-menu-panel {
|
||||
max-width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:host::ng-deep.mat-mdc-menu-content:not(:empty) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
.filter-button{
|
||||
padding-top: .6rem;
|
||||
padding-bottom: .6rem;
|
||||
}
|
||||
|
||||
::ng-deep .mdc-form-field {
|
||||
label {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
import { Component, effect, EventEmitter, input, Output } from '@angular/core';
|
||||
import { DescriptionStatusFilter } from '@app/core/query/description-status.lookup';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { IsActive } from '@notification-service/core/enum/is-active.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-status-listing-filters',
|
||||
templateUrl: './description-status-listing-filters.component.html',
|
||||
styleUrl: './description-status-listing-filters.component.scss'
|
||||
})
|
||||
export class DescriptionStatusListingFiltersComponent extends BaseComponent{
|
||||
readonly filter = input<DescriptionStatusFilter>();
|
||||
@Output() filterChange = new EventEmitter<DescriptionStatusFilter>();
|
||||
|
||||
internalFilters: DescriptionStatusListingFilters = this._getEmptyFilters();
|
||||
appliedFilterCount: number = 0;
|
||||
|
||||
constructor(){
|
||||
super();
|
||||
effect(() => {
|
||||
const newFilters = this.filter();
|
||||
if(newFilters){
|
||||
this.updateFilters();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private _parseToInternalFilters(inputFilter: DescriptionStatusFilter): DescriptionStatusListingFilters {
|
||||
if (!inputFilter) {
|
||||
return this._getEmptyFilters();
|
||||
}
|
||||
|
||||
let { isActive, like } = inputFilter;
|
||||
|
||||
return {
|
||||
isActive: (isActive ?? [])?.includes(IsActive.Active) || !isActive?.length,
|
||||
like: like,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private _computeAppliedFilters(filters: DescriptionStatusListingFilters): number {
|
||||
let count = 0;
|
||||
if (!filters?.isActive) {
|
||||
count++
|
||||
}
|
||||
if(filters?.like){
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private _getEmptyFilters(): DescriptionStatusListingFilters {
|
||||
return {
|
||||
isActive: true,
|
||||
like: null,
|
||||
}
|
||||
}
|
||||
|
||||
protected updateFilters(): void {
|
||||
this.internalFilters = this._parseToInternalFilters(this.filter());
|
||||
this.appliedFilterCount = this._computeAppliedFilters(this.internalFilters);
|
||||
}
|
||||
|
||||
protected applyFilters(): void {
|
||||
const { isActive, like } = this.internalFilters ?? {}
|
||||
this.filterChange.emit({
|
||||
...this.filter(),
|
||||
like,
|
||||
isActive: isActive ? [IsActive.Active] : [IsActive.Inactive]
|
||||
})
|
||||
}
|
||||
|
||||
protected onSearchTermChange(searchTerm: string): void {
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
|
||||
protected clearFilters() {
|
||||
this.internalFilters = this._getEmptyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
interface DescriptionStatusListingFilters {
|
||||
isActive: boolean;
|
||||
like: string;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row description-status-listing">
|
||||
<div class="col-md-10 offset-md-1">
|
||||
<div class="row mb-4 mt-4">
|
||||
<div class="col">
|
||||
<app-navigation-breadcrumb />
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button class="create-btn" *ngIf="authService.hasPermission(authService.permissionEnum.EditDescriptionStatus)" [routerLink]="routerUtils.generateUrl(['/description-statuses/new'])">
|
||||
<mat-icon>add</mat-icon>
|
||||
{{'PLAN-STATUS-LISTING.ACTIONS.CREATE-PLAN-STATUS' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-hybrid-listing
|
||||
[rows]="gridRows"
|
||||
[columns]="gridColumns"
|
||||
[visibleColumns]="visibleColumns"
|
||||
[count]="totalElements"
|
||||
[offset]="currentPageNumber"
|
||||
[limit]="lookup.page.size"
|
||||
[defaultSort]="lookup.order?.items"
|
||||
[externalSorting]="true"
|
||||
(rowActivated)="onRowActivated($event, routerUtils.generateUrl('/description-statuses'))"
|
||||
(pageLoad)="alterPage($event)"
|
||||
(columnSort)="onColumnSort($event)"
|
||||
(columnsChanged)="onColumnsChanged($event)"
|
||||
>
|
||||
|
||||
<app-description-status-listing-filters hybrid-listing-filters [(filter)]="lookup" (filterChange)="filterChanged($event)" />
|
||||
|
||||
<app-user-settings-picker [key]="userSettingsKey" [userPreference]="lookup" (onSettingSelected)="changeSetting($event)" [autoSelectUserSettings]="autoSelectUserSettings" user-preference-settings />
|
||||
</app-hybrid-listing>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #status let-row="row" let-item>
|
||||
<div
|
||||
class="status-chip"
|
||||
[class.status-chip-finalized]="row.internalStatus === DescriptionStatusEnum.Finalized"
|
||||
[class.status-chip-draft]="row.internalStatus === DescriptionStatusEnum.Draft"
|
||||
[class.status-chip-cancelled]="row.internalStatus === DescriptionStatusEnum.Canceled"
|
||||
>
|
||||
{{enumUtils.toDescriptionStatusString(row.internalStatus)}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #actions let-row="row" let-item>
|
||||
<div class="row" (click)="$event.stopPropagation()">
|
||||
<div class="col-auto" *ngIf="row?.belongsToCurrentTenant && !isDeleted(row)">
|
||||
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button *ngIf="canEdit" mat-menu-item [routerLink]="routerUtils.generateUrl(['/description-statuses/', row.id])">
|
||||
<mat-icon>edit</mat-icon>{{'PLAN-STATUS-LISTING.ACTIONS.EDIT' | translate}}
|
||||
</button>
|
||||
<button *ngIf="canDelete" mat-menu-item (click)="delete(row.id)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'PLAN-STATUS-LISTING.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
|
@ -0,0 +1,34 @@
|
|||
.create-btn {
|
||||
border-radius: 30px;
|
||||
background-color: var(--secondary-color);
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
|
||||
.button-text {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.status-chip {
|
||||
width: fit-content;
|
||||
border-radius: 20px;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
padding-top: 0.2em;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.status-chip-finalized {
|
||||
color: #568b5a;
|
||||
background: #9dd1a1 0% 0% no-repeat padding-box;
|
||||
}
|
||||
|
||||
.status-chip-draft {
|
||||
color: #00c4ff;
|
||||
background: #d3f5ff 0% 0% no-repeat padding-box;
|
||||
}
|
||||
|
||||
.status-chip-cancelled {
|
||||
color: #cf1407;
|
||||
background: #ffc8c5 0% 0% no-repeat padding-box;
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatus } from '@app/core/model/description-status/description-status';
|
||||
import { UserSettingsKey } from '@app/core/model/user-settings/user-settings.model';
|
||||
import { DataTableDateTimeFormatPipe } from '@app/core/pipes/date-time-format.pipe';
|
||||
import { DescriptionStatusLookup } from '@app/core/query/description-status.lookup';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionStatusService } from '@app/core/services/description-status/description-status.service';
|
||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
|
||||
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
import { BaseListingComponent } from '@common/base/base-listing-component';
|
||||
import { PipeService } from '@common/formatting/pipe.service';
|
||||
import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe';
|
||||
import { QueryResult } from '@common/model/query-result';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { ColumnDefinition, HybridListingComponent, ColumnsChangedEvent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { IsActive } from '@notification-service/core/enum/is-active.enum';
|
||||
import { Observable, takeUntil } from 'rxjs';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { DescriptionStatusEditorResolver } from '../../editor/description-status-editor/description-status-editor.resolver';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-status-listing',
|
||||
templateUrl: './description-status-listing.component.html',
|
||||
styleUrl: './description-status-listing.component.scss'
|
||||
})
|
||||
export class DescriptionStatusListingComponent extends BaseListingComponent<DescriptionStatus, DescriptionStatusLookup> implements OnInit{
|
||||
userSettingsKey: UserSettingsKey = {key: 'DescriptionStatusListingUserSettings'};
|
||||
|
||||
publish = false;
|
||||
propertiesAvailableForOrder: ColumnDefinition[];
|
||||
|
||||
DescriptionStatusEnum = DescriptionStatusEnum;
|
||||
|
||||
@ViewChild('actions', { static: true }) actions: TemplateRef<any>;
|
||||
@ViewChild('status', { static: true }) status: TemplateRef<any>;
|
||||
@ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent;
|
||||
|
||||
constructor(
|
||||
public routerUtils: RouterUtilsService,
|
||||
public authService: AuthService,
|
||||
protected router: Router,
|
||||
protected route: ActivatedRoute,
|
||||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected queryParamsService: QueryParamsService,
|
||||
protected enumUtils: EnumUtils,
|
||||
private pipeService: PipeService,
|
||||
private descriptionStatusService: DescriptionStatusService,
|
||||
private analyticsService: AnalyticsService,
|
||||
private language: TranslateService,
|
||||
private dialog: MatDialog
|
||||
){
|
||||
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
|
||||
this.lookup = this.initializeLookup();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.analyticsService.trackPageView(AnalyticsService.DescriptionStatusListing);
|
||||
}
|
||||
|
||||
private readonly lookupFields = DescriptionStatusEditorResolver.lookupFields();
|
||||
|
||||
protected initializeLookup(): DescriptionStatusLookup {
|
||||
const lookup = new DescriptionStatusLookup();
|
||||
lookup.metadata = { countAll: true };
|
||||
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
|
||||
lookup.isActive = [IsActive.Active];
|
||||
lookup.order = { items: [this.toDescSortField(nameof<DescriptionStatus>(x => x.createdAt))] };
|
||||
this.updateOrderUiFields(lookup.order);
|
||||
|
||||
lookup.project = {
|
||||
fields: this.lookupFields
|
||||
};
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
onColumnsChanged(event: ColumnsChangedEvent) {
|
||||
super.onColumnsChanged(event);
|
||||
this.onColumnsChangedInternal(event.properties.map(x => x.toString()));
|
||||
}
|
||||
|
||||
private onColumnsChangedInternal(columns: string[]) {
|
||||
const fields = new Set(this.lookupFields);
|
||||
this.gridColumns.map(x => x.prop)
|
||||
.filter(x => !columns?.includes(x as string))
|
||||
.forEach(item => {
|
||||
fields.delete(item as string)
|
||||
});
|
||||
this.lookup.project = { fields: [...fields] };
|
||||
this.onPageLoad({ offset: 0 } as PageLoadEvent);
|
||||
}
|
||||
|
||||
protected loadListing(): Observable<QueryResult<DescriptionStatus>> {
|
||||
return this.descriptionStatusService.query(this.lookup);
|
||||
}
|
||||
|
||||
protected setupColumns() {
|
||||
this.gridColumns.push(...[
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.name),
|
||||
sortable: true,
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.NAME'
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.description),
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.DESCRIPTION'
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.internalStatus),
|
||||
sortable: true,
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.STATUS',
|
||||
cellTemplate: this.status
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.createdAt),
|
||||
sortable: true,
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.CREATED-AT',
|
||||
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.updatedAt),
|
||||
sortable: true,
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.UPDATED-AT',
|
||||
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionStatus>(x => x.isActive),
|
||||
sortable: true,
|
||||
languageName: 'PLAN-STATUS-LISTING.FIELDS.IS-ACTIVE',
|
||||
pipe: this.pipeService.getPipe<IsActiveTypePipe>(IsActiveTypePipe)
|
||||
},
|
||||
{
|
||||
alwaysShown: true,
|
||||
cellTemplate: this.actions,
|
||||
maxWidth: 120
|
||||
}
|
||||
]);
|
||||
this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable);
|
||||
}
|
||||
|
||||
delete(id){
|
||||
if (id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: {
|
||||
isDeleteConfirmation: true,
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionStatusService.delete(id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe({
|
||||
complete: () => this.onCallbackSuccess(),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
isDeleted(row: DescriptionStatus): boolean {
|
||||
return row?.isActive === IsActive.Inactive;
|
||||
}
|
||||
|
||||
get canEdit(): boolean {
|
||||
return this.authService.hasPermission(this.authService.permissionEnum.EditDescriptionStatus);
|
||||
}
|
||||
|
||||
get canDelete(): boolean {
|
||||
return this.authService.hasPermission(this.authService.permissionEnum.DeleteDescriptionStatus);
|
||||
}
|
||||
}
|
|
@ -8,18 +8,18 @@
|
|||
<div class="col-auto">
|
||||
<button mat-button class="action-btn cancel-btn" (click)="cancel()" type="button">{{'PLAN-STATUS-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="!isNew">
|
||||
<button mat-button class="action-btn delete-btn" type="button" (click)="delete()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canSave">
|
||||
<button mat-button class="action-btn save-btn" (click)="formSubmit()">
|
||||
<mat-icon>save</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canDelete">
|
||||
<button mat-button class="action-btn delete-btn" type="button" (click)="delete()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canSave">
|
||||
<button mat-button class="action-btn save-btn" (click)="formSubmit()">
|
||||
<mat-icon>save</mat-icon>
|
||||
{{'PLAN-STATUS-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()">
|
||||
|
|
|
@ -40,6 +40,7 @@ export class PlanStatusEditorComponent extends BaseEditor<PlanStatusEditorModel,
|
|||
protected internalStatusEnum = this.enumUtils.getEnumValues<PlanStatusEnum>(PlanStatusEnum);
|
||||
protected userRolesEnum = this.enumUtils.getEnumValues<AppRole>(AppRole);
|
||||
protected planRolesEnum = this.enumUtils.getEnumValues<PlanUserRole>(PlanUserRole);
|
||||
protected belongsToCurrentTenant: boolean;
|
||||
|
||||
constructor(
|
||||
protected enumUtils: EnumUtils,
|
||||
|
@ -87,6 +88,7 @@ export class PlanStatusEditorComponent extends BaseEditor<PlanStatusEditorModel,
|
|||
try {
|
||||
this.editorModel = data ? new PlanStatusEditorModel().fromModel(data) : new PlanStatusEditorModel();
|
||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||
this.belongsToCurrentTenant = data?.belongsToCurrentTenant;
|
||||
this.buildForm();
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse planStatus item: ' + data + error);
|
||||
|
@ -95,7 +97,7 @@ export class PlanStatusEditorComponent extends BaseEditor<PlanStatusEditorModel,
|
|||
}
|
||||
|
||||
buildForm(): void {
|
||||
this.formGroup = this.editorModel.buildForm({disabled: this.isDeleted || !this.authService.hasPermission(AppPermission.EditPlanStatus)});
|
||||
this.formGroup = this.editorModel.buildForm({disabled: !this.belongsToCurrentTenant || this.isDeleted || !this.authService.hasPermission(AppPermission.EditPlanStatus)});
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
|
@ -158,6 +160,11 @@ export class PlanStatusEditorComponent extends BaseEditor<PlanStatusEditorModel,
|
|||
|
||||
protected get canSave(): boolean {
|
||||
const editPlanStatus = this.authService.permissionEnum.EditPlanStatus;
|
||||
return !this.isDeleted && this.authService.hasPermission(editPlanStatus);
|
||||
return (this.isNew || (this.belongsToCurrentTenant && !this.isDeleted)) && this.authService.hasPermission(editPlanStatus);
|
||||
}
|
||||
|
||||
protected get canDelete(): boolean {
|
||||
const deletedPlanStatus = this.authService.permissionEnum.DeletePlanStatus;
|
||||
return this.belongsToCurrentTenant && !this.isNew && !this.isDeleted && this.authService.hasPermission(deletedPlanStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,21 +38,25 @@
|
|||
</div>
|
||||
|
||||
<ng-template #status let-row="row" let-item>
|
||||
<div class="status-chip" [ngClass]="{'status-chip-finalized': row.internalStatus === PlanStatusEnum.Finalized, 'status-chip-draft' : row.internalStatus === PlanStatusEnum.Draft}">
|
||||
<div
|
||||
class="status-chip"
|
||||
[class.status-chip-finalized]="row.internalStatus === PlanStatusEnum.Finalized"
|
||||
[class.status-chip-draft]="row.internalStatus === PlanStatusEnum.Draft"
|
||||
>
|
||||
{{enumUtils.toPlanStatusString(row.internalStatus)}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #actions let-row="row" let-item>
|
||||
<div class="row" (click)="$event.stopPropagation()">
|
||||
<div class="col-auto">
|
||||
<div class="col-auto" *ngIf="row?.belongsToCurrentTenant && !isDeleted(row)">
|
||||
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button *ngIf="authService.hasPermission(authService.permissionEnum.EditPlanStatus)" mat-menu-item [routerLink]="routerUtils.generateUrl(['/plan-statuses/', row.id])">
|
||||
<button *ngIf="canEdit" mat-menu-item [routerLink]="routerUtils.generateUrl(['/plan-statuses/', row.id])">
|
||||
<mat-icon>edit</mat-icon>{{'PLAN-STATUS-LISTING.ACTIONS.EDIT' | translate}}
|
||||
</button>
|
||||
<button *ngIf="row.belongsToCurrentTenant != false" mat-menu-item (click)="delete(row.id)">
|
||||
<button *ngIf="canDelete" mat-menu-item (click)="delete(row.id)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'PLAN-STATUS-LISTING.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
|
|
|
@ -175,4 +175,16 @@ export class PlanStatusListingComponent extends BaseListingComponent<PlanStatus,
|
|||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
isDeleted(row: PlanStatus): boolean {
|
||||
return row?.isActive === IsActive.Inactive;
|
||||
}
|
||||
|
||||
get canEdit(): boolean {
|
||||
return this.authService.hasPermission(this.authService.permissionEnum.EditPlanStatus);
|
||||
}
|
||||
|
||||
get canDelete(): boolean {
|
||||
return this.authService.hasPermission(this.authService.permissionEnum.DeletePlanStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Location } from '@angular/common';
|
|||
import { Component, Input, OnInit, Output } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { PlanStatusEnum } from '@app/core/common/enum/plan-status';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
|
@ -210,16 +210,16 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
|
|||
if (item.plan){
|
||||
if (item.plan.descriptions) {
|
||||
if (item.plan.status == PlanStatusEnum.Finalized) {
|
||||
item.plan.descriptions = item.plan.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||
item.plan.descriptions = item.plan.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatusEnum.Finalized);
|
||||
} else {
|
||||
item.plan.descriptions = item.plan.descriptions.filter(x => x.isActive === IsActive.Active && x.status != DescriptionStatus.Canceled);
|
||||
item.plan.descriptions = item.plan.descriptions.filter(x => x.isActive === IsActive.Active && x.status != DescriptionStatusEnum.Canceled);
|
||||
}
|
||||
}
|
||||
item.plan.planUsers = item.plan.planUsers.filter(x=> x.isActive === IsActive.Active);
|
||||
this.listingItems.push(item);
|
||||
}
|
||||
if (item.description){
|
||||
if (item.description.status != DescriptionStatus.Canceled) this.listingItems.push(item);
|
||||
if (item.description.status != DescriptionStatusEnum.Canceled) this.listingItems.push(item);
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||
|
@ -46,7 +46,7 @@ export class DescriptionBaseFieldsEditorComponent extends BaseComponent {
|
|||
if (this.description?.descriptionTemplate != null) {
|
||||
const isPreviousVersion: boolean = this.description.descriptionTemplate.versionStatus === DescriptionTemplateVersionStatus.Previous;
|
||||
if (isPreviousVersion === true) {
|
||||
if (this.description.status === DescriptionStatus.Draft) {
|
||||
if (this.description.status === DescriptionStatusEnum.Draft) {
|
||||
this.openDeprecatedDescriptionTemplateDialog();
|
||||
} else {
|
||||
this.availableDescriptionTemplates.push(this.description.descriptionTemplate);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { AbstractControl, UntypedFormArray, UntypedFormGroup } from '@angular/fo
|
|||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||
|
@ -245,9 +245,9 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
|
||||
// this.selectedSystemFields = this.selectedSystemFieldDisabled();
|
||||
this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted || !this.canEdit) {
|
||||
if (this.editorModel.status == DescriptionStatusEnum.Finalized || this.isDeleted || !this.canEdit) {
|
||||
this.viewOnly = true;
|
||||
this.isFinalized = this.editorModel.status == DescriptionStatus.Finalized;
|
||||
this.isFinalized = this.editorModel.status == DescriptionStatusEnum.Finalized;
|
||||
this.formGroup.disable();
|
||||
} else {
|
||||
this.viewOnly = false;
|
||||
|
@ -308,11 +308,11 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
complete => {
|
||||
onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete);
|
||||
this.descriptionIsOnceSaved = true;
|
||||
if (this.formGroup.get('status').value == DescriptionStatus.Finalized) this.isFinalized = true;
|
||||
if (this.formGroup.get('status').value == DescriptionStatusEnum.Finalized) this.isFinalized = true;
|
||||
},
|
||||
error => {
|
||||
if (this.formGroup.get('status').value == DescriptionStatus.Finalized) {
|
||||
this.formGroup.get('status').setValue(DescriptionStatus.Draft);
|
||||
if (this.formGroup.get('status').value == DescriptionStatusEnum.Finalized) {
|
||||
this.formGroup.get('status').setValue(DescriptionStatusEnum.Draft);
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-FINALIZE'), SnackBarNotificationLevel.Error);
|
||||
} else {
|
||||
this.onCallbackError(error);
|
||||
|
@ -727,7 +727,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.formGroup.get('status').setValue(DescriptionStatus.Finalized);
|
||||
this.formGroup.get('status').setValue(DescriptionStatusEnum.Finalized);
|
||||
this.persistEntity();
|
||||
}
|
||||
});
|
||||
|
@ -747,7 +747,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
if (result) {
|
||||
const planUserRemovePersist: DescriptionStatusPersist = {
|
||||
id: this.formGroup.get('id').value,
|
||||
status: DescriptionStatus.Draft,
|
||||
status: DescriptionStatusEnum.Draft,
|
||||
hash: this.formGroup.get('hash').value
|
||||
};
|
||||
this.descriptionService.persistStatus(planUserRemovePersist, DescriptionEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { DescriptionStatus } from "@app/core/common/enum/description-status";
|
||||
import { DescriptionStatusEnum } from "@app/core/common/enum/description-status";
|
||||
import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
|
||||
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
|
||||
import { IsActive } from "@app/core/common/enum/is-active.enum";
|
||||
|
@ -18,7 +18,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
|
|||
planId: Guid;
|
||||
planDescriptionTemplateId: Guid;
|
||||
descriptionTemplateId: Guid;
|
||||
status: DescriptionStatus;
|
||||
status: DescriptionStatusEnum;
|
||||
description: string;
|
||||
properties: DescriptionPropertyDefinitionEditorModel = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel);
|
||||
tags: string[] = [];
|
||||
|
@ -36,7 +36,7 @@ export class DescriptionEditorModel extends BaseEditorModel implements Descripti
|
|||
this.planId = item.plan?.id;
|
||||
this.planDescriptionTemplateId = item.planDescriptionTemplate?.id;
|
||||
this.descriptionTemplateId = item.descriptionTemplate?.id;
|
||||
this.status = item.status ?? DescriptionStatus.Draft;
|
||||
this.status = item.status ?? DescriptionStatusEnum.Draft;
|
||||
this.description = item.description;
|
||||
this.tags = item.descriptionTags?.filter(x => x.isActive === IsActive.Active).map(x => x.tag?.label);
|
||||
this.properties = new DescriptionPropertyDefinitionEditorModel(this.validationErrorModel).fromModel(item.properties, descriptionTemplate, item.descriptionReferences);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||
import { Description, DescriptionExternalIdentifier, DescriptionField, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionReference, DescriptionReferenceData, DescriptionTag } from '@app/core/model/description/description';
|
||||
|
@ -200,7 +200,7 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver {
|
|||
|
||||
description.id = null;
|
||||
description.hash = null;
|
||||
description.status = DescriptionStatus.Draft;
|
||||
description.status = DescriptionStatusEnum.Draft;
|
||||
description.plan = plan;
|
||||
description.planDescriptionTemplate = {
|
||||
id: plan.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { PlanUserRole } from '@app/core/common/enum/plan-user-role';
|
||||
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
||||
import { Reference } from '@app/core/model/reference/reference';
|
||||
|
@ -41,7 +41,7 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
|
|||
public criteria: any;
|
||||
public filteringTagsAsync = false;
|
||||
|
||||
statuses = DescriptionStatus;
|
||||
statuses = DescriptionStatusEnum;
|
||||
planRole = PlanUserRole;
|
||||
options: UntypedFormGroup;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog
|
|||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DescriptionStatus } from '../../../../core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '../../../../core/common/enum/description-status';
|
||||
import { DescriptionCopyDialogComponent } from '../../description-copy-dialog/description-copy-dialog.component';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
|
||||
|
@ -47,7 +47,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
|
|||
isDraft: boolean;
|
||||
isDeleted: boolean;
|
||||
isUserOwner: boolean;
|
||||
descriptionStatusEnum = DescriptionStatus;
|
||||
descriptionStatusEnum = DescriptionStatusEnum;
|
||||
fileTransformerEntityTypeEnum = FileTransformerEntityType;
|
||||
planAccessTypeEnum = PlanAccessType;
|
||||
canDelete: boolean = false;
|
||||
|
@ -82,7 +82,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
|
|||
this.analyticsService.trackPageView(AnalyticsService.DescriptionListingItem);
|
||||
if (this.description.isActive === IsActive.Inactive) {
|
||||
this.isDeleted = true;
|
||||
} else if (this.description.status === DescriptionStatus.Draft) {
|
||||
} else if (this.description.status === DescriptionStatusEnum.Draft) {
|
||||
this.isDraft = true;
|
||||
this.isDeleted = false;
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Component, OnInit } from '@angular/core';
|
|||
import { UntypedFormBuilder, Validators } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { PlanAccessType } from '@app/core/common/enum/plan-access-type';
|
||||
import { PlanStatusEnum } from '@app/core/common/enum/plan-status';
|
||||
import { PlanUserRole } from '@app/core/common/enum/plan-user-role';
|
||||
|
@ -61,7 +61,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
|||
hasPublishButton: boolean = true;
|
||||
expand = false;
|
||||
isLocked: Boolean;
|
||||
descriptionStatusEnum = DescriptionStatus;
|
||||
descriptionStatusEnum = DescriptionStatusEnum;
|
||||
planAccessTypeEnum = PlanAccessType;
|
||||
planStatusEnum = PlanStatusEnum;
|
||||
planUserRoleEnum = PlanUserRole;
|
||||
|
@ -286,7 +286,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
|||
}
|
||||
|
||||
isDraftDescription(description: Description) {
|
||||
return description.status == DescriptionStatus.Draft;
|
||||
return description.status == DescriptionStatusEnum.Draft;
|
||||
}
|
||||
|
||||
editClicked(description: Description) {
|
||||
|
@ -443,7 +443,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
|||
if (result) {
|
||||
const descriptionStatusPersist: DescriptionStatusPersist = {
|
||||
id: description.id,
|
||||
status: DescriptionStatus.Finalized,
|
||||
status: DescriptionStatusEnum.Finalized,
|
||||
hash: description.hash
|
||||
};
|
||||
this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed))
|
||||
|
@ -467,7 +467,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
|||
}
|
||||
|
||||
hasReversableStatus(description: Description): boolean {
|
||||
return description.plan.status == PlanStatusEnum.Draft && description.status == DescriptionStatus.Finalized && this.canFinalize
|
||||
return description.plan.status == PlanStatusEnum.Draft && description.status == DescriptionStatusEnum.Finalized && this.canFinalize
|
||||
}
|
||||
|
||||
reverseFinalization(description: Description) {
|
||||
|
@ -484,7 +484,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
|||
if (result) {
|
||||
const planUserRemovePersist: DescriptionStatusPersist = {
|
||||
id: description.id,
|
||||
status: DescriptionStatus.Draft,
|
||||
status: DescriptionStatusEnum.Draft,
|
||||
hash: description.hash
|
||||
};
|
||||
this.descriptionService.persistStatus(planUserRemovePersist).pipe(takeUntil(this._destroyed))
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Location } from '@angular/common';
|
|||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { PlanAccessType } from '@app/core/common/enum/plan-access-type';
|
||||
import { PlanStatusEnum } from '@app/core/common/enum/plan-status';
|
||||
import { PlanUserRole } from '@app/core/common/enum/plan-user-role';
|
||||
|
@ -75,7 +75,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
|
|||
|
||||
depositRepos: DepositConfiguration[] = [];
|
||||
|
||||
descriptionStatusEnum = DescriptionStatus;
|
||||
descriptionStatusEnum = DescriptionStatusEnum;
|
||||
planAccessTypeEnum = PlanAccessType;
|
||||
planStatusEnum = PlanStatusEnum;
|
||||
planUserRoleEnum = PlanUserRole;
|
||||
|
@ -133,9 +133,9 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
|
|||
this.plan.otherPlanVersions = data.otherPlanVersions?.filter(x => x.isActive === IsActive.Active) || null;
|
||||
if (this.plan.descriptions) {
|
||||
if (this.plan.status == PlanStatusEnum.Finalized) {
|
||||
this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||
this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatusEnum.Finalized);
|
||||
} else {
|
||||
this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
||||
this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatusEnum.Canceled);
|
||||
}
|
||||
}
|
||||
if (data.entityDois && data.entityDois.length > 0) this.plan.entityDois = data.entityDois.filter(x => x.isActive === IsActive.Active);
|
||||
|
|
|
@ -5,7 +5,7 @@ import { MatDialog } from '@angular/material/dialog';
|
|||
import { Title } from '@angular/platform-browser';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { AnnotationEntityType } from '@app/core/common/enum/annotation-entity-type';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||
|
@ -78,7 +78,7 @@ export class PlanEditorComponent extends BaseEditor<PlanEditorModel, Plan> imple
|
|||
annotationsPerAnchor: Map<string, number> = new Map<string, number>();
|
||||
|
||||
//Enums
|
||||
descriptionStatusEnum = DescriptionStatus;
|
||||
descriptionStatusEnum = DescriptionStatusEnum;
|
||||
planBlueprintSectionFieldCategoryEnum = PlanBlueprintFieldCategory;
|
||||
planBlueprintSystemFieldTypeEnum = PlanBlueprintSystemFieldType;
|
||||
planBlueprintExtraFieldDataTypeEnum = PlanBlueprintExtraFieldDataType;
|
||||
|
@ -262,9 +262,9 @@ export class PlanEditorComponent extends BaseEditor<PlanEditorModel, Plan> imple
|
|||
if (data) {
|
||||
if (data.descriptions) {
|
||||
if (data.status == PlanStatusEnum.Finalized) {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatusEnum.Finalized);
|
||||
} else {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatusEnum.Canceled);
|
||||
}
|
||||
}
|
||||
if (data.planDescriptionTemplates) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { DescriptionStatusEnum } from '@app/core/common/enum/description-status';
|
||||
import { PlanAccessType } from '@app/core/common/enum/plan-access-type';
|
||||
import { Plan } from '@app/core/model/plan/plan';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
|
@ -23,7 +23,7 @@ export class PlanFinalizeDialogComponent extends BaseComponent implements OnInit
|
|||
isPlanValid: boolean;
|
||||
planErrors: string[];
|
||||
planAccessTypeEnum = PlanAccessType;
|
||||
descriptionStatusEnum = DescriptionStatus;
|
||||
descriptionStatusEnum = DescriptionStatusEnum;
|
||||
descriptionValidationOutputEnum = DescriptionValidationOutput;
|
||||
validationResults: DescriptionValidationResult[] = [];
|
||||
descriptionsToBeFinalized: Guid[] = [];
|
||||
|
@ -74,7 +74,7 @@ export class PlanFinalizeDialogComponent extends BaseComponent implements OnInit
|
|||
|
||||
getFinalizedDescriptions() {
|
||||
if (!this.plan.descriptions) return [];
|
||||
const finalizedDescriptions = this.plan.descriptions.filter(x => x.status === DescriptionStatus.Finalized);
|
||||
const finalizedDescriptions = this.plan.descriptions.filter(x => x.status === DescriptionStatusEnum.Finalized);
|
||||
if (finalizedDescriptions?.length > 0){
|
||||
finalizedDescriptions.forEach(finalize => {
|
||||
this.descriptionValidationOutputMap.set(finalize.id, DescriptionValidationOutput.Valid);
|
||||
|
@ -88,16 +88,16 @@ export class PlanFinalizeDialogComponent extends BaseComponent implements OnInit
|
|||
}
|
||||
|
||||
validateDescriptions(plan: Plan) {
|
||||
if (!plan.descriptions?.some(x => x.status == DescriptionStatus.Draft)) return;
|
||||
if (!plan.descriptions?.some(x => x.status == DescriptionStatusEnum.Draft)) return;
|
||||
|
||||
const draftDescriptions = this.plan.descriptions.filter(x => x.status == DescriptionStatus.Draft) || [];
|
||||
const draftDescriptions = this.plan.descriptions.filter(x => x.status == DescriptionStatusEnum.Draft) || [];
|
||||
if ( draftDescriptions.length > 0){
|
||||
draftDescriptions.forEach(draft => {
|
||||
this.descriptionValidationOutputMap.set(draft.id, DescriptionValidationOutput.Pending);
|
||||
});
|
||||
}
|
||||
|
||||
this.descriptionService.validate(plan.descriptions.filter(x => x.status == DescriptionStatus.Draft).map(x => x.id)).pipe(takeUntil(this._destroyed),)
|
||||
this.descriptionService.validate(plan.descriptions.filter(x => x.status == DescriptionStatusEnum.Draft).map(x => x.id)).pipe(takeUntil(this._destroyed),)
|
||||
.subscribe(result => {
|
||||
this.validationResults = result;
|
||||
},
|
||||
|
|
|
@ -114,8 +114,10 @@ export class SidebarComponent implements OnInit {
|
|||
routes: [],
|
||||
}
|
||||
if (this.authentication.hasPermission(AppPermission.ViewPlanBlueprintPage)) this.adminItems.routes.push({ path: '/plan-blueprints', title: 'SIDE-BAR.PLAN-BLUEPRINTS', icon: 'library_books', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewPlanStatusPage)) this.adminItems.routes.push({ path: '/plan-statuses', title: 'SIDE-BAR.PLAN-STATUSES', icon: 'library_books', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplatePage)) this.adminItems.routes.push({ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'description', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplateTypePage)) this.adminItems.routes.push({ path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'stack', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewDescriptionStatusPage)) this.adminItems.routes.push({ path: '/description-statuses', title: 'SIDE-BAR.DESCRIPTION-STATUSES', icon: 'description', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewEntityLockPage)) this.adminItems.routes.push({ path: '/entity-locks', title: 'SIDE-BAR.ENTITY-LOCKS', icon: 'lock_person', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewReferencePage)) this.adminItems.routes.push({ path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'dataset_linked', routeType: RouteType.System });
|
||||
if (this.authentication.hasPermission(AppPermission.ViewReferenceTypePage)) this.adminItems.routes.push({ path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'add_link', routeType: RouteType.System });
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES":"Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL":"Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -315,7 +316,9 @@
|
|||
"ADMIN": "ADMIN",
|
||||
"DESCRIPTION-TEMPLATES": "Description Templates",
|
||||
"DESCRIPTION-TEMPLATE-TYPES": "Description Types",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-BLUEPRINTS": "Plan Blueprints",
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"USERS": "Users",
|
||||
"TENANT-USERS": "Tenant Users",
|
||||
"CO-BRANDING": "Co-Branding",
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
|
@ -180,7 +180,8 @@
|
|||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"SUPPORTIVE-MATERIAL": "Supportive Material",
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
"PLAN-STATUSES": "Plan Statuses",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses"
|
||||
},
|
||||
"FILE-TRANSFORMER": {
|
||||
"PDF": "PDF",
|
||||
|
@ -333,7 +334,9 @@
|
|||
"TENANT-CONFIGURATION": "Tenant Configuration",
|
||||
"ENTITY-LOCKS": "Entity Locks",
|
||||
"ANNOTATION-STATUSES": "Annotation Statuses",
|
||||
"USAGE-LIMITS": "Usage Limits"
|
||||
"USAGE-LIMITS": "Usage Limits",
|
||||
"DESCRIPTION-STATUSES": "Description Statuses",
|
||||
"PLAN-STATUSES": "Plan Statuses"
|
||||
},
|
||||
"DESCRIPTION-TEMPLATE-PREVIEW": {
|
||||
"TEMPLATE": "Template"
|
||||
|
|
Loading…
Reference in New Issue