argos/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts

233 lines
8.3 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { Component, Inject } from '@angular/core';
import { FormBuilder, FormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { Annotation, AnnotationPersist } from '@annotation-service/core/model/annotation.model';
import { AnnotationLookup } from '@annotation-service/core/query/annotation.lookup';
import { AnnotationService } from '@annotation-service/services/http/annotation.service';
import { AnnotationProtectionType } from '@app/core/common/enum/annotation-protection-type.enum';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { BaseComponent } from '@common/base/base.component';
import { FormService } from '@common/forms/form-service';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({
selector: 'app-annotation-dialog',
templateUrl: './annotation-dialog.component.html',
styleUrls: ['./annotation-dialog.component.scss']
})
export class AnnotationDialogComponent extends BaseComponent {
annotationProtectionTypeEnumValues = this.enumUtils.getEnumValues<AnnotationProtectionType>(AnnotationProtectionType);
annotationProtectionTypeEnum = AnnotationProtectionType;
private entityId: Guid;
private anchor: string;
private entityType: string;
public comments = new Array<Annotation>();
public threads = new Set<Guid>();
public annotationsPerThread = {};
public parentAnnotationsPerThread = {};
threadReplyTextsFG: Array<UntypedFormGroup>;
threadFormGroup: UntypedFormGroup;
private formBuilder: FormBuilder = new FormBuilder();
constructor(
public dialogRef: MatDialogRef<AnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
private router: Router,
public dialog: MatDialog,
private uiNotificationService: UiNotificationService,
private language: TranslateService,
private annotationService: AnnotationService,
private formService: FormService,
private enumUtils: EnumUtils
) {
super();
this.entityId = data.entityId;
this.anchor = data.anchor;
this.entityType = data.entityType;
}
ngOnInit(): void {
this.threadFormGroup = new UntypedFormGroup({
text: new FormControl(null, [Validators.required]),
protectionType: new FormControl(AnnotationProtectionType.EntityAccessors, [Validators.required])
});
if (this.entityId != null) {
this.loadThreads();
}
}
createThread() {
this.formService.removeAllBackEndErrors(this.threadFormGroup);
this.formService.touchAllFormFields(this.threadFormGroup);
if (!this.isFormValid(this.threadFormGroup)) {
return;
}
const threadToCreate: AnnotationPersist = {
threadId: Guid.create(),
payload: this.threadFormGroup.get('text').value,
protectionType: this.threadFormGroup.get('protectionType').value,
entityId: this.entityId,
entityType: this.entityType,
anchor: this.anchor
};
this.annotationService.persist(threadToCreate).pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(),
error => this.onCallbackError(error)
);
}
replyThread(threadId: Guid) {
// if (!this.threadReplyTexts[threadId.toString()] || this.threadReplyTexts[threadId.toString()].length === 0) { return; }
this.formService.removeAllBackEndErrors(this.threadReplyTextsFG[threadId.toString()]);
this.formService.touchAllFormFields(this.threadReplyTextsFG[threadId.toString()]);
if (!this.isFormValid(this.threadReplyTextsFG[threadId.toString()])) {
return;
}
const replyToCreate: AnnotationPersist = {
threadId: threadId,
payload: this.threadReplyTextsFG[threadId.toString()].get('replyText').value,
protectionType: this.parentAnnotationsPerThread[threadId.toString()].protectionType,
entityId: this.entityId,
entityType: this.entityType,
anchor: this.anchor,
parentId: this.parentAnnotationsPerThread[threadId.toString()].id
};
this.annotationService.persist(replyToCreate).pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCallbackSuccess(),
error => this.onCallbackError(error)
);
}
private refreshAnnotations() {
this.threadReplyTextsFG.forEach(element => {
element.reset();
});
this.loadThreads();
}
private loadThreads() {
const lookup: AnnotationLookup = new AnnotationLookup();
lookup.entityIds = [this.entityId];
lookup.anchors = [this.anchor];
lookup.entityTypes = [this.entityType];
lookup.project = {
fields: [
nameof<Annotation>(x => x.id),
nameof<Annotation>(x => x.threadId),
nameof<Annotation>(x => x.parent.id),
nameof<Annotation>(x => x.timeStamp),
nameof<Annotation>(x => x.author.name),
nameof<Annotation>(x => x.payload),
nameof<Annotation>(x => x.protectionType),
]
};
this.annotationService.query(lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(
data => {
console.log(data);
this.annotationsPerThread = {};
this.parentAnnotationsPerThread = {};
this.threads = new Set();
this.threadReplyTextsFG = new Array<UntypedFormGroup>();
this.resetFormGroup();
this.comments = data.items.sort((a1, a2) => new Date(a2.timeStamp).getTime() - new Date(a1.timeStamp).getTime());
this.comments.forEach(element => {
// this.threadReplyTextsFG.addControl(element.id.toString(), new FormControl(null));
this.threadReplyTextsFG[element.threadId.toString()] = this.formBuilder.group({ replyText: new FormControl(null, [Validators.required]) });
this.annotationsPerThread[element.threadId.toString()] = data.items.filter(x => x.threadId === element.threadId && x.id !== element.id).sort((a1, a2) => new Date(a1.timeStamp).getTime() - new Date(a2.timeStamp).getTime());
this.parentAnnotationsPerThread[element.threadId.toString()] = data.items.filter(x => x.threadId === element.threadId && x.id === element.id)[0];
this.threads.add(element.threadId);
});
console.log(this.parentAnnotationsPerThread);
// console.log(this.comments);
// console.log(this.threads);
// console.log(this.parentAnnotationsPerThread);
// console.log(this.annotationsPerThread);
// this.annotationsChanged.emit(this.threads);
},
error => this.onCallbackError(error),
);
}
getParentAnnotation(thread: Guid): Annotation {
return this.parentAnnotationsPerThread[thread.toString()];
}
resetFormGroup() {
this.threadFormGroup.reset();
this.threadFormGroup.get('protectionType').setValue(AnnotationProtectionType.EntityAccessors);
}
isValidText(text: string): boolean {
return !isNullOrUndefined(text) && text.length !== 0 && text !== '';
}
// ngOnInit() {
// const lookup: AnnotationLookup = new AnnotationLookup();
// lookup.entityIds = [this.entityId];
// // lookup.anchors = [this.anchor];
// lookup.entityTypes = [this.entityType];
// this.annotationService.query(lookup).pipe(takeUntil(this._destroyed))
// .subscribe(
// data => {
// this.annotations = data.items;
// },
// error => this.onCallbackError(error)
// );
// }
public isFormValid(value: any) {
return value.valid;
}
private onCallbackSuccess() {
this.uiNotificationService.snackBarNotification(this.language.instant('ANNOTATION-DIALOG.SUCCESS'), SnackBarNotificationLevel.Success);
this.refreshAnnotations();
// this.router.navigate(['/reload']).then(() => this.router.navigate(['/plans']));
// this.router.navigate(['/reload']).then(() => this.isPublic ? this.router.navigate(['/explore-plans']) : this.router.navigate(['/plans']));
}
private onCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
}
getAnnotationProtectionType(thread: Guid): string {
return this.enumUtils.toAnnotationProtectionTypeString(this.parentAnnotationsPerThread[thread.toString()].protectionType);
}
cancel() {
this.dialogRef.close();
}
send() {
this.dialogRef.close(this.data);
}
close() {
this.dialogRef.close(false);
}
startWizard() {
this.router.navigate(['/plans/new']);
this.close();
}
}