Sending replies and new messages using the annotation dialog is now possible, displayed hierarchically as message threads, layout tweaks
This commit is contained in:
parent
1bdafbc9e6
commit
00815b4b80
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-12 mb-3 pt-2 gr-color" *ngIf="threads?.length > 0">{{'ANNOTATION-DIALOG.TITLE' | translate}}</div>
|
||||
<div class="col-12 mb-3 pt-2 gr-color" *ngIf="threads?.size > 0">{{'ANNOTATION-DIALOG.TITLE' | translate}}</div>
|
||||
<div class="col-12">
|
||||
<div *ngFor="let thread of threads" class="row">
|
||||
<!-- Parent Thread -->
|
||||
|
@ -43,12 +43,12 @@
|
|||
<div class="row reply-content">
|
||||
<div class="col-12">
|
||||
<div class="row h-100">
|
||||
<div class="col annotation-time">{{thread.timeStamp | date:'EEEE, MMMM d, y, h:mm a'}}</div>
|
||||
<div class="col-auto" *ngIf="thread.protectionType === annotationProtectionTypeEnum.Private" matTooltip="{{'ANNOTATION-DIALOG.PROTECTION.PRIVATE' | translate}}"><i class="material-icons protection-icon icon-{{getAnnotationProtectionType(thread)}}"></i>{{getAnnotationProtectionType(thread)}}</div>
|
||||
<div class="col-auto" *ngIf="thread.protectionType === annotationProtectionTypeEnum.EntityAccessors" matTooltip="{{'ANNOTATION-DIALOG.PROTECTION.ENTITY-ACCESSORS' | translate}}"><i class="material-icons protection-icon icon-{{getAnnotationProtectionType(thread)}}"></i>{{getAnnotationProtectionType(thread)}}</div>
|
||||
<div class="col-md-12 annotation-full-text">{{thread.payload}}</div>
|
||||
<div class="col-10 annotation-time">{{getParentAnnotation(thread).timeStamp | date:'EEEE, MMMM d, y, h:mm a'}}</div>
|
||||
<div class="col-auto" *ngIf="getParentAnnotation(thread).protectionType === annotationProtectionTypeEnum.Private" matTooltip="{{'ANNOTATION-DIALOG.PROTECTION.PRIVATE' | translate}}"><i class="material-icons protection-icon icon-{{getAnnotationProtectionType(thread)}}"></i>{{getAnnotationProtectionType(thread)}}</div>
|
||||
<div class="col-auto" *ngIf="getParentAnnotation(thread).protectionType === annotationProtectionTypeEnum.EntityAccessors" matTooltip="{{'ANNOTATION-DIALOG.PROTECTION.ENTITY-ACCESSORS' | translate}}"><i class="material-icons protection-icon icon-{{getAnnotationProtectionType(thread)}}"></i>{{getAnnotationProtectionType(thread)}}</div>
|
||||
<div class="col-md-12 annotation-full-text">{{getParentAnnotation(thread).payload}}</div>
|
||||
<div class="col-md-12">
|
||||
<em class="user">{{'ANNOTATION-DIALOG.THREADS.FROM-USER' | translate}} {{thread.author.name}}</em>
|
||||
<em class="user">{{'ANNOTATION-DIALOG.THREADS.FROM-USER' | translate}} {{getParentAnnotation(thread).author.name}}</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,10 +59,10 @@
|
|||
|
||||
<!-- Previous Replies -->
|
||||
<div class="col-12">
|
||||
<div *ngFor="let annotation of annotationsPerThread[thread.threadId]; let i = index;" class="row replies">
|
||||
<div *ngFor="let annotation of annotationsPerThread[thread]; let i = index;" class="row replies">
|
||||
<div class="col-auto pr-0">
|
||||
<div class="col reply child"></div>
|
||||
<div class="col reply child dummy-for-next-child" *ngIf="i != annotationsPerThread[thread.threadId].length - 1"></div>
|
||||
<div class="col reply child dummy-for-next-child" *ngIf="i != annotationsPerThread[thread].length - 1"></div>
|
||||
</div>
|
||||
<div class="col pl-0 pt-1">
|
||||
<div class="parent row m-0">
|
||||
|
@ -72,7 +72,7 @@
|
|||
<div class="col reply-content">
|
||||
<div class="row h-100">
|
||||
<div class="col-md-12 annotation-time">{{annotation.timeStamp | date:'EEEE, MMMM d, y, h:mm a'}}</div>
|
||||
<div class="col-md-12 annotation-full-text">{{annotation.text}}</div>
|
||||
<div class="col-md-12 annotation-full-text">{{annotation.payload}}</div>
|
||||
<div class="col-md-12">
|
||||
<em class="gr-color">{{'ANNOTATION-DIALOG.THREADS.FROM-USER' | translate}}</em>
|
||||
{{annotation.author.name}}
|
||||
|
@ -89,11 +89,11 @@
|
|||
<div class="col-12">
|
||||
<div class="row new-reply mr-0">
|
||||
<mat-form-field class="col pt-2 pb-2 pr-0">
|
||||
<textarea matInput matTextareaAutosize matAutosizeMinRows="1" [formControl]="this.threadReplyTextsFG[thread.id.toString()].get('replyText')" placeholder="{{'ANNOTATION-DIALOG.THREADS.REPLY' | translate}}"></textarea>
|
||||
<mat-error *ngIf="this.threadReplyTextsFG[thread.id.toString()]?.get('replyText')?.hasError('required')">{{'COMMONS.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
<textarea matInput matTextareaAutosize matAutosizeMinRows="1" [formControl]="this.threadReplyTextsFG[thread.toString()].get('replyText')" placeholder="{{'ANNOTATION-DIALOG.THREADS.REPLY' | translate}}"></textarea>
|
||||
<mat-error *ngIf="this.threadReplyTextsFG[thread.toString()]?.get('replyText')?.hasError('required')">{{'COMMONS.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<div class="col-auto send-msg">
|
||||
<button class="form-field-margin" mat-icon-button type="button" color="accent" (click)="replyThread(thread.threadId, thread.protectionType)" matTooltip="{{'ANNOTATION-DIALOG.THREADS.REPLY' | translate}}">
|
||||
<button class="form-field-margin" mat-icon-button type="button" color="accent" (click)="replyThread(thread)" matTooltip="{{'ANNOTATION-DIALOG.THREADS.REPLY' | translate}}">
|
||||
<i class="fa fa-paper-plane"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -30,10 +30,11 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
private entityId: Guid;
|
||||
private anchor: string;
|
||||
private entityType: string;
|
||||
// public annotations: Array<Annotation> = [];
|
||||
|
||||
public threads = new Array<Annotation>();
|
||||
public comments = new Array<Annotation>();
|
||||
public threads = new Set<Guid>();
|
||||
public annotationsPerThread = {};
|
||||
public parentAnnotationsPerThread = {};
|
||||
threadReplyTextsFG: Array<UntypedFormGroup>;
|
||||
threadFormGroup: UntypedFormGroup;
|
||||
private formBuilder: FormBuilder = new FormBuilder();
|
||||
|
@ -73,6 +74,7 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
return;
|
||||
}
|
||||
const threadToCreate: AnnotationPersist = {
|
||||
threadId: Guid.create(),
|
||||
payload: this.threadFormGroup.get('text').value,
|
||||
protectionType: this.threadFormGroup.get('protectionType').value,
|
||||
entityId: this.entityId,
|
||||
|
@ -86,7 +88,7 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
);
|
||||
}
|
||||
|
||||
replyThread(threadId: Guid, threadProtection: AnnotationProtectionType) {
|
||||
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()]);
|
||||
|
@ -96,10 +98,11 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
const replyToCreate: AnnotationPersist = {
|
||||
threadId: threadId,
|
||||
payload: this.threadReplyTextsFG[threadId.toString()].get('replyText').value,
|
||||
protectionType: threadProtection,
|
||||
protectionType: this.parentAnnotationsPerThread[threadId.toString()].protectionType,
|
||||
entityId: this.entityId,
|
||||
entityType: this.entityType,
|
||||
anchor: this.anchor
|
||||
anchor: this.anchor,
|
||||
parentId: this.parentAnnotationsPerThread[threadId.toString()].id
|
||||
};
|
||||
this.annotationService.persist(replyToCreate).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
|
@ -118,12 +121,13 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
private loadThreads() {
|
||||
const lookup: AnnotationLookup = new AnnotationLookup();
|
||||
lookup.entityIds = [this.entityId];
|
||||
// lookup.anchors = [this.anchor];
|
||||
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),
|
||||
|
@ -135,23 +139,33 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => {
|
||||
// this.annotationsPerThread = {};
|
||||
// this.threadReplyTextsFG = new Array<UntypedFormGroup>();
|
||||
// this.resetFormGroup();
|
||||
// this.threads = data.items.filter(item => item.id === item.threadId).sort((a1, a2) => new Date(a2.timeStamp).getTime() - new Date(a1.timeStamp).getTime());
|
||||
// this.threads.forEach(element => {
|
||||
// // this.threadReplyTextsFG.addControl(element.id.toString(), new FormControl(null));
|
||||
// this.threadReplyTextsFG[element.id.toString()] = this.fb.group({ replyText: new FormControl(null, [Validators.required]) });
|
||||
// this.annotationsPerThread[element.id.toString()] = data.items.filter(x => x.threadId === element.id && x.id !== element.id).sort((a1, a2) => new Date(a1.timeStamp).getTime() - new Date(a2.timeStamp).getTime());
|
||||
// });
|
||||
// // this.annotationsChanged.emit(this.threads);
|
||||
|
||||
this.threads = data.items;
|
||||
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.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);
|
||||
|
@ -181,8 +195,9 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
}
|
||||
|
||||
private onCallbackSuccess() {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('DMP-UPLOAD.UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success);
|
||||
this.router.navigate(['/reload']).then(() => this.router.navigate(['/plans']));
|
||||
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']));
|
||||
}
|
||||
|
||||
|
@ -191,8 +206,8 @@ export class AnnotationDialogComponent extends BaseComponent {
|
|||
}
|
||||
|
||||
|
||||
getAnnotationProtectionType(thread: Annotation): string {
|
||||
return this.enumUtils.toAnnotationProtectionTypeString(thread.protectionType);
|
||||
getAnnotationProtectionType(thread: Guid): string {
|
||||
return this.enumUtils.toAnnotationProtectionTypeString(this.parentAnnotationsPerThread[thread.toString()].protectionType);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
|
|||
const dialogRef = this.dialog.open(AnnotationDialogComponent, {
|
||||
width: '40rem',
|
||||
maxWidth: '90vw',
|
||||
maxHeight: '90vh',
|
||||
data: {
|
||||
entityId: this.descriptionId,
|
||||
anchor: fieldSetId,
|
||||
|
|
Loading…
Reference in New Issue