240 lines
8.5 KiB
TypeScript
240 lines
8.5 KiB
TypeScript
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;
|
|
|
|
private changesMade: boolean = false;
|
|
|
|
public comments = new Array<Annotation>();
|
|
public threads = new Set<Guid>();
|
|
public annotationsCount: number = 0;
|
|
public annotationsPerThread = {};
|
|
public showRepliesPerThread = {};
|
|
public replyEnabledPerThread = {};
|
|
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;
|
|
dialogRef.backdropClick().pipe(takeUntil(this._destroyed)).subscribe(() => dialogRef.close(this.changesMade));
|
|
}
|
|
|
|
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 => {
|
|
this.annotationsCount = data.count;
|
|
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.changesMade = true;
|
|
}
|
|
|
|
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(this.changesMade);
|
|
}
|
|
|
|
close() {
|
|
this.dialogRef.close(this.changesMade);
|
|
}
|
|
|
|
startWizard() {
|
|
this.router.navigate(['/plans/new']);
|
|
this.close();
|
|
}
|
|
|
|
showReplies(threadId: string): void {
|
|
this.showRepliesPerThread[threadId] = true;
|
|
}
|
|
|
|
enableReply(threadId: string): void {
|
|
this.replyEnabledPerThread[threadId] = true;
|
|
}
|
|
}
|