mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Merge pull request #1375 from tim-vogel/add_comments
Feature: document comments
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<div *ngIf="comments">
|
||||
<form [formGroup]="commentForm" class="needs-validation mt-3" novalidate>
|
||||
<div class="form-group">
|
||||
<textarea class="form-control form-control-sm" [class.is-invalid]="newCommentError" rows="3" formControlName="newComment" placeholder="Enter comment" i18n-placeholder required></textarea>
|
||||
<div class="invalid-feedback" i18n>
|
||||
Please enter a comment.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-2 d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-primary btn-sm" [disabled]="networkActive" (click)="addComment()" i18n>Add comment</button>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<div *ngFor="let comment of comments" class="card border mb-3">
|
||||
<div class="card-body text-dark">
|
||||
<p class="card-text">{{comment.comment}}</p>
|
||||
</div>
|
||||
<div class="d-flex card-footer small bg-light text-primary justify-content-between align-items-center">
|
||||
<span>{{displayName(comment)}} - {{ comment.created | customDate}}</span>
|
||||
<button type="button" class="btn btn-link btn-sm p-0 fade" (click)="deleteComment(comment.id)">
|
||||
<svg width="13" height="13" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#trash" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,9 @@
|
||||
.card-body {
|
||||
max-height: 12rem;
|
||||
overflow: scroll;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.card:hover .fade {
|
||||
opacity: 1;
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { DocumentCommentsService } from 'src/app/services/rest/document-comments.service'
|
||||
import { PaperlessDocumentComment } from 'src/app/data/paperless-document-comment'
|
||||
import { FormControl, FormGroup } from '@angular/forms'
|
||||
import { first } from 'rxjs/operators'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-comments',
|
||||
templateUrl: './document-comments.component.html',
|
||||
styleUrls: ['./document-comments.component.scss'],
|
||||
})
|
||||
export class DocumentCommentsComponent implements OnInit {
|
||||
commentForm: FormGroup = new FormGroup({
|
||||
newComment: new FormControl(''),
|
||||
})
|
||||
|
||||
networkActive = false
|
||||
comments: PaperlessDocumentComment[] = []
|
||||
newCommentError: boolean = false
|
||||
|
||||
@Input()
|
||||
documentId: number
|
||||
|
||||
constructor(
|
||||
private commentsService: DocumentCommentsService,
|
||||
private toastService: ToastService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.commentsService
|
||||
.getComments(this.documentId)
|
||||
.pipe(first())
|
||||
.subscribe((comments) => (this.comments = comments))
|
||||
}
|
||||
|
||||
addComment() {
|
||||
const comment: string = this.commentForm
|
||||
.get('newComment')
|
||||
.value.toString()
|
||||
.trim()
|
||||
if (comment.length == 0) {
|
||||
this.newCommentError = true
|
||||
return
|
||||
}
|
||||
this.newCommentError = false
|
||||
this.networkActive = true
|
||||
this.commentsService.addComment(this.documentId, comment).subscribe({
|
||||
next: (result) => {
|
||||
this.comments = result
|
||||
this.commentForm.get('newComment').reset()
|
||||
this.networkActive = false
|
||||
},
|
||||
error: (e) => {
|
||||
this.networkActive = false
|
||||
this.toastService.showError(
|
||||
$localize`Error saving comment: ${e.toString()}`
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
deleteComment(commentId: number) {
|
||||
this.commentsService.deleteComment(this.documentId, commentId).subscribe({
|
||||
next: (result) => {
|
||||
this.comments = result
|
||||
this.networkActive = false
|
||||
},
|
||||
error: (e) => {
|
||||
this.networkActive = false
|
||||
this.toastService.showError(
|
||||
$localize`Error deleting comment: ${e.toString()}`
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
displayName(comment: PaperlessDocumentComment): string {
|
||||
if (!comment.user) return ''
|
||||
let nameComponents = []
|
||||
if (comment.user.firstname) nameComponents.unshift(comment.user.firstname)
|
||||
if (comment.user.lastname) nameComponents.unshift(comment.user.lastname)
|
||||
if (comment.user.username) {
|
||||
if (nameComponents.length > 0)
|
||||
nameComponents.push(`(${comment.user.username})`)
|
||||
else nameComponents.push(comment.user.username)
|
||||
}
|
||||
return nameComponents.join(' ')
|
||||
}
|
||||
}
|
@@ -170,6 +170,12 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
</li>
|
||||
<li [ngbNavItem]="5" *ngIf="commentsEnabled">
|
||||
<a ngbNavLink i18n>Comments</a>
|
||||
<ng-template ngbNavContent>
|
||||
<app-document-comments [documentId]="documentId"></app-document-comments>
|
||||
</ng-template>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div [ngbNavOutlet]="nav" class="mt-2"></div>
|
||||
|
@@ -551,4 +551,8 @@ export class DocumentDetailComponent
|
||||
this.password = (event.target as HTMLInputElement).value
|
||||
}
|
||||
}
|
||||
|
||||
get commentsEnabled(): boolean {
|
||||
return this.settings.get(SETTINGS_KEYS.COMMENTS_ENABLED)
|
||||
}
|
||||
}
|
||||
|
@@ -125,6 +125,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4" i18n>Comments</h4>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="offset-md-3 col">
|
||||
<app-input-check i18n-title title="Enable comments" formControlName="commentsEnabled"></app-input-check>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-template>
|
||||
</li>
|
||||
|
||||
|
@@ -44,6 +44,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
notificationsConsumerSuccess: new FormControl(null),
|
||||
notificationsConsumerFailed: new FormControl(null),
|
||||
notificationsConsumerSuppressOnDashboard: new FormControl(null),
|
||||
commentsEnabled: new FormControl(null),
|
||||
})
|
||||
|
||||
savedViews: PaperlessSavedView[]
|
||||
@@ -116,6 +117,7 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
notificationsConsumerSuppressOnDashboard: this.settings.get(
|
||||
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD
|
||||
),
|
||||
commentsEnabled: this.settings.get(SETTINGS_KEYS.COMMENTS_ENABLED),
|
||||
}
|
||||
|
||||
for (let view of this.savedViews) {
|
||||
@@ -234,6 +236,10 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD,
|
||||
this.settingsForm.value.notificationsConsumerSuppressOnDashboard
|
||||
)
|
||||
this.settings.set(
|
||||
SETTINGS_KEYS.COMMENTS_ENABLED,
|
||||
this.settingsForm.value.commentsEnabled
|
||||
)
|
||||
this.settings.setLanguage(this.settingsForm.value.displayLanguage)
|
||||
this.settings
|
||||
.storeSettings()
|
||||
|
Reference in New Issue
Block a user