add description workflow editor to tenant configuration, move plan workflow files
This commit is contained in:
parent
0a0bc0ee1b
commit
34490e268a
|
@ -221,6 +221,9 @@ export enum AppPermission {
|
|||
EditPlanWorkflow = "EditPlanWorkflow",
|
||||
DeletePlanWorkflow = "DeletePlanWorkflow",
|
||||
|
||||
//DescriptionWorkflow
|
||||
EditDescriptionWorkflow = "EditDescriptionWorkflow",
|
||||
DeleteDescriptionWorkflow = "DeleteDescriptionWorkflow",
|
||||
|
||||
// UI Pages
|
||||
ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage",
|
||||
|
@ -249,6 +252,7 @@ export enum AppPermission {
|
|||
ViewUsageLimitPage = "ViewUsageLimitPage",
|
||||
ViewPlanStatusPage = "ViewPlanStatusPage",
|
||||
ViewDescriptionStatusPage = "ViewDescriptionStatusPage",
|
||||
ViewPlanWorkflowPage = "ViewPlanWorkflowPage"
|
||||
ViewPlanWorkflowPage = "ViewPlanWorkflowPage",//TODO remove if workflows remain in tenant config view
|
||||
ViewDescriptionWorkflowPage = "ViewDescriptionWorkflowPage"//TODO remove if workflows remain in tenant config view
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ 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';
|
||||
import { PlanWorkflowService } from './services/plan/plan-workflow.service';
|
||||
import { DescriptionWorkflowService } from './services/description-workflow/description-workflow.service';
|
||||
//
|
||||
//
|
||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||
|
@ -121,7 +122,8 @@ export class CoreServiceModule {
|
|||
UsageLimitService,
|
||||
PlanStatusService,
|
||||
DescriptionStatusService,
|
||||
PlanWorkflowService
|
||||
PlanWorkflowService,
|
||||
DescriptionWorkflowService
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { BaseEntityPersist } from "@common/base/base-entity.model";
|
||||
import { Guid } from "@common/types/guid";
|
||||
|
||||
export interface DescriptionWorkflowPersist extends BaseEntityPersist {
|
||||
name: string;
|
||||
description: string;
|
||||
definition: DescriptionWorkflowDefinitionPersist;
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinitionPersist {
|
||||
startingStatusId: Guid;
|
||||
statusTransitions: DescriptionWorkflowDefinitionTransitionPersist[];
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinitionTransitionPersist {
|
||||
fromStatusId: Guid;
|
||||
toStatusId: Guid;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { BaseEntity } from "@common/base/base-entity.model";
|
||||
import { DescriptionStatus } from "../description-status/description-status";
|
||||
|
||||
export interface DescriptionWorkflow extends BaseEntity {
|
||||
name: string;
|
||||
description: string;
|
||||
definition: DescriptionWorkflowDefinition;
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinition {
|
||||
startingStatus: DescriptionStatus;
|
||||
statusTransitions: DescriptionWorkflowDefinitionTransition[];
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinitionTransition {
|
||||
fromStatus: DescriptionStatus;
|
||||
toStatus: DescriptionStatus;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { Lookup } from "@common/model/lookup";
|
||||
|
||||
export class DescriptionWorkflowLookup extends Lookup{
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -1,14 +1,7 @@
|
|||
import { Lookup } from "@common/model/lookup";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { IsActive } from "../common/enum/is-active.enum";
|
||||
|
||||
export class PlanWorkflowLookup extends Lookup implements PlanWorkflowFilter{
|
||||
tenantId: Guid;
|
||||
export class PlanWorkflowLookup extends Lookup{
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface PlanWorkflowFilter {
|
||||
tenantId: Guid;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { HttpHeaders } from "@angular/common/http";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { DescriptionWorkflow } from "@app/core/model/workflow/description-workflow";
|
||||
import { DescriptionWorkflowPersist } from "@app/core/model/workflow/description-workflow-persist";
|
||||
import { QueryResult } from "@common/model/query-result";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { Observable, catchError, throwError } from "rxjs";
|
||||
import { ConfigurationService } from "../configuration/configuration.service";
|
||||
import { BaseHttpV2Service } from "../http/base-http-v2.service";
|
||||
import { DescriptionWorkflowLookup } from "@app/core/query/description-workflow.lookup";
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionWorkflowService {
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(
|
||||
private http: BaseHttpV2Service,
|
||||
private configurationService: ConfigurationService,
|
||||
) {
|
||||
}
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}description-workflow`; }
|
||||
|
||||
getCurrent(reqFields: string[] = []): Observable<DescriptionWorkflow> {
|
||||
const url = `${this.apiBase}/current-tenant`;
|
||||
const options = { params: { f: reqFields } };
|
||||
return this.http
|
||||
.get<DescriptionWorkflow>(url, options).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
|
||||
query(q: DescriptionWorkflowLookup): Observable<QueryResult<DescriptionWorkflow>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<DescriptionWorkflow>>(url, q).pipe(
|
||||
catchError((error: any) => throwError(() => error))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
persist(item: DescriptionWorkflowPersist): Observable<DescriptionWorkflow> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http
|
||||
.post<DescriptionWorkflow>(url, item).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<void> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<void>(url).pipe(
|
||||
catchError((error: any) => throwError(() => error)));
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ export class AnalyticsService {
|
|||
public static FileTransformerEditor: string = 'Admin: TenantConfigurations';
|
||||
public static LogoEditor: string = 'Admin: TenantConfigurations';
|
||||
public static PlanWorkflowEditor: string = 'Admin: TenantConfigurations';
|
||||
public static DescriptionWorkflowEditor: string = 'Admin: TenantConfigurations';
|
||||
public static ContactContent: string = 'Contact Content';
|
||||
public static RecentEditedActivity: string = 'Recent DMP Activity';
|
||||
public static DescriptionEditor: string = 'Description Editor';
|
||||
|
|
|
@ -2,8 +2,8 @@ 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 { PlanWorkflowPersist } from "@app/core/model/plan-workflow/plan-workflow-persist";
|
||||
import { PlanWorkflow } from "@app/core/model/plan-workflow/plan-workflow";
|
||||
import { PlanWorkflowPersist } from "@app/core/model/workflow/plan-workflow-persist";
|
||||
import { PlanWorkflow } from "@app/core/model/workflow/plan-workflow";
|
||||
import { catchError, map, Observable, of, throwError } from "rxjs";
|
||||
import { PlanWorkflowLookup } from "@app/core/query/plan-workflow.lookup";
|
||||
import { QueryResult } from "@common/model/query-result";
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from "@angular/forms";
|
||||
import { DescriptionWorkflow } from "@app/core/model/workflow/description-workflow";
|
||||
import { DescriptionWorkflowDefinitionPersist, DescriptionWorkflowPersist } from "@app/core/model/workflow/description-workflow-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 DescriptionWorkflowEditorModel extends BaseEditorModel implements DescriptionWorkflowPersist {
|
||||
name: string = 'default';
|
||||
description: string;
|
||||
definition: DescriptionWorkflowDefinitionPersist;
|
||||
|
||||
public fromModel(item: DescriptionWorkflow): DescriptionWorkflowEditorModel {
|
||||
if(item){
|
||||
super.fromModel(item);
|
||||
this.description = item.description;
|
||||
this.definition = {
|
||||
startingStatusId: item.definition?.startingStatus?.id ?? null,
|
||||
statusTransitions: []
|
||||
};
|
||||
item.definition?.statusTransitions?.forEach((st) =>
|
||||
this.definition.statusTransitions.push({
|
||||
fromStatusId: st.fromStatus?.id,
|
||||
toStatusId: st.toStatus?.id
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(params: {context?: ValidationContext, disabled?: boolean}): FormGroup<DescriptionWorkflowForm> {
|
||||
const {context, disabled = false} = params;
|
||||
const mainContext = context ?? this.createValidationContext();
|
||||
const formGroup = new FormGroup<DescriptionWorkflowForm>({
|
||||
id: new FormControl({value: this.id, disabled }, mainContext.getValidation('id').validators),
|
||||
hash: new FormControl({value: this.hash, disabled }, mainContext.getValidation('hash').validators),
|
||||
name: new FormControl({value: this.name, disabled}, mainContext.getValidation('name').validators),
|
||||
description: new FormControl({value: this.description, disabled}, mainContext.getValidation('description').validators),
|
||||
definition: new FormGroup<DescriptionWorkflowDefinitionForm>({
|
||||
startingStatusId: new FormControl({value: this.definition?.startingStatusId, disabled}, mainContext.getValidation('startingStatusId').validators),
|
||||
statusTransitions: new FormArray<FormGroup<DescriptionWorkflowDefinitionTransitionForm>>([], mainContext.getValidation('statusTransitions').validators)
|
||||
}, mainContext.getValidation('definition').validators)
|
||||
})
|
||||
|
||||
this.definition?.statusTransitions?.forEach((st, index) => {
|
||||
const itemContext = context ?? this.createValidationContext(`StatusTransition[${index}]`)
|
||||
formGroup.controls.definition.controls.statusTransitions.push(new FormGroup({
|
||||
fromStatusId: new FormControl({value: st.fromStatusId,disabled}, itemContext.getValidation('fromStatusId').validators),
|
||||
toStatusId: new FormControl({value: st.toStatusId,disabled}, itemContext.getValidation('fromStatusId').validators)
|
||||
}, this.differentStatusId()))
|
||||
})
|
||||
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
buildStatusTransitionForm(index: number): FormGroup<DescriptionWorkflowDefinitionTransitionForm> {
|
||||
const itemContext = this.createValidationContext(`StatusTransition[${index}]`)
|
||||
return new FormGroup({
|
||||
fromStatusId: new FormControl(null, itemContext.getValidation('fromStatusId').validators),
|
||||
toStatusId: new FormControl(null, itemContext.getValidation('toStatusId').validators)
|
||||
}, this.differentStatusId())
|
||||
}
|
||||
|
||||
reApplyDefinitionValidators(formGroup: FormGroup<DescriptionWorkflowDefinitionForm>) {
|
||||
if(!formGroup?.controls?.statusTransitions?.length) { return; }
|
||||
formGroup.controls.statusTransitions.controls.forEach((st, index) => {
|
||||
const context = this.createValidationContext(`StatusTransition[${index}]`);
|
||||
st.clearValidators();
|
||||
st.addValidators(this.differentStatusId());
|
||||
st.controls.fromStatusId.clearValidators();
|
||||
st.controls.fromStatusId.addValidators(context.getValidation('fromStatusId').validators);
|
||||
st.controls.toStatusId.clearValidators();
|
||||
st.controls.toStatusId.addValidators(context.getValidation('toStatusId').validators);
|
||||
})
|
||||
}
|
||||
|
||||
createValidationContext(rootPath?: string): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, `${rootPath}id`)] });
|
||||
baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}name`)] });
|
||||
baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, `${rootPath}description`)] });
|
||||
baseValidationArray.push({ key: 'hash', validators: [] });
|
||||
baseValidationArray.push({ key: 'definition', validators: [BackendErrorValidator(this.validationErrorModel, `${rootPath}definition`)] });
|
||||
baseValidationArray.push({ key: 'statusTransitions', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}statusTransitions`)] });
|
||||
baseValidationArray.push({ key: 'startingStatusId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}startingStatusId`)] });
|
||||
baseValidationArray.push({ key: 'fromStatusId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}fromStatusId`)] });
|
||||
baseValidationArray.push({ key: 'toStatusId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, `${rootPath}toStatusId`)] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
}
|
||||
|
||||
differentStatusId(): ValidatorFn {
|
||||
return (formGroup: FormGroup<DescriptionWorkflowDefinitionTransitionForm>): { [key: string]: any } => {
|
||||
const fromStatusId = formGroup?.controls?.fromStatusId?.value;
|
||||
const toStatusId = formGroup?.controls?.toStatusId?.value;
|
||||
if(!fromStatusId || !toStatusId){
|
||||
return null;
|
||||
}
|
||||
return fromStatusId?.toString().toLowerCase() == toStatusId?.toString()?.toLowerCase() ?
|
||||
{'differentStatusId': true} : null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowForm {
|
||||
id: FormControl<Guid>;
|
||||
hash: FormControl<string>;
|
||||
name: FormControl<string>;
|
||||
description: FormControl<string>;
|
||||
definition: FormGroup<DescriptionWorkflowDefinitionForm>;
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinitionForm {
|
||||
startingStatusId: FormControl<Guid>;
|
||||
statusTransitions: FormArray<FormGroup<DescriptionWorkflowDefinitionTransitionForm>>
|
||||
}
|
||||
|
||||
export interface DescriptionWorkflowDefinitionTransitionForm {
|
||||
fromStatusId: FormControl<Guid>;
|
||||
toStatusId: FormControl<Guid>;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import { Injectable } from "@angular/core";
|
||||
import { DescriptionWorkflow, DescriptionWorkflowDefinition, DescriptionWorkflowDefinitionTransition } from "@app/core/model/workflow/description-workflow";
|
||||
import { DescriptionWorkflowService } from "@app/core/services/description-workflow/description-workflow.service";
|
||||
import { BaseEditorResolver } from "@common/base/base-editor.resolver";
|
||||
import { takeUntil } from "rxjs";
|
||||
import { nameof } from "ts-simple-nameof";
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionWorkflowEditorResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(private descriptionWorkflowService: DescriptionWorkflowService) {
|
||||
super();
|
||||
}
|
||||
|
||||
public static lookupFields(): string[] {
|
||||
return [
|
||||
...BaseEditorResolver.lookupFields(),
|
||||
nameof<DescriptionWorkflow>(x => x.name),
|
||||
nameof<DescriptionWorkflow>(x => x.description),
|
||||
nameof<DescriptionWorkflow>(x => x.definition),
|
||||
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.startingStatus.id)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.startingStatus.name)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.statusTransitions)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.statusTransitions), nameof<DescriptionWorkflowDefinitionTransition>(x => x.fromStatus.id)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.statusTransitions), nameof<DescriptionWorkflowDefinitionTransition>(x => x.fromStatus.name)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.statusTransitions), nameof<DescriptionWorkflowDefinitionTransition>(x => x.toStatus.id)].join('.'),
|
||||
[nameof<DescriptionWorkflow>(x => x.definition), nameof<DescriptionWorkflowDefinition>(x => x.statusTransitions), nameof<DescriptionWorkflowDefinitionTransition>(x => x.toStatus.name)].join('.'),
|
||||
]
|
||||
}
|
||||
|
||||
resolve() {
|
||||
|
||||
const fields = [
|
||||
...DescriptionWorkflowEditorResolver.lookupFields()
|
||||
];
|
||||
|
||||
return this.descriptionWorkflowService.getCurrent(fields).pipe(takeUntil(this._destroyed));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<div *ngIf="formGroup" class="container-fluid description-workflow">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.STARTING-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="definitionForm?.controls?.startingStatusId"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-DESCRIPTION-STATUS' | translate}}"
|
||||
[configuration]="descriptionStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="definitionForm?.controls?.startingStatusId.hasError('backendError')">{{definitionForm?.controls?.startingStatusId.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="definitionForm?.controls.startingStatusId.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button mat-button class="action-btn row" type="button" (click)="addStatusTransition()" [disabled]="formGroup.disabled">{{'WORKFLOW-EDITOR.ACTIONS.ADD-STATUS-TRANSITION' | translate}}</button>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<mat-error class="pl-3 pt-2" *ngIf="definitionForm?.touched && definitionForm?.controls?.statusTransitions?.hasError('required')">
|
||||
{{'WORKFLOW-EDITOR.ERRORS.STATUS-TRANSITION-REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
@for(transitionForm of definitionForm?.controls?.statusTransitions?.controls; track transitionForm; let index = $index){
|
||||
<div class="col-12">
|
||||
<div class="row mb-3 d-flex align-items-center">
|
||||
<div class="col-auto d-flex">
|
||||
<mat-card-title>{{'WORKFLOW-EDITOR.FIELDS.STATUS-TRANSITION' | translate}} {{index + 1}}</mat-card-title>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'WORKFLOW-EDITOR.ACTIONS.REMOVE-STATUS-TRANSITION' | translate}}" (click)="removeStatusTransition(index)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.FROM-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="transitionForm?.controls?.fromStatusId"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-DESCRIPTION-STATUS' | translate}}"
|
||||
[configuration]="descriptionStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="transitionForm?.controls?.fromStatusId.hasError('backendError')">{{transitionForm?.controls?.fromStatusId.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="transitionForm?.controls.fromStatusId.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.TO-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="transitionForm?.controls?.toStatusId"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-DESCRIPTION-STATUS' | translate}}"
|
||||
[configuration]="descriptionStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="transitionForm?.controls?.toStatusId.hasError('backendError')">{{transitionForm?.controls?.toStatusId.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="transitionForm?.controls.toStatusId.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-error class="pl-3" *ngIf="transitionForm.hasError('differentStatusId')">{{'WORKFLOW-EDITOR.ERRORS.DIFFERENT-STATUS' | translate}}</mat-error>
|
||||
}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="row actions-row">
|
||||
<div class="col"></div>
|
||||
@if(canDelete){
|
||||
<div class="col-auto">
|
||||
<button class="normal-btn-sm" (click)="delete()">
|
||||
{{'TENANT-CONFIGURATION-EDITOR.ACTIONS.RESET-TO-DEFAULT' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@if(canSave){
|
||||
<div class="col-auto">
|
||||
<button class="normal-btn-sm" (click)="formSubmit()">
|
||||
{{'TENANT-CONFIGURATION-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,24 @@
|
|||
.description-workflow {
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep label {
|
||||
margin: 0;
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionStatus } from '@app/core/model/description-status/description-status';
|
||||
import { DescriptionWorkflow } from '@app/core/model/workflow/description-workflow';
|
||||
import { DescriptionWorkflowPersist } from '@app/core/model/workflow/description-workflow-persist';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionStatusService } from '@app/core/services/description-status/description-status.service';
|
||||
import { DescriptionWorkflowService } from '@app/core/services/description-workflow/description-workflow.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 { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { HttpErrorHandlingService, HttpError } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { takeUntil, Observable, map } from 'rxjs';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { DescriptionWorkflowForm, DescriptionWorkflowEditorModel, DescriptionWorkflowDefinitionForm } from '../description-workflow-editor.model';
|
||||
import { DescriptionWorkflowEditorResolver } from '../description-workflow-editor.resolver';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-workflow-editor',
|
||||
templateUrl: './description-workflow-editor.component.html',
|
||||
styleUrl: './description-workflow-editor.component.scss'
|
||||
})
|
||||
export class DescriptionWorkflowEditorComponent extends BasePendingChangesComponent implements OnInit{
|
||||
formGroup: FormGroup<DescriptionWorkflowForm>;
|
||||
editorModel: DescriptionWorkflowEditorModel;
|
||||
|
||||
constructor(
|
||||
protected dialog: MatDialog,
|
||||
protected language: TranslateService,
|
||||
protected formService: FormService,
|
||||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected authService: AuthService,
|
||||
protected enumUtils: EnumUtils,
|
||||
private logger: LoggingService,
|
||||
private descriptionWorkflowService: DescriptionWorkflowService,
|
||||
private analyticsService: AnalyticsService,
|
||||
private descriptionStatusService: DescriptionStatusService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.analyticsService.trackPageView(AnalyticsService.DescriptionWorkflowEditor);
|
||||
this.getItem((entity) => {
|
||||
this.prepareForm(entity);
|
||||
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
|
||||
this.formGroup.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected getItem(successFunction: (item: DescriptionWorkflow) => void) {
|
||||
this.descriptionWorkflowService.getCurrent(DescriptionWorkflowEditorResolver.lookupFields())
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe({
|
||||
next: (data) => successFunction(data),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
|
||||
protected prepareForm(data: DescriptionWorkflow) {
|
||||
try {
|
||||
this.editorModel = data ? new DescriptionWorkflowEditorModel().fromModel(data) : new DescriptionWorkflowEditorModel();
|
||||
this.formGroup = this.editorModel.buildForm({disabled: !this.authService.hasPermission(AppPermission.EditDescriptionWorkflow)});
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse DescriptionWorkflow item: ' + data + error);
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
protected refreshData(): void {
|
||||
this.getItem((entity) => {
|
||||
this.prepareForm(entity);
|
||||
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
|
||||
this.formGroup.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected get canDelete(): boolean {
|
||||
return this.editorModel?.id && this.authService.hasPermission(this.authService.permissionEnum.DeleteDescriptionWorkflow);
|
||||
}
|
||||
|
||||
protected get canSave(): boolean {
|
||||
return this.formGroup.touched && this.authService.hasPermission(this.authService.permissionEnum.EditDescriptionWorkflow);
|
||||
}
|
||||
|
||||
protected get definitionForm(): FormGroup<DescriptionWorkflowDefinitionForm> {
|
||||
return this.formGroup?.controls?.definition;
|
||||
}
|
||||
|
||||
protected onCallbackError(errorResponse: HttpErrorResponse) {
|
||||
this.httpErrorHandlingService.handleBackedRequestError(errorResponse)
|
||||
|
||||
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
||||
if (error.statusCode === 400) {
|
||||
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
||||
this.formService.validateAllFormFields(this.formGroup);
|
||||
}
|
||||
}
|
||||
|
||||
protected onCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.editorModel.validationErrorModel.clear();
|
||||
this.formService.removeAllBackEndErrors(this.formGroup);
|
||||
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
this.formService.validateAllFormFields(this.formGroup);
|
||||
|
||||
if (!this.formGroup?.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.persistEntity();
|
||||
}
|
||||
|
||||
persistEntity(): void {
|
||||
const formData = JSON.parse(JSON.stringify(this.formGroup.value)) as DescriptionWorkflowPersist;
|
||||
|
||||
|
||||
|
||||
this.descriptionWorkflowService.persist(formData)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe({
|
||||
complete: () => this.onCallbackSuccess(),
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
|
||||
delete() {
|
||||
const value = this.formGroup.value;
|
||||
if (value.id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
data: {
|
||||
message: this.language.instant('TENANT-CONFIGURATION-EDITOR.RESET-TO-DEFAULT-DIALOG.RESET-TO-DEFAULT'),
|
||||
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.descriptionWorkflowService.delete(value.id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe({
|
||||
complete: () => {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-RESET'), SnackBarNotificationLevel.Success);
|
||||
this.prepareForm(null);
|
||||
},
|
||||
error: (error) => this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addStatusTransition(){
|
||||
const index = this.formGroup.controls.definition.controls.statusTransitions.length;
|
||||
this.formGroup.controls.definition.controls.statusTransitions.push(this.editorModel.buildStatusTransitionForm(index));
|
||||
this.formGroup.markAsTouched();
|
||||
}
|
||||
|
||||
removeStatusTransition(index: number){
|
||||
this.formGroup.controls.definition.controls.statusTransitions.removeAt(index);
|
||||
this.editorModel.reApplyDefinitionValidators(this.formGroup.controls.definition);
|
||||
this.formGroup.markAsTouched();
|
||||
}
|
||||
|
||||
canDeactivate(): boolean | Observable<boolean> {
|
||||
return this.formGroup ? !this.formGroup.dirty : true;
|
||||
}
|
||||
|
||||
private descriptionStatusLookupFields = [
|
||||
nameof<DescriptionStatus>(x => x.id),
|
||||
nameof<DescriptionStatus>(x => x.name),
|
||||
]
|
||||
|
||||
descriptionStatusAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
initialItems: (excludedItems: any[], data?: any) => this.descriptionStatusService.query(
|
||||
this.descriptionStatusService.buildLookup({
|
||||
size: 20,
|
||||
lookupFields: this.descriptionStatusLookupFields,
|
||||
excludedIds: excludedItems
|
||||
})).pipe(map(x => x.items)),
|
||||
filterFn: (searchQuery: string, data?: any) => this.descriptionStatusService.query(
|
||||
this.descriptionStatusService.buildLookup({
|
||||
size: 20,
|
||||
like: searchQuery,
|
||||
lookupFields: this.descriptionStatusLookupFields
|
||||
})
|
||||
).pipe(map(x => x.items)),
|
||||
getSelectedItem: (id: Guid) => this.descriptionStatusService.getSingle(id, this.descriptionStatusLookupFields),
|
||||
displayFn: (item: DescriptionStatus) => item.name,
|
||||
titleFn: (item: DescriptionStatus) => item.name,
|
||||
valueAssign: (item: DescriptionStatus) => {this.formGroup.markAsTouched(); return item.id},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from "@angular/forms";
|
||||
import { PlanWorkflow } from "@app/core/model/plan-workflow/plan-workflow";
|
||||
import { PlanWorkflowDefinitionPersist, PlanWorkflowPersist } from "@app/core/model/plan-workflow/plan-workflow-persist";
|
||||
import { PlanWorkflow } from "@app/core/model/workflow/plan-workflow";
|
||||
import { PlanWorkflowDefinitionPersist, PlanWorkflowPersist } from "@app/core/model/workflow/plan-workflow-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";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable } from "@angular/core";
|
||||
import { PlanWorkflow, PlanWorkflowDefinition, PlanWorkflowDefinitionTransition } from "@app/core/model/plan-workflow/plan-workflow";
|
||||
import { PlanWorkflow, PlanWorkflowDefinition, PlanWorkflowDefinitionTransition } from "@app/core/model/workflow/plan-workflow";
|
||||
import { PlanWorkflowService } from "@app/core/services/plan/plan-workflow.service";
|
||||
import { BaseEditorResolver } from "@common/base/base-editor.resolver";
|
||||
import { takeUntil } from "rxjs";
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-WORKFLOW-EDITOR.FIELDS.STARTING-STATUS' | translate}}*</mat-label>
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.STARTING-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="definitionForm?.controls?.startingStatusId"
|
||||
placeholder="{{'PLAN-WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
[configuration]="planStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="definitionForm?.controls?.startingStatusId.hasError('backendError')">{{definitionForm?.controls?.startingStatusId.getError('backendError').message}}</mat-error>
|
||||
|
@ -14,20 +14,20 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button mat-button class="action-btn row" type="button" (click)="addStatusTransition()" [disabled]="formGroup.disabled">{{'PLAN-WORKFLOW-EDITOR.ACTIONS.ADD-STATUS-TRANSITION' | translate}}</button>
|
||||
<button mat-button class="action-btn row" type="button" (click)="addStatusTransition()" [disabled]="formGroup.disabled">{{'WORKFLOW-EDITOR.ACTIONS.ADD-STATUS-TRANSITION' | translate}}</button>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<mat-error class="pl-3 pt-2" *ngIf="definitionForm?.touched && definitionForm?.controls?.statusTransitions?.hasError('required')">
|
||||
{{'PLAN-WORKFLOW-EDITOR.ERRORS.STATUS-TRANSITION-REQUIRED' | translate}}
|
||||
{{'WORKFLOW-EDITOR.ERRORS.STATUS-TRANSITION-REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
@for(transitionForm of definitionForm?.controls?.statusTransitions?.controls; track transitionForm; let index = $index){
|
||||
<div class="col-12">
|
||||
<div class="row mb-3 d-flex align-items-center">
|
||||
<div class="col-auto d-flex">
|
||||
<mat-card-title>{{'PLAN-WORKFLOW-EDITOR.FIELDS.STATUS-TRANSITION' | translate}} {{index + 1}}</mat-card-title>
|
||||
<mat-card-title>{{'WORKFLOW-EDITOR.FIELDS.STATUS-TRANSITION' | translate}} {{index + 1}}</mat-card-title>
|
||||
</div>
|
||||
<div class="col-auto d-flex">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-WORKFLOW-EDITOR.ACTIONS.REMOVE-STATUS-TRANSITION' | translate}}" (click)="removeStatusTransition(index)" [disabled]="formGroup.disabled">
|
||||
<button mat-icon-button class="action-list-icon" matTooltip="{{'WORKFLOW-EDITOR.ACTIONS.REMOVE-STATUS-TRANSITION' | translate}}" (click)="removeStatusTransition(index)" [disabled]="formGroup.disabled">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -35,11 +35,11 @@
|
|||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-WORKFLOW-EDITOR.FIELDS.FROM-STATUS' | translate}}*</mat-label>
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.FROM-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="transitionForm?.controls?.fromStatusId"
|
||||
placeholder="{{'PLAN-WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
[configuration]="planStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="transitionForm?.controls?.fromStatusId.hasError('backendError')">{{transitionForm?.controls?.fromStatusId.getError('backendError').message}}</mat-error>
|
||||
|
@ -48,18 +48,18 @@
|
|||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'PLAN-WORKFLOW-EDITOR.FIELDS.TO-STATUS' | translate}}*</mat-label>
|
||||
<mat-label>{{'WORKFLOW-EDITOR.FIELDS.TO-STATUS' | translate}}*</mat-label>
|
||||
<app-single-auto-complete
|
||||
[required]="true"
|
||||
[formControl]="transitionForm?.controls?.toStatusId"
|
||||
placeholder="{{'PLAN-WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
placeholder="{{'WORKFLOW-EDITOR.ACTIONS.SELECT-PLAN-STATUS' | translate}}"
|
||||
[configuration]="planStatusAutoCompleteConfiguration"
|
||||
/>
|
||||
<mat-error *ngIf="transitionForm?.controls?.toStatusId.hasError('backendError')">{{transitionForm?.controls?.toStatusId.getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="transitionForm?.controls.toStatusId.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-error class="pl-3" *ngIf="transitionForm.hasError('differentStatusId')">{{'PLAN-WORKFLOW-EDITOR.ERRORS.DIFFERENT-STATUS' | translate}}</mat-error>
|
||||
<mat-error class="pl-3" *ngIf="transitionForm.hasError('differentStatusId')">{{'WORKFLOW-EDITOR.ERRORS.DIFFERENT-STATUS' | translate}}</mat-error>
|
||||
}
|
||||
</div>
|
||||
<div class="col-12">
|
||||
|
|
|
@ -5,7 +5,7 @@ import { PlanWorkflowDefinitionForm, PlanWorkflowEditorModel, PlanWorkflowForm }
|
|||
import { FormGroup } from '@angular/forms';
|
||||
import { PlanWorkflowService } from '@app/core/services/plan/plan-workflow.service';
|
||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||
import { PlanWorkflow } from '@app/core/model/plan-workflow/plan-workflow';
|
||||
import { PlanWorkflow } from '@app/core/model/workflow/plan-workflow';
|
||||
import { PlanWorkflowEditorResolver } from '../plan-workflow-editor.resolver';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
|
@ -15,7 +15,7 @@ import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/serv
|
|||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PlanWorkflowPersist } from '@app/core/model/plan-workflow/plan-workflow-persist';
|
||||
import { PlanWorkflowPersist } from '@app/core/model/workflow/plan-workflow-persist';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
|
@ -192,9 +192,11 @@ export class PlanWorkflowEditorComponent extends BasePendingChangesComponent imp
|
|||
]
|
||||
|
||||
planStatusAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
initialItems: (data?: any) => this.planStatusService.query(
|
||||
initialItems: (excludedItems: any[], data?: any) => this.planStatusService.query(
|
||||
this.planStatusService.buildLookup({
|
||||
size: 20, lookupFields: this.planStatusLookupFields
|
||||
size: 20,
|
||||
lookupFields: this.planStatusLookupFields,
|
||||
excludedIds: excludedItems
|
||||
})).pipe(map(x => x.items)),
|
||||
filterFn: (searchQuery: string, data?: any) => this.planStatusService.query(
|
||||
this.planStatusService.buildLookup({
|
||||
|
|
|
@ -81,6 +81,15 @@
|
|||
<ng-template matExpansionPanelContent>
|
||||
<app-plan-workflow-editor></app-plan-workflow-editor>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>{{'TENANT-CONFIGURATION-EDITOR.DESCRIPTION-WORKFLOW.TITLE' | translate}}</mat-panel-title>
|
||||
<mat-panel-description>{{'TENANT-CONFIGURATION-EDITOR.DESCRIPTION-WORKFLOW.HINT' | translate}}</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent>
|
||||
<app-description-workflow-editor></app-description-workflow-editor>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
|
|
|
@ -21,6 +21,7 @@ import { LogoEditorComponent } from './editor/logo/logo-editor.component';
|
|||
import { NgxColorsModule } from 'ngx-colors';
|
||||
import { NotifierListModule } from '@notification-service/ui/admin/tenant-configuration/notifier-list/notifier-list-editor.module';
|
||||
import { PlanWorkflowEditorComponent } from './editor/plan-workflow/plan-workflow-editor/plan-workflow-editor.component';
|
||||
import { DescriptionWorkflowEditorComponent } from './editor/description-workflow/description-workflow-editor/description-workflow-editor.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -47,7 +48,8 @@ import { PlanWorkflowEditorComponent } from './editor/plan-workflow/plan-workflo
|
|||
DepositEditorComponent,
|
||||
FileTransformerEditorComponent,
|
||||
LogoEditorComponent,
|
||||
PlanWorkflowEditorComponent
|
||||
PlanWorkflowEditorComponent,
|
||||
DescriptionWorkflowEditorComponent
|
||||
]
|
||||
})
|
||||
export class TenantConfigurationModule { }
|
||||
|
|
Loading…
Reference in New Issue