diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.html b/src-ui/src/app/components/common/preview-popup/preview-popup.component.html index f9a8b9771..fc4daba8f 100644 --- a/src-ui/src/app/components/common/preview-popup/preview-popup.component.html +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.html @@ -1,30 +1,37 @@ -
- @if (error) { -
-

Error loading preview

-
- } @else { - @if (renderAsObject) { - @if (previewText) { -
{{previewText}}
- } @else { - - } + + + + +
+ @if (error) { +
+

Error loading preview

+
} @else { - @if (requiresPassword) { -
- -
- } - @if (!requiresPassword) { - - + @if (renderAsObject) { + @if (previewText) { +
{{previewText}}
+ } @else { + + } + } @else { + @if (requiresPassword) { +
+ +
+ } + @if (!requiresPassword) { + + + } } } - } -
+
+ diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts b/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts index 2b9f71cef..15ee10833 100644 --- a/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.spec.ts @@ -1,4 +1,9 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing' +import { + ComponentFixture, + fakeAsync, + TestBed, + tick, +} from '@angular/core/testing' import { PreviewPopupComponent } from './preview-popup.component' import { By } from '@angular/platform-browser' @@ -122,4 +127,19 @@ describe('PreviewPopupComponent', () => { component.init() expect(component.previewText).toEqual('Preview text') }) + + it('should show preview on mouseover after delay to preload content', fakeAsync(() => { + component.mouseEnterPreview() + expect(component.popover.isOpen()).toBeTruthy() + expect(component.popoverHidden).toBeTruthy() + tick(600) + expect(component.popoverHidden).toBeFalsy() + component.close() + + component.mouseEnterPreview() + tick(100) + component.mouseLeavePreview() + tick(600) + expect(component.popover.isOpen()).toBeFalsy() + })) }) diff --git a/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts b/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts index 6d2ede266..bac2c0121 100644 --- a/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts +++ b/src-ui/src/app/components/common/preview-popup/preview-popup.component.ts @@ -1,5 +1,6 @@ import { HttpClient } from '@angular/common/http' -import { Component, Input, OnDestroy } from '@angular/core' +import { Component, Input, OnDestroy, ViewChild } from '@angular/core' +import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' import { first, Subject, takeUntil } from 'rxjs' import { Document } from 'src/app/data/document' import { SETTINGS_KEYS } from 'src/app/data/ui-settings' @@ -23,6 +24,9 @@ export class PreviewPopupComponent implements OnDestroy { return this._document } + @Input() + btn_classes: string = 'btn btn-sm btn-outline-secondary' + unsubscribeNotifier: Subject = new Subject() error = false @@ -31,6 +35,11 @@ export class PreviewPopupComponent implements OnDestroy { previewText: string + @ViewChild('popover') popover: NgbPopover + + mouseOnPreview: boolean + popoverHidden: boolean + get renderAsObject(): boolean { return (this.isPdf && this.useNativePdfViewer) || !this.isPdf } @@ -83,4 +92,33 @@ export class PreviewPopupComponent implements OnDestroy { this.error = true } } + + get previewUrl() { + return this.documentService.getPreviewUrl(this.document.id) + } + + mouseEnterPreview() { + this.mouseOnPreview = true + if (!this.popover.isOpen()) { + // we're going to open but hide to pre-load content during hover delay + this.popover.open() + this.popoverHidden = true + setTimeout(() => { + if (this.mouseOnPreview) { + // show popover + this.popoverHidden = false + } else { + this.popover.close() + } + }, 600) + } + } + + mouseLeavePreview() { + this.mouseOnPreview = false + } + + public close() { + this.popover.close() + } } diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html index 04f3a236a..34557be31 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html @@ -1,4 +1,4 @@ -
+
@@ -56,14 +56,9 @@  Open - +  View - - - - +  Download diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts index efd5076be..95b12d7ec 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.spec.ts @@ -1,11 +1,6 @@ import { DatePipe } from '@angular/common' import { provideHttpClientTesting } from '@angular/common/http/testing' -import { - ComponentFixture, - TestBed, - fakeAsync, - tick, -} from '@angular/core/testing' +import { ComponentFixture, TestBed } from '@angular/core/testing' import { By } from '@angular/platform-browser' import { RouterTestingModule } from '@angular/router/testing' import { @@ -84,21 +79,6 @@ describe('DocumentCardLargeComponent', () => { expect(fixture.nativeElement.textContent).toContain('8 pages') }) - it('should show preview on mouseover after delay to preload content', fakeAsync(() => { - component.mouseEnterPreview() - expect(component.popover.isOpen()).toBeTruthy() - expect(component.popoverHidden).toBeTruthy() - tick(600) - expect(component.popoverHidden).toBeFalsy() - component.mouseLeaveCard() - - component.mouseEnterPreview() - tick(100) - component.mouseLeavePreview() - tick(600) - expect(component.popover.isOpen()).toBeFalsy() - })) - it('should trim content', () => { expect(component.contentTrimmed).toHaveLength(503) // includes ... }) diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts index a3d57d950..99597ca5a 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.ts @@ -12,9 +12,9 @@ import { } from 'src/app/data/document' import { DocumentService } from 'src/app/services/rest/document.service' import { SettingsService } from 'src/app/services/settings.service' -import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component' +import { PreviewPopupComponent } from '../../common/preview-popup/preview-popup.component' @Component({ selector: 'pngx-document-card-large', @@ -65,7 +65,7 @@ export class DocumentCardLargeComponent extends ComponentWithPermissions { @Output() clickMoreLike = new EventEmitter() - @ViewChild('popover') popover: NgbPopover + @ViewChild('popupPreview') popupPreview: PreviewPopupComponent mouseOnPreview = false popoverHidden = true @@ -112,29 +112,8 @@ export class DocumentCardLargeComponent extends ComponentWithPermissions { return this.documentService.getPreviewUrl(this.document.id) } - mouseEnterPreview() { - this.mouseOnPreview = true - if (!this.popover.isOpen()) { - // we're going to open but hide to pre-load content during hover delay - this.popover.open() - this.popoverHidden = true - setTimeout(() => { - if (this.mouseOnPreview) { - // show popover - this.popoverHidden = false - } else { - this.popover.close() - } - }, 600) - } - } - - mouseLeavePreview() { - this.mouseOnPreview = false - } - mouseLeaveCard() { - this.popover.close() + this.popupPreview.close() } get contentTrimmed() { diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html index 57bd6048b..60713ef02 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.html @@ -1,5 +1,5 @@
-
+
@@ -129,14 +129,9 @@ - + - - - - + diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts index b86453a25..0c0c82103 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.spec.ts @@ -1,11 +1,6 @@ import { DatePipe } from '@angular/common' import { provideHttpClientTesting } from '@angular/common/http/testing' -import { - ComponentFixture, - TestBed, - fakeAsync, - tick, -} from '@angular/core/testing' +import { ComponentFixture, TestBed } from '@angular/core/testing' import { RouterTestingModule } from '@angular/router/testing' import { NgbPopoverModule, @@ -116,19 +111,4 @@ describe('DocumentCardSmallComponent', () => { fixture.debugElement.queryAll(By.directive(TagComponent)) ).toHaveLength(6) }) - - it('should show preview on mouseover after delay to preload content', fakeAsync(() => { - component.mouseEnterPreview() - expect(component.popover.isOpen()).toBeTruthy() - expect(component.popoverHidden).toBeTruthy() - tick(600) - expect(component.popoverHidden).toBeFalsy() - component.mouseLeaveCard() - - component.mouseEnterPreview() - tick(100) - component.mouseLeavePreview() - tick(600) - expect(component.popover.isOpen()).toBeFalsy() - })) }) diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts index 5cd583fb0..7397159af 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.ts @@ -13,9 +13,9 @@ import { } from 'src/app/data/document' import { DocumentService } from 'src/app/services/rest/document.service' import { SettingsService } from 'src/app/services/settings.service' -import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' import { SETTINGS_KEYS } from 'src/app/data/ui-settings' import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component' +import { PreviewPopupComponent } from '../../common/preview-popup/preview-popup.component' @Component({ selector: 'pngx-document-card-small', @@ -61,10 +61,7 @@ export class DocumentCardSmallComponent extends ComponentWithPermissions { moreTags: number = null - @ViewChild('popover') popover: NgbPopover - - mouseOnPreview = false - popoverHidden = true + @ViewChild('popupPreview') popupPreview: PreviewPopupComponent getIsThumbInverted() { return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED) @@ -78,10 +75,6 @@ export class DocumentCardSmallComponent extends ComponentWithPermissions { return this.documentService.getDownloadUrl(this.document.id) } - get previewUrl() { - return this.documentService.getPreviewUrl(this.document.id) - } - get privateName() { return $localize`Private` } @@ -100,29 +93,8 @@ export class DocumentCardSmallComponent extends ComponentWithPermissions { ) } - mouseEnterPreview() { - this.mouseOnPreview = true - if (!this.popover.isOpen()) { - // we're going to open but hide to pre-load content during hover delay - this.popover.open() - this.popoverHidden = true - setTimeout(() => { - if (this.mouseOnPreview) { - // show popover - this.popoverHidden = false - } else { - this.popover.close() - } - }, 600) - } - } - - mouseLeavePreview() { - this.mouseOnPreview = false - } - mouseLeaveCard() { - this.popover.close() + this.popupPreview.close() } get notesEnabled(): boolean { diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss index 331f6e6d8..fe1466d58 100644 --- a/src-ui/src/styles.scss +++ b/src-ui/src/styles.scss @@ -564,11 +564,6 @@ table.table { } } -.popover-hidden .popover { - opacity: 0; - pointer-events: none; -} - // Tour .tour-active .popover { min-width: 360px; @@ -728,3 +723,27 @@ i-bs svg { vertical-align: middle; } } + +// fixes for buttons in preview popup +.btn-group pngx-preview-popup:not(:last-child) { + // Prevent double borders when buttons are next to each other + > .btn { + margin-left: calc(#{$btn-border-width} * -1); + } + > .btn { + @include border-end-radius(0); + } +} +.btn-group pngx-preview-popup:not(:first-child) { + > .btn { + @include border-start-radius(0); + } +} +.btn-group pngx-preview-popup { + position: relative; + flex: 1 1 auto; + + > .btn { + display: block; + } +}