Compare commits
21 Commits
master
...
aai_roles_
Author | SHA1 | Date |
---|---|---|
Konstantinos Spyrou | c9740cdf35 | |
Konstantinos Spyrou | a34bed1d62 | |
Konstantinos Spyrou | 026747dcaa | |
Konstantinos Spyrou | 6d492ae919 | |
Konstantinos Spyrou | 940fd326ad | |
Konstantinos Spyrou | 27d6111874 | |
Konstantinos Spyrou | cb9d651f89 | |
Konstantinos Spyrou | 443c936ce0 | |
Konstantinos Spyrou | d2c45c2db7 | |
Konstantinos Spyrou | b8c1e18d27 | |
Konstantinos Spyrou | aaecacd58b | |
Konstantinos Spyrou | 90827f99d3 | |
Konstantinos Spyrou | 95929e6587 | |
Konstantinos Spyrou | 301e680136 | |
Konstantinos Spyrou | e0c193f86b | |
Konstantinos Spyrou | fc4b182e0f | |
Konstantinos Spyrou | 7b9e1ef4a7 | |
Konstantinos Spyrou | f05ccb0b43 | |
Konstantinos Spyrou | b58d9d38f0 | |
Antonis Koulalis | f9b12e56f5 | |
Antonis Koulalis | 4f7cc920da |
35
_fonts.scss
35
_fonts.scss
|
@ -1,35 +0,0 @@
|
||||||
/* You can add fonts */
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "CharterITCW05";
|
|
||||||
src: url("assets/fonts/CharterITCW05-Regular.woff") format("woff");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@font-face {
|
|
||||||
font-family: "HelveticaNeue";
|
|
||||||
src: url("assets/fonts/HelveticaNeue-Regular.ttf") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "PragmaticaMedium";
|
|
||||||
src: url("assets/fonts/PragmaticaMedium.otf") format("opentype");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
:host ::ng-deep {
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
font-family: "CharterITCW05";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*label, .p-button, th {
|
|
||||||
font-family: "PragmaticaMedium";
|
|
||||||
font-weight: 100;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/** {
|
|
||||||
:not(h1, h2, h3, h4, h5, h6, label, .p-button, th, .pi) {
|
|
||||||
font-family: "HelveticaNeue";
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
1263
_general.scss
1263
_general.scss
File diff suppressed because it is too large
Load Diff
32
_media.scss
32
_media.scss
|
@ -1,32 +0,0 @@
|
||||||
/* You can add media styles */
|
|
||||||
|
|
||||||
@media (max-width: 991px) {
|
|
||||||
|
|
||||||
//header
|
|
||||||
.header {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
//main-content
|
|
||||||
.main-content {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 961px) {
|
|
||||||
|
|
||||||
.hidden-left-panel {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 961px) {
|
|
||||||
|
|
||||||
.hidden-horizontal-menu {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/* You can add reusable colors */
|
|
||||||
|
|
||||||
// Primary
|
|
||||||
$dark-orange-1: #933401;
|
|
||||||
$dark-orange-2: #571F01;
|
|
||||||
$orange: #D04A02;
|
|
||||||
$light-orange-1: #FD6412;
|
|
||||||
$light-orange-2: #FEB791;
|
|
||||||
|
|
||||||
$dark-tangerine-1: #AE6800;
|
|
||||||
$dark-tangerine-2: #714300;
|
|
||||||
$tangerine: #EB8C00;
|
|
||||||
$light-tangerine-1: #FFA929;
|
|
||||||
$light-tangerine-2: #FFDCA9;
|
|
||||||
|
|
||||||
$dark-yellow-1: #C28A00;
|
|
||||||
$dark-yellow-2: #855F00;
|
|
||||||
$yellow: #FFB600;
|
|
||||||
$light-yellow-1: #FFC83D;
|
|
||||||
$light-yellow-2: #FFECBD;
|
|
||||||
|
|
||||||
$dark-rose-1: #A43E50;
|
|
||||||
$dark-rose-2: #6E2A35;
|
|
||||||
$rose: #DB536A;
|
|
||||||
$light-rose-1: #E27588;
|
|
||||||
$light-rose-2: #F1BAC3;
|
|
||||||
|
|
||||||
$dark-red-1: #AA2417;
|
|
||||||
$dark-red-2: #741910;
|
|
||||||
$red: #E0301E;
|
|
||||||
$light-red-1: #E86153;
|
|
||||||
$Light-red-2: #F7C8C4;
|
|
||||||
|
|
||||||
$white: white;
|
|
||||||
$black: black;
|
|
||||||
$dark-grey: #2D2D2D;
|
|
||||||
$medium-grey: #464646;
|
|
||||||
$grey: #7D7D7D;
|
|
||||||
$light-grey: #DEDEDE;
|
|
||||||
|
|
||||||
// Secondary
|
|
||||||
$dark-purple-1: #6A1CE2;
|
|
||||||
$dark-purple-2: #4B06B2;
|
|
||||||
$purple: #9013FE;
|
|
||||||
$light-purple-1: #B15AFE;
|
|
||||||
$light-purple-2: #DEB8FF;
|
|
||||||
|
|
||||||
$dark-blue-1: #0060D7;
|
|
||||||
$dark-blue-2: #003DAB;
|
|
||||||
$blue: #0089EB;
|
|
||||||
$light-blue-1: #4DACF1;
|
|
||||||
$light-blue-2: #B3DCF9;
|
|
||||||
|
|
||||||
$dark-green-1: #2C8646;
|
|
||||||
$dark-green-2: #175C2C;
|
|
||||||
$green: #4EB523;
|
|
||||||
$light-green-1: #86DB4F;
|
|
||||||
$light-green-2: #C4FC9F;
|
|
||||||
$rose-for-white-type: #D93954;
|
|
||||||
|
|
||||||
// Status Colors
|
|
||||||
$status-red: #E0301E;
|
|
||||||
$status-yellow: #FFB600;
|
|
||||||
$status-green: #175C2C;
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
const routes: Routes = [];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forRoot(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class AppRoutingModule { }
|
|
|
@ -1,9 +0,0 @@
|
||||||
<p-toast preventOpenDuplicates="true"></p-toast>
|
|
||||||
<div class="container">
|
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<div class="p-col-12">
|
|
||||||
<app-header></app-header>
|
|
||||||
<app-main-page></app-main-page>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,35 +0,0 @@
|
||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
RouterTestingModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
}).compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create the app', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have as title 'RTA-Admin-UI'`, () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.componentInstance;
|
|
||||||
expect(app.title).toEqual('RTA-Admin-UI');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render title', () => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.nativeElement;
|
|
||||||
expect(compiled.querySelector('.content span').textContent).toContain('RTA-Admin-UI app is running!');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { AuthService } from './shared/services/auth.service';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { PrimeNGConfig } from 'primeng/api';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
templateUrl: './app.component.html',
|
|
||||||
styleUrls: ['./app.component.scss']
|
|
||||||
})
|
|
||||||
export class AppComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor(private primengConfig: PrimeNGConfig, private authService: AuthService) { }
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.primengConfig.ripple = true;
|
|
||||||
this.authService.initializeOAuth2Login();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
import { ToastModule } from 'primeng/toast';
|
|
||||||
import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
|
|
||||||
import { environment } from './../environments/environment';
|
|
||||||
import { HttpClientModule, HttpClient } from '@angular/common/http';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
import { CoreModule } from './core/core.module';
|
|
||||||
import { FeaturesModule } from './features/features.module';
|
|
||||||
import { SharedModule } from './shared/shared.module';
|
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
|
||||||
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
||||||
import { SearchListStateService } from './shared/back-button/search-list-state.service';
|
|
||||||
|
|
||||||
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
|
|
||||||
return new TranslateHttpLoader(http);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Settings localStorage as OAuth2 storage.
|
|
||||||
// We need a factory, since localStorage is not available during AOT build time.
|
|
||||||
export function storageFactory(): OAuthStorage {
|
|
||||||
return localStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
AppRoutingModule,
|
|
||||||
CoreModule,
|
|
||||||
FeaturesModule,
|
|
||||||
SharedModule,
|
|
||||||
HttpClientModule,
|
|
||||||
ToastModule,
|
|
||||||
OAuthModule.forRoot({
|
|
||||||
resourceServer: {
|
|
||||||
allowedUrls: [environment.baseApiUrl],
|
|
||||||
sendAccessToken: true
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useFactory: HttpLoaderFactory,
|
|
||||||
deps: [HttpClient]
|
|
||||||
},
|
|
||||||
defaultLanguage: environment.defaultLanguage,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
providers: [ConfirmationService, { provide: OAuthStorage, useFactory: storageFactory }, MessageService, SearchListStateService],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { SharedModule } from 'primeng/api';
|
|
||||||
import { PrimengSharedModule } from './../shared/primeng-shared/primeng-shared.module';
|
|
||||||
import { ErrorHandlingModule } from './error-handling/error-handling.module';
|
|
||||||
|
|
||||||
import { HeaderComponent } from './header/header.component';
|
|
||||||
import { MainPageComponent } from './main-page/main-page.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [HeaderComponent, MainPageComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
PrimengSharedModule,
|
|
||||||
SharedModule,
|
|
||||||
ErrorHandlingModule
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
HeaderComponent,
|
|
||||||
MainPageComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class CoreModule { }
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { HttpErrorInterceptor } from './http-error.interceptor';
|
|
||||||
import { GlobalErrorHandler } from './global-error-handler';
|
|
||||||
import { NgModule, ErrorHandler } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [],
|
|
||||||
imports: [CommonModule],
|
|
||||||
providers: [
|
|
||||||
{ provide: ErrorHandler, useClass: GlobalErrorHandler },
|
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ErrorHandlingModule { }
|
|
|
@ -1,21 +0,0 @@
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
import { ErrorHandlingService } from './../../shared/services/error-handling/error-handling.service';
|
|
||||||
import { ErrorHandler, Injectable, NgZone } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class GlobalErrorHandler implements ErrorHandler {
|
|
||||||
constructor(private errorHandlingService: ErrorHandlingService, private zone: NgZone) {}
|
|
||||||
|
|
||||||
handleError(error: Error): void {
|
|
||||||
|
|
||||||
this.zone.run(() => {
|
|
||||||
if (!(error instanceof HttpErrorResponse) && environment.enableGlobalErrorToast){
|
|
||||||
this.errorHandlingService.showErrorMessage(error.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
console.error('Error from global error handler', error);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
import { ErrorHandlingService } from './../../shared/services/error-handling/error-handling.service';
|
|
||||||
import {
|
|
||||||
HttpHandler,
|
|
||||||
HttpRequest,
|
|
||||||
HttpEvent,
|
|
||||||
HttpErrorResponse,
|
|
||||||
HttpInterceptor
|
|
||||||
} from '@angular/common/http';
|
|
||||||
import { Observable, throwError } from 'rxjs';
|
|
||||||
import { catchError } from 'rxjs/operators';
|
|
||||||
import { Injectable, Injector } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class HttpErrorInterceptor implements HttpInterceptor {
|
|
||||||
constructor(
|
|
||||||
private injector: Injector,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
intercept(
|
|
||||||
request: HttpRequest<any>,
|
|
||||||
next: HttpHandler
|
|
||||||
): Observable<HttpEvent<any>> {
|
|
||||||
return next.handle(request).pipe(
|
|
||||||
catchError((error: HttpErrorResponse) => {
|
|
||||||
// We don't inject an HttpClient dependent service directly to an http interceptor's constructor,
|
|
||||||
// or we'll get cyclic dependency errors
|
|
||||||
const errorHandlingService = this.injector.get(ErrorHandlingService);
|
|
||||||
|
|
||||||
errorHandlingService.showHttpResponseError(error);
|
|
||||||
return throwError(error);
|
|
||||||
})
|
|
||||||
) as Observable<HttpEvent<any>>;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<div class="p-grid p-nogutter p-ai-center vertical-container header">
|
|
||||||
<div class="p-col-4">
|
|
||||||
<div class="p-grid p-nogutter p-jc-start">
|
|
||||||
<a routerLink=''>
|
|
||||||
<img src="assets/images/pwc-logo.svg" height="50">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="p-col-8">
|
|
||||||
<div class="p-grid p-nogutter p-jc-end">
|
|
||||||
<p-selectButton class="p-ml-auto" [options]="languages" [(ngModel)]="selectedLang" (ngModelChange)="changeLanguage($event)" optionLabel="name" optionValue="code"></p-selectButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { HeaderComponent } from './header.component';
|
|
||||||
|
|
||||||
describe('HeaderComponent', () => {
|
|
||||||
let component: HeaderComponent;
|
|
||||||
let fixture: ComponentFixture<HeaderComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ HeaderComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(HeaderComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,28 +0,0 @@
|
||||||
import { Language } from './../../shared/models/language.interface';
|
|
||||||
import { environment } from './../../../environments/environment';
|
|
||||||
import { AuthService } from './../../shared/services/auth.service';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { MenuItem } from 'primeng/api';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import {Router} from "@angular/router";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-header',
|
|
||||||
templateUrl: './header.component.html',
|
|
||||||
styleUrls: ['./header.component.scss']
|
|
||||||
})
|
|
||||||
export class HeaderComponent implements OnInit {
|
|
||||||
|
|
||||||
languages: Language[] = environment.languages;
|
|
||||||
selectedLang = environment.defaultLanguage;
|
|
||||||
|
|
||||||
constructor(private auth: AuthService, private translateService: TranslateService, private router: Router) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
changeLanguage($event): void {
|
|
||||||
this.translateService.use($event);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
<router-outlet></router-outlet>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { MainPageComponent } from './main-page.component';
|
|
||||||
|
|
||||||
describe('MainPageComponent', () => {
|
|
||||||
let component: MainPageComponent;
|
|
||||||
let fixture: ComponentFixture<MainPageComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ MainPageComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(MainPageComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,22 +0,0 @@
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-main-page',
|
|
||||||
templateUrl: './main-page.component.html',
|
|
||||||
styleUrls: ['./main-page.component.scss']
|
|
||||||
})
|
|
||||||
export class MainPageComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor(private auth: AuthService, private router: Router) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.auth.authStatusChanged.subscribe((isAuthenticated) => {
|
|
||||||
if (!isAuthenticated) {
|
|
||||||
this.router.navigateByUrl('login');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
|
|
||||||
<app-left-panel class="hidden-left-panel"></app-left-panel>
|
|
||||||
|
|
||||||
<div class="p-col main-content">
|
|
||||||
<h1>{{'ADMINISTRATION' | translate}}</h1>
|
|
||||||
|
|
||||||
<div class="p-mb-5 hidden-horizontal-menu">
|
|
||||||
<app-horizontal-menu></app-horizontal-menu>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ng-template ngFor let-section [ngForOf]="adminSections">
|
|
||||||
<h3 class="sub-title" id="{{section.title}}">{{section.title}}</h3>
|
|
||||||
<div class="sub-content">
|
|
||||||
<div class="p-grid">
|
|
||||||
<ng-template ngFor let-subSection [ngForOf]="section.subSections">
|
|
||||||
<div class="p-col-12 p-sm-6 p-xl-3">
|
|
||||||
<app-card [data]="subSection"></app-card>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AdministrationComponent } from './administration.component';
|
|
||||||
|
|
||||||
describe('WelcomeComponent', () => {
|
|
||||||
let component: AdministrationComponent;
|
|
||||||
let fixture: ComponentFixture<AdministrationComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [AdministrationComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(AdministrationComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,103 +0,0 @@
|
||||||
import { AuthService } from './../../shared/services/auth.service';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { CardItem } from './../../shared/models/card-item.interface';
|
|
||||||
import { AdministrationSection } from './../../shared/models/administration-section.interface';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-administration',
|
|
||||||
templateUrl: './administration.component.html',
|
|
||||||
styleUrls: ['./administration.component.scss']
|
|
||||||
})
|
|
||||||
export class AdministrationComponent implements OnInit {
|
|
||||||
|
|
||||||
data: CardItem;
|
|
||||||
adminSections: AdministrationSection[];
|
|
||||||
|
|
||||||
constructor(public authService: AuthService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initializeData();
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeData() {
|
|
||||||
this.adminSections = [
|
|
||||||
{
|
|
||||||
title: 'Monitoring',
|
|
||||||
subSections: [
|
|
||||||
{
|
|
||||||
title: 'Downloads Monitoring',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-desktop',
|
|
||||||
path: '/pages/administration/downloads-monitoring'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Configurations',
|
|
||||||
subSections: [
|
|
||||||
{
|
|
||||||
title: 'Categories Managenent',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-cog',
|
|
||||||
path: '/pages/administration/categories-management'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Templates Managenent',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-cog',
|
|
||||||
path: '/pages/administration/templates-management'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Verification Managenent',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-cog',
|
|
||||||
path: '/pages/administration/verification-management'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Configurator',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-cog',
|
|
||||||
path: '/pages/administration/configurator'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Access',
|
|
||||||
subSections: [
|
|
||||||
{
|
|
||||||
title: 'Users Managenent',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-key',
|
|
||||||
path: '/pages/administration/users-management'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Roles Managenent',
|
|
||||||
subtitle: 'View File\'s Downloading Process and Manage...',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-key',
|
|
||||||
path: '/pages/administration/roles-management'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Exception Handling',
|
|
||||||
subSections: [
|
|
||||||
{
|
|
||||||
title: 'Application Level Exceptions',
|
|
||||||
subtitle: 'View Application Level exceptions thrown by the Platform',
|
|
||||||
headerImage: 'pi-image',
|
|
||||||
footerImage: 'pi-exclamation-triangle',
|
|
||||||
path: '/pages/administration/application-level-exceptions'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<p-dialog [header]="header"
|
|
||||||
[(visible)]="displayDialog "
|
|
||||||
[closable]="false"
|
|
||||||
[draggable]="false"
|
|
||||||
[modal]="true"
|
|
||||||
appendTo="body">
|
|
||||||
<ng-template pTemplate="content">
|
|
||||||
<pre>
|
|
||||||
{{this.trace}}
|
|
||||||
</pre>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template pTemplate="footer">
|
|
||||||
<p-button (onClick)="cancel()"
|
|
||||||
label="Close"
|
|
||||||
styleClass="p-mt-3 p-button-warning">
|
|
||||||
</p-button>
|
|
||||||
</ng-template>
|
|
||||||
</p-dialog>
|
|
|
@ -1,13 +0,0 @@
|
||||||
@import 'src/styles';
|
|
||||||
|
|
||||||
pre {
|
|
||||||
width: 900px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991px) {
|
|
||||||
|
|
||||||
pre {
|
|
||||||
width: 420px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ApplicationLevelDialogComponent } from './application-level-dialog.component';
|
|
||||||
|
|
||||||
describe('ApplicationLevelDialogComponent', () => {
|
|
||||||
let component: ApplicationLevelDialogComponent;
|
|
||||||
let fixture: ComponentFixture<ApplicationLevelDialogComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ApplicationLevelDialogComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ApplicationLevelDialogComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,24 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { ApplicationLevelExceptionService } from 'src/app/shared/services/administration/application-level-exception.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-level-dialog',
|
|
||||||
templateUrl: './application-level-dialog.component.html',
|
|
||||||
styleUrls: ['./application-level-dialog.component.scss']
|
|
||||||
})
|
|
||||||
export class ApplicationLevelDialogComponent implements OnInit {
|
|
||||||
@Input() displayDialog: boolean;
|
|
||||||
@Input() header: string;
|
|
||||||
@Input() trace: string;
|
|
||||||
@Output() cancelled = new EventEmitter<boolean>();
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.cancelled.emit(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<div class="p-col main-content">
|
|
||||||
|
|
||||||
<h1>{{'APPLICATION-LEVEL-EXCEPTIONS' | translate}}</h1>
|
|
||||||
|
|
||||||
<app-horizontal-menu></app-horizontal-menu>
|
|
||||||
|
|
||||||
<app-breadcrumb></app-breadcrumb>
|
|
||||||
|
|
||||||
<div class="p-grid p-nogutter p-pt-5 p-pb-5">
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12 p-mt-5">
|
|
||||||
<app-application-level-search-form [paginationEventRequest]="paginationEventRequest"
|
|
||||||
(searchResults)="searchMade($event)"
|
|
||||||
(loading)="passloading($event)">
|
|
||||||
</app-application-level-search-form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12 p-mt-5">
|
|
||||||
<app-application-level-table [searchResultsPage]="searchResults"
|
|
||||||
(paginationEvent)="paginationEvent($event)"
|
|
||||||
[loading]="loading">
|
|
||||||
</app-application-level-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ApplicationLevelExceptionsComponent } from './application-level-exceptions.component';
|
|
||||||
|
|
||||||
describe('ApplicationLevelExceptionsComponent', () => {
|
|
||||||
let component: ApplicationLevelExceptionsComponent;
|
|
||||||
let fixture: ComponentFixture<ApplicationLevelExceptionsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ApplicationLevelExceptionsComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ApplicationLevelExceptionsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,33 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Page } from 'src/app/shared/models/paging/page.interface';
|
|
||||||
import { SystemException } from 'src/app/shared/models/system-exception.interface';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-level-exceptions',
|
|
||||||
templateUrl: './application-level-exceptions.component.html',
|
|
||||||
styleUrls: ['./application-level-exceptions.component.scss']
|
|
||||||
})
|
|
||||||
export class ApplicationLevelExceptionsComponent implements OnInit {
|
|
||||||
|
|
||||||
searchResults: Page<SystemException> = null;
|
|
||||||
paginationEventRequest: { page: number, offset: number } ;
|
|
||||||
loading: boolean;
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
searchMade(results) {
|
|
||||||
this.searchResults = results;
|
|
||||||
}
|
|
||||||
|
|
||||||
passloading(loading) {
|
|
||||||
this.loading = loading;
|
|
||||||
}
|
|
||||||
|
|
||||||
paginationEvent(paginationEvent) {
|
|
||||||
this.paginationEventRequest = paginationEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<p-fieldset legend="Search Filters"
|
|
||||||
[toggleable]="true">
|
|
||||||
<app-application-level-form></app-application-level-form>
|
|
||||||
<div class="p-formgroup-inline p-jc-center p-mt-3">
|
|
||||||
<p-button (onClick)="clear()" label="Clear" styleClass="p-mr-2 p-button-warning"
|
|
||||||
[disabled]="!canPreviewLevelExceptions()">
|
|
||||||
</p-button>
|
|
||||||
<p-button (onClick)="search()"
|
|
||||||
label="Search"
|
|
||||||
styleClass="p-button-primary"
|
|
||||||
[disabled]="!canPreviewLevelExceptions()">
|
|
||||||
</p-button>
|
|
||||||
</div>
|
|
||||||
</p-fieldset>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ApplicationLevelSearchFormComponent } from './application-level-search-form.component';
|
|
||||||
|
|
||||||
describe('ApplicationLevelSearchFormComponent', () => {
|
|
||||||
let component: ApplicationLevelSearchFormComponent;
|
|
||||||
let fixture: ComponentFixture<ApplicationLevelSearchFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ApplicationLevelSearchFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ApplicationLevelSearchFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,59 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { Page } from 'src/app/shared/models/paging/page.interface';
|
|
||||||
import { SystemException } from 'src/app/shared/models/system-exception.interface';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { ApplicationLevelExceptionService } from 'src/app/shared/services/administration/application-level-exception.service';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { ApplicationLevelFormComponent } from '../../forms/application-level-form/application-level-form.component';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-level-search-form',
|
|
||||||
templateUrl: './application-level-search-form.component.html',
|
|
||||||
styleUrls: ['./application-level-search-form.component.scss']
|
|
||||||
})
|
|
||||||
export class ApplicationLevelSearchFormComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() set paginationEventRequest(value: { page: number, offset: number }) {
|
|
||||||
|
|
||||||
// This setter may be called on page setup without arguments.
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// this._value = Object.assign(value);
|
|
||||||
this.search(value.page, value.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Output() searchResults = new EventEmitter<Page<SystemException>>();
|
|
||||||
@Output() loading = new EventEmitter<boolean>();
|
|
||||||
@ViewChild(ApplicationLevelFormComponent)
|
|
||||||
private searchCriteriaForm: ApplicationLevelFormComponent;
|
|
||||||
_value : {page: number , offset: number};
|
|
||||||
|
|
||||||
constructor(private applicationLevelService: ApplicationLevelExceptionService,private errorHandlingService: ErrorHandlingService, private auth: AuthService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
search(pageNumber = 0, pageSize = 10) {
|
|
||||||
this.loading.emit(true);
|
|
||||||
this.applicationLevelService.searchByCriteriaPaged(pageNumber, pageSize, this.searchCriteriaForm?.formValue(), 'search').subscribe((results: Page<SystemException>) => {
|
|
||||||
this.searchResults.emit(results);
|
|
||||||
this.loading.emit(false);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
this.loading.emit(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canPreviewLevelExceptions(): boolean {
|
|
||||||
return this.auth.userHasRightForClient(USER_RIGHTS.K01, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.searchCriteriaForm.resetForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
<p-fieldset legend="List of Exceptions"
|
|
||||||
[toggleable]="_searchResultsPage?.data !== null"
|
|
||||||
[collapsed]="_searchResultsPage?.data === null">
|
|
||||||
<p-table [value]="_searchResultsPage?.data"
|
|
||||||
[lazy]="true"
|
|
||||||
(onLazyLoad)="onLazyLoad($event)"
|
|
||||||
[paginator]="true"
|
|
||||||
[rows]="rows"
|
|
||||||
[totalRecords]="totalRecords"
|
|
||||||
styleClass="p-datatable-gridlines"
|
|
||||||
[rowHover]="true"
|
|
||||||
[loading]="loading"
|
|
||||||
[autoLayout]="true"
|
|
||||||
[lazyLoadOnInit]="false">
|
|
||||||
<ng-template pTemplate="header">
|
|
||||||
<tr>
|
|
||||||
<th>Date-Time</th>
|
|
||||||
<th>Process Id</th>
|
|
||||||
<th>Job Name</th>
|
|
||||||
<th>File Code</th>
|
|
||||||
<th>iPower Client Code</th>
|
|
||||||
<th>Message</th>
|
|
||||||
<th>Cause</th>
|
|
||||||
<th class="one-button">Trace</th>
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template pTemplate="body" let-systemException>
|
|
||||||
<tr>
|
|
||||||
<td>{{systemException.creationDatetime|date: "dd/MM/yyyy HH:mm"}}</td>
|
|
||||||
<td>{{systemException.processId}}</td>
|
|
||||||
<td>{{systemException.jobName}}</td>
|
|
||||||
<td>{{systemException.dmsFileCode}}</td>
|
|
||||||
<td>{{systemException.clientId}}</td>
|
|
||||||
<td>{{systemException.message}}</td>
|
|
||||||
<td>{{systemException.cause}}</td>
|
|
||||||
<!-- Edit & Delete icons -->
|
|
||||||
<td>
|
|
||||||
<button pButton
|
|
||||||
(click)="edit(systemException.id)"
|
|
||||||
icon="pi pi-align-justify"
|
|
||||||
pTooltip="{{'TRACE' | translate}}"
|
|
||||||
class="p-button-secondary p-button-rounded p-button-outlined">
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
</p-table>
|
|
||||||
</p-fieldset>
|
|
||||||
|
|
||||||
<app-application-level-dialog [displayDialog]="displayTraceDialog"
|
|
||||||
[header]="header"
|
|
||||||
(cancelled)="cancelEditLevelException()"
|
|
||||||
[trace]="trace">
|
|
||||||
</app-application-level-dialog>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ApplicationLevelTableComponent } from './application-level-table.component';
|
|
||||||
|
|
||||||
describe('ApplicationLevelTableComponent', () => {
|
|
||||||
let component: ApplicationLevelTableComponent;
|
|
||||||
let fixture: ComponentFixture<ApplicationLevelTableComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ApplicationLevelTableComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ApplicationLevelTableComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,64 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { LazyLoadEvent } from 'primeng/api';
|
|
||||||
import { Page } from 'src/app/shared/models/paging/page.interface';
|
|
||||||
import { SystemException } from 'src/app/shared/models/system-exception.interface';
|
|
||||||
import { ApplicationLevelExceptionService } from 'src/app/shared/services/administration/application-level-exception.service';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-level-table',
|
|
||||||
templateUrl: './application-level-table.component.html',
|
|
||||||
styleUrls: ['./application-level-table.component.scss']
|
|
||||||
})
|
|
||||||
export class ApplicationLevelTableComponent implements OnInit {
|
|
||||||
|
|
||||||
@Output() paginationEvent = new EventEmitter<{ page: number, offset: number }>(); // TODO: Use interface.
|
|
||||||
@Input() loading: boolean;
|
|
||||||
@Input() set searchResultsPage(results: Page<SystemException>) {
|
|
||||||
|
|
||||||
// This setter may be called on page setup without arguments.
|
|
||||||
if (!results) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._searchResultsPage = results;
|
|
||||||
this.totalRecords = results.totalElements;
|
|
||||||
// this.loading = false;
|
|
||||||
}
|
|
||||||
_searchResultsPage: Page<SystemException>;
|
|
||||||
totalRecords: number;
|
|
||||||
rows: number = 10;
|
|
||||||
header: string;
|
|
||||||
trace: string;
|
|
||||||
displayTraceDialog: boolean;
|
|
||||||
|
|
||||||
constructor(private errorHandlingService: ErrorHandlingService, private applicationLevelService: ApplicationLevelExceptionService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
onLazyLoad(event: LazyLoadEvent) {
|
|
||||||
let pageToRequest = Math.floor(event.first / event.rows);
|
|
||||||
let pageSize = event.rows;
|
|
||||||
this.paginationEvent.emit({ page: pageToRequest, offset: pageSize });
|
|
||||||
}
|
|
||||||
|
|
||||||
edit(id: number) {
|
|
||||||
this.header = "Trace";
|
|
||||||
if(id){
|
|
||||||
this.applicationLevelService.getById(id).subscribe(result => {
|
|
||||||
this.trace = result.trace;
|
|
||||||
this.displayTraceDialog = true;
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelEditLevelException() {
|
|
||||||
this.displayTraceDialog = false;
|
|
||||||
this.trace = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<div class="p-col main-content">
|
|
||||||
|
|
||||||
<h1>{{'CATEGORIES-MANAGEMENT' | translate}}</h1>
|
|
||||||
|
|
||||||
<app-horizontal-menu></app-horizontal-menu>
|
|
||||||
|
|
||||||
<app-breadcrumb></app-breadcrumb>
|
|
||||||
|
|
||||||
<div class="p-grid p-nogutter p-pt-5 p-pb-5">
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12">
|
|
||||||
<div class="p-grid p-nogutter p-jc-end">
|
|
||||||
<button pButton
|
|
||||||
pRipple
|
|
||||||
type="button"
|
|
||||||
label="{{'ADD-NEW-CATEGORY' | translate}}"
|
|
||||||
icon="pi pi-plus-circle"
|
|
||||||
class="p-button-primary"
|
|
||||||
[disabled]="!canAddNewCategory()"
|
|
||||||
(click)="addCategory()">
|
|
||||||
</button>
|
|
||||||
<app-create-category-dialog [displayDialog]="displayCategoryCreationDialog"
|
|
||||||
[header]="header"
|
|
||||||
(cancelled)="displayCategoryCreationDialog = false"
|
|
||||||
(valueChange)="passEvent($event)">
|
|
||||||
</app-create-category-dialog>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12 p-mt-5">
|
|
||||||
<app-categories-search [paginationEventRequest]="paginationEventRequest"
|
|
||||||
(searchResults)="searchMade($event)"
|
|
||||||
(loading)="passLoadingForTable($event)"
|
|
||||||
[passChange]="passChange"
|
|
||||||
(loading)="passloading($event)"
|
|
||||||
[valueTableChange]="valueOfTableChanged">
|
|
||||||
</app-categories-search>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12 p-mt-5">
|
|
||||||
<app-categories-search-results [searchResultsPage]="searchResults"
|
|
||||||
[loading]="loading"
|
|
||||||
(paginationEvent)="paginationEvent($event)"
|
|
||||||
(valueChange)="passEvent($event)"
|
|
||||||
[loading]="loading">
|
|
||||||
</app-categories-search-results>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CategoriesManagementComponent } from './categories-management.component';
|
|
||||||
|
|
||||||
describe('CategoriesManagementComponent', () => {
|
|
||||||
let component: CategoriesManagementComponent;
|
|
||||||
let fixture: ComponentFixture<CategoriesManagementComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CategoriesManagementComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CategoriesManagementComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,59 +0,0 @@
|
||||||
import { environment } from './../../../../environments/environment.prod';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { AuthService } from './../../../shared/services/auth.service';
|
|
||||||
import { Category } from 'src/app/shared/models/category.interface';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Page } from '../../../shared/models/paging/page.interface';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-categories-management',
|
|
||||||
templateUrl: './categories-management.component.html',
|
|
||||||
styleUrls: ['./categories-management.component.scss']
|
|
||||||
})
|
|
||||||
export class CategoriesManagementComponent implements OnInit {
|
|
||||||
|
|
||||||
displayCategoryCreationDialog: boolean = false;
|
|
||||||
searchResults: Page<Category> = null;
|
|
||||||
paginationEventRequest: { page: number, offset: number } = { page: 10, offset: 0 };
|
|
||||||
header: string;
|
|
||||||
passChange: boolean;
|
|
||||||
valueOfTableChanged: any;
|
|
||||||
loading: boolean;
|
|
||||||
|
|
||||||
constructor(private authService: AuthService, private translate: TranslateService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
searchMade(results) {
|
|
||||||
this.searchResults = results;
|
|
||||||
}
|
|
||||||
|
|
||||||
passLoadingForTable(loading) {
|
|
||||||
this.loading = loading;
|
|
||||||
}
|
|
||||||
|
|
||||||
paginationEvent(paginationEvent) {
|
|
||||||
this.paginationEventRequest = paginationEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
canAddNewCategory(): boolean {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.H02, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
|
|
||||||
addCategory(): void {
|
|
||||||
this.header = this.translate.instant('ADD-NEW-CATEGORY');
|
|
||||||
this.displayCategoryCreationDialog = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
passEvent(passEvent: any) {
|
|
||||||
if (passEvent) {
|
|
||||||
this.valueOfTableChanged = passEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
passloading(loading) {
|
|
||||||
this.loading = loading;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
<p-fieldset legend="Results"
|
|
||||||
[toggleable]="_searchResultsPage?.data !== null"
|
|
||||||
[collapsed]="_searchResultsPage?.data === null">
|
|
||||||
<p-confirmDialog message="{{'DELETE-MESSAGE-CATEGORY' | translate}}"
|
|
||||||
header="{{'DELETE-CONFIRMATION' | translate}}"
|
|
||||||
acceptLabel="{{'ACCEPT_LABEL' | translate}}"
|
|
||||||
rejectLabel="{{'REJECT_LABEL' | translate}}"
|
|
||||||
acceptButtonStyleClass="p-button-primary"
|
|
||||||
rejectButtonStyleClass="p-button-warning"
|
|
||||||
acceptIcon="null"
|
|
||||||
rejectIcon="null">
|
|
||||||
</p-confirmDialog>
|
|
||||||
<p-table [value]="_searchResultsPage?.data"
|
|
||||||
[lazy]="true"
|
|
||||||
(onLazyLoad)="onLazyLoad($event)"
|
|
||||||
[paginator]="true"
|
|
||||||
[rows]="rows"
|
|
||||||
[totalRecords]="totalRecords"
|
|
||||||
styleClass="p-datatable-gridlines"
|
|
||||||
[rowHover]="true"
|
|
||||||
[loading]="loading"
|
|
||||||
[autoLayout]="true">
|
|
||||||
<ng-template pTemplate="header">
|
|
||||||
<tr>
|
|
||||||
<th>Document Classification</th>
|
|
||||||
<th>Category Name</th>
|
|
||||||
<th>Category Code</th>
|
|
||||||
<!-- TODO: Fix hacky way of locking the icon-columns in place -->
|
|
||||||
<th class="two-buttons">Actions</th>
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template pTemplate="body" let-category>
|
|
||||||
<tr>
|
|
||||||
<td>{{category.documentClassification.classificationName}}</td>
|
|
||||||
<td>{{category.categoryName}}</td>
|
|
||||||
<td>{{category.categoryCode}}</td>
|
|
||||||
<!-- Edit & Delete icons -->
|
|
||||||
<td>
|
|
||||||
<button pButton
|
|
||||||
[disabled]="!canEditCategories()"
|
|
||||||
(click)="edit(category)"
|
|
||||||
icon="pi pi-pencil"
|
|
||||||
pTooltip="{{'EDIT-CATEGORY' | translate}}"
|
|
||||||
class="p-button-secondary p-button-rounded p-button-outlined">
|
|
||||||
</button>
|
|
||||||
<button pButton
|
|
||||||
[disabled]="!canDeleteCategories()"
|
|
||||||
(click)="delete(category)"
|
|
||||||
icon="pi pi pi-trash"
|
|
||||||
pTooltip="{{'DELETE-CATEGORY' | translate}}"
|
|
||||||
class="p-button-danger p-button-rounded p-button-outlined p-ml-2">
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
</p-table>
|
|
||||||
</p-fieldset>
|
|
||||||
|
|
||||||
<app-create-category-dialog [displayDialog]="displayEditCategoryDialog"
|
|
||||||
[header]="header"
|
|
||||||
(cancelled)="cancelEditCategory()"
|
|
||||||
[categoryToEdit]="categoryToEdit"
|
|
||||||
(valueChange)="passEvent($event)">
|
|
||||||
</app-create-category-dialog>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CategoriesSearchResultsComponent } from './categories-search-results.component';
|
|
||||||
|
|
||||||
describe('CategoriesSearchResultsComponent', () => {
|
|
||||||
let component: CategoriesSearchResultsComponent;
|
|
||||||
let fixture: ComponentFixture<CategoriesSearchResultsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CategoriesSearchResultsComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CategoriesSearchResultsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,103 +0,0 @@
|
||||||
import { AuthService } from './../../../../shared/services/auth.service';
|
|
||||||
import { environment } from './../../../../../environments/environment.prod';
|
|
||||||
import { ErrorHandlingService } from './../../../../shared/services/error-handling/error-handling.service';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { Category } from './../../../../shared/models/category.interface';
|
|
||||||
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
|
|
||||||
import { ConfirmationService, LazyLoadEvent } from 'primeng/api';
|
|
||||||
import { Page } from '../../../../shared/models/paging/page.interface';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { NotificationsHandlingService } from 'src/app/shared/services/notifications-handling/notifications-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-categories-search-results',
|
|
||||||
templateUrl: './categories-search-results.component.html',
|
|
||||||
styleUrls: ['./categories-search-results.component.scss']
|
|
||||||
})
|
|
||||||
export class CategoriesSearchResultsComponent implements OnInit {
|
|
||||||
|
|
||||||
@Output() paginationEvent = new EventEmitter<{ page: number, offset: number }>(); // TODO: Use interface.
|
|
||||||
@Output() valueChange = new EventEmitter<any>();
|
|
||||||
@Input() loading: boolean;
|
|
||||||
@Input() set searchResultsPage(results: Page<Category>) {
|
|
||||||
|
|
||||||
// This setter may be called on page setup without arguments.
|
|
||||||
if (!results) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._searchResultsPage = results;
|
|
||||||
this.totalRecords = results.totalElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
_searchResultsPage: Page<Category>;
|
|
||||||
totalRecords: number;
|
|
||||||
rows: number = 10;
|
|
||||||
header: string;
|
|
||||||
|
|
||||||
displayEditCategoryDialog: boolean;
|
|
||||||
categoryToEdit: Category;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private errorHandlingService: ErrorHandlingService,
|
|
||||||
private authService: AuthService,
|
|
||||||
private translate: TranslateService,
|
|
||||||
private confirmationService: ConfirmationService,
|
|
||||||
private notifications: NotificationsHandlingService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
onLazyLoad(event: LazyLoadEvent) {
|
|
||||||
let pageToRequest = Math.floor(event.first / event.rows);
|
|
||||||
let pageSize = event.rows;
|
|
||||||
this.paginationEvent.emit({ page: pageToRequest, offset: pageSize });
|
|
||||||
}
|
|
||||||
|
|
||||||
edit(category: Category) {
|
|
||||||
this.header = this.translate.instant('EDIT-CATEGORY');
|
|
||||||
this.categoryToEdit = category;
|
|
||||||
this.displayEditCategoryDialog = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelEditCategory() {
|
|
||||||
this.displayEditCategoryDialog = false;
|
|
||||||
this.categoryToEdit = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(category: Category): void {
|
|
||||||
this.confirmationService.confirm({
|
|
||||||
accept: () => {
|
|
||||||
this.categoriesService.delete(category.id).subscribe((success) => {
|
|
||||||
this.valueChange.emit(success);
|
|
||||||
this.notifications.showDeleteCategorySuccess();
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
// Actual logic to perform a confirmation
|
|
||||||
}, reject: () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UserRights-check Methods
|
|
||||||
*/
|
|
||||||
canEditCategories(): boolean {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.H03, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
|
|
||||||
canDeleteCategories(): boolean {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.H04, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
|
|
||||||
passEvent(passEvent : any) {
|
|
||||||
if(passEvent){
|
|
||||||
this.valueChange.emit(passEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<p-fieldset legend="Search Filters"
|
|
||||||
[toggleable]="true">
|
|
||||||
<app-category-form [autosuggestInputs]="true"></app-category-form>
|
|
||||||
<div class="p-formgroup-inline p-jc-center p-mt-3">
|
|
||||||
<p-button (onClick)="clear()"
|
|
||||||
label="Clear"
|
|
||||||
styleClass="p-mr-2 p-button-warning">
|
|
||||||
</p-button>
|
|
||||||
<p-button (onClick)="searchButtonClicked()"
|
|
||||||
label="Search"
|
|
||||||
styleClass="p-ml-2 p-button-primary"
|
|
||||||
[disabled]="!canPreviewAllCategories()">
|
|
||||||
</p-button>
|
|
||||||
</div>
|
|
||||||
</p-fieldset>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CategoriesSearchComponent } from './categories-search.component';
|
|
||||||
|
|
||||||
describe('CategoriesSearchComponent', () => {
|
|
||||||
let component: CategoriesSearchComponent;
|
|
||||||
let fixture: ComponentFixture<CategoriesSearchComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CategoriesSearchComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CategoriesSearchComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,101 +0,0 @@
|
||||||
import { environment } from './../../../../../environments/environment.prod';
|
|
||||||
import { ErrorHandlingService } from './../../../../shared/services/error-handling/error-handling.service';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { CategoryFormComponent } from './../../forms/category-form/category-form.component';
|
|
||||||
import { Category } from './../../../../shared/models/category.interface';
|
|
||||||
import { DocumentClassificationsService } from './../../../../shared/services/administration/document-classifications.service';
|
|
||||||
import { Component, OnInit, Output, EventEmitter, Input, ViewChild } from '@angular/core';
|
|
||||||
import { FormBuilder } from '@angular/forms';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { DocumentClassification } from 'src/app/shared/models/document-classification.interface';
|
|
||||||
import { Page } from '../../../../shared/models/paging/page.interface';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-categories-search',
|
|
||||||
templateUrl: './categories-search.component.html',
|
|
||||||
styleUrls: ['./categories-search.component.scss']
|
|
||||||
})
|
|
||||||
export class CategoriesSearchComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() set paginationEventRequest(value: { page: number, offset: number }) {
|
|
||||||
|
|
||||||
// This setter may be called on page setup without arguments.
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._value = Object.assign(value);
|
|
||||||
this.search(value.page, value.offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input() set valueTableChange(results: any) {
|
|
||||||
if (results) {
|
|
||||||
this.search(this._value.page, this._value.offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Output() searchResults = new EventEmitter<Page<Category>>();
|
|
||||||
@Output() loading = new EventEmitter<boolean>();
|
|
||||||
@Output() searchInitiated = new EventEmitter<boolean>();
|
|
||||||
@Input() passChange: any;
|
|
||||||
|
|
||||||
@ViewChild(CategoryFormComponent)
|
|
||||||
private categoryForm: CategoryFormComponent;
|
|
||||||
_value: { page: number, offset: number };
|
|
||||||
lastSearchCriteria: { docClassificationId: number | string, categoryName: string, categoryCode: string };
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private authService: AuthService,
|
|
||||||
private errorHandlingService: ErrorHandlingService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.categoryForm.resetForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
searchButtonClicked() {
|
|
||||||
|
|
||||||
// Inform anyone interested there is a new search underway.
|
|
||||||
this.searchInitiated.emit(true);
|
|
||||||
|
|
||||||
// Remember the search for future pagination/whatever requests.
|
|
||||||
let categoryFormValue = this.categoryForm.formValue();
|
|
||||||
let docClassId = categoryFormValue.documentClassification ? categoryFormValue.documentClassification.classificationId : null;
|
|
||||||
let catName = categoryFormValue.categoryName;
|
|
||||||
let catCode = categoryFormValue.categoryCode;
|
|
||||||
|
|
||||||
this.lastSearchCriteria = {
|
|
||||||
docClassificationId: docClassId ? docClassId : '',
|
|
||||||
categoryName: catName ? catName : '',
|
|
||||||
categoryCode: catCode ? catCode : ''
|
|
||||||
};
|
|
||||||
|
|
||||||
// Then actually search.
|
|
||||||
this.search();
|
|
||||||
}
|
|
||||||
|
|
||||||
search(pageNumber = 0, pageSize = 10) {
|
|
||||||
this.loading.emit(true);
|
|
||||||
|
|
||||||
// A search may be issued by the paginationEventRequest setter upon setting up the page.
|
|
||||||
if (!this.lastSearchCriteria) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.categoriesService.searchByCriteriaPaged(pageNumber, pageSize, this.lastSearchCriteria, 'search').subscribe((results: Page<Category>) => {
|
|
||||||
this.searchResults.emit(results);
|
|
||||||
this.loading.emit(false);
|
|
||||||
},err => {
|
|
||||||
this.loading.emit(false);
|
|
||||||
this.errorHandlingService.showHttpResponseError(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canPreviewAllCategories(): boolean {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.H01, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
<p-dialog [header]="header"
|
|
||||||
[(visible)]="displayDialog"
|
|
||||||
[closable]="false"
|
|
||||||
[draggable]="false"
|
|
||||||
[modal]="true"
|
|
||||||
(onHide)="reset()"
|
|
||||||
(onShow)="onShow()"
|
|
||||||
appendTo="body">
|
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<app-category-form [dialogLayout]="true"
|
|
||||||
[requiredFields]="true"
|
|
||||||
[displayValidationMessagesEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-category-form>
|
|
||||||
</div>
|
|
||||||
<div class="p-grid p-nogutter p-jc-center">
|
|
||||||
<div class="p-formgroup-inline p-mt-3">
|
|
||||||
<p-button (onClick)="cancel()"
|
|
||||||
label="Cancel"
|
|
||||||
styleClass="p-mr-2 p-button-warning">
|
|
||||||
</p-button>
|
|
||||||
<p-button *ngIf="!categoryToEdit"
|
|
||||||
(onClick)="addCategory()"
|
|
||||||
label="Add"
|
|
||||||
styleClass="p-ml-2 p-mr-2 p-button-primary">
|
|
||||||
</p-button>
|
|
||||||
<p-button *ngIf="categoryToEdit && categoryToEdit.id"
|
|
||||||
(onClick)="editCategory()"
|
|
||||||
label="Update"
|
|
||||||
styleClass="p-ml-2 p-button-primary">
|
|
||||||
</p-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</p-dialog>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CreateCategoryDialogComponent } from './create-category-dialog.component';
|
|
||||||
|
|
||||||
describe('CreateCategoryComponent', () => {
|
|
||||||
let component: CreateCategoryDialogComponent;
|
|
||||||
let fixture: ComponentFixture<CreateCategoryDialogComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CreateCategoryDialogComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CreateCategoryDialogComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,86 +0,0 @@
|
||||||
import { CategoryFormComponent } from './../../forms/category-form/category-form.component';
|
|
||||||
import { Category } from './../../../../shared/models/category.interface';
|
|
||||||
import { CategoriesService } from '../../../../shared/services/administration/categories.service';
|
|
||||||
import { Component, Input, OnInit, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
||||||
import { NotificationsHandlingService } from 'src/app/shared/services/notifications-handling/notifications-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-create-category-dialog',
|
|
||||||
templateUrl: './create-category-dialog.component.html',
|
|
||||||
styleUrls: ['./create-category-dialog.component.scss']
|
|
||||||
})
|
|
||||||
export class CreateCategoryDialogComponent implements OnInit {
|
|
||||||
|
|
||||||
@ViewChild(CategoryFormComponent) private categoryForm: CategoryFormComponent;
|
|
||||||
@Input() displayDialog: boolean;
|
|
||||||
@Input() header: string;
|
|
||||||
@Input() categoryToEdit: Category;
|
|
||||||
@Output() cancelled = new EventEmitter<boolean>();
|
|
||||||
@Output() valueChange = new EventEmitter<any>();
|
|
||||||
|
|
||||||
displayValidationMessagesEvenIfPristine: boolean;
|
|
||||||
|
|
||||||
constructor(private categoriesService: CategoriesService,
|
|
||||||
private notificationHandling: NotificationsHandlingService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.reset(); // Make sure everything is cleanly initialised.
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = false;
|
|
||||||
this.categoryForm?.resetForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
// If a categoryToEdit was provided.
|
|
||||||
if (this.categoryToEdit) {
|
|
||||||
this.categoryForm.setValue(this.categoryToEdit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.cancelled.emit(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
addCategory() {
|
|
||||||
// If the form is not valid, make sure validator messages are displayed and then return without doing anything.
|
|
||||||
if (!this.categoryForm.isValid()) {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: What is returned from backend on create()??
|
|
||||||
this.categoriesService.createNewCategory(this.categoryForm.formValue()).subscribe(result => {
|
|
||||||
this.valueChange.emit(result);
|
|
||||||
this.notificationHandling.showCreateCategorySuccess();
|
|
||||||
this.cancel();
|
|
||||||
this.notificationHandling.showCreateNewCategorySuccess();
|
|
||||||
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
editCategory() {
|
|
||||||
// If the form is not valid, make sure validator messages are displayed and then return without doing anything.
|
|
||||||
if (!this.categoryForm.isValid()) {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: What is returned from backend on create()??
|
|
||||||
// TODO: It's to ugly having to provide the categoryId separately.
|
|
||||||
this.categoriesService.updateCategory(this.categoryForm.formValue()).subscribe(result => {
|
|
||||||
this.valueChange.emit(result);
|
|
||||||
this.cancel();
|
|
||||||
this.notificationHandling.showUpdateCategorySuccess();
|
|
||||||
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
<p-fieldset legend="Edit Value" [toggleable]="true">
|
|
||||||
<app-configurator-form [editableParameter]="editParameterRequestInput" (valueChange)="passValueChange($event)"></app-configurator-form>
|
|
||||||
</p-fieldset>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ConfiguratorEditValueComponent } from './configurator-edit-value.component';
|
|
||||||
|
|
||||||
describe('ConfiguratorEditValueComponent', () => {
|
|
||||||
let component: ConfiguratorEditValueComponent;
|
|
||||||
let fixture: ComponentFixture<ConfiguratorEditValueComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ConfiguratorEditValueComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ConfiguratorEditValueComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,28 +0,0 @@
|
||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
|
||||||
import {ConfiguratorParameter} from "../../../../shared/models/configurator-parameter.interface";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-configurator-edit-value',
|
|
||||||
templateUrl: './configurator-edit-value.component.html',
|
|
||||||
styleUrls: ['./configurator-edit-value.component.scss']
|
|
||||||
})
|
|
||||||
export class ConfiguratorEditValueComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() editParameterRequestInput: ConfiguratorParameter;
|
|
||||||
@Output() newConfiguratorParameter = new EventEmitter<ConfiguratorParameter>();
|
|
||||||
|
|
||||||
selectedParameter: ConfiguratorParameter = null;
|
|
||||||
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
console.log('editParameterRequestInput in edit: ' + JSON.stringify(this.editParameterRequestInput));
|
|
||||||
}
|
|
||||||
|
|
||||||
passValueChange(newConfigurator: ConfiguratorParameter) {
|
|
||||||
this.newConfiguratorParameter.emit(newConfigurator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<p-fieldset legend="List of Parameters" [toggleable]="true">
|
|
||||||
|
|
||||||
<p-table [value]="parametersListInput"
|
|
||||||
[lazy]="true"
|
|
||||||
[loading]="loadingInput"
|
|
||||||
[autoLayout]="true"
|
|
||||||
[rowHover]="true"
|
|
||||||
styleClass="p-datatable-gridlines"
|
|
||||||
[(selection)]="selectedParameterRequest"
|
|
||||||
(click)="passSelectedConfigurator(selectedParameterRequest)">
|
|
||||||
<ng-template pTemplate="header">
|
|
||||||
<tr>
|
|
||||||
<th style="width: 3rem"></th>
|
|
||||||
<th>Parameter Name</th>
|
|
||||||
<th>Parameter Type</th>
|
|
||||||
<th>Parameter Value </th>
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template pTemplate="body"
|
|
||||||
let-parameter>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p-tableRadioButton *ngIf="parameter.configurationVariable != 'CRON_EXPRESSION'" [value]="parameter"></p-tableRadioButton>
|
|
||||||
</td>
|
|
||||||
<td>{{parameter.configurationVariable}}</td>
|
|
||||||
<td>{{parameter.variableType}}</td>
|
|
||||||
<td>
|
|
||||||
<span *ngIf="parameter.variableType === 'Integer'" >{{parameter.integerValue}}<br></span>
|
|
||||||
<span *ngIf="parameter.variableType === 'String'" >{{parameter.stringValue}}<br></span>
|
|
||||||
</td>
|
|
||||||
<!-- <td *ngIf="parameter.variableType === 'Integer'">{{parameter.integerValue}}</td>
|
|
||||||
<td *ngIf="parameter.variableType === 'String'">{{parameter.stringValue}}</td> -->
|
|
||||||
<!-- Edit & Delete icons -->
|
|
||||||
</tr>
|
|
||||||
</ng-template>
|
|
||||||
</p-table>
|
|
||||||
|
|
||||||
</p-fieldset>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ConfiguratorListOfParametersComponent } from './configurator-list-of-parameters.component';
|
|
||||||
|
|
||||||
describe('ConfiguratorListOfParametersComponent', () => {
|
|
||||||
let component: ConfiguratorListOfParametersComponent;
|
|
||||||
let fixture: ComponentFixture<ConfiguratorListOfParametersComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ConfiguratorListOfParametersComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ConfiguratorListOfParametersComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,40 +0,0 @@
|
||||||
import {AfterViewChecked, AfterViewInit, Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
|
||||||
import {ConfiguratorParameter} from '../../../../shared/models/configurator-parameter.interface';
|
|
||||||
import {Page} from '../../../../shared/models/paging/page.interface';
|
|
||||||
import {LazyLoadEvent} from 'primeng/api';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-configurator-list-of-parameters',
|
|
||||||
templateUrl: './configurator-list-of-parameters.component.html',
|
|
||||||
styleUrls: ['./configurator-list-of-parameters.component.scss']
|
|
||||||
})
|
|
||||||
export class ConfiguratorListOfParametersComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() parametersListInput: ConfiguratorParameter[];
|
|
||||||
@Input() loadingInput: boolean;
|
|
||||||
@Output() editEventRequest = new EventEmitter<ConfiguratorParameter>();
|
|
||||||
|
|
||||||
editParameterRequest: ConfiguratorParameter;
|
|
||||||
parametersList: ConfiguratorParameter[];
|
|
||||||
selectedParameterRequest: ConfiguratorParameter;
|
|
||||||
totalRecords: number;
|
|
||||||
rows = 10;
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
const initParameter: ConfiguratorParameter = {
|
|
||||||
configurationId: null,
|
|
||||||
configurationVariable: null,
|
|
||||||
variableType: null,
|
|
||||||
integerValue: null,
|
|
||||||
stringValue: null
|
|
||||||
};
|
|
||||||
this.editEventRequest.emit(initParameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
passSelectedConfigurator(parameter: ConfiguratorParameter) {
|
|
||||||
this.editEventRequest.emit(parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<div class="p-col main-content">
|
|
||||||
|
|
||||||
<h1>{{'CONFIGURATOR' | translate}}</h1>
|
|
||||||
|
|
||||||
<app-horizontal-menu></app-horizontal-menu>
|
|
||||||
|
|
||||||
<app-breadcrumb></app-breadcrumb>
|
|
||||||
|
|
||||||
<div class="p-grid p-nogutter p-pt-5 p-pb-5">
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12">
|
|
||||||
<app-configurator-list-of-parameters [parametersListInput]="parametersList"
|
|
||||||
[loadingInput] = "loading"
|
|
||||||
(editEventRequest)="editEvent($event)">
|
|
||||||
</app-configurator-list-of-parameters>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col p-nogutter p-col-12 p-mt-5">
|
|
||||||
<app-configurator-edit-value [editParameterRequestInput]="editEventRequest" (newConfiguratorParameter)="passNewConfigurator($event)">
|
|
||||||
</app-configurator-edit-value>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ConfiguratorComponent } from './configurator.component';
|
|
||||||
|
|
||||||
describe('ConfiguratorComponent', () => {
|
|
||||||
let component: ConfiguratorComponent;
|
|
||||||
let fixture: ComponentFixture<ConfiguratorComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ConfiguratorComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ConfiguratorComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,51 +0,0 @@
|
||||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
import {ConfiguratorParameter} from '../../../shared/models/configurator-parameter.interface';
|
|
||||||
import {ConfiguratorService} from "../../../shared/services/administration/configurator.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-configurator',
|
|
||||||
templateUrl: './configurator.component.html',
|
|
||||||
styleUrls: ['./configurator.component.scss']
|
|
||||||
})
|
|
||||||
export class ConfiguratorComponent implements OnInit {
|
|
||||||
|
|
||||||
// @Input() parametersListInput: [ConfiguratorParameter];
|
|
||||||
// @Input() editParameterRequestInput: ConfiguratorParameter;
|
|
||||||
// @Output() editEventRequest = new EventEmitter<ConfiguratorParameter>();
|
|
||||||
|
|
||||||
parametersList: ConfiguratorParameter[];
|
|
||||||
editEventRequest: ConfiguratorParameter;
|
|
||||||
loading = true;
|
|
||||||
|
|
||||||
constructor(private configuratorService: ConfiguratorService, private errorHandlingService: ErrorHandlingService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
|
|
||||||
this.initData();
|
|
||||||
console.log('this.parametersList: ' + JSON.stringify(this.parametersList));
|
|
||||||
}
|
|
||||||
|
|
||||||
initData() {
|
|
||||||
this.loading = true;
|
|
||||||
this.configuratorService.getConfiguratorParameters().subscribe(values => {
|
|
||||||
this.parametersList = values;
|
|
||||||
this.loading = false;
|
|
||||||
console.log('IN this.parametersList: ' + JSON.stringify(this.parametersList));
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
this.errorHandlingService.showHttpResponseError(err);
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
editEvent(request) {
|
|
||||||
this.editEventRequest = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
passNewConfigurator(newConfigurator: ConfiguratorParameter){
|
|
||||||
this.initData();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
<div [formGroup]="searchCriteriaForm">
|
|
||||||
<div class="p-fluid p-grid">
|
|
||||||
|
|
||||||
<div class="p-col-12">
|
|
||||||
<div class="p-grid p-formgrid">
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="dateFrom">
|
|
||||||
Date From
|
|
||||||
</label>
|
|
||||||
<p-calendar id="dateFrom"
|
|
||||||
formControlName="dateFrom"
|
|
||||||
[maxDate]="searchCriteriaForm.get('dateFrom').value"
|
|
||||||
[readonlyInput]="false"
|
|
||||||
showButtonBar="true"
|
|
||||||
todayButtonStyleClass="p-button-set-today"
|
|
||||||
clearButtonStyleClass="p-button-clear-date"
|
|
||||||
[showIcon]="true"
|
|
||||||
dateFormat="dd/mm/yy">
|
|
||||||
</p-calendar>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="dateTo">
|
|
||||||
Date To
|
|
||||||
</label>
|
|
||||||
<p-calendar id="dateTo"
|
|
||||||
formControlName="dateTo"
|
|
||||||
showButtonBar="true"
|
|
||||||
[minDate]="searchCriteriaForm.get('dateTo').value"
|
|
||||||
[readonlyInput]="false"
|
|
||||||
todayButtonStyleClass="p-button-set-today"
|
|
||||||
clearButtonStyleClass="p-button-clear-date"
|
|
||||||
[showIcon]="true"
|
|
||||||
dateFormat="dd/mm/yy">
|
|
||||||
</p-calendar>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="clientName">
|
|
||||||
iPower Client Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="clientName"
|
|
||||||
formControlName="clientName"
|
|
||||||
[suggestions]="iPowerClientNameSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientName($event)"
|
|
||||||
(onSelect)="iPowerClientNameSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="clientId">
|
|
||||||
iPower Client Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="clientId"
|
|
||||||
formControlName="clientId"
|
|
||||||
[suggestions]="iPowerClientCodeSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientCode($event)"
|
|
||||||
(onSelect)="iPowerClientCodeSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-12">
|
|
||||||
<div class="p-grid p-formgrid">
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="processId">
|
|
||||||
Process Id
|
|
||||||
</label>
|
|
||||||
<input id="processId"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="processId">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="jobName">
|
|
||||||
Job Name
|
|
||||||
</label>
|
|
||||||
<input id="jobName"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="jobName">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-sm-6 p-lg-3">
|
|
||||||
<label for="dmsFileCode">
|
|
||||||
File Code
|
|
||||||
</label>
|
|
||||||
<input id="dmsFileCode"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="dmsFileCode">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ApplicationLevelFormComponent } from './application-level-form.component';
|
|
||||||
|
|
||||||
describe('ApplicationLevelFormComponent', () => {
|
|
||||||
let component: ApplicationLevelFormComponent;
|
|
||||||
let fixture: ComponentFixture<ApplicationLevelFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ApplicationLevelFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ApplicationLevelFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,111 +0,0 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { FormBuilder } from '@angular/forms';
|
|
||||||
import { IPowerClient } from 'src/app/shared/models/ipower-client.interface';
|
|
||||||
import { SearchSystemException} from 'src/app/shared/models/request/search-system-exceptions.interface';
|
|
||||||
import { IpowerClientsService } from 'src/app/shared/services/administration/ipower-clients.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-application-level-form',
|
|
||||||
templateUrl: './application-level-form.component.html',
|
|
||||||
styleUrls: ['./application-level-form.component.scss']
|
|
||||||
})
|
|
||||||
export class ApplicationLevelFormComponent implements OnInit {
|
|
||||||
|
|
||||||
iPowerClientNameSuggestions: any;
|
|
||||||
iPowerClientCodeSuggestions: any;
|
|
||||||
private iPowerClientSuggestions: IPowerClient[];
|
|
||||||
private selectedIPowerClient: IPowerClient;
|
|
||||||
|
|
||||||
searchCriteriaForm = this.fb.group({
|
|
||||||
processId: [null],
|
|
||||||
clientId: [null],
|
|
||||||
clientName: [null],
|
|
||||||
jobName: [null],
|
|
||||||
dmsFileCode: [null],
|
|
||||||
dateFrom: [null],
|
|
||||||
dateTo: [null],
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private fb: FormBuilder, private iPowerClientsService: IpowerClientsService) { }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public formValue(): SearchSystemException {
|
|
||||||
let formValue: SearchSystemException = {
|
|
||||||
processId: this.searchCriteriaForm.get('processId').value,
|
|
||||||
clientId: this.searchCriteriaForm.get('clientId').value,
|
|
||||||
jobName: this.searchCriteriaForm.get('jobName').value,
|
|
||||||
dmsFileCode: this.searchCriteriaForm.get('dmsFileCode').value,
|
|
||||||
dateFrom: this.searchCriteriaForm.get('dateFrom').value,
|
|
||||||
dateTo: this.searchCriteriaForm.get('dateTo').value
|
|
||||||
};
|
|
||||||
|
|
||||||
formValue.dateFrom = new Date(Date.UTC(formValue.dateFrom?.getFullYear(), formValue.dateFrom?.getMonth(), formValue.dateFrom?.getDate()));
|
|
||||||
formValue.dateTo = new Date(Date.UTC(formValue.dateTo?.getFullYear(), formValue.dateTo?.getMonth(),formValue.dateTo?.getDate() + 1));
|
|
||||||
formValue.dateTo?.setMilliseconds(formValue.dateTo?.getMilliseconds() -1);
|
|
||||||
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete IPower Client
|
|
||||||
*/
|
|
||||||
autosuggestIPowerClientName(event): void {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.iPowerClientNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByNameOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.name));
|
|
||||||
this.iPowerClientNameSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => console.error(err) // TODO: Handle this via a Messaging Service
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestIPowerClientCode(event): void {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.iPowerClientCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByCodeOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.clientCode));
|
|
||||||
this.iPowerClientCodeSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => console.error(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientNameSelected(name: string): void {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.name === name);
|
|
||||||
this.searchCriteriaForm.get('clientId').patchValue(this.selectedIPowerClient ? this.selectedIPowerClient.clientCode : '');
|
|
||||||
this.searchCriteriaForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientCodeSelected(code: string): void {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.clientCode === code);
|
|
||||||
this.searchCriteriaForm.get('clientName').patchValue(this.selectedIPowerClient ? this.selectedIPowerClient.name : '');
|
|
||||||
this.searchCriteriaForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
resetForm() {
|
|
||||||
this.searchCriteriaForm.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
<div [formGroup]="categoryForm">
|
|
||||||
<div class="p-fluid p-formgrid"
|
|
||||||
[ngClass]="{'p-grid': !dialogLayout}">
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="document-classification">
|
|
||||||
Document Classification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="document-classification"
|
|
||||||
[options]="documentClassificationsList"
|
|
||||||
optionLabel="classificationName"
|
|
||||||
placeholder="Select"
|
|
||||||
formControlName="documentClassification"
|
|
||||||
[showClear]="true">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="categoryForm.get('documentClassification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="categoryName">
|
|
||||||
Category Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="categoryName"
|
|
||||||
formControlName="categoryName"
|
|
||||||
*ngIf="autosuggestInputs"
|
|
||||||
[suggestions]="categoryNameSuggestions"
|
|
||||||
(completeMethod)="autosuggestCategoryName($event)"
|
|
||||||
(onSelect)="categoryNameSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
<input id="categoryName"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="categoryName"
|
|
||||||
*ngIf="!autosuggestInputs">
|
|
||||||
<app-validation-message [control]="categoryForm.get('categoryName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="categoryCode">
|
|
||||||
Category Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="categoryCode"
|
|
||||||
formControlName="categoryCode"
|
|
||||||
*ngIf="autosuggestInputs"
|
|
||||||
[suggestions]="categoryCodeSuggestions"
|
|
||||||
(completeMethod)="autosuggestCategoryCode($event)"
|
|
||||||
(onSelect)="categoryCodeSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
<input id="categoryCode"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="categoryCode"
|
|
||||||
*ngIf="!autosuggestInputs">
|
|
||||||
<app-validation-message [control]="categoryForm.get('categoryCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CategoryFormComponent } from './category-form.component';
|
|
||||||
|
|
||||||
describe('CategoryFormComponent', () => {
|
|
||||||
let component: CategoryFormComponent;
|
|
||||||
let fixture: ComponentFixture<CategoryFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CategoryFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CategoryFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,183 +0,0 @@
|
||||||
import { Category } from './../../../../shared/models/category.interface';
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { FormBuilder, Validators, FormGroup } from '@angular/forms';
|
|
||||||
import { DocumentClassification } from 'src/app/shared/models/document-classification.interface';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { DocumentClassificationsService } from 'src/app/shared/services/administration/document-classifications.service';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-category-form',
|
|
||||||
templateUrl: './category-form.component.html',
|
|
||||||
styleUrls: ['./category-form.component.scss']
|
|
||||||
})
|
|
||||||
export class CategoryFormComponent implements OnInit {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inputs
|
|
||||||
*/
|
|
||||||
@Input() dialogLayout: boolean = false; // Controls .scss classes to allow for better dispay in a dialog.
|
|
||||||
@Input() requiredFields: string[] | boolean = false; // True/False indicates that all/none are required. String[] specifies the form controls required.
|
|
||||||
@Input() displayValidationMessagesEvenIfPristine: boolean = false; // Serves for manually treating the controls as dirty.
|
|
||||||
@Input() autosuggestInputs: boolean = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reactive Form
|
|
||||||
*/
|
|
||||||
categoryForm = this.fb.group({
|
|
||||||
documentClassification: [null],
|
|
||||||
categoryName: [null],
|
|
||||||
categoryCode: [null]
|
|
||||||
});
|
|
||||||
|
|
||||||
setFormValue: Category = null;
|
|
||||||
selectedCategory: Category;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other Variables
|
|
||||||
*/
|
|
||||||
documentClassificationsList: DocumentClassification[];
|
|
||||||
|
|
||||||
categoryNameSuggestions: string[];
|
|
||||||
categoryCodeSuggestions: string[];
|
|
||||||
categorySuggestions: Category[];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constructor & Initialisers
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private documentClassificationsService: DocumentClassificationsService,
|
|
||||||
private errorHandlingService: ErrorHandlingService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initData();
|
|
||||||
this.initValidators()
|
|
||||||
}
|
|
||||||
|
|
||||||
initData() {
|
|
||||||
this.documentClassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentClassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Have this mechanism offer the use of custom validators too.
|
|
||||||
initValidators() {
|
|
||||||
|
|
||||||
if (!this.requiredFields) { return; }
|
|
||||||
|
|
||||||
// In a true/false case.
|
|
||||||
if (typeof this.requiredFields == 'boolean') {
|
|
||||||
// If true, enable the required validator for all controls and sub-controls.
|
|
||||||
if (this.requiredFields) {
|
|
||||||
this.setRequiredValidatorRecursively(this.categoryForm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If false, do nothing.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it was a string array, enable the validators for all provided field-names. TODO: This ONLY supports 1st level controls and not nested ones.
|
|
||||||
(<string[]>this.requiredFields).forEach(field => this.categoryForm.controls[field].setValidators(Validators.required))
|
|
||||||
}
|
|
||||||
|
|
||||||
setRequiredValidatorRecursively(group: FormGroup) {
|
|
||||||
Object.keys(group.controls).forEach(key => {
|
|
||||||
group.controls[key].setValidators(Validators.required);
|
|
||||||
|
|
||||||
if (group.controls[key]['controls']) {
|
|
||||||
this.setRequiredValidatorRecursively(<FormGroup>group.controls[key])
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete Category
|
|
||||||
*/
|
|
||||||
autosuggestCategoryName(event) {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.categoryNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.categoryForm.get('documentClassification').value ? this.categoryForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryName(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryName));
|
|
||||||
this.categoryNameSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestCategoryCode(event) {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.categoryCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.categoryForm.get('documentClassification').value ? this.categoryForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryCode(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryCode));
|
|
||||||
this.categoryCodeSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryNameSelected(name: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryName == name);
|
|
||||||
this.categoryForm.get('categoryCode').patchValue(this.selectedCategory.categoryCode);
|
|
||||||
this.categoryForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCodeSelected(code: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryCode == code);
|
|
||||||
this.categoryForm.get('categoryName').patchValue(this.selectedCategory.categoryName);
|
|
||||||
this.categoryForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API methods
|
|
||||||
*/
|
|
||||||
public resetForm(): void {
|
|
||||||
this.categoryForm.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public formValue(): Category {
|
|
||||||
let formValue: Category = {
|
|
||||||
id: this.setFormValue ? this.setFormValue.id : null,
|
|
||||||
documentClassification: this.categoryForm.get('documentClassification').value,
|
|
||||||
categoryName: this.categoryForm.get('categoryName').value,
|
|
||||||
categoryCode: this.categoryForm.get('categoryCode').value
|
|
||||||
};
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setValue(value: Category): void {
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setFormValue = value;
|
|
||||||
this.categoryForm.get('documentClassification').setValue(value.documentClassification);
|
|
||||||
this.categoryForm.get('categoryName').setValue(value.categoryName);
|
|
||||||
this.categoryForm.get('categoryCode').setValue(value.categoryCode);
|
|
||||||
this.categoryForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValid(): boolean {
|
|
||||||
return this.categoryForm.valid;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
<div [formGroup]="configuratorForm">
|
|
||||||
<div class="p-fluid p-formgrid"
|
|
||||||
[ngClass]="{'p-grid': !dialogLayout}">
|
|
||||||
|
|
||||||
<!-- Configurator Form - Start -->
|
|
||||||
<div class="p-field p-col-12"
|
|
||||||
[ngClass]="{'p-lg-4': !dialogLayout}">
|
|
||||||
<label for="parameterName">Parameter Name</label>
|
|
||||||
<input id="parameterName"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
disabled
|
|
||||||
formControlName="parameterName"
|
|
||||||
value="{{editableParameter?.configurationVariable}}">
|
|
||||||
<app-validation-message [control]="configuratorForm.get('parameterName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 "
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="parameterType">Parameter Type</label>
|
|
||||||
<input id="parameterType"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
disabled
|
|
||||||
formControlName="parameterType"
|
|
||||||
value="{{editableParameter?.variableType}}">
|
|
||||||
<app-validation-message [control]="configuratorForm.get('parameterType')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 "
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="parameterValue">Parameter Value</label>
|
|
||||||
<input id="parameterValue"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="parameterValue"
|
|
||||||
value="{{editableParameter?.variableType == 'Integer' ? editableParameter?.integerValue : editableParameter?.stringValue}}">
|
|
||||||
<app-validation-message [control]="configuratorForm.get('parameterValue')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-formgroup-inline p-jc-center p-mt-3">
|
|
||||||
<p-button (onClick)="updateButtonClicked()"
|
|
||||||
label="Update"
|
|
||||||
styleClass="p-button-primary"
|
|
||||||
[disabled]="!canEditParameterValue()">
|
|
||||||
</p-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ConfiguratorFormComponent } from './configurator-form.component';
|
|
||||||
|
|
||||||
describe('ConfiguratorFormComponent', () => {
|
|
||||||
let component: ConfiguratorFormComponent;
|
|
||||||
let fixture: ComponentFixture<ConfiguratorFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ConfiguratorFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ConfiguratorFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,69 +0,0 @@
|
||||||
import { AfterViewChecked, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { FormBuilder } from '@angular/forms';
|
|
||||||
import { ConfiguratorParameter } from '../../../../shared/models/configurator-parameter.interface';
|
|
||||||
import { ConfiguratorService } from "../../../../shared/services/administration/configurator.service";
|
|
||||||
import { Category } from "../../../../shared/models/category.interface";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { NotificationsHandlingService } from 'src/app/shared/services/notifications-handling/notifications-handling.service';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-configurator-form',
|
|
||||||
templateUrl: './configurator-form.component.html',
|
|
||||||
styleUrls: ['./configurator-form.component.scss']
|
|
||||||
})
|
|
||||||
export class ConfiguratorFormComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() dialogLayout: boolean = false; // Controls .scss classes to allow for better dispay in a dialog.
|
|
||||||
@Input() displayValidationMessagesEvenIfPristine: boolean = false; // Serves for manually treating the controls as dirty.
|
|
||||||
@Input() editableParameter: ConfiguratorParameter;
|
|
||||||
@Output() valueChange = new EventEmitter<ConfiguratorParameter>();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reactive Form
|
|
||||||
*/
|
|
||||||
configuratorForm = this.fb.group({
|
|
||||||
parameterName: null,
|
|
||||||
parameterType: null,
|
|
||||||
parameterValue: null
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private fb: FormBuilder, private configuratorService: ConfiguratorService, private router: Router, private notificationService: NotificationsHandlingService,
|
|
||||||
private authService: AuthService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
public formValue(): ConfiguratorParameter {
|
|
||||||
let formValue: ConfiguratorParameter = {
|
|
||||||
configurationId: this.editableParameter.configurationId,
|
|
||||||
configurationVariable: this.editableParameter.configurationVariable,
|
|
||||||
variableType: this.editableParameter.variableType,
|
|
||||||
integerValue: this.editableParameter.variableType === 'Integer' ? Number(this.configuratorForm.get('parameterValue').value) : null,
|
|
||||||
stringValue: this.editableParameter.variableType === 'String' ? String(this.configuratorForm.get('parameterValue').value) : null
|
|
||||||
};
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateButtonClicked(): void {
|
|
||||||
if (this.editableParameter.configurationId !== null) {
|
|
||||||
this.configuratorService.updateConfiguratorParameter(this.formValue()).subscribe(result => {
|
|
||||||
this.valueChange.emit(this.formValue());
|
|
||||||
this.notificationService.showUpdateConfiguratorParameterSuccess();
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
canEditParameterValue(): boolean {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.J01, environment.globalRightsClientID) && this.editableParameter.configurationVariable != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
<div [formGroup]="templateForm">
|
|
||||||
<div class="p-fluid p-formgrid"
|
|
||||||
[ngClass]="{'p-grid': !dialogLayout}">
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('documentClassification')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="documentClassification">
|
|
||||||
Document Classification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="documentClassification"
|
|
||||||
[options]="documentClassificationsList"
|
|
||||||
optionLabel="classificationName"
|
|
||||||
placeholder="Select"
|
|
||||||
formControlName="documentClassification"
|
|
||||||
(onChange)="documentClassificationSelected($event.value)"
|
|
||||||
[showClear]="true">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="templateForm.get('documentClassification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('categoryName')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="categoryName">
|
|
||||||
Category Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="categoryName"
|
|
||||||
formControlName="categoryName"
|
|
||||||
[suggestions]="categoryNameSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestCategoryName($event)"
|
|
||||||
(onSelect)="categoryNameSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="templateForm.get('categoryName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('categoryName')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="categoryCode">
|
|
||||||
Category Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="categoryCode"
|
|
||||||
formControlName="categoryCode"
|
|
||||||
[suggestions]="categoryCodeSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestCategoryCode($event)"
|
|
||||||
(onSelect)="categoryCodeSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="templateForm.get('categoryCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('iPowerClient')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="iPowerClientName">
|
|
||||||
iPower Client Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="iPowerClientName"
|
|
||||||
formControlName="iPowerClientName"
|
|
||||||
[suggestions]="iPowerClientNameSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientName($event)"
|
|
||||||
(onSelect)="iPowerClientNameSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="templateForm.get('iPowerClientName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('iPowerClient')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="iPowerClientCode">
|
|
||||||
iPower Client Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="iPowerClientCode"
|
|
||||||
formControlName="iPowerClientCode"
|
|
||||||
[suggestions]="iPowerClientCodeSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientCode($event)"
|
|
||||||
(onSelect)="iPowerClientCodeSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="templateForm.get('iPowerClientCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('documentSubclassification')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="documentSubclassification">
|
|
||||||
Sub-Category Name
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="documentSubclassification"
|
|
||||||
[options]="availableDocumentSubclassifications"
|
|
||||||
[disabled]="subCategoryCodeDisabled"
|
|
||||||
optionLabel="subclassificationName"
|
|
||||||
placeholder="Select a Document Classification first"
|
|
||||||
formControlName="documentSubclassification">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="templateForm.get('documentSubclassification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field"
|
|
||||||
*ngIf="!excludedFormControls?.includes('abbyyTemplateCode')"
|
|
||||||
[ngClass]="{'p-col-12 p-lg-4': !dialogLayout}">
|
|
||||||
<label for="abbyyTemplateCode"
|
|
||||||
>
|
|
||||||
ABBYY Template Code
|
|
||||||
</label>
|
|
||||||
<input id="abbyyTemplateCode"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="abbyyTemplateCode">
|
|
||||||
<app-validation-message [control]="templateForm.get('abbyyTemplateCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { TemplateFormComponent } from './template-form.component';
|
|
||||||
|
|
||||||
describe('TemplateFormComponent', () => {
|
|
||||||
let component: TemplateFormComponent;
|
|
||||||
let fixture: ComponentFixture<TemplateFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ TemplateFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(TemplateFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,369 +0,0 @@
|
||||||
import { DocumentClassification } from './../../../../shared/models/document-classification.interface';
|
|
||||||
import { Category } from './../../../../shared/models/category.interface';
|
|
||||||
import { DocumentSubclassificationsService } from './../../../../shared/services/administration/document-subclassifications.service';
|
|
||||||
import { DocumentSubclassification } from './../../../../shared/models/document-subclassification.interface';
|
|
||||||
import { IPowerClient } from './../../../../shared/models/ipower-client.interface';
|
|
||||||
import { Template } from './../../../../shared/models/template.interface';
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { FormBuilder, Validators } from '@angular/forms';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { DocumentClassificationsService } from 'src/app/shared/services/administration/document-classifications.service';
|
|
||||||
import { IpowerClientsService } from 'src/app/shared/services/administration/ipower-clients.service';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-template-form',
|
|
||||||
templateUrl: './template-form.component.html',
|
|
||||||
styleUrls: ['./template-form.component.scss']
|
|
||||||
})
|
|
||||||
export class TemplateFormComponent implements OnInit {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inputs
|
|
||||||
*/
|
|
||||||
@Input() dialogLayout: boolean = false; // Controls .scss classes to allow for better dispay in a dialog.
|
|
||||||
@Input() requiredFields: string[] | boolean = false; // True/False indicates that all/none are required. String[] specifies the form controls required.
|
|
||||||
@Input() displayValidationMessagesEvenIfPristine: boolean = false; // Serves for manually treating the controls as dirty.
|
|
||||||
@Input() excludedFormControls: string[]; // Specifies the form controls to be removed and NOT displayed.
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reactive Form
|
|
||||||
*/
|
|
||||||
templateForm = this.fb.group({
|
|
||||||
documentClassification: [null],
|
|
||||||
categoryName: [null],
|
|
||||||
categoryCode: [null],
|
|
||||||
iPowerClientName: [null],
|
|
||||||
iPowerClientCode: [null],
|
|
||||||
documentSubclassification: [null],
|
|
||||||
abbyyTemplateCode: [null]
|
|
||||||
});
|
|
||||||
initiallySetFormValue: Template;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other Variables
|
|
||||||
*/
|
|
||||||
documentClassificationsList: DocumentClassification[];
|
|
||||||
|
|
||||||
categoryNameSuggestions: string[];
|
|
||||||
categoryCodeSuggestions: string[];
|
|
||||||
categorySuggestions: Category[];
|
|
||||||
selectedCategory: Category;
|
|
||||||
|
|
||||||
iPowerClientNameSuggestions: string[];
|
|
||||||
iPowerClientCodeSuggestions: string[];
|
|
||||||
iPowerClientSuggestions: IPowerClient[];
|
|
||||||
selectedIPowerClient: IPowerClient;
|
|
||||||
|
|
||||||
documentSubclassificationsList: DocumentSubclassification[];
|
|
||||||
availableDocumentSubclassifications: DocumentSubclassification[];
|
|
||||||
subCategoryCodeDisabled: boolean = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constructor & Initialisers
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private documentClassificationsService: DocumentClassificationsService,
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private iPowerClientsService: IpowerClientsService,
|
|
||||||
private documentSubclassificationsService: DocumentSubclassificationsService,
|
|
||||||
private errorHandlingService: ErrorHandlingService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initData();
|
|
||||||
this.initValidators()
|
|
||||||
this.excludeFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
initData() {
|
|
||||||
this.documentClassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentClassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
|
|
||||||
// This is NOT the list of Subclassifications used for the dropdown.
|
|
||||||
this.documentSubclassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentSubclassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Have this mechanism offer the use of custom validators too.
|
|
||||||
initValidators() {
|
|
||||||
|
|
||||||
if (!this.requiredFields) { return; }
|
|
||||||
|
|
||||||
// In a true/false case.
|
|
||||||
if (typeof this.requiredFields == 'boolean') {
|
|
||||||
// If true, enable the required validator for all controls.
|
|
||||||
if (this.requiredFields) {
|
|
||||||
Object.keys(this.templateForm.controls).forEach(key => this.templateForm.controls[key].setValidators(Validators.required));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If false, do nothing.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it was a string array, enable the validators for all provided field-names.
|
|
||||||
(<string[]>this.requiredFields).forEach(field => this.templateForm.controls[field].setValidators(Validators.required))
|
|
||||||
}
|
|
||||||
|
|
||||||
excludeFields() {
|
|
||||||
if (!this.excludedFormControls) { return; }
|
|
||||||
this.excludedFormControls.forEach(field => this.templateForm.removeControl(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete Category
|
|
||||||
*/
|
|
||||||
autosuggestCategoryName(event) {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.categoryNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.templateForm.get('documentClassification').value ? this.templateForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryName(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryName));
|
|
||||||
this.categoryNameSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestCategoryCode(event) {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.categoryCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.templateForm.get('documentClassification').value ? this.templateForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryCode(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryCode));
|
|
||||||
this.categoryCodeSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryNameSelected(name: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryName == name);
|
|
||||||
this.templateForm.get('categoryCode')?.patchValue(this.selectedCategory.categoryCode);
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCodeSelected(code: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryCode == code);
|
|
||||||
this.templateForm.get('categoryName')?.patchValue(this.selectedCategory?.categoryName);
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete IPower Client
|
|
||||||
*/
|
|
||||||
autosuggestIPowerClientName(event): void {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.iPowerClientNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByNameOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.name));
|
|
||||||
this.iPowerClientNameSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestIPowerClientCode(event): void {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.iPowerClientCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByCodeOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.clientCode));
|
|
||||||
this.iPowerClientCodeSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientNameSelected(name: string) {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.name == name);
|
|
||||||
this.templateForm.get('iPowerClientCode')?.patchValue(this.selectedIPowerClient ? this.selectedIPowerClient.clientCode : '');
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientCodeSelected(code: string) {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.clientCode == code);
|
|
||||||
this.templateForm.get('iPowerClientName')?.patchValue(this.selectedIPowerClient ? this.selectedIPowerClient.name : '');
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other Methods
|
|
||||||
*/
|
|
||||||
documentClassificationSelected(selection: DocumentClassification) {
|
|
||||||
this.availableDocumentSubclassifications = this.documentSubclassificationsList.filter(element => element.documentClassification.classificationId == selection.classificationId);
|
|
||||||
this.templateForm.get('documentSubclassification')?.setValue(this.availableDocumentSubclassifications[0]); //TODO CHECK
|
|
||||||
this.subCategoryCodeDisabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility Methods
|
|
||||||
*/
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedCategory, otherwise truncate it.
|
|
||||||
syncSelectedCategory() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedCategory either way.
|
|
||||||
if (!this.templateForm.get('categoryName')?.value && !this.templateForm.get('categoryCode').value) {
|
|
||||||
this.selectedCategory = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedCategory's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedCategory.
|
|
||||||
if (
|
|
||||||
this.templateForm.get('categoryName')?.value == this.selectedCategory.categoryName
|
|
||||||
|| this.templateForm.get('categoryCode')?.value == this.selectedCategory.categoryCode
|
|
||||||
) {
|
|
||||||
this.selectedCategory.categoryName = this.templateForm.get('categoryName')?.value;
|
|
||||||
this.selectedCategory.categoryCode = this.templateForm.get('categoryCode')?.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedCategory's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedCategory()', 'Both of our form\'s values were different from the selectedCategory\'s.');
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.templateForm.get('categoryName')?.setValue('');
|
|
||||||
this.templateForm.get('categoryCode')?.setValue('');
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedIPowerClient, otherwise truncate it.
|
|
||||||
syncSelectedIPowerClient() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedIPowerClient either way.
|
|
||||||
if (!this.templateForm.get('iPowerClientName')?.value && !this.templateForm.get('iPowerClientCode')?.value) {
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedIPowerClient's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedIPowerClient.
|
|
||||||
if (
|
|
||||||
this.templateForm.get('iPowerClientName')?.value == this.selectedIPowerClient.name
|
|
||||||
|| this.templateForm.get('iPowerClientCode')?.value == this.selectedIPowerClient.clientCode
|
|
||||||
) {
|
|
||||||
this.selectedIPowerClient.name = this.templateForm.get('iPowerClientName')?.value;
|
|
||||||
this.selectedIPowerClient.clientCode = this.templateForm.get('iPowerClientCode')?.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedIPowerClient's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedIPowerClient()', 'Both of our form\'s values were different from the selectedIPowerClient\'s.');
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
this.templateForm.get('iPowerClientName')?.setValue('');
|
|
||||||
this.templateForm.get('iPowerClientCode')?.setValue('');
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API methods
|
|
||||||
*/
|
|
||||||
public resetForm(): void {
|
|
||||||
this.templateForm.reset();
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public formValue(): Template {
|
|
||||||
|
|
||||||
// A field ('documentSubclassification') may be excluded, so we have to check for that too.
|
|
||||||
let subCatCode = this.templateForm.get('documentSubclassification') ? this.templateForm.get('documentSubclassification').value : null;
|
|
||||||
let abbyy = this.templateForm.get('abbyyTemplateCode') ? this.templateForm.get('abbyyTemplateCode').value : null;
|
|
||||||
let docClass = this.templateForm.get('documentClassification') ? this.templateForm.get('documentClassification').value : null;
|
|
||||||
|
|
||||||
// We keep track of those two using object-variables separate from our ReactiveForm.
|
|
||||||
// Thus, we now have to make sure the ReactiveForm really has values that match those objects, before we forward them.
|
|
||||||
// Also, keep in mind that our auto-suggest inputs limit the user in choosing one of their values.
|
|
||||||
this.syncSelectedCategory();
|
|
||||||
this.syncSelectedIPowerClient();
|
|
||||||
|
|
||||||
let formValue: Template = {
|
|
||||||
id: this.initiallySetFormValue ? this.initiallySetFormValue.id : null,
|
|
||||||
category: this.selectedCategory,
|
|
||||||
subCategoryCode: subCatCode ? subCatCode.subclassificationName : '',
|
|
||||||
abbyyTemplate: abbyy,
|
|
||||||
client: this.selectedIPowerClient,
|
|
||||||
documentClassification: docClass
|
|
||||||
};
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setValue(value: Template): void {
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initiallySetFormValue = value;
|
|
||||||
|
|
||||||
// If a documentClassification is already selected, enable the subclassification dropdown.
|
|
||||||
this.subCategoryCodeDisabled = !value.documentClassification;
|
|
||||||
|
|
||||||
this.templateForm.get('documentClassification')?.setValue(value.documentClassification);
|
|
||||||
// Having set the documentClassification -and provided there was one- we must also set the availableDocumentSubclassifications.
|
|
||||||
this.availableDocumentSubclassifications = this.documentSubclassificationsList.filter(element =>
|
|
||||||
element.documentClassification.classificationId == value.documentClassification.classificationId
|
|
||||||
);
|
|
||||||
|
|
||||||
this.selectedCategory = value.category;
|
|
||||||
this.templateForm.get('categoryName')?.setValue(value.category.categoryName);
|
|
||||||
this.templateForm.get('categoryCode')?.setValue(value.category.categoryCode);
|
|
||||||
|
|
||||||
this.selectedIPowerClient = value.client;
|
|
||||||
this.templateForm.get('iPowerClientName')?.setValue(value.client.name);
|
|
||||||
this.templateForm.get('iPowerClientCode')?.setValue(value.client.clientCode);
|
|
||||||
|
|
||||||
this.templateForm.get('abbyyTemplateCode')?.setValue(value.abbyyTemplate);
|
|
||||||
|
|
||||||
// To set the subcategory/subclassification we also have to make sure the documentClassification is the same.
|
|
||||||
// WARNING: Since we have enabled the [forceSelection] option of the <p-autoComplete>,
|
|
||||||
// if the availableDocumentSubclassifications are not set, documentSubclassification won't be displayed.
|
|
||||||
this.templateForm.get('documentSubclassification').setValue(
|
|
||||||
this.documentSubclassificationsList.find(subClass => (
|
|
||||||
subClass.subclassificationName == value.subCategoryCode && subClass.documentClassification.classificationId == value.documentClassification.classificationId
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
this.templateForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValid(): boolean {
|
|
||||||
return this.templateForm.valid;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
import { JournalVerification } from './../../../../shared/models/journal-verification.interface';
|
|
||||||
import { CapturingVerification } from './../../../../shared/models/capturing-verification.interface';
|
|
||||||
import { Template } from 'src/app/shared/models/template.interface';
|
|
||||||
|
|
||||||
export interface CreateVerificationRuleFormValue {
|
|
||||||
id: number;
|
|
||||||
confidenceLevelMinThreshold: number;
|
|
||||||
clientId: string
|
|
||||||
categoryId: number;
|
|
||||||
subCategoryCode: string;
|
|
||||||
verificationRuleStatus: string;
|
|
||||||
capturingVerification: CapturingVerification;
|
|
||||||
journalVerification: JournalVerification;
|
|
||||||
alteryxRoutineId: string;
|
|
||||||
template: Template;
|
|
||||||
}
|
|
|
@ -1,200 +0,0 @@
|
||||||
<div [formGroup]="verificationRuleForm">
|
|
||||||
|
|
||||||
<div class="p-fluid"
|
|
||||||
[ngClass]="{'p-formgrid': !dialogLayout}">
|
|
||||||
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="document-classification">
|
|
||||||
Document Classification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="document-classification"
|
|
||||||
[options]="documentClassificationsList"
|
|
||||||
optionLabel="classificationName"
|
|
||||||
placeholder="Select"
|
|
||||||
formControlName="documentClassification"
|
|
||||||
[disabled]="editMode"
|
|
||||||
(onChange)="documentClassificationSelected($event)">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('documentClassification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="ipower-name">
|
|
||||||
iPower Client Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="ipower-name"
|
|
||||||
formControlName="ipowerName"
|
|
||||||
[suggestions]="iPowerClientNameSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientName($event)"
|
|
||||||
[disabled]="editMode"
|
|
||||||
(onSelect)="iPowerClientNameSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('ipowerName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="ipower-code">
|
|
||||||
iPower Client Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="ipower-code"
|
|
||||||
formControlName="ipowerCode"
|
|
||||||
[suggestions]="iPowerClientCodeSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestIPowerClientCode($event)"
|
|
||||||
[disabled]="editMode"
|
|
||||||
(onSelect)="iPowerClientCodeSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('ipowerCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="category-name">
|
|
||||||
Category Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="category-name"
|
|
||||||
formControlName="categoryName"
|
|
||||||
[suggestions]="categoryNameSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestCategoryName($event)"
|
|
||||||
[disabled]="editMode"
|
|
||||||
(onSelect)="categoryNameSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('categoryName')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="category-code">
|
|
||||||
Category Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="category-code"
|
|
||||||
formControlName="categoryCode"
|
|
||||||
[suggestions]="categoryCodeSuggestions"
|
|
||||||
[forceSelection]="true"
|
|
||||||
(completeMethod)="autosuggestCategoryCode($event)"
|
|
||||||
[disabled]="editMode"
|
|
||||||
(onSelect)="categoryCodeSelected($event)">
|
|
||||||
</p-autoComplete>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('categoryCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="document-subclassification">
|
|
||||||
Sub-Category Name
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="document-subclassification"
|
|
||||||
[options]="availableDocumentSubclassifications"
|
|
||||||
[disabled]="subCategoryCodeDisabled || editMode"
|
|
||||||
optionLabel="subclassificationName"
|
|
||||||
placeholder="Select a Document Classification first"
|
|
||||||
formControlName="subCategoryCode">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('subCategoryCode')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid"
|
|
||||||
[ngClass]="{'p-pt-4': (initiallySetFormValue && initiallySetFormValue.id)}">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="capturing-verification">
|
|
||||||
Capturing Verification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="capturing-verification"
|
|
||||||
formControlName="capturingVerification"
|
|
||||||
[options]="capturingVerificationsList"
|
|
||||||
optionLabel="capturingVerificationName"
|
|
||||||
placeholder="Select">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('capturingVerification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="journal-verification">
|
|
||||||
Journal Verification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="journal-verification"
|
|
||||||
formControlName="journalVerification"
|
|
||||||
[options]="journalVerificationsList"
|
|
||||||
optionLabel="journalVerificationName"
|
|
||||||
placeholder="Select">
|
|
||||||
</p-dropdown>
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('journalVerification')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="confidence-level">
|
|
||||||
Confidence Level
|
|
||||||
</label>
|
|
||||||
<input id="confidence-level"
|
|
||||||
type="number"
|
|
||||||
pInputText
|
|
||||||
formControlName="confidenceLevelMinThreshold">
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('confidenceLevelMinThreshold')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="alteryx-routine-id">
|
|
||||||
Alteryx Routine Name
|
|
||||||
</label>
|
|
||||||
<input id="alteryx-routine-id"
|
|
||||||
type="text"
|
|
||||||
pInputText
|
|
||||||
formControlName="alteryxRoutineId">
|
|
||||||
<app-validation-message [control]="verificationRuleForm.get('alteryxRoutineId')"
|
|
||||||
[validationMessage]="'This field is required.'"
|
|
||||||
[displayEvenIfPristine]="displayValidationMessagesEvenIfPristine">
|
|
||||||
</app-validation-message>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-grid p-jc-center" *ngIf="editMode">
|
|
||||||
<div class="p-field p-col-5 p-m-2">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-5 p-m-2">
|
|
||||||
<p-checkbox id="verification-rule-status" name="verification-rule-status"
|
|
||||||
[formControl]="verificationRuleForm.get('verificationRuleStatus')" binary="true" label="Rule Status"
|
|
||||||
[disabled]="!canEditRuleStatus()">
|
|
||||||
</p-checkbox>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { VerificationRuleFormComponent } from './verification-rule-form.component';
|
|
||||||
|
|
||||||
describe('VerificationRuleFormComponent', () => {
|
|
||||||
let component: VerificationRuleFormComponent;
|
|
||||||
let fixture: ComponentFixture<VerificationRuleFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ VerificationRuleFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(VerificationRuleFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,527 +0,0 @@
|
||||||
import { Right } from './../../../../shared/models/right.interface';
|
|
||||||
import { environment } from './../../../../../environments/environment';
|
|
||||||
import { USER_RIGHTS } from './../../../../shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { CreateVerificationRuleFormValue } from './create-verification-rule-form-value.interface';
|
|
||||||
import { JournalVerificationsService } from './../../../../shared/services/administration/journal-verifications.service';
|
|
||||||
import { CapturingVerificationsService } from './../../../../shared/services/administration/capturing-verifications.service';
|
|
||||||
import { DocumentSubclassificationsService } from 'src/app/shared/services/administration/document-subclassifications.service';
|
|
||||||
import { IpowerClientsService } from 'src/app/shared/services/administration/ipower-clients.service';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { DocumentClassificationsService } from 'src/app/shared/services/administration/document-classifications.service';
|
|
||||||
import { FormBuilder, Validators } from '@angular/forms';
|
|
||||||
import { DocumentSubclassification } from 'src/app/shared/models/document-subclassification.interface';
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { CapturingVerification } from '../../../../shared/models/capturing-verification.interface';
|
|
||||||
import { Category } from '../../../../shared/models/category.interface';
|
|
||||||
import { IPowerClient } from '../../../../shared/models/ipower-client.interface';
|
|
||||||
import { JournalVerification } from '../../../../shared/models/journal-verification.interface';
|
|
||||||
import { VerificationRule } from './../../../../shared/models/verification-rule.interface';
|
|
||||||
import { DocumentClassification } from '../../../../shared/models/document-classification.interface';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-verification-rule-form',
|
|
||||||
templateUrl: './verification-rule-form.component.html',
|
|
||||||
styleUrls: ['./verification-rule-form.component.scss']
|
|
||||||
})
|
|
||||||
export class VerificationRuleFormComponent implements OnInit {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inputs
|
|
||||||
*/
|
|
||||||
@Input() dialogLayout: boolean = false; // Controls .scss classes to allow for better dispay in a dialog.
|
|
||||||
@Input() requiredFields: string[] | boolean = false; // True/False indicates that all/none are required. String[] specifies the form controls required.
|
|
||||||
@Input() displayValidationMessagesEvenIfPristine: boolean = false; // Serves for manually treating the controls as dirty.
|
|
||||||
@Input() excludedFormControls: string[]; // Specifies the form controls to be removed and NOT displayed.
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reactive Form
|
|
||||||
*/
|
|
||||||
verificationRuleForm = this.fb.group({
|
|
||||||
documentClassification: [null],
|
|
||||||
ipowerName: [null],
|
|
||||||
ipowerCode: [null],
|
|
||||||
categoryName: [null],
|
|
||||||
categoryCode: [null],
|
|
||||||
subCategoryCode: [null], // This actually represents the complete DocumentSubclassification object.
|
|
||||||
confidenceLevelMinThreshold: [null],
|
|
||||||
capturingVerification: [null],
|
|
||||||
journalVerification: [null],
|
|
||||||
alteryxRoutineId: [null],
|
|
||||||
verificationRuleStatus: [true],
|
|
||||||
template: [null]
|
|
||||||
});
|
|
||||||
initiallySetFormValue: VerificationRule;
|
|
||||||
editMode: boolean = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other Variables
|
|
||||||
*/
|
|
||||||
documentClassificationsList: DocumentClassification[];
|
|
||||||
|
|
||||||
categoryNameSuggestions: string[];
|
|
||||||
categoryCodeSuggestions: string[];
|
|
||||||
categorySuggestions: Category[];
|
|
||||||
selectedCategory: Category;
|
|
||||||
|
|
||||||
iPowerClientNameSuggestions: string[];
|
|
||||||
iPowerClientCodeSuggestions: string[];
|
|
||||||
iPowerClientSuggestions: IPowerClient[];
|
|
||||||
selectedIPowerClient: IPowerClient;
|
|
||||||
|
|
||||||
capturingVerificationsList: CapturingVerification[];
|
|
||||||
journalVerificationsList: JournalVerification[];
|
|
||||||
|
|
||||||
documentSubclassificationsList: DocumentSubclassification[];
|
|
||||||
availableDocumentSubclassifications: DocumentSubclassification[];
|
|
||||||
subCategoryCodeDisabled: boolean = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constructor & Initialisers
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private documentClassificationsService: DocumentClassificationsService,
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private iPowerClientsService: IpowerClientsService,
|
|
||||||
private documentSubclassificationsService: DocumentSubclassificationsService,
|
|
||||||
private capturingVerificationsService: CapturingVerificationsService,
|
|
||||||
private journalVerificationsService: JournalVerificationsService,
|
|
||||||
private authService: AuthService,
|
|
||||||
private errorHandlingService: ErrorHandlingService
|
|
||||||
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initData();
|
|
||||||
this.initValidators()
|
|
||||||
this.excludeFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
initData() {
|
|
||||||
this.documentClassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentClassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
|
|
||||||
// This is NOT the list of Subclassifications used for the dropdown.
|
|
||||||
this.documentSubclassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentSubclassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.journalVerificationsService.getJournalVerifications().subscribe(
|
|
||||||
values => this.journalVerificationsList = values,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.capturingVerificationsService.getCapturingVerifications().subscribe(
|
|
||||||
values => this.capturingVerificationsList = values,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Have this mechanism offer the use of custom validators too.
|
|
||||||
initValidators() {
|
|
||||||
|
|
||||||
if (!this.requiredFields) { return; }
|
|
||||||
|
|
||||||
// In a true/false case.
|
|
||||||
if (typeof this.requiredFields == 'boolean') {
|
|
||||||
// If true, enable the required validator for all controls.
|
|
||||||
if (this.requiredFields) {
|
|
||||||
Object.keys(this.verificationRuleForm.controls).forEach(key => this.verificationRuleForm.controls[key].setValidators(Validators.required));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If false, do nothing.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it was a string array, enable the validators for all provided field-names.
|
|
||||||
(<string[]>this.requiredFields).forEach(field => this.verificationRuleForm.controls[field].setValidators(Validators.required))
|
|
||||||
}
|
|
||||||
|
|
||||||
excludeFields() {
|
|
||||||
if (!this.excludedFormControls) { return; }
|
|
||||||
this.excludedFormControls.forEach(field => this.verificationRuleForm.removeControl(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete Category
|
|
||||||
*/
|
|
||||||
autosuggestCategoryName(event) {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.categoryNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.verificationRuleForm.get('documentClassification').value ? this.verificationRuleForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryName(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryName));
|
|
||||||
this.categoryNameSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestCategoryCode(event) {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.categoryCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.verificationRuleForm.get('documentClassification').value ? this.verificationRuleForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryCode(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryCode));
|
|
||||||
this.categoryCodeSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryNameSelected(name: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryName == name);
|
|
||||||
this.verificationRuleForm.get('categoryCode').patchValue(this.selectedCategory.categoryCode);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCodeSelected(code: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryCode == code);
|
|
||||||
this.verificationRuleForm.get('categoryName').patchValue(this.selectedCategory.categoryName);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * Auto-suggest & Auto-complete IPower Client
|
|
||||||
// */
|
|
||||||
// /*
|
|
||||||
// * Rights-check Warning:
|
|
||||||
// * If we are NOT in editMode (and are thus on "addMode"), we should only suggest clients for which we actually CAN add a new rule.
|
|
||||||
// * Note:
|
|
||||||
// * I know that if on editMode the client-input is disabled and thus this check is redundant,
|
|
||||||
// * but I think it is better to work with as an abstract perspective as possible, not entailing business logic that may either be unrelated or prone to changes.
|
|
||||||
// */
|
|
||||||
// autosuggestIPowerClientName(event) {
|
|
||||||
|
|
||||||
// if (!event.query || event.query.length < 3) {
|
|
||||||
// this.iPowerClientNameSuggestions = [];
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If the user has the right to preview all rules (B01), we use the endpoint that returns all iPowerClients,
|
|
||||||
// // otherwise, the one that checks for the user's User_Access too. Whether the user can see ANY rule has already been handled by the 'search' button.
|
|
||||||
// let endpointToSubscribeTo: Observable<IPowerClient[]> = USER_RIGHTS.B01.isGrantedToUser(
|
|
||||||
// this.authService.userRights.find(rbc => rbc.client.id == environment.globalRightsClientID)?.rights
|
|
||||||
// )
|
|
||||||
// ? this.iPowerClientsService.getClientsByNameOnly(event.query)
|
|
||||||
// : this.iPowerClientsService.getClientsByNameDistinct(event.query);
|
|
||||||
|
|
||||||
// endpointToSubscribeTo.subscribe(
|
|
||||||
// (values: IPowerClient[]) => {
|
|
||||||
|
|
||||||
// // ***See comment at method level***
|
|
||||||
// if (!this.editMode) {
|
|
||||||
// values = values.filter(client => USER_RIGHTS.B03.isGrantedToUser(
|
|
||||||
// this.authService.userRights.find(rdc => rdc.client.id == client.id)?.rights
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let temp: string[] = [];
|
|
||||||
// this.iPowerClientSuggestions = values;
|
|
||||||
// values.map(val => temp.push(val.name));
|
|
||||||
// this.iPowerClientNameSuggestions = temp
|
|
||||||
// },
|
|
||||||
// err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * Rights-check Warning:
|
|
||||||
// * If we are NOT in editMode (and are thus on "addMode"), we should only suggest clients for which we actually CAN add a new rule.
|
|
||||||
// * Note:
|
|
||||||
// * I know that if on editMode the client-input is disabled and thus this check is redundant,
|
|
||||||
// * but I think it is better to work with as an abstract perspective as possible, not entailing business logic that may either be unrelated or prone to changes.
|
|
||||||
// */
|
|
||||||
// autosuggestIPowerClientCode(event) {
|
|
||||||
|
|
||||||
// if (event.query.length < 3) {
|
|
||||||
// this.iPowerClientCodeSuggestions = [];
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // If the user has the right to preview all rules (B01), we use the endpoint that returns all iPowerClients,
|
|
||||||
// // otherwise, the one that checks for the user's User_Access too. Whether the user can see ANY rule has already been handled by the 'search' button.
|
|
||||||
// let endpointToSubscribeTo: Observable<IPowerClient[]> = USER_RIGHTS.B01.isGrantedToUser(
|
|
||||||
// this.authService.userRights.find(rbc => rbc.client.id == environment.globalRightsClientID)?.rights
|
|
||||||
// )
|
|
||||||
// ? this.iPowerClientsService.getClientsByCodeOnly(event.query): null;
|
|
||||||
|
|
||||||
// endpointToSubscribeTo.subscribe(
|
|
||||||
// (values: IPowerClient[]) => {
|
|
||||||
|
|
||||||
// // ***See comment at method level***
|
|
||||||
// if (!this.editMode) {
|
|
||||||
// values = values;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let temp: string[] = [];
|
|
||||||
// this.iPowerClientSuggestions = values;
|
|
||||||
// values.map(val => temp.push(val.clientCode));
|
|
||||||
// this.iPowerClientCodeSuggestions = temp
|
|
||||||
// },
|
|
||||||
// err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete IPower Client
|
|
||||||
*/
|
|
||||||
autosuggestIPowerClientName(event): void {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.iPowerClientNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByNameOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.name));
|
|
||||||
this.iPowerClientNameSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestIPowerClientCode(event): void {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.iPowerClientCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.iPowerClientsService.getClientsByCodeOnly(event.query).subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.iPowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.clientCode));
|
|
||||||
this.iPowerClientCodeSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientNameSelected(name: string) {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.name == name);
|
|
||||||
this.verificationRuleForm.get('ipowerCode').patchValue(this.selectedIPowerClient.clientCode);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
iPowerClientCodeSelected(code: string) {
|
|
||||||
this.selectedIPowerClient = this.iPowerClientSuggestions.find(client => client.clientCode == code);
|
|
||||||
this.verificationRuleForm.get('ipowerName').patchValue(this.selectedIPowerClient.name);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Other Methods
|
|
||||||
*/
|
|
||||||
documentClassificationSelected(selection) {
|
|
||||||
this.availableDocumentSubclassifications = this.documentSubclassificationsList.filter(element => element.documentClassification.classificationId == selection.value.classificationId);
|
|
||||||
this.verificationRuleForm.get('subCategoryCode').setValue(this.availableDocumentSubclassifications[0]);
|
|
||||||
this.subCategoryCodeDisabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility Methods
|
|
||||||
*/
|
|
||||||
initiateEditMode() {
|
|
||||||
// let controlsToDisableInEditMode = ['documentClassification', 'ipowerName', 'ipowerCode', 'categoryName', 'categoryCode', 'subCategoryCode']
|
|
||||||
// controlsToDisableInEditMode.forEach(ctrl => this.verificationRuleForm.get(ctrl).disable());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedCategory, otherwise truncate it.
|
|
||||||
syncSelectedCategory() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedCategory either way.
|
|
||||||
if (!this.verificationRuleForm.get('categoryName').value && !this.verificationRuleForm.get('categoryCode').value) {
|
|
||||||
this.selectedCategory = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedCategory's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedCategory.
|
|
||||||
if (
|
|
||||||
this.verificationRuleForm.get('categoryName').value == this.selectedCategory.categoryName
|
|
||||||
|| this.verificationRuleForm.get('categoryCode').value == this.selectedCategory.categoryCode
|
|
||||||
) {
|
|
||||||
this.selectedCategory.categoryName = this.verificationRuleForm.get('categoryName').value;
|
|
||||||
this.selectedCategory.categoryCode = this.verificationRuleForm.get('categoryCode').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedCategory's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedCategory()', 'Both of our form\'s values were different from the selectedCategory\'s.');
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.verificationRuleForm.get('categoryName').setValue('');
|
|
||||||
this.verificationRuleForm.get('categoryCode').setValue('');
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedIPowerClient, otherwise truncate it.
|
|
||||||
syncSelectedIPowerClient() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedIPowerClient either way.
|
|
||||||
if (!this.verificationRuleForm.get('ipowerName').value && !this.verificationRuleForm.get('ipowerCode').value) {
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedIPowerClient's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedIPowerClient.
|
|
||||||
if (
|
|
||||||
this.verificationRuleForm.get('ipowerName').value == this.selectedIPowerClient.name
|
|
||||||
|| this.verificationRuleForm.get('ipowerCode').value == this.selectedIPowerClient.clientCode
|
|
||||||
) {
|
|
||||||
this.selectedIPowerClient.name = this.verificationRuleForm.get('ipowerName').value;
|
|
||||||
this.selectedIPowerClient.clientCode = this.verificationRuleForm.get('ipowerCode').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedIPowerClient's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedIPowerClient()', 'Both of our form\'s values were different from the selectedIPowerClient\'s.');
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
this.verificationRuleForm.get('ipowerName').setValue('');
|
|
||||||
this.verificationRuleForm.get('ipowerCode').setValue('');
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Rights-check Methods
|
|
||||||
*/
|
|
||||||
canEditRuleStatus(): boolean {
|
|
||||||
if (this.initiallySetFormValue) {
|
|
||||||
return this.authService.userHasRightForClient(USER_RIGHTS.B06, environment.globalRightsClientID);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// canEditConfidenceLevel(): boolean {
|
|
||||||
// if (this.initiallySetFormValue) {
|
|
||||||
// return this.authService.userHasRightForClient(USER_RIGHTS.B07, this.initiallySetFormValue.client.id);
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API methods
|
|
||||||
*/
|
|
||||||
public resetForm(): void {
|
|
||||||
this.verificationRuleForm.reset();
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
this.editMode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public formValue(): CreateVerificationRuleFormValue {
|
|
||||||
|
|
||||||
// We keep track of those two using object-variables separate from our ReactiveForm.
|
|
||||||
// Thus, we now have to make sure the ReactiveForm really has values that match those objects, before we forward them.
|
|
||||||
// Also, keep in mind that our auto-suggest inputs limit the user in choosing one of their values.
|
|
||||||
this.syncSelectedCategory();
|
|
||||||
this.syncSelectedIPowerClient();
|
|
||||||
|
|
||||||
let formValue: CreateVerificationRuleFormValue = {
|
|
||||||
id: this.initiallySetFormValue ? this.initiallySetFormValue.id : null,
|
|
||||||
confidenceLevelMinThreshold: this.verificationRuleForm.get('confidenceLevelMinThreshold').value,
|
|
||||||
clientId: this.selectedIPowerClient ? this.selectedIPowerClient.id : null,
|
|
||||||
categoryId: this.selectedCategory ? this.selectedCategory.id : null,
|
|
||||||
// The backend only requires the subcategory's name, and not the whole object. Don't ask me.
|
|
||||||
subCategoryCode: this.verificationRuleForm.get('subCategoryCode').value ? this.verificationRuleForm.get('subCategoryCode').value['subclassificationName'] : '',
|
|
||||||
capturingVerification: this.verificationRuleForm.get('capturingVerification').value,
|
|
||||||
journalVerification: this.verificationRuleForm.get('journalVerification').value,
|
|
||||||
alteryxRoutineId: this.verificationRuleForm.get('alteryxRoutineId').value,
|
|
||||||
template: this.verificationRuleForm.get('template').value,
|
|
||||||
|
|
||||||
// Convert 'verificationRuleStatus' from boolean to string.
|
|
||||||
verificationRuleStatus: this.verificationRuleForm.get('verificationRuleStatus').value ? 'Enabled' : 'Disabled'
|
|
||||||
};
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setValue(value: VerificationRule): void {
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.editMode = true;
|
|
||||||
this.initiateEditMode();
|
|
||||||
|
|
||||||
this.initiallySetFormValue = value
|
|
||||||
|
|
||||||
// If a documentClassification is already selected, enable the subclassification dropdown.
|
|
||||||
this.subCategoryCodeDisabled = !value.docClassificationCategory;
|
|
||||||
|
|
||||||
this.verificationRuleForm.get('documentClassification').setValue(value.docClassificationCategory);
|
|
||||||
// Having set the documentClassification -and provided there was one- we must also set the availableDocumentSubclassifications.
|
|
||||||
this.availableDocumentSubclassifications = this.documentSubclassificationsList.filter(element =>
|
|
||||||
element.documentClassification.classificationId == value.docClassificationCategory.classificationId
|
|
||||||
);
|
|
||||||
|
|
||||||
this.verificationRuleForm.get('ipowerName').setValue(value.client.name);
|
|
||||||
this.verificationRuleForm.get('ipowerCode').setValue(value.client.clientCode);
|
|
||||||
this.selectedIPowerClient = value.client;
|
|
||||||
|
|
||||||
this.verificationRuleForm.get('categoryName').setValue(value.template.category.categoryName);
|
|
||||||
this.verificationRuleForm.get('categoryCode').setValue(value.template.category.categoryCode);
|
|
||||||
this.selectedCategory = value.template.category;
|
|
||||||
|
|
||||||
this.verificationRuleForm.get('confidenceLevelMinThreshold').setValue(value.confidenceLevelMinThreshold);
|
|
||||||
this.verificationRuleForm.get('capturingVerification').setValue(value.capturingVerification);
|
|
||||||
this.verificationRuleForm.get('journalVerification').setValue(value.journalVerification);
|
|
||||||
this.verificationRuleForm.get('alteryxRoutineId').setValue(value.alteryxRoutineId);
|
|
||||||
this.verificationRuleForm.get('template').setValue(value.template);
|
|
||||||
|
|
||||||
// Convert 'verificationRuleStatus' from string to boolean.
|
|
||||||
this.verificationRuleForm.get('verificationRuleStatus').setValue(value.verificationRuleStatus.trim().toLowerCase() == 'enabled');
|
|
||||||
|
|
||||||
// To set the subcategory/subclassification we also have to make sure the documentClassification is the same.
|
|
||||||
// WARNING: Since we have enabled the [forceSelection] option of the <p-autoComplete>,
|
|
||||||
// if the availableDocumentSubclassifications are not set, documentSubclassification won't be displayed.
|
|
||||||
this.verificationRuleForm.get('subCategoryCode').setValue(
|
|
||||||
this.documentSubclassificationsList.find(subClass =>
|
|
||||||
subClass.subclassificationName == value.template.subCategoryCode && subClass.documentClassification.classificationId == value.docClassificationCategory.classificationId
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValid(): boolean {
|
|
||||||
return this.verificationRuleForm.valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public initForCreation() {
|
|
||||||
this.editMode = false;
|
|
||||||
this.verificationRuleForm.get('verificationRuleStatus').setValue(true); // The default value in creation mode.
|
|
||||||
this.verificationRuleForm.get('template').setValidators(null); // 'template' is not required during the creation.
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
export interface VerificationRuleSearchFormValue {
|
|
||||||
clientId: string;
|
|
||||||
categoryId: number;
|
|
||||||
docClassificationId: number;
|
|
||||||
docSubcategory: string;
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
<div [formGroup]="verificationRuleForm">
|
|
||||||
<div class="p-fluid p-grid">
|
|
||||||
|
|
||||||
<div class="p-col-12 p-lg-8">
|
|
||||||
<div class="p-grid p-formgrid">
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="ipower-name">
|
|
||||||
iPower Client Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="ipower-name"
|
|
||||||
formControlName="ipowerName"
|
|
||||||
[suggestions]="ipowerClientNameSuggestions"
|
|
||||||
(completeMethod)="autosuggestIPowerClientName($event)"
|
|
||||||
(onSelect)="ipowerClientNameSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="ipower-code">
|
|
||||||
iPower Client Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="ipower-code"
|
|
||||||
formControlName="ipowerCode"
|
|
||||||
[suggestions]="ipowerClientCodeSuggestions"
|
|
||||||
(completeMethod)="autosuggestIPowerClientCode($event)"
|
|
||||||
(onSelect)="ipowerClientCodeSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="category-name">
|
|
||||||
Category Name
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="category-name"
|
|
||||||
formControlName="categoryName"
|
|
||||||
[suggestions]="categoryNameSuggestions"
|
|
||||||
(completeMethod)="autosuggestCategoryName($event)"
|
|
||||||
(onSelect)="categoryNameSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12 p-lg-6">
|
|
||||||
<label for="category-code">
|
|
||||||
Category Code
|
|
||||||
</label>
|
|
||||||
<p-autoComplete id="category-code"
|
|
||||||
formControlName="categoryCode"
|
|
||||||
[suggestions]="categoryCodeSuggestions"
|
|
||||||
(completeMethod)="autosuggestCategoryCode($event)"
|
|
||||||
(onSelect)="categoryCodeSelected($event)"
|
|
||||||
[forceSelection]="true">
|
|
||||||
</p-autoComplete>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-12 p-lg-4">
|
|
||||||
<div class="p-grid p-formgrid">
|
|
||||||
<div class="p-field p-col-12">
|
|
||||||
<label for="document-classification">
|
|
||||||
Document Classification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="document-classification"
|
|
||||||
[options]="documentClassificationsList"
|
|
||||||
optionLabel="classificationName"
|
|
||||||
placeholder="Select"
|
|
||||||
formControlName="documentClassification"
|
|
||||||
(onChange)="documentClassificationSelected($event.value)"
|
|
||||||
[showClear]="true">
|
|
||||||
</p-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-12">
|
|
||||||
<label for="subCategoryCode">
|
|
||||||
Document Subclassification
|
|
||||||
</label>
|
|
||||||
<p-dropdown inputId="subCategoryCode"
|
|
||||||
[options]="availableDocumentSubclassifications"
|
|
||||||
optionLabel="subclassificationName"
|
|
||||||
placeholder="Select"
|
|
||||||
formControlName="subCategoryCode"
|
|
||||||
(onChange)="documentSubclassificationSelected($event.value)"
|
|
||||||
[showClear]="true">
|
|
||||||
</p-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { VerificationRuleSearchFormComponent } from './verification-rule-search-form.component';
|
|
||||||
|
|
||||||
describe('VerificationRuleSearchFormComponent', () => {
|
|
||||||
let component: VerificationRuleSearchFormComponent;
|
|
||||||
let fixture: ComponentFixture<VerificationRuleSearchFormComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ VerificationRuleSearchFormComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(VerificationRuleSearchFormComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,358 +0,0 @@
|
||||||
import { VerificationRulesService } from './../../../../shared/services/administration/verification-rules.service';
|
|
||||||
import { VerificationRule } from './../../../../shared/models/verification-rule.interface';
|
|
||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { AbstractControl, FormBuilder } from '@angular/forms';
|
|
||||||
import { Category } from 'src/app/shared/models/category.interface';
|
|
||||||
import { DocumentClassification } from 'src/app/shared/models/document-classification.interface';
|
|
||||||
import { DocumentSubclassification } from 'src/app/shared/models/document-subclassification.interface';
|
|
||||||
import { IPowerClient } from 'src/app/shared/models/ipower-client.interface';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { DocumentClassificationsService } from 'src/app/shared/services/administration/document-classifications.service';
|
|
||||||
import { DocumentSubclassificationsService } from 'src/app/shared/services/administration/document-subclassifications.service';
|
|
||||||
import { IpowerClientsService } from 'src/app/shared/services/administration/ipower-clients.service';
|
|
||||||
import { VerificationRuleSearchFormValue } from './verification-rule-search-form-value.interface';
|
|
||||||
import { ErrorHandlingService } from 'src/app/shared/services/error-handling/error-handling.service';
|
|
||||||
import { USER_RIGHTS } from 'src/app/shared/enums/USER_RIGHTS.enum';
|
|
||||||
import { AuthService } from 'src/app/shared/services/auth.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-verification-rule-search-form',
|
|
||||||
templateUrl: './verification-rule-search-form.component.html',
|
|
||||||
styleUrls: ['./verification-rule-search-form.component.scss']
|
|
||||||
})
|
|
||||||
export class VerificationRuleSearchFormComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() disabled: boolean = false;
|
|
||||||
|
|
||||||
documentClassificationsList: DocumentClassification[];
|
|
||||||
documentSubclassificationsList: DocumentSubclassification[];
|
|
||||||
availableDocumentSubclassifications: DocumentSubclassification[];
|
|
||||||
previouslySelectedClassificationId: number;
|
|
||||||
|
|
||||||
categoryNameSuggestions: string[];
|
|
||||||
categoryCodeSuggestions: string[];
|
|
||||||
categorySuggestions: Category[];
|
|
||||||
selectedCategory: Category = null;
|
|
||||||
|
|
||||||
ipowerClientNameSuggestions: string[];
|
|
||||||
ipowerClientCodeSuggestions: string[];
|
|
||||||
ipowerClientSuggestions: IPowerClient[];
|
|
||||||
selectedIPowerClient: IPowerClient = null;
|
|
||||||
|
|
||||||
displayValidationMessagesEvenIfPristine: boolean;
|
|
||||||
|
|
||||||
verificationRuleForm = this.fb.group({
|
|
||||||
ipowerName: [null],
|
|
||||||
ipowerCode: [null],
|
|
||||||
categoryName: [null],
|
|
||||||
categoryCode: [null],
|
|
||||||
documentClassification: [null],
|
|
||||||
subCategoryCode: [null] // This actually represents the complete DocumentSubclassification object.
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private documentClassificationsService: DocumentClassificationsService,
|
|
||||||
private documentSubclassificationsService: DocumentSubclassificationsService,
|
|
||||||
private verificationRulesService: VerificationRulesService,
|
|
||||||
private categoriesService: CategoriesService,
|
|
||||||
private ipowerClientsService: IpowerClientsService,
|
|
||||||
private errorHandlingService: ErrorHandlingService,
|
|
||||||
private authService: AuthService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
|
|
||||||
if (this.disabled) {
|
|
||||||
Object.keys(this.verificationRuleForm.controls).forEach(ctrl => this.verificationRuleForm.get(ctrl).disable());
|
|
||||||
return; // Don't even bother initialising or requesting anything.
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initData();
|
|
||||||
}
|
|
||||||
|
|
||||||
initData() {
|
|
||||||
this.documentClassificationsService.getAll().subscribe(
|
|
||||||
value => this.documentClassificationsList = value,
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
|
|
||||||
// This is NOT the list of Subclassifications used for the dropdown.
|
|
||||||
this.documentSubclassificationsService.getAll().subscribe(
|
|
||||||
value => {
|
|
||||||
this.documentSubclassificationsList = value;
|
|
||||||
this.availableDocumentSubclassifications = value;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.verificationRuleForm.reset();
|
|
||||||
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
documentClassificationSelected(selection: DocumentClassification) {
|
|
||||||
|
|
||||||
// If a different Classification has been selected, reset the Subclassification's value.
|
|
||||||
if (this.previouslySelectedClassificationId && selection.classificationId != this.previouslySelectedClassificationId) {
|
|
||||||
this.verificationRuleForm.get('subCategoryCode').reset();
|
|
||||||
}
|
|
||||||
this.previouslySelectedClassificationId = this.verificationRuleForm.get('documentClassification').value.classificationId;
|
|
||||||
|
|
||||||
this.availableDocumentSubclassifications = this.documentSubclassificationsList.filter(element => element.documentClassification.classificationId == selection.classificationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
documentSubclassificationSelected(selection: DocumentSubclassification) {
|
|
||||||
this.verificationRuleForm.get('documentClassification').setValue(selection.documentClassification);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest/complete Categories
|
|
||||||
*/
|
|
||||||
autosuggestCategoryName(event) {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.categoryNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.verificationRuleForm.get('documentClassification').value ? this.verificationRuleForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryName(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryName));
|
|
||||||
this.categoryNameSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autosuggestCategoryCode(event) {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.categoryCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classId = this.verificationRuleForm.get('documentClassification').value ? this.verificationRuleForm.get('documentClassification').value.classificationId : null;
|
|
||||||
this.categoriesService.autosuggestCategoryCode(event.query, classId).subscribe(
|
|
||||||
(values: Category[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.categorySuggestions = values;
|
|
||||||
values.map(val => temp.push(val.categoryCode));
|
|
||||||
this.categoryCodeSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryNameSelected(name: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryName == name);
|
|
||||||
this.verificationRuleForm.get('categoryCode').patchValue(this.selectedCategory.categoryCode);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCodeSelected(code: string) {
|
|
||||||
this.selectedCategory = this.categorySuggestions.find(cat => cat.categoryCode == code);
|
|
||||||
this.verificationRuleForm.get('categoryName').patchValue(this.selectedCategory.categoryName);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// * Auto-suggest/complete iPower Clients
|
|
||||||
// */
|
|
||||||
// autosuggestIPowerClientName(event) {
|
|
||||||
|
|
||||||
// if (!event.query || event.query.length < 3) {
|
|
||||||
// this.ipowerClientNameSuggestions = [];
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.ipowerClientsService.getClientsByNameDistinct(event.query).subscribe(
|
|
||||||
// (values: IPowerClient[]) => {
|
|
||||||
// let temp: string[] = [];
|
|
||||||
// this.ipowerClientSuggestions = values;
|
|
||||||
// values.map(val => temp.push(val.name));
|
|
||||||
// this.ipowerClientNameSuggestions = temp
|
|
||||||
// },
|
|
||||||
// err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// autosuggestIPowerClientCode(event) {
|
|
||||||
|
|
||||||
// if (!event.query || event.query.length < 3) {
|
|
||||||
// this.ipowerClientCodeSuggestions = [];
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.ipowerClientsService.getClientsByCodeDistinct(event.query).subscribe(
|
|
||||||
// (values: IPowerClient[]) => {
|
|
||||||
// let temp: string[] = [];
|
|
||||||
// this.ipowerClientSuggestions = values;
|
|
||||||
// values.map(val => temp.push(val.clientCode));
|
|
||||||
// this.ipowerClientCodeSuggestions = temp
|
|
||||||
// },
|
|
||||||
// err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
autosuggestIPowerClientCode(event) {
|
|
||||||
|
|
||||||
if (event.query.length < 3) {
|
|
||||||
this.ipowerClientCodeSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user has the right to Preview of Scheduling Procedure (A02), we use the endpoint that returns all iPowerClients,
|
|
||||||
// otherwise, the one that checks for the user's User_Access too. Whether the user can see ANY rule has already been handled by the 'search' button.
|
|
||||||
let endpointToSubscribeTo: Observable<IPowerClient[]> = this.authService.userHasRightForClient(USER_RIGHTS.B01, environment.globalRightsClientID)
|
|
||||||
? this.ipowerClientsService.getClientsByCodeOnly(event.query)
|
|
||||||
: this.authService.userRights.find(rdc => USER_RIGHTS.B02.isGrantedToUser(rdc.rights)) != null ? this.ipowerClientsService.getClientsByCodeDistinct(event.query) : null;
|
|
||||||
|
|
||||||
endpointToSubscribeTo.subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
let temp: string[] = [];
|
|
||||||
this.ipowerClientSuggestions = values;
|
|
||||||
values.map(val => temp.push(val.clientCode));
|
|
||||||
this.ipowerClientCodeSuggestions = temp
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auto-suggest & Auto-complete IPower Client
|
|
||||||
*/
|
|
||||||
autosuggestIPowerClientName(event): void {
|
|
||||||
|
|
||||||
if (!event.query || event.query.length < 3) {
|
|
||||||
this.ipowerClientNameSuggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user has the right to Preview of Scheduling Procedure (A02), we use the endpoint that returns all iPowerClients,
|
|
||||||
// otherwise, the one that checks for the user's User_Access too. Whether the user can see ANY rule has already been handled by the 'search' button.
|
|
||||||
let endpointToSubscribeTo: Observable<IPowerClient[]> = this.authService.userHasRightForClient(USER_RIGHTS.B01, environment.globalRightsClientID)
|
|
||||||
? this.ipowerClientsService.getClientsByNameOnly(event.query)
|
|
||||||
: this.authService.userRights.find(rdc => USER_RIGHTS.B02.isGrantedToUser(rdc.rights)) != null ? this.ipowerClientsService.getClientsByNameDistinct(event.query) : null;
|
|
||||||
|
|
||||||
endpointToSubscribeTo.subscribe(
|
|
||||||
(values: IPowerClient[]) => {
|
|
||||||
this.ipowerClientSuggestions = values;
|
|
||||||
|
|
||||||
const temp: string[] = [];
|
|
||||||
values.map(val => temp.push(val.name));
|
|
||||||
this.ipowerClientNameSuggestions = temp;
|
|
||||||
},
|
|
||||||
err => this.errorHandlingService.showHttpResponseError(err)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipowerClientNameSelected(name: string) {
|
|
||||||
this.selectedIPowerClient = this.ipowerClientSuggestions.find(client => client.name == name);
|
|
||||||
this.verificationRuleForm.get('ipowerCode').patchValue(this.selectedIPowerClient.clientCode);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
ipowerClientCodeSelected(code: string) {
|
|
||||||
this.selectedIPowerClient = this.ipowerClientSuggestions.find(client => client.clientCode == code);
|
|
||||||
this.verificationRuleForm.get('ipowerName').patchValue(this.selectedIPowerClient.name);
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Utility Methods
|
|
||||||
*/
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedCategory, otherwise truncate it.
|
|
||||||
syncSelectedCategory() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedCategory either way.
|
|
||||||
if (!this.verificationRuleForm.get('categoryName').value && !this.verificationRuleForm.get('categoryCode').value) {
|
|
||||||
this.selectedCategory = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedCategory's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedCategory.
|
|
||||||
if (
|
|
||||||
this.verificationRuleForm.get('categoryName').value == this.selectedCategory.categoryName
|
|
||||||
|| this.verificationRuleForm.get('categoryCode').value == this.selectedCategory.categoryCode
|
|
||||||
) {
|
|
||||||
this.selectedCategory.categoryName = this.verificationRuleForm.get('categoryName').value;
|
|
||||||
this.selectedCategory.categoryCode = this.verificationRuleForm.get('categoryCode').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedCategory's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedCategory()', 'Both of our form\'s values were different from the selectedCategory\'s.');
|
|
||||||
this.selectedCategory = null;
|
|
||||||
this.verificationRuleForm.get('categoryName').setValue('');
|
|
||||||
this.verificationRuleForm.get('categoryCode').setValue('');
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-suggest inputs - We have to ensure our reactive form holds values that represent the selectedIPowerClient, otherwise truncate it.
|
|
||||||
syncSelectedIPowerClient() {
|
|
||||||
|
|
||||||
// Ιf our form has no value, truncate the selectedIPowerClient either way.
|
|
||||||
if (!this.verificationRuleForm.get('ipowerName').value && !this.verificationRuleForm.get('ipowerCode').value) {
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both or either of our form's values match the selectedIPowerClient's and the other one doesn't have a value, all is good.
|
|
||||||
// Just sync the values in case one is missing. Otherwise truncate the selectedIPowerClient.
|
|
||||||
if (
|
|
||||||
this.verificationRuleForm.get('ipowerName').value == this.selectedIPowerClient.name
|
|
||||||
|| this.verificationRuleForm.get('ipowerCode').value == this.selectedIPowerClient.clientCode
|
|
||||||
) {
|
|
||||||
this.selectedIPowerClient.name = this.verificationRuleForm.get('ipowerName').value;
|
|
||||||
this.selectedIPowerClient.clientCode = this.verificationRuleForm.get('ipowerCode').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both our values were different from the selectedIPowerClient's, truncate it. This is an extremely abnormal scenario.
|
|
||||||
else {
|
|
||||||
console.error('WARNING - syncSelectedIPowerClient()', 'Both of our form\'s values were different from the selectedIPowerClient\'s.');
|
|
||||||
this.selectedIPowerClient = null;
|
|
||||||
this.verificationRuleForm.get('ipowerName').setValue('');
|
|
||||||
this.verificationRuleForm.get('ipowerCode').setValue('');
|
|
||||||
this.verificationRuleForm.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API methods
|
|
||||||
*/
|
|
||||||
public resetForm(): void {
|
|
||||||
this.verificationRuleForm.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Set type
|
|
||||||
public formValue(): VerificationRuleSearchFormValue {
|
|
||||||
|
|
||||||
this.syncSelectedCategory();
|
|
||||||
this.syncSelectedIPowerClient();
|
|
||||||
|
|
||||||
let formValue: VerificationRuleSearchFormValue = {
|
|
||||||
clientId: this.selectedIPowerClient ? this.selectedIPowerClient.id : '',
|
|
||||||
categoryId: this.selectedCategory ? this.selectedCategory.id : null,
|
|
||||||
docClassificationId: this.verificationRuleForm.get('documentClassification').value ? this.verificationRuleForm.get('documentClassification').value.classificationId : '',
|
|
||||||
// The backend only requires the subcategory's name, and not the whole object. Don't ask me.
|
|
||||||
docSubcategory: this.verificationRuleForm.get('subCategoryCode').value ? this.verificationRuleForm.get('subCategoryCode').value['subclassificationName'] : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
return formValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValid(): boolean {
|
|
||||||
return this.verificationRuleForm.valid;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
<p-dialog [header]= "header"
|
|
||||||
[(visible)]="displayDialog"
|
|
||||||
[closable]="false"
|
|
||||||
[draggable]="false"
|
|
||||||
[modal]="true"
|
|
||||||
(onHide)="reset()"
|
|
||||||
(onShow)="onShow()"
|
|
||||||
appendTo="body">
|
|
||||||
<div class="p-grid p-nogutter">
|
|
||||||
<app-template-form [dialogLayout]="true"></app-template-form>
|
|
||||||
</div>
|
|
||||||
<div class="p-grid p-nogutter p-jc-center">
|
|
||||||
<div class="p-formgroup-inline p-mt-3">
|
|
||||||
<p-button (onClick)="cancel()"
|
|
||||||
label="Cancel"
|
|
||||||
styleClass="p-mr-2 p-button-warning">
|
|
||||||
</p-button>
|
|
||||||
<p-button *ngIf="!templateToEdit"
|
|
||||||
(onClick)="addTemplate()"
|
|
||||||
label="Add"
|
|
||||||
styleClass="p-ml-2 p-mr-2 p-button-primary">
|
|
||||||
</p-button>
|
|
||||||
<p-button *ngIf="templateToEdit && templateToEdit.id"
|
|
||||||
(onClick)="editTemplate()"
|
|
||||||
label="Update"
|
|
||||||
styleClass="p-ml-2 p-button-primary">
|
|
||||||
</p-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</p-dialog>
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'src/styles';
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CreateTemplateDialogComponent } from './create-template-dialog.component';
|
|
||||||
|
|
||||||
describe('CreateTemplateDialogComponent', () => {
|
|
||||||
let component: CreateTemplateDialogComponent;
|
|
||||||
let fixture: ComponentFixture<CreateTemplateDialogComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CreateTemplateDialogComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CreateTemplateDialogComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,92 +0,0 @@
|
||||||
import { TemplateFormComponent } from './../../forms/template-form/template-form.component';
|
|
||||||
import { CategoriesService } from 'src/app/shared/services/administration/categories.service';
|
|
||||||
import { IpowerClientsService } from './../../../../shared/services/administration/ipower-clients.service';
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
|
||||||
import { FormBuilder, Validators } from '@angular/forms';
|
|
||||||
import { Category } from 'src/app/shared/models/category.interface';
|
|
||||||
import { DocumentClassification } from 'src/app/shared/models/document-classification.interface';
|
|
||||||
import { DocumentSubclassification } from 'src/app/shared/models/document-subclassification.interface';
|
|
||||||
import { IPowerClient } from 'src/app/shared/models/ipower-client.interface';
|
|
||||||
import { Template } from 'src/app/shared/models/template.interface';
|
|
||||||
import { DocumentClassificationsService } from 'src/app/shared/services/administration/document-classifications.service';
|
|
||||||
import { DocumentSubclassificationsService } from 'src/app/shared/services/administration/document-subclassifications.service';
|
|
||||||
import { TemplatesService } from 'src/app/shared/services/administration/templates.service';
|
|
||||||
import { NotificationsHandlingService } from 'src/app/shared/services/notifications-handling/notifications-handling.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-create-template-dialog',
|
|
||||||
templateUrl: './create-template-dialog.component.html',
|
|
||||||
styleUrls: ['./create-template-dialog.component.scss']
|
|
||||||
})
|
|
||||||
export class CreateTemplateDialogComponent implements OnInit {
|
|
||||||
|
|
||||||
@ViewChild(TemplateFormComponent) templateForm: TemplateFormComponent;
|
|
||||||
|
|
||||||
@Input() displayDialog: boolean;
|
|
||||||
@Input() header: string;
|
|
||||||
@Input() templateToEdit: Template;
|
|
||||||
@Output() cancelled = new EventEmitter<boolean>();
|
|
||||||
@Output() valueChange = new EventEmitter<any>();
|
|
||||||
|
|
||||||
displayValidationMessagesEvenIfPristine: boolean;
|
|
||||||
|
|
||||||
constructor(private templatesService: TemplatesService, private notificationService: NotificationsHandlingService) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.reset(); // Make sure everything is cleanly initialised.
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = false;
|
|
||||||
if (this.templateForm) {
|
|
||||||
this.templateForm.resetForm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
// If a categoryToEdit was provided.
|
|
||||||
if (this.templateToEdit) {
|
|
||||||
this.templateForm.setValue(this.templateToEdit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.cancelled.emit(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
addTemplate() {
|
|
||||||
// If the form is not valid, make sure validator messages are displayed and then return without doing anything.
|
|
||||||
if (!this.templateForm.isValid()) {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: What is returned from backend on create()??
|
|
||||||
this.templatesService.createNewTemplate(this.templateForm.formValue()).subscribe(result => {
|
|
||||||
this.valueChange.emit(result);
|
|
||||||
this.cancel();
|
|
||||||
this.notificationService.showCreateNewTemplateSuccess();
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
editTemplate() {
|
|
||||||
// If the form is not valid, make sure validator messages are displayed and then return without doing anything.
|
|
||||||
if (!this.templateForm.isValid()) {
|
|
||||||
this.displayValidationMessagesEvenIfPristine = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: What is returned from backend on create()??
|
|
||||||
this.templatesService.updateTemplate(this.templateForm.formValue()).subscribe(result => {
|
|
||||||
this.valueChange.emit(result);
|
|
||||||
this.cancel();
|
|
||||||
this.notificationService.showUpdateTemplateSuccess();
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue