mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ACS-5184] Show progress spinner on file navigation (#10596)
* [ACS-5184] show progress spinner on file navigation * [ACS-5184] show spinner unitl content is ready * [ACS-5184] unit test fix * [ACS-5184] cr fix * [ACS-5184] spelling error fix
This commit is contained in:
parent
2d21340947
commit
cd63f67e0a
@ -8,6 +8,7 @@
|
|||||||
<img #image id="viewer-image"
|
<img #image id="viewer-image"
|
||||||
[src]="urlFile"
|
[src]="urlFile"
|
||||||
[alt]="fileName"
|
[alt]="fileName"
|
||||||
|
(load)="imageLoaded.emit()"
|
||||||
(error)="onImageError()" />
|
(error)="onImageError()" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -80,6 +80,9 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
isSaving = new EventEmitter<boolean>();
|
isSaving = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
imageLoaded = new EventEmitter<void>();
|
||||||
|
|
||||||
@ViewChild('image', { static: false })
|
@ViewChild('image', { static: false })
|
||||||
imageElement: ElementRef;
|
imageElement: ElementRef;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<video controls class="adf-video-player"
|
<video controls class="adf-video-player" (canplay)="canPlay.emit()"
|
||||||
[ngClass]="{ 'adf-audio-file': mimeType && mimeType.startsWith('audio') }">
|
[ngClass]="{ 'adf-audio-file': mimeType && mimeType.startsWith('audio') }">
|
||||||
<source [src]="urlFile"
|
<source [src]="urlFile"
|
||||||
[type]="mimeType"
|
[type]="mimeType"
|
||||||
|
@ -49,6 +49,9 @@ export class MediaPlayerComponent implements OnChanges {
|
|||||||
@Output()
|
@Output()
|
||||||
error = new EventEmitter<any>();
|
error = new EventEmitter<any>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
canPlay = new EventEmitter<void>();
|
||||||
|
|
||||||
constructor(private urlService: UrlService) {}
|
constructor(private urlService: UrlService) {}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
@ -103,6 +103,9 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
close = new EventEmitter<any>();
|
close = new EventEmitter<any>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
pagesLoaded = new EventEmitter<void>();
|
||||||
|
|
||||||
page: number;
|
page: number;
|
||||||
displayPage: number;
|
displayPage: number;
|
||||||
totalPages: number;
|
totalPages: number;
|
||||||
@ -565,6 +568,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
onPagesLoaded() {
|
onPagesLoaded() {
|
||||||
|
this.pagesLoaded.emit();
|
||||||
this.isPanelDisabled = false;
|
this.isPanelDisabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
<div *ngIf="isLoading"
|
<div *ngIf="(viewerType === 'media' || viewerType === 'pdf' || viewerType === 'image') ? isLoading || !isContentReady : isLoading"
|
||||||
class="adf-viewer-render-main">
|
class="adf-viewer-render-main-loader">
|
||||||
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
||||||
<div class="adf-viewer-render-content-container">
|
<div class="adf-viewer-render-content-container">
|
||||||
<ng-container *ngIf="isLoading">
|
<div class="adf-viewer-render__loading-screen ">
|
||||||
<div class="adf-viewer-render__loading-screen">
|
|
||||||
<h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
|
<h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
|
||||||
<div>
|
<div>
|
||||||
<mat-spinner class="adf-viewer-render__loading-screen__spinner" />
|
<mat-spinner class="adf-viewer-render__loading-screen__spinner"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,6 +32,7 @@
|
|||||||
[urlFile]="urlFile"
|
[urlFile]="urlFile"
|
||||||
[fileName]="internalFileName"
|
[fileName]="internalFileName"
|
||||||
[cacheType]="cacheTypeForContent"
|
[cacheType]="cacheTypeForContent"
|
||||||
|
(pagesLoaded)="isContentReady = true"
|
||||||
(close)="onClose()"
|
(close)="onClose()"
|
||||||
(error)="onUnsupportedFile()" />
|
(error)="onUnsupportedFile()" />
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -47,6 +45,7 @@
|
|||||||
[blobFile]="blobFile"
|
[blobFile]="blobFile"
|
||||||
(error)="onUnsupportedFile()"
|
(error)="onUnsupportedFile()"
|
||||||
(submit)="onSubmitFile($event)"
|
(submit)="onSubmitFile($event)"
|
||||||
|
(imageLoaded)="isContentReady = true"
|
||||||
(isSaving)="isSaving.emit($event)"
|
(isSaving)="isSaving.emit($event)"
|
||||||
/>
|
/>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -58,7 +57,8 @@
|
|||||||
[mimeType]="mimeType"
|
[mimeType]="mimeType"
|
||||||
[blobFile]="blobFile"
|
[blobFile]="blobFile"
|
||||||
[fileName]="internalFileName"
|
[fileName]="internalFileName"
|
||||||
(error)="onUnsupportedFile()" />
|
(error)="onUnsupportedFile()"
|
||||||
|
(canPlay)="isContentReady = true"/>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'text'">
|
<ng-container *ngSwitchCase="'text'">
|
||||||
|
@ -7,6 +7,18 @@
|
|||||||
background-color: var(--adf-theme-background-card-color);
|
background-color: var(--adf-theme-background-card-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.adf-viewer-render-main-loader {
|
||||||
|
position: fixed;
|
||||||
|
top: 64px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.adf-viewer-render {
|
.adf-viewer-render {
|
||||||
&-main {
|
&-main {
|
||||||
width: 0;
|
width: 0;
|
||||||
|
@ -18,13 +18,13 @@
|
|||||||
import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { SpyLocation } from '@angular/common/testing';
|
import { SpyLocation } from '@angular/common/testing';
|
||||||
import { Component, TemplateRef, ViewChild } from '@angular/core';
|
import { Component, DebugElement, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||||
import { NoopTranslateModule, UnitTestingUtils } from '../../../testing';
|
import { NoopTranslateModule, UnitTestingUtils } from '../../../testing';
|
||||||
import { RenderingQueueServices } from '../../services/rendering-queue.services';
|
import { RenderingQueueServices } from '../../services/rendering-queue.services';
|
||||||
import { ViewerRenderComponent } from './viewer-render.component';
|
import { ViewerRenderComponent } from './viewer-render.component';
|
||||||
import { ViewerExtensionDirective } from '@alfresco/adf-core';
|
import { ImgViewerComponent, MediaPlayerComponent, PdfViewerComponent, ViewerExtensionDirective } from '@alfresco/adf-core';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -476,4 +476,75 @@ describe('ViewerComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Spinner', () => {
|
||||||
|
const getMainLoader = (): DebugElement => testingUtils.getByCSS('.adf-viewer-render-main-loader');
|
||||||
|
|
||||||
|
it('should show spinner when isLoading is true', () => {
|
||||||
|
component.isLoading = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getMainLoader()).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show spinner until content is ready when viewerType is media', () => {
|
||||||
|
component.isLoading = false;
|
||||||
|
component.urlFile = 'some-file.mp4';
|
||||||
|
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).not.toBeNull();
|
||||||
|
|
||||||
|
const mediaViewer = testingUtils.getByDirective(MediaPlayerComponent);
|
||||||
|
mediaViewer.triggerEventHandler('canPlay', null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
|
expect(component.viewerType).toBe('media');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show spinner until content is ready when viewerType is pdf', () => {
|
||||||
|
component.isLoading = false;
|
||||||
|
component.urlFile = 'some-url.pdf';
|
||||||
|
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).not.toBeNull();
|
||||||
|
|
||||||
|
const pdfViewer = testingUtils.getByDirective(PdfViewerComponent);
|
||||||
|
pdfViewer.triggerEventHandler('pagesLoaded', null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
|
expect(component.viewerType).toBe('pdf');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show spinner until content is ready when viewerType is image', () => {
|
||||||
|
component.isLoading = false;
|
||||||
|
component.urlFile = 'some-url.png';
|
||||||
|
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getMainLoader()).not.toBeNull();
|
||||||
|
|
||||||
|
const imgViewer = testingUtils.getByDirective(ImgViewerComponent);
|
||||||
|
imgViewer.triggerEventHandler('imageLoaded', null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
|
expect(component.viewerType).toBe('image');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show spinner when isLoading = false and isContentReady = false for other viewer types', () => {
|
||||||
|
component.isLoading = false;
|
||||||
|
component.urlFile = 'some-url.txt';
|
||||||
|
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
|
expect(component.isContentReady).toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -142,6 +142,7 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
extension: string;
|
extension: string;
|
||||||
internalFileName: string;
|
internalFileName: string;
|
||||||
viewerType: string = 'unknown';
|
viewerType: string = 'unknown';
|
||||||
|
isContentReady = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the active Viewer content extensions.
|
* Returns a list of the active Viewer content extensions.
|
||||||
@ -184,6 +185,7 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
|
this.isContentReady = false;
|
||||||
this.isLoading = !this.blobFile && !this.urlFile;
|
this.isLoading = !this.blobFile && !this.urlFile;
|
||||||
|
|
||||||
if (this.blobFile) {
|
if (this.blobFile) {
|
||||||
|
@ -121,6 +121,26 @@ describe('ViewerComponent', () => {
|
|||||||
expect(thumbnailService.getMimeTypeIcon).toHaveBeenCalledWith('application/pdf');
|
expect(thumbnailService.getMimeTypeIcon).toHaveBeenCalledWith('application/pdf');
|
||||||
expect(component.mimeTypeIconUrl).toBe('application/pdf');
|
expect(component.mimeTypeIconUrl).toBe('application/pdf');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should reset urlFile and blobFile on onNavigateBeforeClick', () => {
|
||||||
|
component.urlFile = 'some-url';
|
||||||
|
component.blobFile = new Blob(['content'], { type: 'text/plain' });
|
||||||
|
|
||||||
|
component.onNavigateBeforeClick(new MouseEvent('click'));
|
||||||
|
|
||||||
|
expect(component.urlFile).toBe('');
|
||||||
|
expect(component.blobFile).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset urlFile and blobFile on onNavigateNextClick', () => {
|
||||||
|
component.urlFile = 'some-url';
|
||||||
|
component.blobFile = new Blob(['content'], { type: 'text/plain' });
|
||||||
|
|
||||||
|
component.onNavigateNextClick(new MouseEvent('click'));
|
||||||
|
|
||||||
|
expect(component.urlFile).toBe('');
|
||||||
|
expect(component.blobFile).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('File Name Test', () => {
|
describe('File Name Test', () => {
|
||||||
|
@ -387,10 +387,12 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onNavigateBeforeClick(event: MouseEvent | KeyboardEvent) {
|
onNavigateBeforeClick(event: MouseEvent | KeyboardEvent) {
|
||||||
|
this.resetLoadingSpinner();
|
||||||
this.navigateBefore.next(event);
|
this.navigateBefore.next(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onNavigateNextClick(event: MouseEvent | KeyboardEvent) {
|
onNavigateNextClick(event: MouseEvent | KeyboardEvent) {
|
||||||
|
this.resetLoadingSpinner();
|
||||||
this.navigateNext.next(event);
|
this.navigateNext.next(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,22 +418,17 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = event.keyCode;
|
if (event.key === 'ArrowLeft' && this.canNavigateBefore) {
|
||||||
|
|
||||||
// Left arrow
|
|
||||||
if (key === 37 && this.canNavigateBefore) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.onNavigateBeforeClick(event);
|
this.onNavigateBeforeClick(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right arrow
|
if (event.key === 'ArrowRight' && this.canNavigateNext) {
|
||||||
if (key === 39 && this.canNavigateNext) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.onNavigateNextClick(event);
|
this.onNavigateNextClick(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl+F
|
if (event.code === 'KeyF' && event.ctrlKey) {
|
||||||
if (key === 70 && event.ctrlKey) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.enterFullScreen();
|
this.enterFullScreen();
|
||||||
}
|
}
|
||||||
@ -527,4 +524,9 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resetLoadingSpinner() {
|
||||||
|
this.urlFile = '';
|
||||||
|
this.blobFile = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user