mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-07-09 05:25:10 +00:00
Sheesh more dialog hangers on
This commit is contained in:
+44
-10
@@ -4,7 +4,7 @@ import {
|
||||
moveItemInArray,
|
||||
} from '@angular/cdk/drag-drop'
|
||||
import { AsyncPipe } from '@angular/common'
|
||||
import { Component, OnInit, inject } from '@angular/core'
|
||||
import { Component, OnInit, inject, signal } from '@angular/core'
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
import { takeUntil } from 'rxjs'
|
||||
@@ -36,15 +36,47 @@ export class MergeConfirmDialogComponent
|
||||
private documentService = inject(DocumentService)
|
||||
private permissionService = inject(PermissionsService)
|
||||
|
||||
public documentIDs: number[] = []
|
||||
public archiveFallback: boolean = false
|
||||
public deleteOriginals: boolean = false
|
||||
private _documents: Document[] = []
|
||||
get documents(): Document[] {
|
||||
return this._documents
|
||||
private documentIDsSignal = signal<number[]>([])
|
||||
private archiveFallbackSignal = signal(false)
|
||||
private deleteOriginalsSignal = signal(false)
|
||||
private documentsSignal = signal<Document[]>([])
|
||||
private metadataDocumentIDSignal = signal(-1)
|
||||
|
||||
public get documentIDs(): number[] {
|
||||
return this.documentIDsSignal()
|
||||
}
|
||||
|
||||
public metadataDocumentID: number = -1
|
||||
public set documentIDs(documentIDs: number[]) {
|
||||
this.documentIDsSignal.set(documentIDs)
|
||||
}
|
||||
|
||||
public get archiveFallback(): boolean {
|
||||
return this.archiveFallbackSignal()
|
||||
}
|
||||
|
||||
public set archiveFallback(archiveFallback: boolean) {
|
||||
this.archiveFallbackSignal.set(archiveFallback)
|
||||
}
|
||||
|
||||
public get deleteOriginals(): boolean {
|
||||
return this.deleteOriginalsSignal()
|
||||
}
|
||||
|
||||
public set deleteOriginals(deleteOriginals: boolean) {
|
||||
this.deleteOriginalsSignal.set(deleteOriginals)
|
||||
}
|
||||
|
||||
get documents(): Document[] {
|
||||
return this.documentsSignal()
|
||||
}
|
||||
|
||||
public get metadataDocumentID(): number {
|
||||
return this.metadataDocumentIDSignal()
|
||||
}
|
||||
|
||||
public set metadataDocumentID(metadataDocumentID: number) {
|
||||
this.metadataDocumentIDSignal.set(metadataDocumentID)
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
@@ -55,12 +87,14 @@ export class MergeConfirmDialogComponent
|
||||
.getFew(this.documentIDs)
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe((r) => {
|
||||
this._documents = r.results
|
||||
this.documentsSignal.set(r.results)
|
||||
})
|
||||
}
|
||||
|
||||
onDrop(event: CdkDragDrop<number[]>) {
|
||||
moveItemInArray(this.documentIDs, event.previousIndex, event.currentIndex)
|
||||
const documentIDs = this.documentIDs.concat()
|
||||
moveItemInArray(documentIDs, event.previousIndex, event.currentIndex)
|
||||
this.documentIDs = documentIDs
|
||||
}
|
||||
|
||||
getDocument(documentID: number): Document {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, inject } from '@angular/core'
|
||||
import { Component, inject, signal } from '@angular/core'
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
const SYMBOLS = {
|
||||
@@ -20,9 +20,24 @@ const SYMBOLS = {
|
||||
})
|
||||
export class HotkeyDialogComponent {
|
||||
activeModal = inject(NgbActiveModal)
|
||||
private titleSignal = signal($localize`Keyboard shortcuts`)
|
||||
private hotkeysSignal = signal<Map<string, string>>(new Map())
|
||||
|
||||
public title: string = $localize`Keyboard shortcuts`
|
||||
public hotkeys: Map<string, string> = new Map()
|
||||
public get title(): string {
|
||||
return this.titleSignal()
|
||||
}
|
||||
|
||||
public set title(title: string) {
|
||||
this.titleSignal.set(title)
|
||||
}
|
||||
|
||||
public get hotkeys(): Map<string, string> {
|
||||
return this.hotkeysSignal()
|
||||
}
|
||||
|
||||
public set hotkeys(hotkeys: Map<string, string>) {
|
||||
this.hotkeysSignal.set(hotkeys)
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.activeModal.close()
|
||||
|
||||
+26
-9
@@ -1,6 +1,6 @@
|
||||
import { Clipboard } from '@angular/cdk/clipboard'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { Component, Input, inject } from '@angular/core'
|
||||
import { Component, Input, inject, signal } from '@angular/core'
|
||||
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
import { Document } from 'src/app/data/document'
|
||||
@@ -38,10 +38,27 @@ export class ShareLinkBundleDialogComponent extends ConfirmDialogComponent {
|
||||
private readonly clipboard = inject(Clipboard)
|
||||
private readonly toastService = inject(ToastService)
|
||||
|
||||
private _documents: Document[] = []
|
||||
private documentsSignal = signal<Document[]>([])
|
||||
private selectionCountSignal = signal(0)
|
||||
private documentPreviewSignal = signal<Document[]>([])
|
||||
private copiedSignal = signal(false)
|
||||
|
||||
get selectionCount(): number {
|
||||
return this.selectionCountSignal()
|
||||
}
|
||||
|
||||
get documentPreview(): Document[] {
|
||||
return this.documentPreviewSignal()
|
||||
}
|
||||
|
||||
get copied(): boolean {
|
||||
return this.copiedSignal()
|
||||
}
|
||||
|
||||
set copied(copied: boolean) {
|
||||
this.copiedSignal.set(copied)
|
||||
}
|
||||
|
||||
selectionCount = 0
|
||||
documentPreview: Document[] = []
|
||||
form: FormGroup = this.formBuilder.group({
|
||||
shareArchiveVersion: true,
|
||||
expirationDays: [7],
|
||||
@@ -51,7 +68,6 @@ export class ShareLinkBundleDialogComponent extends ConfirmDialogComponent {
|
||||
readonly expirationOptions = SHARE_LINK_EXPIRATION_OPTIONS
|
||||
|
||||
createdBundle: ShareLinkBundleSummary | null = null
|
||||
copied = false
|
||||
onOpenManage?: () => void
|
||||
readonly statuses = ShareLinkBundleStatus
|
||||
|
||||
@@ -64,15 +80,16 @@ export class ShareLinkBundleDialogComponent extends ConfirmDialogComponent {
|
||||
|
||||
@Input()
|
||||
set documents(docs: Document[]) {
|
||||
this._documents = docs.concat()
|
||||
this.selectionCount = this._documents.length
|
||||
this.documentPreview = this._documents.slice(0, 10)
|
||||
const documents = docs.concat()
|
||||
this.documentsSignal.set(documents)
|
||||
this.selectionCountSignal.set(documents.length)
|
||||
this.documentPreviewSignal.set(documents.slice(0, 10))
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.createdBundle) return
|
||||
this.payload = {
|
||||
document_ids: this._documents.map((doc) => doc.id),
|
||||
document_ids: this.documentsSignal().map((doc) => doc.id),
|
||||
file_version: this.form.value.shareArchiveVersion
|
||||
? FileVersion.Archive
|
||||
: FileVersion.Original,
|
||||
|
||||
+73
-21
@@ -1,5 +1,12 @@
|
||||
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'
|
||||
import { Component, OnDestroy, OnInit, inject } from '@angular/core'
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
inject,
|
||||
signal,
|
||||
} from '@angular/core'
|
||||
import {
|
||||
NgbActiveModal,
|
||||
NgbModalModule,
|
||||
@@ -50,15 +57,40 @@ export class SystemStatusDialogComponent implements OnInit, OnDestroy {
|
||||
|
||||
public SystemStatusItemStatus = SystemStatusItemStatus
|
||||
public PaperlessTaskType = PaperlessTaskType
|
||||
public status: SystemStatus
|
||||
private statusSignal = signal<SystemStatus>(undefined)
|
||||
public frontendVersion: string = environment.version
|
||||
public versionMismatch: boolean = false
|
||||
private versionMismatchSignal = signal(false)
|
||||
|
||||
public copied: boolean = false
|
||||
private copiedSignal = signal(false)
|
||||
|
||||
private runningTasks: Set<PaperlessTaskType> = new Set()
|
||||
private runningTasksSignal = signal<Set<PaperlessTaskType>>(new Set())
|
||||
private unsubscribeNotifier: Subject<any> = new Subject()
|
||||
|
||||
@Input()
|
||||
get status(): SystemStatus {
|
||||
return this.statusSignal()
|
||||
}
|
||||
|
||||
set status(status: SystemStatus) {
|
||||
this.statusSignal.set(status)
|
||||
}
|
||||
|
||||
get versionMismatch(): boolean {
|
||||
return this.versionMismatchSignal()
|
||||
}
|
||||
|
||||
set versionMismatch(versionMismatch: boolean) {
|
||||
this.versionMismatchSignal.set(versionMismatch)
|
||||
}
|
||||
|
||||
get copied(): boolean {
|
||||
return this.copiedSignal()
|
||||
}
|
||||
|
||||
set copied(copied: boolean) {
|
||||
this.copiedSignal.set(copied)
|
||||
}
|
||||
|
||||
get currentUserIsSuperUser(): boolean {
|
||||
return this.permissionsService.isSuperUser()
|
||||
}
|
||||
@@ -68,25 +100,23 @@ export class SystemStatusDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public ngOnInit() {
|
||||
const status = this.status
|
||||
this.versionMismatch =
|
||||
environment.production &&
|
||||
this.status.pngx_version &&
|
||||
status.pngx_version &&
|
||||
this.frontendVersion &&
|
||||
this.status.pngx_version !== this.frontendVersion
|
||||
status.pngx_version !== this.frontendVersion
|
||||
if (this.versionMismatch) {
|
||||
this.status.pngx_version = `${this.status.pngx_version} (frontend: ${this.frontendVersion})`
|
||||
this.status = {
|
||||
...status,
|
||||
pngx_version: `${status.pngx_version} (frontend: ${this.frontendVersion})`,
|
||||
}
|
||||
}
|
||||
this.status.websocket_connected = this.websocketStatusService.isConnected()
|
||||
? SystemStatusItemStatus.OK
|
||||
: SystemStatusItemStatus.ERROR
|
||||
this.updateWebsocketStatus(this.websocketStatusService.isConnected())
|
||||
this.websocketStatusService
|
||||
.onConnectionStatus()
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe((connected) => {
|
||||
this.status.websocket_connected = connected
|
||||
? SystemStatusItemStatus.OK
|
||||
: SystemStatusItemStatus.ERROR
|
||||
})
|
||||
.subscribe((connected) => this.updateWebsocketStatus(connected))
|
||||
}
|
||||
|
||||
public close() {
|
||||
@@ -108,23 +138,26 @@ export class SystemStatusDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public isRunning(taskName: PaperlessTaskType): boolean {
|
||||
return this.runningTasks.has(taskName)
|
||||
return this.runningTasksSignal().has(taskName)
|
||||
}
|
||||
|
||||
public runTask(taskName: PaperlessTaskType) {
|
||||
this.runningTasks.add(taskName)
|
||||
this.setTaskRunning(taskName, true)
|
||||
this.toastService.showInfo(`Task ${taskName} started`)
|
||||
this.tasksService.run(taskName).subscribe({
|
||||
next: () => {
|
||||
this.runningTasks.delete(taskName)
|
||||
this.setTaskRunning(taskName, false)
|
||||
this.systemStatusService.get().subscribe({
|
||||
next: (status) => {
|
||||
Object.assign(this.status, status)
|
||||
this.status = {
|
||||
...this.status,
|
||||
...status,
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
error: (err) => {
|
||||
this.runningTasks.delete(taskName)
|
||||
this.setTaskRunning(taskName, false)
|
||||
this.toastService.showError(
|
||||
`Failed to start task ${taskName}, see the logs for more details`,
|
||||
err
|
||||
@@ -133,6 +166,25 @@ export class SystemStatusDialogComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
}
|
||||
|
||||
private updateWebsocketStatus(connected: boolean): void {
|
||||
this.status = {
|
||||
...this.status,
|
||||
websocket_connected: connected
|
||||
? SystemStatusItemStatus.OK
|
||||
: SystemStatusItemStatus.ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
private setTaskRunning(taskName: PaperlessTaskType, running: boolean): void {
|
||||
const runningTasks = new Set(this.runningTasksSignal())
|
||||
if (running) {
|
||||
runningTasks.add(taskName)
|
||||
} else {
|
||||
runningTasks.delete(taskName)
|
||||
}
|
||||
this.runningTasksSignal.set(runningTasks)
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.unsubscribeNotifier.next(this)
|
||||
this.unsubscribeNotifier.complete()
|
||||
|
||||
+50
-12
@@ -1,5 +1,5 @@
|
||||
import { SlicePipe } from '@angular/common'
|
||||
import { Component, inject, Input, OnInit } from '@angular/core'
|
||||
import { Component, inject, Input, OnInit, signal } from '@angular/core'
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||
import {
|
||||
NgbActiveModal,
|
||||
@@ -36,15 +36,50 @@ export class ProcessedMailDialogComponent implements OnInit {
|
||||
private readonly processedMailService = inject(ProcessedMailService)
|
||||
private readonly toastService = inject(ToastService)
|
||||
|
||||
public processedMails: ProcessedMail[] = []
|
||||
private ruleSignal = signal<MailRule>(undefined)
|
||||
private processedMailsSignal = signal<ProcessedMail[]>([])
|
||||
private loadingSignal = signal(true)
|
||||
private toggleAllEnabledSignal = signal(false)
|
||||
private selectedMailIdsSignal = signal<Set<number>>(new Set())
|
||||
|
||||
public loading: boolean = true
|
||||
public toggleAllEnabled: boolean = false
|
||||
public readonly selectedMailIds: Set<number> = new Set<number>()
|
||||
public get processedMails(): ProcessedMail[] {
|
||||
return this.processedMailsSignal()
|
||||
}
|
||||
|
||||
public set processedMails(processedMails: ProcessedMail[]) {
|
||||
this.processedMailsSignal.set(processedMails)
|
||||
}
|
||||
|
||||
public get loading(): boolean {
|
||||
return this.loadingSignal()
|
||||
}
|
||||
|
||||
public set loading(loading: boolean) {
|
||||
this.loadingSignal.set(loading)
|
||||
}
|
||||
|
||||
public get toggleAllEnabled(): boolean {
|
||||
return this.toggleAllEnabledSignal()
|
||||
}
|
||||
|
||||
public set toggleAllEnabled(toggleAllEnabled: boolean) {
|
||||
this.toggleAllEnabledSignal.set(toggleAllEnabled)
|
||||
}
|
||||
|
||||
public get selectedMailIds(): Set<number> {
|
||||
return this.selectedMailIdsSignal()
|
||||
}
|
||||
|
||||
public page: number = 1
|
||||
|
||||
@Input() rule: MailRule
|
||||
@Input()
|
||||
get rule(): MailRule {
|
||||
return this.ruleSignal()
|
||||
}
|
||||
|
||||
set rule(rule: MailRule) {
|
||||
this.ruleSignal.set(rule)
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadProcessedMails()
|
||||
@@ -75,9 +110,10 @@ export class ProcessedMailDialogComponent implements OnInit {
|
||||
}
|
||||
|
||||
public toggleAll(event: PointerEvent) {
|
||||
const selectedMailIds = new Set<number>()
|
||||
if ((event.target as HTMLInputElement).checked) {
|
||||
this.selectedMailIds.clear()
|
||||
this.processedMails.forEach((mail) => this.selectedMailIds.add(mail.id))
|
||||
this.processedMails.forEach((mail) => selectedMailIds.add(mail.id))
|
||||
this.selectedMailIdsSignal.set(selectedMailIds)
|
||||
} else {
|
||||
this.clearSelection()
|
||||
}
|
||||
@@ -85,12 +121,14 @@ export class ProcessedMailDialogComponent implements OnInit {
|
||||
|
||||
public clearSelection() {
|
||||
this.toggleAllEnabled = false
|
||||
this.selectedMailIds.clear()
|
||||
this.selectedMailIdsSignal.set(new Set())
|
||||
}
|
||||
|
||||
public toggleSelected(mail: ProcessedMail) {
|
||||
this.selectedMailIds.has(mail.id)
|
||||
? this.selectedMailIds.delete(mail.id)
|
||||
: this.selectedMailIds.add(mail.id)
|
||||
const selectedMailIds = new Set(this.selectedMailIds)
|
||||
selectedMailIds.has(mail.id)
|
||||
? selectedMailIds.delete(mail.id)
|
||||
: selectedMailIds.add(mail.id)
|
||||
this.selectedMailIdsSignal.set(selectedMailIds)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user