diff --git a/src-ui/src/app/app.component.html b/src-ui/src/app/app.component.html index d9b7dd09b..2b050ed3f 100644 --- a/src-ui/src/app/app.component.html +++ b/src-ui/src/app/app.component.html @@ -1,3 +1,13 @@ - + + +
+

Drop files to begin upload

+
+
+ +
+
+
diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index b21c771ae..f8c98fbc7 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -4,6 +4,8 @@ import { Router } from '@angular/router' import { Subscription } from 'rxjs' import { ConsumerStatusService } from './services/consumer-status.service' import { ToastService } from './services/toast.service' +import { NgxFileDropEntry } from 'ngx-file-drop' +import { UploadDocumentsService } from './services/upload-documents.service' @Component({ selector: 'app-root', @@ -15,11 +17,16 @@ export class AppComponent implements OnInit, OnDestroy { successSubscription: Subscription failedSubscription: Subscription + private fileLeaveTimeoutID: any + fileIsOver: boolean = false + hidden: boolean = true + constructor( private settings: SettingsService, private consumerStatusService: ConsumerStatusService, private toastService: ToastService, - private router: Router + private router: Router, + private uploadDocumentsService: UploadDocumentsService ) { let anyWindow = window as any anyWindow.pdfWorkerSrc = 'assets/js/pdf.worker.min.js' @@ -100,4 +107,36 @@ export class AppComponent implements OnInit, OnDestroy { } }) } + + public get dragDropEnabled(): boolean { + return !this.router.url.includes('dashboard') + } + + public fileOver() { + // allows transition + setTimeout(() => { + this.fileIsOver = true + }, 1) + this.hidden = false + // stop fileLeave timeout + clearTimeout(this.fileLeaveTimeoutID) + } + + public fileLeave(immediate: boolean = false) { + const ms = immediate ? 0 : 500 + + this.fileLeaveTimeoutID = setTimeout(() => { + this.fileIsOver = false + // await transition completed + setTimeout(() => { + this.hidden = true + }, 150) + }, ms) + } + + public dropped(files: NgxFileDropEntry[]) { + this.fileLeave(true) + this.uploadDocumentsService.uploadFiles(files) + this.toastService.showInfo($localize`Initiating upload...`, 3000) + } } diff --git a/src-ui/src/app/components/common/toasts/toasts.component.html b/src-ui/src/app/components/common/toasts/toasts.component.html index 9d4ae6bb6..b79208ebf 100644 --- a/src-ui/src/app/components/common/toasts/toasts.component.html +++ b/src-ui/src/app/components/common/toasts/toasts.component.html @@ -2,7 +2,7 @@ *ngFor="let toast of toasts" [header]="toast.title" [autohide]="true" [delay]="toast.delay" [class]="toast.classname" - (hide)="toastService.closeToast(toast)"> + (hidden)="toastService.closeToast(toast)">

{{toast.content}}

diff --git a/src-ui/src/app/components/common/toasts/toasts.component.scss b/src-ui/src/app/components/common/toasts/toasts.component.scss index 4d1c95fce..d2aaf20b0 100644 --- a/src-ui/src/app/components/common/toasts/toasts.component.scss +++ b/src-ui/src/app/components/common/toasts/toasts.component.scss @@ -5,3 +5,7 @@ margin: 0.5em; z-index: 1200; } + +.toast:not(.show) { + display: block; // this corrects an ng-bootstrap bug that prevented animations +} \ No newline at end of file diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss index c13a7bd47..47dbff83e 100644 --- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss +++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss @@ -33,3 +33,7 @@ form { mix-blend-mode: soft-light; pointer-events: none; } + +::ng-deep .ngx-file-drop__drop-zone--over { + background-color: var(--ngx-primary-faded) !important; +} diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts index 6ba6103d3..e2f59a0a4 100644 --- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts +++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts @@ -6,7 +6,7 @@ import { FileStatus, FileStatusPhase, } from 'src/app/services/consumer-status.service' -import { DocumentService } from 'src/app/services/rest/document.service' +import { UploadDocumentsService } from 'src/app/services/upload-documents.service' const MAX_ALERTS = 5 @@ -19,8 +19,8 @@ export class UploadFileWidgetComponent implements OnInit { alertsExpanded = false constructor( - private documentService: DocumentService, - private consumerStatusService: ConsumerStatusService + private consumerStatusService: ConsumerStatusService, + private uploadDocumentsService: UploadDocumentsService ) {} getStatus() { @@ -116,48 +116,6 @@ export class UploadFileWidgetComponent implements OnInit { public fileLeave(event) {} public dropped(files: NgxFileDropEntry[]) { - for (const droppedFile of files) { - if (droppedFile.fileEntry.isFile) { - const fileEntry = droppedFile.fileEntry as FileSystemFileEntry - fileEntry.file((file: File) => { - let formData = new FormData() - formData.append('document', file, file.name) - let status = this.consumerStatusService.newFileUpload(file.name) - - status.message = $localize`Connecting...` - - this.documentService.uploadDocument(formData).subscribe( - (event) => { - if (event.type == HttpEventType.UploadProgress) { - status.updateProgress( - FileStatusPhase.UPLOADING, - event.loaded, - event.total - ) - status.message = $localize`Uploading...` - } else if (event.type == HttpEventType.Response) { - status.taskId = event.body['task_id'] - status.message = $localize`Upload complete, waiting...` - } - }, - (error) => { - switch (error.status) { - case 400: { - this.consumerStatusService.fail(status, error.error.document) - break - } - default: { - this.consumerStatusService.fail( - status, - $localize`HTTP error: ${error.status} ${error.statusText}` - ) - break - } - } - } - ) - }) - } - } + this.uploadDocumentsService.uploadFiles(files) } } diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html index c7d53a848..1ce61f931 100644 --- a/src-ui/src/app/components/document-list/document-list.component.html +++ b/src-ui/src/app/components/document-list/document-list.component.html @@ -75,7 +75,7 @@ -
+
@@ -185,7 +185,7 @@ -
+
diff --git a/src-ui/src/app/components/document-list/document-list.component.scss b/src-ui/src/app/components/document-list/document-list.component.scss index 09bffc731..abac427da 100644 --- a/src-ui/src/app/components/document-list/document-list.component.scss +++ b/src-ui/src/app/components/document-list/document-list.component.scss @@ -1,5 +1,9 @@ @import "/src/theme"; +::ng-deep app-document-list app-page-header > div.mb-3 { + margin-bottom: 0 !important; +} + tr { user-select: none; } diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html index 61214d085..6280cff10 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.html @@ -50,7 +50,7 @@
-
+