mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-1634] floating toolbar for PDF viewer (#2413)
* floating toolbar for PDF viewer * use routing settings to toggle app menu * remove dialog viewer * remove duplicate menu
This commit is contained in:
committed by
Eugenio Romano
parent
d378d2702b
commit
e3fbe21340
@@ -1 +1,2 @@
|
||||
<adf-app-menu *ngIf="showAppMenu"></adf-app-menu>
|
||||
<router-outlet></router-outlet>
|
||||
|
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||
import { AlfrescoSettingsService, PageTitleService, StorageService } from 'ng2-alfresco-core';
|
||||
|
||||
@Component({
|
||||
@@ -26,12 +27,34 @@ import { AlfrescoSettingsService, PageTitleService, StorageService } from 'ng2-a
|
||||
})
|
||||
export class AppComponent {
|
||||
searchTerm: string = '';
|
||||
showAppMenu = true;
|
||||
|
||||
constructor(private settingsService: AlfrescoSettingsService,
|
||||
private storage: StorageService,
|
||||
pageTitleService: PageTitleService) {
|
||||
pageTitleService: PageTitleService,
|
||||
route: ActivatedRoute,
|
||||
router: Router) {
|
||||
this.setProvider();
|
||||
pageTitleService.setTitle();
|
||||
|
||||
router.events
|
||||
.filter(event => event instanceof NavigationEnd)
|
||||
.subscribe(() => {
|
||||
let currentRoute = route.root;
|
||||
|
||||
while (currentRoute.firstChild) {
|
||||
currentRoute = currentRoute.firstChild;
|
||||
}
|
||||
|
||||
const snapshot: any = currentRoute.snapshot || {};
|
||||
const data: any = snapshot.data || {};
|
||||
|
||||
if (data && data['showAppMenu'] !== undefined) {
|
||||
this.showAppMenu = data && data.showAppMenu;
|
||||
} else {
|
||||
this.showAppMenu = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setProvider() {
|
||||
|
@@ -44,7 +44,13 @@ import { CustomSourcesComponent } from './components/files/custom-sources.compon
|
||||
import { FormListDemoComponent } from './components/form/form-list-demo.component';
|
||||
|
||||
export const appRoutes: Routes = [
|
||||
{ path: 'login', component: LoginDemoComponent },
|
||||
{
|
||||
path: 'login',
|
||||
component: LoginDemoComponent,
|
||||
data: {
|
||||
showAppMenu: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: HomeComponent,
|
||||
@@ -68,7 +74,10 @@ export const appRoutes: Routes = [
|
||||
{
|
||||
path: 'files/:nodeId/view',
|
||||
component: FileViewComponent,
|
||||
canActivate: [ AuthGuardEcm ]
|
||||
canActivate: [ AuthGuardEcm ],
|
||||
data: {
|
||||
showAppMenu: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'dl-custom-sources',
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<div class="about-container">
|
||||
<h3>Server settings</h3>
|
||||
<md-list>
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<md-tab-group [(selectedIndex)]="activeTab">
|
||||
<md-tab id="tasks-header" href="#tasks" label="{{'PS-TAB.TASKS-TAB' | translate}}">
|
||||
<div class="page-content">
|
||||
|
@@ -22,7 +22,6 @@ import { AppDefinitionRepresentationModel } from 'ng2-activiti-tasklist';
|
||||
@Component({
|
||||
selector: 'activiti-apps-view',
|
||||
template: `
|
||||
<adf-app-menu></adf-app-menu>
|
||||
<activiti-apps (appClick)="onAppClicked($event)"></activiti-apps>
|
||||
`
|
||||
})
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<div class="p-10">
|
||||
<alfresco-datatable
|
||||
[data]="data"
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
<adf-toolbar>
|
||||
<adf-toolbar-title>
|
||||
<md-select [(ngModel)]="selectedSource">
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<div class="container">
|
||||
<div class="adf-demo-site-container-style" id="demo-container">
|
||||
<adf-sites-dropdown (change)="getSiteContent($event)">
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<div class="form-container">
|
||||
<adf-form [form]="form">
|
||||
</adf-form>
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<!-- DOCUMENT LIST-->
|
||||
<md-card class="adf-home-card">
|
||||
<md-card-title class="adf-home-card-title adf-primary-background-color" routerLink="/files">
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
||||
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
||||
<md-grid-list cols="2" rowHeight="100px">
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<adf-app-menu></adf-app-menu>
|
||||
|
||||
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
||||
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
||||
<div class="adf-tag-example-area">
|
||||
|
@@ -26,18 +26,9 @@ import { MediaPlayerComponent } from './src/components/mediaPlayer.component';
|
||||
import { PdfViewerComponent } from './src/components/pdfViewer.component';
|
||||
import { TxtViewerComponent } from './src/components/txtViewer.component';
|
||||
import { UnknownFormatComponent } from './src/components/unknown-format/unknown-format.component';
|
||||
import { PdfViewComponent } from './src/components/viewer-dialog/pdf-view/pdf-view.component';
|
||||
import { ViewerDialogComponent } from './src/components/viewer-dialog/viewer-dialog.component';
|
||||
import { ViewerComponent } from './src/components/viewer.component';
|
||||
|
||||
import { ExtensionViewerDirective } from './src/directives/extension-viewer.directive';
|
||||
|
||||
import { RenderingQueueServices } from './src/services/rendering-queue.services';
|
||||
import { ViewerService } from './src/services/viewer.service';
|
||||
|
||||
export { ViewerDialogComponent } from './src/components/viewer-dialog/viewer-dialog.component';
|
||||
export { ViewerDialogSettings } from './src/components/viewer-dialog/viewer-dialog.settings';
|
||||
export { ViewerService } from './src/services/viewer.service';
|
||||
|
||||
export function declarations() {
|
||||
return [
|
||||
@@ -47,8 +38,6 @@ export function declarations() {
|
||||
MediaPlayerComponent,
|
||||
PdfViewerComponent,
|
||||
ExtensionViewerDirective,
|
||||
ViewerDialogComponent,
|
||||
PdfViewComponent,
|
||||
UnknownFormatComponent
|
||||
];
|
||||
}
|
||||
@@ -60,15 +49,11 @@ export function declarations() {
|
||||
],
|
||||
declarations: declarations(),
|
||||
providers: [
|
||||
RenderingQueueServices,
|
||||
ViewerService
|
||||
RenderingQueueServices
|
||||
],
|
||||
exports: [
|
||||
MaterialModule,
|
||||
...declarations()
|
||||
],
|
||||
entryComponents: [
|
||||
ViewerDialogComponent
|
||||
]
|
||||
})
|
||||
export class ViewerModule {}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<!-- Start Pdf Canvas -->
|
||||
<div id="viewer-pdf-container" class="viewer-pdf-container" (window:resize)="onResize()">
|
||||
<div id="viewer-viewerPdf" class="pdfViewer">
|
||||
<div id="loader-container" class="loader-container">
|
||||
@@ -8,66 +7,68 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Pdf Canvas -->
|
||||
|
||||
<div class="adf-pdf-viewer__toolbar">
|
||||
<adf-toolbar>
|
||||
|
||||
<!-- Pagination toolbar start -->
|
||||
<div *ngIf="showToolbar" class="viewer-toolbar-pagination">
|
||||
<div
|
||||
<button md-icon-button>
|
||||
<md-icon>dashboard</md-icon>
|
||||
</button>
|
||||
|
||||
<adf-toolbar-divider></adf-toolbar-divider>
|
||||
|
||||
<button
|
||||
id="viewer-previous-page-button"
|
||||
aria-label="arrow left"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
aria-label="previous page"
|
||||
md-icon-button
|
||||
(click)="previousPage()">
|
||||
<md-icon>keyboard_arrow_left</md-icon>
|
||||
</div>
|
||||
<md-icon>keyboard_arrow_up</md-icon>
|
||||
</button>
|
||||
|
||||
<div class="viewer-page-counter left" >
|
||||
<button
|
||||
id="viewer-next-page-button"
|
||||
aria-label="arrow right"
|
||||
md-icon-button
|
||||
(click)="nextPage()">
|
||||
<md-icon>keyboard_arrow_down</md-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
Showing
|
||||
<input #page
|
||||
class="viewer-pagenumber-input left"
|
||||
class="adf-pdf-viewer__toolbar-page-selector"
|
||||
type="text"
|
||||
pattern="-?[0-9]*(\.[0-9]+)?"
|
||||
value="{{ displayPage }}"
|
||||
(keyup.enter)="inputPage(page.value)">
|
||||
<div class="left viewer-total-pages">/ {{ totalPages }}</div>
|
||||
of {{ totalPages }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="viewer-next-page-button"
|
||||
aria-label="arrow right"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="nextPage()">
|
||||
<md-icon>keyboard_arrow_right</md-icon>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pagination toolbar end -->
|
||||
<adf-toolbar-divider></adf-toolbar-divider>
|
||||
|
||||
<!-- Command toolbar start -->
|
||||
<div *ngIf="showToolbar" class="viewer-toolbar-command">
|
||||
<div
|
||||
id="viewer-scale-page-button"
|
||||
aria-label="zoom out map"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="pageFit()">
|
||||
<md-icon>zoom_out_map</md-icon>
|
||||
</div>
|
||||
<div
|
||||
<button
|
||||
id="viewer-zoom-in-button"
|
||||
aria-label="zoom in"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
md-icon-button
|
||||
(click)="zoomIn()">
|
||||
<md-icon>zoom_in</md-icon>
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="viewer-zoom-out-button"
|
||||
aria-label="zoom out"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
md-icon-button
|
||||
(click)="zoomOut()">
|
||||
<md-icon>zoom_out</md-icon>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="viewer-scale-page-button"
|
||||
aria-label="zoom out map"
|
||||
md-icon-button
|
||||
(click)="pageFit()">
|
||||
<md-icon>zoom_out_map</md-icon>
|
||||
</button>
|
||||
|
||||
</adf-toolbar>
|
||||
</div>
|
||||
<!-- Command toolbar end -->
|
||||
|
@@ -17,75 +17,22 @@
|
||||
max-width:300px;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
&__toolbar {
|
||||
position: absolute;
|
||||
bottom: 60px;
|
||||
|
||||
.viewer-toolbar-pagination{
|
||||
padding-top: 4px;
|
||||
top: 80px;
|
||||
right:35px;
|
||||
width:auto;
|
||||
position:absolute;
|
||||
border-radius: 10px;
|
||||
background: #3E3E3E;
|
||||
color: white;
|
||||
}
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.viewer-toolbar-command{
|
||||
height: 30px;
|
||||
padding-top: 4px;
|
||||
top: 80px;
|
||||
left:35px;
|
||||
width:auto;
|
||||
position:absolute;
|
||||
border-radius: 10px;
|
||||
background: #3E3E3E;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.viewer-pagenumber-input {
|
||||
border: none;
|
||||
display: block;
|
||||
&-page-selector {
|
||||
font-size: 16px;
|
||||
padding: 4px 0;
|
||||
background: 0 0;
|
||||
text-align: right;
|
||||
color: inherit;
|
||||
width: 33px;
|
||||
margin-right: 4px;
|
||||
height: 20px;
|
||||
outline-width: 1px;
|
||||
outline-color: gray;
|
||||
}
|
||||
|
||||
.viewer-total-pages {
|
||||
border: medium none;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
padding: 4px 0px;
|
||||
background: transparent none repeat scroll 0px 0px;
|
||||
text-align: right;
|
||||
color: inherit;
|
||||
margin-right: 4px;
|
||||
height: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.viewer-page-counter {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.button-page {
|
||||
margin-right: 4px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button-page:hover {
|
||||
cursor: pointer;
|
||||
background: grey;
|
||||
border-radius: 24px;
|
||||
}
|
||||
}
|
||||
|
@@ -1,69 +0,0 @@
|
||||
<div id="viewer-pdf-container" class="viewer-pdf-container" (window:resize)="onResize()">
|
||||
<div id="viewer-viewerPdf" class="pdfViewer">
|
||||
<div *ngIf="isLoading" class="adf-pdf-view__loading-screen">
|
||||
<h2>Loading</h2>
|
||||
<div>
|
||||
<md-spinner></md-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="showToolbar">
|
||||
<div class="viewer-toolbar-pagination">
|
||||
<div
|
||||
id="viewer-previous-page-button"
|
||||
aria-label="arrow left"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="previousPage()">
|
||||
<md-icon>keyboard_arrow_left</md-icon>
|
||||
</div>
|
||||
|
||||
<div class="viewer-page-counter left" >
|
||||
<input #page
|
||||
class="viewer-pagenumber-input left"
|
||||
type="text"
|
||||
pattern="-?[0-9]*(\.[0-9]+)?"
|
||||
value="{{ displayPage }}"
|
||||
(keyup.enter)="inputPage(page.value)">
|
||||
<div class="left viewer-total-pages">/ {{ totalPages }}</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="viewer-next-page-button"
|
||||
aria-label="arrow right"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="nextPage()">
|
||||
<md-icon>keyboard_arrow_right</md-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="viewer-toolbar-command">
|
||||
<div
|
||||
id="viewer-scale-page-button"
|
||||
aria-label="zoom out map"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="pageFit()">
|
||||
<md-icon>zoom_out_map</md-icon>
|
||||
</div>
|
||||
<div
|
||||
id="viewer-zoom-in-button"
|
||||
aria-label="zoom in"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="zoomIn()">
|
||||
<md-icon>zoom_in</md-icon>
|
||||
</div>
|
||||
<div
|
||||
id="viewer-zoom-out-button"
|
||||
aria-label="zoom out"
|
||||
class="button-page left"
|
||||
tabindex="0"
|
||||
(click)="zoomOut()">
|
||||
<md-icon>zoom_out</md-icon>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
@@ -1,339 +0,0 @@
|
||||
.adf-pdf-view {
|
||||
|
||||
&__loading-screen {
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 85vh;
|
||||
|
||||
.md-spinner {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.viewer-toolbar-pagination{
|
||||
padding-top: 4px;
|
||||
top: 80px;
|
||||
right:35px;
|
||||
width:auto;
|
||||
position:absolute;
|
||||
border-radius: 10px;
|
||||
background: #3E3E3E;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.viewer-toolbar-command{
|
||||
height: 30px;
|
||||
padding-top: 4px;
|
||||
top: 80px;
|
||||
left:35px;
|
||||
width:auto;
|
||||
position:absolute;
|
||||
border-radius: 10px;
|
||||
background: #3E3E3E;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.viewer-pagenumber-input {
|
||||
border: none;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
padding: 4px 0;
|
||||
background: 0 0;
|
||||
text-align: right;
|
||||
color: inherit;
|
||||
width: 33px;
|
||||
margin-right: 4px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.viewer-total-pages {
|
||||
border: medium none;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
padding: 4px 0px;
|
||||
background: transparent none repeat scroll 0px 0px;
|
||||
text-align: right;
|
||||
color: inherit;
|
||||
margin-right: 4px;
|
||||
height: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.viewer-page-counter {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.button-page {
|
||||
margin-right: 4px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button-page:hover {
|
||||
cursor: pointer;
|
||||
background: grey;
|
||||
border-radius: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.adf-pdf-view {
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0.2;
|
||||
line-height: 1.0;
|
||||
|
||||
& > div {
|
||||
color: transparent;
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
cursor: text;
|
||||
-webkit-transform-origin: 0% 0%;
|
||||
-moz-transform-origin: 0% 0%;
|
||||
-o-transform-origin: 0% 0%;
|
||||
-ms-transform-origin: 0% 0%;
|
||||
transform-origin: 0% 0%;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
margin: -1px;
|
||||
padding: 1px;
|
||||
|
||||
background-color: rgb(180, 0, 170);
|
||||
border-radius: 4px;
|
||||
|
||||
&.begin {
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
|
||||
&.end {
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
}
|
||||
|
||||
&.middle {
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgb(0, 100, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&::selection { background: rgb(0,0,255); }
|
||||
&::-moz-selection { background: rgb(0,0,255); }
|
||||
|
||||
.endOfContent {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 100%;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
z-index: -1;
|
||||
cursor: default;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-moz-user-select: none;
|
||||
|
||||
&.active {
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.annotationLayer {
|
||||
section {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.linkAnnotation {
|
||||
& > a {
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.2;
|
||||
background: #ff0;
|
||||
box-shadow: 0px 2px 10px #ff0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.textAnnotation {
|
||||
img {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.popupWrapper {
|
||||
position: absolute;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
z-index: 200;
|
||||
max-width: 20em;
|
||||
background-color: #FFFF99;
|
||||
box-shadow: 0px 2px 5px #333;
|
||||
border-radius: 2px;
|
||||
padding: 0.6em;
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
word-wrap: break-word;
|
||||
|
||||
h1 {
|
||||
font-size: 1em;
|
||||
border-bottom: 1px solid #000000;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-top: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.highlightAnnotation,
|
||||
.underlineAnnotation,
|
||||
.squigglyAnnotation,
|
||||
.strikeoutAnnotation,
|
||||
.fileAttachmentAnnotation {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.pdfViewer {
|
||||
canvasWrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page {
|
||||
direction: ltr;
|
||||
width: 816px;
|
||||
height: 1056px;
|
||||
margin: 1px auto -8px auto;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
border: 9px solid transparent;
|
||||
background-clip: content-box;
|
||||
background-color: white;
|
||||
|
||||
canvas {
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.loadingIcon {
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.removePageBorders {
|
||||
.page {
|
||||
margin: 0px auto 10px auto;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.loadingIcon {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
left: 50% !important;
|
||||
top: 50% !important;
|
||||
|
||||
margin-top: -50px;
|
||||
margin-left: -50px;
|
||||
|
||||
font-size: 5px;
|
||||
text-indent: -9999em;
|
||||
border-top: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-right: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-bottom: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-left: 1.1em solid #030002;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
|
||||
border-radius: 50%;
|
||||
&:after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hidden, [hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.viewer-pdf-container {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
outline: none;
|
||||
}
|
||||
html[dir='ltr'] .viewer-pdf-container {
|
||||
box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05);
|
||||
}
|
||||
html[dir='rtl'] .viewer-pdf-container {
|
||||
box-shadow: inset -1px 0 0 hsla(0,0%,100%,.05);
|
||||
}
|
@@ -1,387 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, HostListener, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { LogService } from 'ng2-alfresco-core';
|
||||
import { RenderingQueueServices } from '../../../services/rendering-queue.services';
|
||||
|
||||
declare let PDFJS: any;
|
||||
|
||||
@Component({
|
||||
selector: 'adf-pdf-view',
|
||||
templateUrl: 'pdf-view.component.html',
|
||||
styleUrls: [ 'pdf-view.component.scss' ],
|
||||
providers: [ RenderingQueueServices ],
|
||||
host: { 'class': 'adf-pdf-view' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PdfViewComponent implements OnInit, OnDestroy {
|
||||
|
||||
@Input()
|
||||
fileUrl: string;
|
||||
|
||||
page: number;
|
||||
displayPage: number;
|
||||
totalPages: number;
|
||||
loadingPercent: number;
|
||||
showToolbar = false;
|
||||
isLoading = false;
|
||||
|
||||
private currentPdfDocument: any;
|
||||
private pdfViewer: any;
|
||||
private currentScaleMode: string = 'auto';
|
||||
private currentScale: number;
|
||||
|
||||
private MAX_AUTO_SCALE: number = 1.25;
|
||||
private DEFAULT_SCALE_DELTA: number = 1.1;
|
||||
private MIN_SCALE: number = 0.25;
|
||||
private MAX_SCALE: number = 10.0;
|
||||
|
||||
constructor(private renderingQueueServices: RenderingQueueServices,
|
||||
private logService: LogService) {
|
||||
// needed to preserve "this" context when setting as a global document event listener
|
||||
this.onDocumentScroll = this.onDocumentScroll.bind(this);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.fileUrl) {
|
||||
this.render(this.fileUrl);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
window.document.removeEventListener('scroll', this.onDocumentScroll, true);
|
||||
}
|
||||
|
||||
private render(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.isLoading = true;
|
||||
const loadingTask = this.getPDFJS().getDocument(src);
|
||||
|
||||
loadingTask.onProgress = (progressData) => {
|
||||
let level = progressData.loaded / progressData.total;
|
||||
this.loadingPercent = Math.round(level * 100);
|
||||
};
|
||||
|
||||
loadingTask.then(
|
||||
(pdfDocument) => {
|
||||
this.currentPdfDocument = pdfDocument;
|
||||
this.totalPages = pdfDocument.numPages;
|
||||
this.page = 1;
|
||||
this.displayPage = 1;
|
||||
this.initPDFViewer(this.currentPdfDocument);
|
||||
|
||||
this.currentPdfDocument.getPage(1).then(
|
||||
() => {
|
||||
this.scalePage('auto');
|
||||
this.showToolbar = true;
|
||||
this.isLoading = false;
|
||||
resolve();
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* return the PDFJS global object (exist to facilitate the mock of PDFJS in the test)
|
||||
*
|
||||
* @returns {PDFJS}
|
||||
*/
|
||||
getPDFJS() {
|
||||
return PDFJS;
|
||||
}
|
||||
|
||||
initPDFViewer(pdfDocument: any) {
|
||||
let documentContainer = document.getElementById('viewer-pdf-container');
|
||||
let viewer: any = document.getElementById('viewer-viewerPdf');
|
||||
|
||||
window.document.addEventListener('scroll', this.onDocumentScroll, true);
|
||||
|
||||
this.pdfViewer = new PDFJS.PDFViewer({
|
||||
container: documentContainer,
|
||||
viewer: viewer,
|
||||
renderingQueue: this.renderingQueueServices
|
||||
});
|
||||
|
||||
this.renderingQueueServices.setViewer(this.pdfViewer);
|
||||
|
||||
this.pdfViewer.setDocument(pdfDocument);
|
||||
}
|
||||
|
||||
private onDocumentScroll(event: Event) {
|
||||
if (event && event.target) {
|
||||
const outputPage = this.getVisibleElement(event.target);
|
||||
|
||||
if (outputPage) {
|
||||
this.page = outputPage.id;
|
||||
this.displayPage = this.page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to scale the page current support implementation
|
||||
*
|
||||
* @param {string} scaleMode - new scale mode
|
||||
*/
|
||||
scalePage(scaleMode) {
|
||||
this.currentScaleMode = scaleMode;
|
||||
|
||||
if (this.pdfViewer) {
|
||||
|
||||
let viewerContainer = document.getElementById('viewer-main-container');
|
||||
let documentContainer = document.getElementById('viewer-pdf-container');
|
||||
|
||||
let widthContainer;
|
||||
let heigthContainer;
|
||||
|
||||
if (viewerContainer && viewerContainer.clientWidth <= documentContainer.clientWidth) {
|
||||
widthContainer = viewerContainer.clientWidth;
|
||||
heigthContainer = viewerContainer.clientHeight;
|
||||
} else {
|
||||
widthContainer = documentContainer.clientWidth;
|
||||
heigthContainer = documentContainer.clientHeight;
|
||||
}
|
||||
|
||||
let currentPage = this.pdfViewer._pages[this.pdfViewer._currentPageNumber - 1];
|
||||
|
||||
let padding = 20;
|
||||
let pageWidthScale = (widthContainer - padding) / currentPage.width * currentPage.scale;
|
||||
let pageHeightScale = (heigthContainer - padding) / currentPage.width * currentPage.scale;
|
||||
|
||||
let scale;
|
||||
|
||||
switch (this.currentScaleMode) {
|
||||
case 'page-actual':
|
||||
scale = 1;
|
||||
break;
|
||||
case 'page-width':
|
||||
scale = pageWidthScale;
|
||||
break;
|
||||
case 'page-height':
|
||||
scale = pageHeightScale;
|
||||
break;
|
||||
case 'page-fit':
|
||||
scale = Math.min(pageWidthScale, pageHeightScale);
|
||||
break;
|
||||
case 'auto':
|
||||
let horizontalScale;
|
||||
if (this.isLandscape) {
|
||||
horizontalScale = Math.min(pageHeightScale, pageWidthScale);
|
||||
} else {
|
||||
horizontalScale = pageWidthScale;
|
||||
}
|
||||
scale = Math.min(this.MAX_AUTO_SCALE, horizontalScale);
|
||||
|
||||
break;
|
||||
default:
|
||||
this.logService.error('pdfViewSetScale: \'' + scaleMode + '\' is an unknown zoom value.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.setScaleUpdatePages(scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all the pages with the newScale scale
|
||||
*
|
||||
* @param {number} newScale - new scale page
|
||||
*/
|
||||
setScaleUpdatePages(newScale: number) {
|
||||
if (!this.isSameScale(this.currentScale, newScale)) {
|
||||
this.currentScale = newScale;
|
||||
|
||||
this.pdfViewer._pages.forEach(function (currentPage) {
|
||||
currentPage.update(newScale);
|
||||
});
|
||||
|
||||
this.pdfViewer.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* method to check if the request scale of the page is the same for avoid unuseful re-rendering
|
||||
*
|
||||
* @param {number} oldScale - old scale page
|
||||
* @param {number} newScale - new scale page
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isSameScale(oldScale: number, newScale: number) {
|
||||
return (newScale === oldScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* method to check if is a land scape view
|
||||
*
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLandscape(width: number, height: number) {
|
||||
return (width > height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method triggered when the page is resized
|
||||
*/
|
||||
onResize() {
|
||||
this.scalePage(this.currentScaleMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle the fit page pdf
|
||||
*/
|
||||
pageFit() {
|
||||
if (this.currentScaleMode !== 'page-fit') {
|
||||
this.scalePage('page-fit');
|
||||
} else {
|
||||
this.scalePage('auto');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* zoom in page pdf
|
||||
*
|
||||
* @param {number} ticks
|
||||
*/
|
||||
zoomIn(ticks: number) {
|
||||
let newScale: any = this.currentScale;
|
||||
do {
|
||||
newScale = (newScale * this.DEFAULT_SCALE_DELTA).toFixed(2);
|
||||
newScale = Math.ceil(newScale * 10) / 10;
|
||||
newScale = Math.min(this.MAX_SCALE, newScale);
|
||||
} while (--ticks > 0 && newScale < this.MAX_SCALE);
|
||||
this.currentScaleMode = 'auto';
|
||||
this.setScaleUpdatePages(newScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* zoom out page pdf
|
||||
*
|
||||
* @param {number} ticks
|
||||
*/
|
||||
zoomOut(ticks: number) {
|
||||
let newScale: any = this.currentScale;
|
||||
do {
|
||||
newScale = (newScale / this.DEFAULT_SCALE_DELTA).toFixed(2);
|
||||
newScale = Math.floor(newScale * 10) / 10;
|
||||
newScale = Math.max(this.MIN_SCALE, newScale);
|
||||
} while (--ticks > 0 && newScale > this.MIN_SCALE);
|
||||
this.currentScaleMode = 'auto';
|
||||
this.setScaleUpdatePages(newScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* load the previous page
|
||||
*/
|
||||
previousPage() {
|
||||
if (this.pdfViewer && this.page > 1) {
|
||||
this.page--;
|
||||
this.displayPage = this.page;
|
||||
|
||||
this.pdfViewer.currentPageNumber = this.page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load the next page
|
||||
*/
|
||||
nextPage() {
|
||||
if (this.pdfViewer && this.page < this.totalPages) {
|
||||
this.page++;
|
||||
this.displayPage = this.page;
|
||||
|
||||
this.pdfViewer.currentPageNumber = this.page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load the page in input
|
||||
*
|
||||
* @param {string} page - page to load
|
||||
*/
|
||||
inputPage(page: string) {
|
||||
let pageInput = parseInt(page, 10);
|
||||
|
||||
if (!isNaN(pageInput) && pageInput > 0 && pageInput <= this.totalPages) {
|
||||
this.page = pageInput;
|
||||
this.displayPage = this.page;
|
||||
this.pdfViewer.currentPageNumber = this.page;
|
||||
} else {
|
||||
this.displayPage = this.page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find out what elements are visible within a scroll pane
|
||||
*
|
||||
* @param {any} target
|
||||
*
|
||||
* @returns {Object} page
|
||||
*/
|
||||
getVisibleElement(target) {
|
||||
return this.pdfViewer._pages.find((page) => {
|
||||
return this.isOnScreen(page, target);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a page is visible
|
||||
*
|
||||
* @param {any} page
|
||||
* @param {any} target
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isOnScreen(page: any, target: any) {
|
||||
let viewport: any = {};
|
||||
viewport.top = target.scrollTop;
|
||||
viewport.bottom = viewport.top + target.scrollHeight;
|
||||
let bounds: any = {};
|
||||
bounds.top = page.div.offsetTop;
|
||||
bounds.bottom = bounds.top + page.viewport.height;
|
||||
return ((bounds.top <= viewport.bottom) && (bounds.bottom >= viewport.top));
|
||||
}
|
||||
|
||||
/**
|
||||
* Litener Keyboard Event
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
@HostListener('document:keydown', ['$event'])
|
||||
handleKeyboardEvent(event: KeyboardEvent) {
|
||||
let key = event.keyCode;
|
||||
if (key === 39) { // right arrow
|
||||
this.nextPage();
|
||||
} else if (key === 37) {// left arrow
|
||||
this.previousPage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,168 +0,0 @@
|
||||
<adf-toolbar color="default">
|
||||
<adf-toolbar-title>
|
||||
<button md-icon-button [md-dialog-close]="true" mdTooltip="Close and go back">
|
||||
<md-icon>arrow_back</md-icon>
|
||||
</button>
|
||||
<span>
|
||||
<img class="adf-viewer-dialog__mimetype-icon" [src]="fileMimeType | adfMimeTypeIcon">
|
||||
<span>{{ fileName }}</span>
|
||||
</span>
|
||||
</adf-toolbar-title>
|
||||
|
||||
<button
|
||||
*ngIf="settings.allowOpenWith"
|
||||
md-button
|
||||
[mdMenuTriggerFor]="mnuOpenWith">
|
||||
Open with
|
||||
<md-icon>arrow_drop_down</md-icon>
|
||||
</button>
|
||||
<md-menu #mnuOpenWith="mdMenu" [overlapTrigger]="false">
|
||||
<button md-menu-item>
|
||||
<md-icon>dialpad</md-icon>
|
||||
<span>Option 1</span>
|
||||
</button>
|
||||
<button md-menu-item disabled>
|
||||
<md-icon>voicemail</md-icon>
|
||||
<span>Option 2</span>
|
||||
</button>
|
||||
<button md-menu-item>
|
||||
<md-icon>notifications_off</md-icon>
|
||||
<span>Option 3</span>
|
||||
</button>
|
||||
</md-menu>
|
||||
|
||||
<adf-toolbar-divider></adf-toolbar-divider>
|
||||
|
||||
<button
|
||||
*ngIf="settings.allowDownload && settings.downloadUrl"
|
||||
md-icon-button
|
||||
mdTooltip="Download"
|
||||
(click)="download()">
|
||||
<md-icon>file_download</md-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
*ngIf="settings.allowPrint"
|
||||
md-icon-button
|
||||
mdTooltip="Print">
|
||||
<md-icon>print</md-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
*ngIf="settings.allowShare"
|
||||
md-icon-button
|
||||
mdTooltip="Share">
|
||||
<md-icon>share</md-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
*ngIf="settings.allowMoreMenu"
|
||||
md-icon-button
|
||||
[mdMenuTriggerFor]="menu">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</button>
|
||||
<md-menu #menu="mdMenu">
|
||||
<button md-menu-item>
|
||||
<md-icon>dialpad</md-icon>
|
||||
<span>Redial</span>
|
||||
</button>
|
||||
<button md-menu-item disabled>
|
||||
<md-icon>voicemail</md-icon>
|
||||
<span>Check voicemail</span>
|
||||
</button>
|
||||
<button md-menu-item>
|
||||
<md-icon>notifications_off</md-icon>
|
||||
<span>Disable alerts</span>
|
||||
</button>
|
||||
</md-menu>
|
||||
|
||||
<ng-container *ngIf="settings.allowInfoDrawer">
|
||||
<adf-toolbar-divider></adf-toolbar-divider>
|
||||
|
||||
<button md-icon-button mdTooltip="Info"
|
||||
[color]="showInfoDrawer ? 'accent' : 'default'"
|
||||
(click)="showInfoDrawer = !showInfoDrawer">
|
||||
<md-icon>info_outline</md-icon>
|
||||
</button>
|
||||
</ng-container>
|
||||
|
||||
</adf-toolbar>
|
||||
|
||||
<md-dialog-content>
|
||||
|
||||
<ng-container *ngIf="isLoading">
|
||||
<div class="adf-viewer-dialog__loading-screen">
|
||||
<h2>Loading</h2>
|
||||
<div>
|
||||
<md-spinner></md-spinner>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="!isLoading" [ngSwitch]="viewerType">
|
||||
|
||||
<ng-container *ngSwitchCase="'image'">
|
||||
<div class="adf-viewer-dialog__image-view">
|
||||
<img *ngIf="fileUrl" [src]="fileUrl">
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'text'">
|
||||
<div class="adf-viewer-dialog__text-view">
|
||||
<pre>{{ asText | async }}</pre>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'pdf'">
|
||||
<adf-pdf-view
|
||||
class="adf-viewer-dialog__pdf-view"
|
||||
[fileUrl]="fileUrl">
|
||||
</adf-pdf-view>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'video'">
|
||||
<div class="adf-viewer-dialog__video-view">
|
||||
<video controls>
|
||||
<source [src]="fileUrl" [type]="fileMimeType">
|
||||
</video>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'audio'">
|
||||
<div class="adf-viewer-dialog__audio-view">
|
||||
<video controls>
|
||||
<source [src]="fileUrl" [type]="fileMimeType">
|
||||
</video>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchDefault>
|
||||
<div class="adf-viewer-dialog-unknown-view">
|
||||
<div>
|
||||
<md-icon class="icon">{{ unknownFormatIcon }}</md-icon>
|
||||
<div class="label">{{ unknownFormatText | translate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="showInfoDrawer">
|
||||
<div class="adf-viewer-dialog__info-drawer">
|
||||
<md-tab-group md-stretch-tabs>
|
||||
<md-tab label="Details">
|
||||
<md-card>
|
||||
DETAILS
|
||||
</md-card>
|
||||
</md-tab>
|
||||
<md-tab label="Activity">
|
||||
<md-card>
|
||||
Activity
|
||||
</md-card>
|
||||
</md-tab>
|
||||
</md-tab-group>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</md-dialog-content>
|
@@ -1,109 +0,0 @@
|
||||
.adf-viewer-dialog-panel {
|
||||
.mat-dialog-container {
|
||||
padding: 0;
|
||||
max-width: none;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
.adf-viewer-dialog {
|
||||
|
||||
.mat-dialog-content {
|
||||
display: flex;
|
||||
max-height: 100vh;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__mimetype-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
&__loading-screen {
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 85vh;
|
||||
|
||||
.md-spinner {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__info-drawer {
|
||||
width: 350px;
|
||||
display: block;
|
||||
padding: 8px 0;
|
||||
background-color: #FAFAFA;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.27);
|
||||
|
||||
.mat-tab-label {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.mat-card {
|
||||
margin: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&-unknown-view {
|
||||
height: 90vh;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__image-view {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
height: 95vh;
|
||||
img {
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&__text-view {
|
||||
display: flex;
|
||||
background-color: white;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
|
||||
& > pre {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__video-view {
|
||||
video {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
max-height: 90vh;
|
||||
}
|
||||
}
|
||||
|
||||
&__audio-view {
|
||||
video {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
max-height: 90vh;
|
||||
}
|
||||
}
|
||||
|
||||
&__pdf-view {
|
||||
.viewer-pdf-container {
|
||||
top: 50px;
|
||||
border: 1px solid lightgray;
|
||||
background-color: lightgray;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,176 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { MD_DIALOG_DATA, MdDialogRef } from '@angular/material';
|
||||
import { RenditionsService } from 'ng2-alfresco-core';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ViewerDialogSettings } from './viewer-dialog.settings';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-viewer-dialog',
|
||||
templateUrl: 'viewer-dialog.component.html',
|
||||
styleUrls: ['viewer-dialog.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { 'class': 'adf-viewer-dialog' }
|
||||
})
|
||||
export class ViewerDialogComponent implements OnInit {
|
||||
|
||||
fileName: string = 'Unknown file';
|
||||
fileUrl: string = null;
|
||||
fileMimeType: string = null;
|
||||
|
||||
unknownFormatIcon = 'wifi_tethering';
|
||||
unknownFormatText = 'Document preview could not be loaded.';
|
||||
|
||||
isLoading: boolean = false;
|
||||
showInfoDrawer = false;
|
||||
viewerType: string = null;
|
||||
asText: Observable<string>;
|
||||
|
||||
settings: ViewerDialogSettings = {
|
||||
allowDownload: true,
|
||||
allowPrint: true,
|
||||
allowShare: true,
|
||||
allowOpenWith: true,
|
||||
allowMoreMenu: true,
|
||||
allowInfoDrawer: true
|
||||
};
|
||||
|
||||
private types = [
|
||||
{ mimeType: 'application/x-javascript', type: 'text' },
|
||||
{ mimeType: 'application/pdf', type: 'pdf' }
|
||||
];
|
||||
|
||||
constructor(private dialogRef: MdDialogRef<ViewerDialogComponent>,
|
||||
@Inject(MD_DIALOG_DATA) settings: ViewerDialogSettings,
|
||||
private http: Http,
|
||||
private renditionService: RenditionsService) {
|
||||
this.settings = Object.assign({}, this.settings, settings);
|
||||
this.setupDialog(this.settings);
|
||||
}
|
||||
|
||||
private setupDialog(settings: ViewerDialogSettings) {
|
||||
this.fileUrl = settings.fileUrl;
|
||||
this.fileName = settings.fileName;
|
||||
this.fileMimeType = settings.fileMimeType;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.viewerType = this.detectViewerType(this.fileMimeType);
|
||||
this.asText = this.getAsText();
|
||||
|
||||
if (this.viewerType === 'unknown') {
|
||||
this.settings.allowInfoDrawer = false;
|
||||
|
||||
if (this.settings.nodeId) {
|
||||
this.displayAsPdf(this.settings.nodeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private detectViewerType(mimeType: string) {
|
||||
if (mimeType) {
|
||||
mimeType = mimeType.toLowerCase();
|
||||
|
||||
if (mimeType.startsWith('image/')) {
|
||||
return 'image';
|
||||
}
|
||||
|
||||
if (mimeType.startsWith('text/')) {
|
||||
return 'text';
|
||||
}
|
||||
|
||||
if (mimeType.startsWith('video/')) {
|
||||
return 'video';
|
||||
}
|
||||
|
||||
if (mimeType.startsWith('audio/')) {
|
||||
return 'audio';
|
||||
}
|
||||
|
||||
const registered = this.types.find(t => t.mimeType === mimeType);
|
||||
if (registered) {
|
||||
return registered.type;
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
download() {
|
||||
if (this.settings.downloadUrl && this.fileName) {
|
||||
const link = document.createElement('a');
|
||||
|
||||
link.style.display = 'none';
|
||||
link.download = this.fileName;
|
||||
link.href = this.settings.downloadUrl;
|
||||
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
private getAsText(): Observable<string> {
|
||||
return this.http.get(this.fileUrl).map((res: Response) => res.text());
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
|
||||
private displayAsPdf(nodeId: string) {
|
||||
this.isLoading = true;
|
||||
|
||||
this.renditionService.getRendition(nodeId, 'pdf').subscribe(
|
||||
(response) => {
|
||||
const status = response.entry.status.toString();
|
||||
|
||||
if (status === 'CREATED') {
|
||||
this.isLoading = false;
|
||||
this.showRenditionPdf(nodeId);
|
||||
} else if (status === 'NOT_CREATED') {
|
||||
this.renditionService.convert(nodeId, 'pdf').subscribe({
|
||||
complete: () => {
|
||||
this.isLoading = false;
|
||||
this.showRenditionPdf(nodeId);
|
||||
},
|
||||
error: (error) => {
|
||||
this.isLoading = false;
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
this.isLoading = false;
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private showRenditionPdf(nodeId: string) {
|
||||
if (nodeId) {
|
||||
this.viewerType = 'pdf';
|
||||
this.fileUrl = this.renditionService.getRenditionUrl(nodeId, 'pdf');
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface ViewerDialogSettings {
|
||||
fileUrl?: string;
|
||||
fileMimeType?: string;
|
||||
fileName?: string;
|
||||
downloadUrl?: string;
|
||||
nodeId?: string;
|
||||
|
||||
allowDownload?: boolean;
|
||||
allowPrint?: boolean;
|
||||
allowShare?: boolean;
|
||||
allowOpenWith?: boolean;
|
||||
allowMoreMenu?: boolean;
|
||||
allowInfoDrawer?: boolean;
|
||||
}
|
@@ -96,7 +96,6 @@
|
||||
|
||||
<div *ngIf="!isLoading" class="adf-viewer-layout">
|
||||
<div class="adf-viewer-layout-content">
|
||||
<div>
|
||||
<div class="adf-viewer-content-container" [ngSwitch]="viewerType">
|
||||
|
||||
<ng-container *ngSwitchCase="'pdf'">
|
||||
@@ -132,7 +131,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<ng-container *ngIf="showInfoDrawer">
|
||||
<div class="adf-viewer__info-drawer">
|
||||
<md-tab-group md-stretch-tabs>
|
||||
|
@@ -1,67 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MdDialog } from '@angular/material';
|
||||
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
import { AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
|
||||
import { ViewerDialogComponent } from './../components/viewer-dialog/viewer-dialog.component';
|
||||
import { ViewerDialogSettings } from './../components/viewer-dialog/viewer-dialog.settings';
|
||||
|
||||
@Injectable()
|
||||
export class ViewerService {
|
||||
|
||||
constructor(private dialog: MdDialog,
|
||||
private apiService: AlfrescoApiService) {
|
||||
}
|
||||
|
||||
showViewerForNode(node: MinimalNodeEntryEntity, settings: ViewerDialogSettings = {}): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
const dialogSettings = Object.assign({}, settings, {
|
||||
fileName: node.name,
|
||||
fileMimeType: node.content.mimeType,
|
||||
fileUrl: this.apiService.contentApi.getContentUrl(node.id, false),
|
||||
downloadUrl: this.apiService.contentApi.getContentUrl(node.id, true),
|
||||
nodeId: node.id
|
||||
});
|
||||
|
||||
const dialogRef = this.dialog.open(ViewerDialogComponent, {
|
||||
panelClass: 'adf-viewer-dialog-panel',
|
||||
data: dialogSettings
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
showViewerForNodeId(nodeId: string, settings: ViewerDialogSettings = {}): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.apiService.nodesApi.getNode(nodeId).then(
|
||||
(node: MinimalNodeEntity) => {
|
||||
if (node && node.entry && node.entry.isFile) {
|
||||
return this.showViewerForNode(node.entry, settings);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user