uoa-repository-manager-service/app/features/administration/forms/verification-rule-search-form/verification-rule-search-fo...

359 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}