mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-1623] routing integration for Viewer (#2404)
* routed viewer (demo app) * toolbar support * app menu component for demo shell * navigate back button * fix unit tests * improve viewer type detection and rendering * download button * automatic pdf rendition, spinners, ui tweaks * border for pdf pages * scroll top support * docs update * info drawer placeholder
This commit is contained in:
committed by
Maurizio Vitale
parent
55a999b492
commit
93a87af4a5
@@ -1,97 +1 @@
|
|||||||
<md-toolbar color="primary" *ngIf="!isAPageWithHeaderBar()" class="adf-app-toolbar" >
|
|
||||||
<adf-userinfo
|
|
||||||
class="adf-app-user-profile"
|
|
||||||
[menuPositionX]="'before'"
|
|
||||||
[menuPositionY]="'above'">
|
|
||||||
</adf-userinfo>
|
|
||||||
|
|
||||||
<span class="adf-app-hide-xsmall" >ADF Demo Application</span>
|
|
||||||
|
|
||||||
<div class="adf-app-menu-spacer"></div>
|
|
||||||
|
|
||||||
<search-bar></search-bar>
|
|
||||||
|
|
||||||
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="home" href="" routerLink="/">Home</a>
|
|
||||||
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="files" href="" routerLink="/files">Content Services</a>
|
|
||||||
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="activiti" href="" routerLink="/activiti">Process Services</a>
|
|
||||||
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="login" href="" routerLink="/login">Login</a>
|
|
||||||
|
|
||||||
<theme-picker></theme-picker>
|
|
||||||
<button md-icon-button [mdMenuTriggerFor]="langMenu">
|
|
||||||
<md-icon>language</md-icon>
|
|
||||||
</button>
|
|
||||||
<md-menu #langMenu="mdMenu">
|
|
||||||
<button md-menu-item (click)="changeLanguage('en')">English</button>
|
|
||||||
<button md-menu-item (click)="changeLanguage('it')">Italian</button>
|
|
||||||
<button md-menu-item (click)="changeLanguage('ru')">Russian</button>
|
|
||||||
</md-menu>
|
|
||||||
|
|
||||||
<button md-icon-button [mdMenuTriggerFor]="appMenu">
|
|
||||||
<md-icon>more_vert</md-icon>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<md-menu #appMenu="mdMenu">
|
|
||||||
<a md-menu-item href="" routerLink="/">
|
|
||||||
<md-icon>home</md-icon>
|
|
||||||
<span>Home</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/files">
|
|
||||||
<md-icon>folder_open</md-icon>
|
|
||||||
<span>Content Services</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/activiti">
|
|
||||||
<md-icon>device_hub</md-icon>
|
|
||||||
<span>Process Services</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/login">
|
|
||||||
<md-icon>vpn_key</md-icon>
|
|
||||||
<span>Login</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/dl-custom-sources">
|
|
||||||
<md-icon>extension</md-icon>
|
|
||||||
<span>DL: Custom Sources</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/datatable">
|
|
||||||
<md-icon>view_module</md-icon>
|
|
||||||
<span>DataTable</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/form">
|
|
||||||
<md-icon>poll</md-icon>
|
|
||||||
<span>Form</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/form-list">
|
|
||||||
<md-icon>library_books</md-icon>
|
|
||||||
<span>Form List</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/uploader">
|
|
||||||
<md-icon>file_upload</md-icon>
|
|
||||||
<span>Uploader</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/webscript">
|
|
||||||
<md-icon>extension</md-icon>
|
|
||||||
<span>Webscript</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/tag">
|
|
||||||
<md-icon>local_offer</md-icon>
|
|
||||||
<span>Tag</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/social">
|
|
||||||
<md-icon>thumb_up</md-icon>
|
|
||||||
<span>Social</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/settings">
|
|
||||||
<md-icon>settings</md-icon>
|
|
||||||
<span>Settings</span>
|
|
||||||
</a>
|
|
||||||
<a md-menu-item href="" routerLink="/about">
|
|
||||||
<md-icon>info_outline</md-icon>
|
|
||||||
<span>About</span>
|
|
||||||
</a>
|
|
||||||
<button md-menu-item adf-logout>
|
|
||||||
<md-icon>exit_to_app</md-icon>
|
|
||||||
<span>Logout</span>
|
|
||||||
</button>
|
|
||||||
</md-menu>
|
|
||||||
</md-toolbar>
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
@@ -16,33 +16,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, ViewEncapsulation } from '@angular/core';
|
import { Component, ViewEncapsulation } from '@angular/core';
|
||||||
import { AlfrescoSettingsService, AlfrescoTranslationService, PageTitle, StorageService } from 'ng2-alfresco-core';
|
import { AlfrescoSettingsService, PageTitle, StorageService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-app',
|
selector: 'adf-app',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.scss', './theme.scss'],
|
styleUrls: ['./theme.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
searchTerm: string = '';
|
searchTerm: string = '';
|
||||||
|
|
||||||
constructor(private settingsService: AlfrescoSettingsService,
|
constructor(private settingsService: AlfrescoSettingsService,
|
||||||
private translateService: AlfrescoTranslationService,
|
|
||||||
private storage: StorageService,
|
private storage: StorageService,
|
||||||
pageTitle: PageTitle) {
|
pageTitle: PageTitle) {
|
||||||
this.setProvider();
|
this.setProvider();
|
||||||
pageTitle.setTitle();
|
pageTitle.setTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
isAPageWithHeaderBar(): boolean {
|
|
||||||
return location.pathname === '/login' || location.pathname === '/settings';
|
|
||||||
}
|
|
||||||
|
|
||||||
changeLanguage(lang: string) {
|
|
||||||
this.translateService.use(lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
private setProvider() {
|
private setProvider() {
|
||||||
if (this.storage.hasItem(`providers`)) {
|
if (this.storage.hasItem(`providers`)) {
|
||||||
this.settingsService.setProviders(this.storage.getItem(`providers`));
|
this.settingsService.setProviders(this.storage.getItem(`providers`));
|
||||||
|
@@ -41,6 +41,8 @@ import { ChartsModule } from 'ng2-charts';
|
|||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { routing } from './app.routes';
|
import { routing } from './app.routes';
|
||||||
import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component';
|
import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component';
|
||||||
|
import { AppMenuComponent } from './components/app-menu/app-menu.component';
|
||||||
|
import { FileViewComponent } from './components/file-view/file-view.component';
|
||||||
import { FormListDemoComponent } from './components/form/form-list-demo.component';
|
import { FormListDemoComponent } from './components/form/form-list-demo.component';
|
||||||
import { ThemePickerModule } from './components/theme-picker/theme-picker';
|
import { ThemePickerModule } from './components/theme-picker/theme-picker';
|
||||||
import { MaterialModule } from './material.module';
|
import { MaterialModule } from './material.module';
|
||||||
@@ -119,7 +121,9 @@ import {
|
|||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
FormDemoComponent,
|
FormDemoComponent,
|
||||||
FormListDemoComponent,
|
FormListDemoComponent,
|
||||||
CustomSourcesComponent
|
CustomSourcesComponent,
|
||||||
|
FileViewComponent,
|
||||||
|
AppMenuComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: AppConfigService, useClass: DebugAppConfigService },
|
{ provide: AppConfigService, useClass: DebugAppConfigService },
|
||||||
|
@@ -39,6 +39,7 @@ import {
|
|||||||
} from './components/index';
|
} from './components/index';
|
||||||
|
|
||||||
import { UploadButtonComponent } from 'ng2-alfresco-upload';
|
import { UploadButtonComponent } from 'ng2-alfresco-upload';
|
||||||
|
import { FileViewComponent } from './components/file-view/file-view.component';
|
||||||
import { CustomSourcesComponent } from './components/files/custom-sources.component';
|
import { CustomSourcesComponent } from './components/files/custom-sources.component';
|
||||||
import { FormListDemoComponent } from './components/form/form-list-demo.component';
|
import { FormListDemoComponent } from './components/form/form-list-demo.component';
|
||||||
|
|
||||||
@@ -64,6 +65,11 @@ export const appRoutes: Routes = [
|
|||||||
component: FilesComponent,
|
component: FilesComponent,
|
||||||
canActivate: [AuthGuardEcm]
|
canActivate: [AuthGuardEcm]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'files/:nodeId/view',
|
||||||
|
component: FileViewComponent,
|
||||||
|
canActivate: [ AuthGuardEcm ]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'dl-custom-sources',
|
path: 'dl-custom-sources',
|
||||||
component: CustomSourcesComponent,
|
component: CustomSourcesComponent,
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<div class="about-container">
|
<div class="about-container">
|
||||||
<h3>Server settings</h3>
|
<h3>Server settings</h3>
|
||||||
<md-list>
|
<md-list>
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Http } from '@angular/http';
|
import { Http } from '@angular/http';
|
||||||
import { AlfrescoAuthenticationService, AppConfigService, BpmProductVersionModel, DiscoveryApiService, EcmProductVersionModel, LogService } from 'ng2-alfresco-core';
|
import { AlfrescoAuthenticationService, AppConfigService, BpmProductVersionModel, DiscoveryApiService, EcmProductVersionModel } from 'ng2-alfresco-core';
|
||||||
import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
|
import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -40,7 +40,6 @@ export class AboutComponent implements OnInit {
|
|||||||
constructor(private http: Http,
|
constructor(private http: Http,
|
||||||
private appConfig: AppConfigService,
|
private appConfig: AppConfigService,
|
||||||
private authService: AlfrescoAuthenticationService,
|
private authService: AlfrescoAuthenticationService,
|
||||||
private logService: LogService,
|
|
||||||
private discovery: DiscoveryApiService) {
|
private discovery: DiscoveryApiService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,13 +61,11 @@ export class AboutComponent implements OnInit {
|
|||||||
let regexp = new RegExp('^(ng2-activiti|ng2-alfresco|alfresco-)');
|
let regexp = new RegExp('^(ng2-activiti|ng2-alfresco|alfresco-)');
|
||||||
|
|
||||||
let alfrescoPackages = Object.keys(response.json().dependencies).filter((val) => {
|
let alfrescoPackages = Object.keys(response.json().dependencies).filter((val) => {
|
||||||
this.logService.log(val);
|
|
||||||
return regexp.test(val);
|
return regexp.test(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
let alfrescoPackagesTableRepresentation = [];
|
let alfrescoPackagesTableRepresentation = [];
|
||||||
alfrescoPackages.forEach((val) => {
|
alfrescoPackages.forEach((val) => {
|
||||||
this.logService.log(response.json().dependencies[val]);
|
|
||||||
alfrescoPackagesTableRepresentation.push({
|
alfrescoPackagesTableRepresentation.push({
|
||||||
name: val,
|
name: val,
|
||||||
version: response.json().dependencies[val].version
|
version: response.json().dependencies[val].version
|
||||||
@@ -77,8 +74,6 @@ export class AboutComponent implements OnInit {
|
|||||||
|
|
||||||
this.gitHubLinkCreation(alfrescoPackagesTableRepresentation);
|
this.gitHubLinkCreation(alfrescoPackagesTableRepresentation);
|
||||||
|
|
||||||
this.logService.log(alfrescoPackagesTableRepresentation);
|
|
||||||
|
|
||||||
this.data = new ObjectDataTableAdapter(alfrescoPackagesTableRepresentation, [
|
this.data = new ObjectDataTableAdapter(alfrescoPackagesTableRepresentation, [
|
||||||
{type: 'text', key: 'name', title: 'Name', sortable: true},
|
{type: 'text', key: 'name', title: 'Name', sortable: true},
|
||||||
{type: 'text', key: 'version', title: 'Version', sortable: true}
|
{type: 'text', key: 'version', title: 'Version', sortable: true}
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<md-tab-group [(selectedIndex)]="activeTab">
|
<md-tab-group [(selectedIndex)]="activeTab">
|
||||||
<md-tab id="tasks-header" href="#tasks" label="{{'PS-TAB.TASKS-TAB' | translate}}">
|
<md-tab id="tasks-header" href="#tasks" label="{{'PS-TAB.TASKS-TAB' | translate}}">
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
|
@@ -22,6 +22,7 @@ import { AppDefinitionRepresentationModel } from 'ng2-activiti-tasklist';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'activiti-apps-view',
|
selector: 'activiti-apps-view',
|
||||||
template: `
|
template: `
|
||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
<activiti-apps (appClick)="onAppClicked($event)"></activiti-apps>
|
<activiti-apps (appClick)="onAppClicked($event)"></activiti-apps>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
|
@@ -0,0 +1,96 @@
|
|||||||
|
<md-toolbar color="primary" class="adf-app-toolbar">
|
||||||
|
<adf-userinfo
|
||||||
|
class="adf-app-user-profile"
|
||||||
|
[menuPositionX]="'before'"
|
||||||
|
[menuPositionY]="'above'">
|
||||||
|
</adf-userinfo>
|
||||||
|
|
||||||
|
<span class="adf-app-hide-xsmall">ADF Demo Application</span>
|
||||||
|
|
||||||
|
<div class="adf-app-menu-spacer"></div>
|
||||||
|
|
||||||
|
<search-bar></search-bar>
|
||||||
|
|
||||||
|
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="home" href="" routerLink="/">Home</a>
|
||||||
|
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="files" href="" routerLink="/files">Content Services</a>
|
||||||
|
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="activiti" href="" routerLink="/activiti">Process Services</a>
|
||||||
|
<a class="adf-app-hide-xsmall adf-app-hide-small" md-button data-automation-id="login" href="" routerLink="/login">Login</a>
|
||||||
|
|
||||||
|
<theme-picker></theme-picker>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="langMenu">
|
||||||
|
<md-icon>language</md-icon>
|
||||||
|
</button>
|
||||||
|
<md-menu #langMenu="mdMenu">
|
||||||
|
<button md-menu-item (click)="changeLanguage('en')">English</button>
|
||||||
|
<button md-menu-item (click)="changeLanguage('it')">Italian</button>
|
||||||
|
<button md-menu-item (click)="changeLanguage('ru')">Russian</button>
|
||||||
|
</md-menu>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="appMenu">
|
||||||
|
<md-icon>more_vert</md-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<md-menu #appMenu="mdMenu">
|
||||||
|
<a md-menu-item href="" routerLink="/">
|
||||||
|
<md-icon>home</md-icon>
|
||||||
|
<span>Home</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/files">
|
||||||
|
<md-icon>folder_open</md-icon>
|
||||||
|
<span>Content Services</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/activiti">
|
||||||
|
<md-icon>device_hub</md-icon>
|
||||||
|
<span>Process Services</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/login">
|
||||||
|
<md-icon>vpn_key</md-icon>
|
||||||
|
<span>Login</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/dl-custom-sources">
|
||||||
|
<md-icon>extension</md-icon>
|
||||||
|
<span>DL: Custom Sources</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/datatable">
|
||||||
|
<md-icon>view_module</md-icon>
|
||||||
|
<span>DataTable</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/form">
|
||||||
|
<md-icon>poll</md-icon>
|
||||||
|
<span>Form</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/form-list">
|
||||||
|
<md-icon>library_books</md-icon>
|
||||||
|
<span>Form List</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/uploader">
|
||||||
|
<md-icon>file_upload</md-icon>
|
||||||
|
<span>Uploader</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/webscript">
|
||||||
|
<md-icon>extension</md-icon>
|
||||||
|
<span>Webscript</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/tag">
|
||||||
|
<md-icon>local_offer</md-icon>
|
||||||
|
<span>Tag</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/social">
|
||||||
|
<md-icon>thumb_up</md-icon>
|
||||||
|
<span>Social</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/settings">
|
||||||
|
<md-icon>settings</md-icon>
|
||||||
|
<span>Settings</span>
|
||||||
|
</a>
|
||||||
|
<a md-menu-item href="" routerLink="/about">
|
||||||
|
<md-icon>info_outline</md-icon>
|
||||||
|
<span>About</span>
|
||||||
|
</a>
|
||||||
|
<button md-menu-item adf-logout>
|
||||||
|
<md-icon>exit_to_app</md-icon>
|
||||||
|
<span>Logout</span>
|
||||||
|
</button>
|
||||||
|
</md-menu>
|
||||||
|
</md-toolbar>
|
@@ -1,6 +1,5 @@
|
|||||||
@import '~@angular/material/theming';
|
@import '~@angular/material/theming';
|
||||||
|
|
||||||
|
|
||||||
.adf-app-user-profile {
|
.adf-app-user-profile {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
34
demo-shell-ng2/app/components/app-menu/app-menu.component.ts
Normal file
34
demo-shell-ng2/app/components/app-menu/app-menu.component.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*!
|
||||||
|
* @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 } from '@angular/core';
|
||||||
|
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-app-menu',
|
||||||
|
templateUrl: 'app-menu.component.html',
|
||||||
|
styleUrls: ['app-menu.component.scss']
|
||||||
|
})
|
||||||
|
export class AppMenuComponent {
|
||||||
|
|
||||||
|
constructor(private translateService: AlfrescoTranslationService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
changeLanguage(lang: string) {
|
||||||
|
this.translateService.use(lang);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<div class="p-10">
|
<div class="p-10">
|
||||||
<alfresco-datatable
|
<alfresco-datatable
|
||||||
[data]="data"
|
[data]="data"
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
<ng-container *ngIf="nodeId">
|
||||||
|
<adf-viewer [fileNodeId]="nodeId">
|
||||||
|
<extension-viewer [supportedExtensions]="['obj','3DS']" #extension>
|
||||||
|
<ng-template let-urlFileContent="urlFileContent" let-extension="extension" >
|
||||||
|
<threed-viewer [urlFile]="urlFileContent" [extension]="extension" ></threed-viewer>
|
||||||
|
</ng-template>
|
||||||
|
</extension-viewer>
|
||||||
|
</adf-viewer>
|
||||||
|
</ng-container>
|
@@ -0,0 +1,36 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { AlfrescoApiService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-file-view',
|
||||||
|
templateUrl: 'file-view.component.html'
|
||||||
|
})
|
||||||
|
export class FileViewComponent implements OnInit {
|
||||||
|
|
||||||
|
nodeId: string = null;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private apiService: AlfrescoApiService) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.route.params.subscribe(params => {
|
||||||
|
const id = params.nodeId;
|
||||||
|
if (id) {
|
||||||
|
this.apiService.getInstance().nodes.getNodeInfo(id).then(
|
||||||
|
(node) => {
|
||||||
|
if (node && node.isFile) {
|
||||||
|
this.nodeId = id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.router.navigate(['/files', id]);
|
||||||
|
},
|
||||||
|
() => this.router.navigate(['/files', id])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,3 +1,4 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
<adf-toolbar>
|
<adf-toolbar>
|
||||||
<adf-toolbar-title>
|
<adf-toolbar-title>
|
||||||
<md-select [(ngModel)]="selectedSource">
|
<md-select [(ngModel)]="selectedSource">
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="adf-demo-site-container-style" id="demo-container">
|
<div class="adf-demo-site-container-style" id="demo-container">
|
||||||
<adf-sites-dropdown (change)="getSiteContent($event)">
|
<adf-sites-dropdown (change)="getSiteContent($event)">
|
||||||
@@ -225,14 +227,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<section *ngIf="!useViewerDialog">
|
|
||||||
<md-slide-toggle [color]="'primary'" [(ngModel)]="useInlineViewer">Use inline viewer (no overlay)</md-slide-toggle>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<md-slide-toggle [color]="'primary'" [(ngModel)]="useViewerDialog">Use File Viewer dialog</md-slide-toggle>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<md-slide-toggle [color]="'primary'" [(ngModel)]="multiselect">Multiselect (with checkboxes)</md-slide-toggle>
|
<md-slide-toggle [color]="'primary'" [(ngModel)]="multiselect">Multiselect (with checkboxes)</md-slide-toggle>
|
||||||
</section>
|
</section>
|
||||||
@@ -309,29 +303,3 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<file-uploading-dialog #fileDialog></file-uploading-dialog>
|
<file-uploading-dialog #fileDialog></file-uploading-dialog>
|
||||||
|
|
||||||
<div *ngIf="showViewer">
|
|
||||||
<ng-container *ngIf="!useInlineViewer">
|
|
||||||
<adf-viewer
|
|
||||||
[(showViewer)]="showViewer"
|
|
||||||
[fileNodeId]="fileNodeId"
|
|
||||||
[overlayMode]="true">
|
|
||||||
|
|
||||||
<extension-viewer [supportedExtensions]="['obj','3DS']" #extension>
|
|
||||||
<ng-template let-urlFileContent="urlFileContent" let-extension="extension" >
|
|
||||||
<threed-viewer [urlFile]="urlFileContent" [extension]="extension" ></threed-viewer>
|
|
||||||
</ng-template>
|
|
||||||
</extension-viewer>
|
|
||||||
|
|
||||||
</adf-viewer>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngIf="useInlineViewer">
|
|
||||||
<div class="adf-not-overlay-viewer">
|
|
||||||
<adf-viewer
|
|
||||||
[(showViewer)]="showViewer"
|
|
||||||
[fileNodeId]="fileNodeId">
|
|
||||||
</adf-viewer>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
|
@@ -27,8 +27,6 @@ import {
|
|||||||
import { DataColumn, DataRow } from 'ng2-alfresco-datatable';
|
import { DataColumn, DataRow } from 'ng2-alfresco-datatable';
|
||||||
import { DocumentListComponent, PermissionStyleModel } from 'ng2-alfresco-documentlist';
|
import { DocumentListComponent, PermissionStyleModel } from 'ng2-alfresco-documentlist';
|
||||||
|
|
||||||
import { ViewerService } from 'ng2-alfresco-viewer';
|
|
||||||
|
|
||||||
const DEFAULT_FOLDER_TO_SHOW = '-my-';
|
const DEFAULT_FOLDER_TO_SHOW = '-my-';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -46,8 +44,6 @@ export class FilesComponent implements OnInit {
|
|||||||
|
|
||||||
toolbarColor = 'default';
|
toolbarColor = 'default';
|
||||||
useDropdownBreadcrumb = false;
|
useDropdownBreadcrumb = false;
|
||||||
useViewerDialog = true;
|
|
||||||
useInlineViewer = false;
|
|
||||||
|
|
||||||
selectionModes = [
|
selectionModes = [
|
||||||
{ value: 'none', viewValue: 'None' },
|
{ value: 'none', viewValue: 'None' },
|
||||||
@@ -91,27 +87,14 @@ export class FilesComponent implements OnInit {
|
|||||||
private contentService: AlfrescoContentService,
|
private contentService: AlfrescoContentService,
|
||||||
private dialog: MdDialog,
|
private dialog: MdDialog,
|
||||||
private translateService: AlfrescoTranslationService,
|
private translateService: AlfrescoTranslationService,
|
||||||
private viewerService: ViewerService,
|
|
||||||
private router: Router,
|
private router: Router,
|
||||||
@Optional() private route: ActivatedRoute) {
|
@Optional() private route: ActivatedRoute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
showFile(event) {
|
showFile(event) {
|
||||||
if (this.useViewerDialog) {
|
const entry = event.value.entry;
|
||||||
if (event.value.entry.isFile) {
|
if (entry && entry.isFile) {
|
||||||
this.viewerService
|
this.router.navigate(['/files', entry.id, 'view']);
|
||||||
.showViewerForNode(event.value.entry)
|
|
||||||
.then(result => {
|
|
||||||
console.log(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (event.value.entry.isFile) {
|
|
||||||
this.fileNodeId = event.value.entry.id;
|
|
||||||
this.showViewer = true;
|
|
||||||
} else {
|
|
||||||
this.showViewer = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<adf-form [form]="form">
|
<adf-form [form]="form">
|
||||||
</adf-form>
|
</adf-form>
|
||||||
|
@@ -22,6 +22,7 @@ import { ActivitiForm } from 'ng2-activiti-form';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'form-list-demo',
|
selector: 'form-list-demo',
|
||||||
template: `
|
template: `
|
||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
<adf-form-list [forms]="formList" (row-dblclick)="onRowDblClick($event)">
|
<adf-form-list [forms]="formList" (row-dblclick)="onRowDblClick($event)">
|
||||||
</adf-form-list>
|
</adf-form-list>
|
||||||
<div class="form-container" *ngIf="!isEmptyForm()">
|
<div class="form-container" *ngIf="!isEmptyForm()">
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<!-- DOCUMENT LIST-->
|
<!-- DOCUMENT LIST-->
|
||||||
<md-card class="adf-home-card">
|
<md-card class="adf-home-card">
|
||||||
<md-card-title class="adf-home-card-title adf-primary-background-color" routerLink="/files">
|
<md-card-title class="adf-home-card-title adf-primary-background-color" routerLink="/files">
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
||||||
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
||||||
<md-grid-list cols="2" rowHeight="100px">
|
<md-grid-list cols="2" rowHeight="100px">
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
|
|
||||||
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
<label for="nodeId"><b>Insert Node Id</b></label><br>
|
||||||
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
<input id="nodeId" type="text" size="48" [(ngModel)]="nodeId"><br>
|
||||||
<div class="adf-tag-example-area">
|
<div class="adf-tag-example-area">
|
||||||
|
@@ -21,6 +21,7 @@ import { LogService } from 'ng2-alfresco-core';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'alfresco-webscript-demo',
|
selector: 'alfresco-webscript-demo',
|
||||||
template: `
|
template: `
|
||||||
|
<adf-app-menu></adf-app-menu>
|
||||||
<label for="script-path"><b>Insert a scriptPath</b></label><br>
|
<label for="script-path"><b>Insert a scriptPath</b></label><br>
|
||||||
<input id="script-path" type="text" size="48" [(ngModel)]="scriptPath"><br>
|
<input id="script-path" type="text" size="48" [(ngModel)]="scriptPath"><br>
|
||||||
<label for="context-root"><b>Insert a contextRoot</b></label><br>
|
<label for="context-root"><b>Insert a contextRoot</b></label><br>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 55 KiB |
@@ -7,7 +7,7 @@ See it live: [Viewer Quickstart](https://embed.plnkr.co/iTuG1lFIXfsP95l6bDW6/)
|
|||||||
<!-- toc -->
|
<!-- toc -->
|
||||||
|
|
||||||
- [Basic usage](#basic-usage)
|
- [Basic usage](#basic-usage)
|
||||||
* [Properties](#properties)
|
- [Properties](#properties)
|
||||||
- [Details](#details)
|
- [Details](#details)
|
||||||
* [Supported file formats](#supported-file-formats)
|
* [Supported file formats](#supported-file-formats)
|
||||||
* [PDF Conversion](#pdf-conversion)
|
* [PDF Conversion](#pdf-conversion)
|
||||||
@@ -39,9 +39,9 @@ Using with file url:
|
|||||||
</adf-viewer>
|
</adf-viewer>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Properties
|
## Properties
|
||||||
|
|
||||||
| Attribute | Options | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| fileNodeId | string | | Node Id of the file to load |
|
| fileNodeId | string | | Node Id of the file to load |
|
||||||
| urlFile | string | | If you want to load an external file that does not come from ECM you can use this Url where to load the file |
|
| urlFile | string | | If you want to load an external file that does not come from ECM you can use this Url where to load the file |
|
||||||
@@ -50,6 +50,13 @@ Using with file url:
|
|||||||
| showViewer | boolean | true | Hide or show the viewer |
|
| showViewer | boolean | true | Hide or show the viewer |
|
||||||
| showToolbar | boolean | true | Hide or show the toolbars |
|
| showToolbar | boolean | true | Hide or show the toolbars |
|
||||||
| displayName | string | | You can specify the name of the file |
|
| displayName | string | | You can specify the name of the file |
|
||||||
|
| allowGoBack | boolean | true | Allow `back` navigation |
|
||||||
|
| allowOpenWith | boolean | true | Toggle `Open With` options |
|
||||||
|
| allowDownload | boolean | true | Toggle download feature |
|
||||||
|
| allowPrint | boolean | true | Toggle printing feature |
|
||||||
|
| allowShare | boolean | true | Toggle sharing feature |
|
||||||
|
| allowInfoDrawer | boolean | true | Toogle info drawer feature |
|
||||||
|
| showInfoDrawer | boolean | false | Toggles info drawer visibility. Requires `allowInfoDrawer` to be set to `true`. |
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
@@ -63,9 +70,7 @@ Using with file url:
|
|||||||
|
|
||||||
### PDF Conversion
|
### PDF Conversion
|
||||||
|
|
||||||

|
For unsupported extensions or mime types the viewer will try to fetch PDF rendition utilising the [renditions service api](https://community.alfresco.com/docs/DOC-5879-rendition-service)
|
||||||
|
|
||||||
Note for unsupported extensions the viewer will offer the possibility to convert to PDF if that kind of extension is supported by the [content service renditions service](https://community.alfresco.com/docs/DOC-5879-rendition-service)
|
|
||||||
|
|
||||||
### Configuring PDF.js library
|
### Configuring PDF.js library
|
||||||
|
|
||||||
|
@@ -23,12 +23,13 @@ import { MaterialModule } from './src/material.module';
|
|||||||
export { ViewerComponent } from './src/components/viewer.component';
|
export { ViewerComponent } from './src/components/viewer.component';
|
||||||
import { ImgViewerComponent } from './src/components/imgViewer.component';
|
import { ImgViewerComponent } from './src/components/imgViewer.component';
|
||||||
import { MediaPlayerComponent } from './src/components/mediaPlayer.component';
|
import { MediaPlayerComponent } from './src/components/mediaPlayer.component';
|
||||||
import { NotSupportedFormatComponent } from './src/components/notSupportedFormat.component';
|
|
||||||
import { PdfViewerComponent } from './src/components/pdfViewer.component';
|
import { PdfViewerComponent } from './src/components/pdfViewer.component';
|
||||||
import { TxtViewerComponent } from './src/components/txtViewer.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 { PdfViewComponent } from './src/components/viewer-dialog/pdf-view/pdf-view.component';
|
||||||
import { ViewerDialogComponent } from './src/components/viewer-dialog/viewer-dialog.component';
|
import { ViewerDialogComponent } from './src/components/viewer-dialog/viewer-dialog.component';
|
||||||
import { ViewerComponent } from './src/components/viewer.component';
|
import { ViewerComponent } from './src/components/viewer.component';
|
||||||
|
|
||||||
import { ExtensionViewerDirective } from './src/directives/extension-viewer.directive';
|
import { ExtensionViewerDirective } from './src/directives/extension-viewer.directive';
|
||||||
|
|
||||||
import { RenderingQueueServices } from './src/services/rendering-queue.services';
|
import { RenderingQueueServices } from './src/services/rendering-queue.services';
|
||||||
@@ -38,33 +39,33 @@ export { ViewerDialogComponent } from './src/components/viewer-dialog/viewer-dia
|
|||||||
export { ViewerDialogSettings } from './src/components/viewer-dialog/viewer-dialog.settings';
|
export { ViewerDialogSettings } from './src/components/viewer-dialog/viewer-dialog.settings';
|
||||||
export { ViewerService } from './src/services/viewer.service';
|
export { ViewerService } from './src/services/viewer.service';
|
||||||
|
|
||||||
export const VIEWER_DIRECTIVES: any[] = [
|
export function declarations() {
|
||||||
ViewerComponent,
|
return [
|
||||||
ImgViewerComponent,
|
ViewerComponent,
|
||||||
TxtViewerComponent,
|
ImgViewerComponent,
|
||||||
MediaPlayerComponent,
|
TxtViewerComponent,
|
||||||
NotSupportedFormatComponent,
|
MediaPlayerComponent,
|
||||||
PdfViewerComponent,
|
PdfViewerComponent,
|
||||||
ExtensionViewerDirective,
|
ExtensionViewerDirective,
|
||||||
ViewerDialogComponent,
|
ViewerDialogComponent,
|
||||||
PdfViewComponent
|
PdfViewComponent,
|
||||||
];
|
UnknownFormatComponent
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CoreModule,
|
CoreModule,
|
||||||
MaterialModule
|
MaterialModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: declarations(),
|
||||||
...VIEWER_DIRECTIVES
|
|
||||||
],
|
|
||||||
providers: [
|
providers: [
|
||||||
RenderingQueueServices,
|
RenderingQueueServices,
|
||||||
ViewerService
|
ViewerService
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
MaterialModule,
|
MaterialModule,
|
||||||
...VIEWER_DIRECTIVES
|
...declarations()
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
ViewerDialogComponent
|
ViewerDialogComponent
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
img {
|
img {
|
||||||
|
width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,47 +0,0 @@
|
|||||||
<md-card *ngIf="!isConversionFinished">
|
|
||||||
<md-card-title>
|
|
||||||
Unknown format
|
|
||||||
</md-card-title>
|
|
||||||
<md-card-content>
|
|
||||||
<h4>File '<span>{{nameFile}}</span>' is of an unsupported format</h4>
|
|
||||||
<md-progress-bar
|
|
||||||
*ngIf="isConversionStarted"
|
|
||||||
mode="indeterminate"
|
|
||||||
data-automation-id="viewer-conversion-spinner">
|
|
||||||
</md-progress-bar>
|
|
||||||
</md-card-content>
|
|
||||||
<md-card-actions>
|
|
||||||
<button
|
|
||||||
md-button
|
|
||||||
data-automation-id="viewer-download-button"
|
|
||||||
(click)="download()">
|
|
||||||
<md-icon>cloud_download</md-icon>
|
|
||||||
Download
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
md-button
|
|
||||||
*ngIf="convertible"
|
|
||||||
[disabled]="isConversionStarted"
|
|
||||||
data-automation-id="viewer-convert-button"
|
|
||||||
(click)="convertToPdf()">
|
|
||||||
<md-icon>insert_drive_file</md-icon>
|
|
||||||
Convert to PDF
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
md-button
|
|
||||||
*ngIf="displayable"
|
|
||||||
data-automation-id="viewer-display-button"
|
|
||||||
(click)="showPDF()">
|
|
||||||
<md-icon>insert_drive_file</md-icon>
|
|
||||||
Show PDF
|
|
||||||
</button>
|
|
||||||
</md-card-actions>
|
|
||||||
</md-card>
|
|
||||||
|
|
||||||
<adf-pdf-viewer
|
|
||||||
*ngIf="isConversionFinished"
|
|
||||||
[showToolbar]="showToolbar"
|
|
||||||
[urlFile]="renditionUrl"
|
|
||||||
[nameFile]="nameFile"
|
|
||||||
data-automation-id="pdf-rendition-viewer">
|
|
||||||
</adf-pdf-viewer>
|
|
@@ -1,5 +0,0 @@
|
|||||||
.adf-not-supported-format {
|
|
||||||
.mat-card {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,271 +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 { DebugElement } from '@angular/core';
|
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { ContentService, CoreModule, RenditionsService } from 'ng2-alfresco-core';
|
|
||||||
import { Subject } from 'rxjs/Subject';
|
|
||||||
import { MaterialModule } from './../material.module';
|
|
||||||
import { NotSupportedFormatComponent } from './notSupportedFormat.component';
|
|
||||||
import { PdfViewerComponent } from './pdfViewer.component';
|
|
||||||
|
|
||||||
interface RenditionResponse {
|
|
||||||
entry: {
|
|
||||||
status: string
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('NotSupportedFormatComponent', () => {
|
|
||||||
|
|
||||||
const nodeId = 'not-supported-node-id';
|
|
||||||
|
|
||||||
let component: NotSupportedFormatComponent;
|
|
||||||
let service: ContentService;
|
|
||||||
let fixture: ComponentFixture<NotSupportedFormatComponent>;
|
|
||||||
let debug: DebugElement;
|
|
||||||
let element: HTMLElement;
|
|
||||||
let renditionsService: RenditionsService;
|
|
||||||
|
|
||||||
let renditionSubject: Subject<RenditionResponse>;
|
|
||||||
let conversionSubject: Subject<any>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
CoreModule,
|
|
||||||
MaterialModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
NotSupportedFormatComponent,
|
|
||||||
PdfViewerComponent
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(NotSupportedFormatComponent);
|
|
||||||
service = fixture.debugElement.injector.get(ContentService);
|
|
||||||
debug = fixture.debugElement;
|
|
||||||
element = fixture.nativeElement;
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
component.nodeId = nodeId;
|
|
||||||
|
|
||||||
renditionSubject = new Subject<RenditionResponse>();
|
|
||||||
conversionSubject = new Subject<any>();
|
|
||||||
renditionsService = TestBed.get(RenditionsService);
|
|
||||||
spyOn(renditionsService, 'getRendition').and.returnValue(renditionSubject);
|
|
||||||
spyOn(renditionsService, 'convert').and.returnValue(conversionSubject);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('View', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the Download button', () => {
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-download-button"]')).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the name of the file', () => {
|
|
||||||
component.nameFile = 'Example Content.xls';
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('h4 span').innerHTML).toEqual('Example Content.xls');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT show loading spinner by default', () => {
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-conversion-spinner"]')).toBeNull('Conversion spinner should NOT be shown by default');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Convertibility to pdf', () => {
|
|
||||||
|
|
||||||
it('should not show the "Convert to PDF" button by default', () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-convert-button"]')).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be checked on ngInit', () => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(renditionsService.getRendition).toHaveBeenCalledWith(nodeId, 'pdf');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT be checked on ngInit if nodeId is not set', () => {
|
|
||||||
component.nodeId = null;
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(renditionsService.getRendition).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show the "Convert to PDF" button if the node is convertible', async(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
renditionSubject.next({ entry: { status: 'NOT_CREATED' } });
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-convert-button"]')).not.toBeNull();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should NOT show the "Convert to PDF" button if the node is NOT convertible', async(() => {
|
|
||||||
component.convertible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
renditionSubject.error(new Error('Mocked error'));
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-convert-button"]')).toBeNull();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should NOT show the "Convert to PDF" button if the node is already converted', async(() => {
|
|
||||||
renditionSubject.next({ entry: { status: 'CREATED' } });
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-convert-button"]')).toBeNull();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should start the conversion when clicking on the "Convert to PDF" button', () => {
|
|
||||||
component.convertible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const convertButton = debug.query(By.css('[data-automation-id="viewer-convert-button"]'));
|
|
||||||
convertButton.triggerEventHandler('click', null);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const conversionSpinner = debug.query(By.css('[data-automation-id="viewer-conversion-spinner"]'));
|
|
||||||
expect(renditionsService.convert).toHaveBeenCalled();
|
|
||||||
expect(conversionSpinner).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the spinner if an error happens during conversion', () => {
|
|
||||||
component.convertToPdf();
|
|
||||||
|
|
||||||
conversionSubject.error('whatever');
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const conversionSpinner = debug.query(By.css('[data-automation-id="viewer-conversion-spinner"]'));
|
|
||||||
expect(conversionSpinner).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the spinner and show the pdf if conversion has finished', () => {
|
|
||||||
component.convertToPdf();
|
|
||||||
|
|
||||||
conversionSubject.complete();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const conversionSpinner = debug.query(By.css('[data-automation-id="viewer-conversion-spinner"]'));
|
|
||||||
const pdfRenditionViewer = debug.query(By.css('[data-automation-id="pdf-rendition-viewer"]'));
|
|
||||||
expect(conversionSpinner).toBeNull();
|
|
||||||
expect(pdfRenditionViewer).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should unsubscribe from the conversion subscription on ngOnDestroy', () => {
|
|
||||||
component.convertToPdf();
|
|
||||||
|
|
||||||
component.ngOnDestroy();
|
|
||||||
conversionSubject.complete();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const pdfRenditionViewer = debug.query(By.css('[data-automation-id="pdf-rendition-viewer"]'));
|
|
||||||
expect(pdfRenditionViewer).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not throw error on ngOnDestroy if the conversion hasn\'t started at all' , () => {
|
|
||||||
const callNgOnDestroy = () => {
|
|
||||||
component.ngOnDestroy();
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(callNgOnDestroy).not.toThrowError();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('User Interaction', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Download', () => {
|
|
||||||
|
|
||||||
it('should call download method if Click on Download button', () => {
|
|
||||||
spyOn(window, 'open');
|
|
||||||
component.urlFile = 'test';
|
|
||||||
|
|
||||||
let downloadButton: any = element.querySelector('[data-automation-id="viewer-download-button"]');
|
|
||||||
downloadButton.click();
|
|
||||||
|
|
||||||
expect(window.open).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call content service download method if Click on Download button', () => {
|
|
||||||
spyOn(service, 'downloadBlob');
|
|
||||||
|
|
||||||
component.blobFile = new Blob();
|
|
||||||
|
|
||||||
let downloadButton: any = element.querySelector('[data-automation-id="viewer-download-button"]');
|
|
||||||
downloadButton.click();
|
|
||||||
|
|
||||||
expect(service.downloadBlob).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Conversion', () => {
|
|
||||||
|
|
||||||
function clickOnConvertButton() {
|
|
||||||
renditionSubject.next({ entry: { status: 'NOT_CREATED' } });
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
let convertButton: any = element.querySelector('[data-automation-id="viewer-convert-button"]');
|
|
||||||
convertButton.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should show loading spinner and disable the "Convert to PDF button" after the button was clicked', () => {
|
|
||||||
clickOnConvertButton();
|
|
||||||
|
|
||||||
let convertButton: any = element.querySelector('[data-automation-id="viewer-convert-button"]');
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-conversion-spinner"]')).not.toBeNull('Conversion spinner should be shown');
|
|
||||||
expect(convertButton.disabled).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should re-enable the "Convert to PDF button" and hide spinner after unsuccessful conversion and hide loading spinner', () => {
|
|
||||||
clickOnConvertButton();
|
|
||||||
|
|
||||||
conversionSubject.error(new Error());
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
let convertButton: any = element.querySelector('[data-automation-id="viewer-convert-button"]');
|
|
||||||
expect(element.querySelector('[data-automation-id="viewer-conversion-spinner"]')).toBeNull('Conversion spinner should be shown');
|
|
||||||
expect(convertButton.disabled).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show the pdf rendition after successful conversion', () => {
|
|
||||||
clickOnConvertButton();
|
|
||||||
|
|
||||||
conversionSubject.next();
|
|
||||||
conversionSubject.complete();
|
|
||||||
fixture.detectChanges();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(element.querySelector('[data-automation-id="pdf-rendition-viewer"]')).not.toBeNull('Pdf rendition should be shown.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,133 +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, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
|
||||||
import { ContentService, RenditionsService } from 'ng2-alfresco-core';
|
|
||||||
|
|
||||||
const DEFAULT_CONVERSION_ENCODING = 'pdf';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'adf-not-supported-format',
|
|
||||||
templateUrl: './notSupportedFormat.component.html',
|
|
||||||
styleUrls: ['./notSupportedFormat.component.scss'],
|
|
||||||
host: { 'class': 'adf-not-supported-format' },
|
|
||||||
encapsulation: ViewEncapsulation.None
|
|
||||||
})
|
|
||||||
export class NotSupportedFormatComponent implements OnInit, OnDestroy {
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
nameFile: string;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
urlFile: string;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
blobFile: Blob;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
nodeId: string|null = null;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
showToolbar: boolean = true;
|
|
||||||
|
|
||||||
convertible: boolean = false;
|
|
||||||
displayable: boolean = false;
|
|
||||||
isConversionStarted: boolean = false;
|
|
||||||
isConversionFinished: boolean = false;
|
|
||||||
renditionUrl: string|null = null;
|
|
||||||
conversionsubscription: any = null;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private contentService: ContentService,
|
|
||||||
private renditionsService: RenditionsService) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks for available renditions if the nodeId is present
|
|
||||||
*/
|
|
||||||
ngOnInit() {
|
|
||||||
if (this.nodeId) {
|
|
||||||
this.checkRendition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download file opening it in a new window
|
|
||||||
*/
|
|
||||||
download() {
|
|
||||||
if (this.urlFile) {
|
|
||||||
window.open(this.urlFile);
|
|
||||||
} else {
|
|
||||||
this.contentService.downloadBlob(this.blobFile, this.nameFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update component's button according to the given rendition's availability
|
|
||||||
*
|
|
||||||
* @param {string} encoding - the rendition id
|
|
||||||
*/
|
|
||||||
checkRendition(encoding: string = DEFAULT_CONVERSION_ENCODING): void {
|
|
||||||
this.renditionsService.getRendition(this.nodeId, encoding)
|
|
||||||
.subscribe(
|
|
||||||
(response) => {
|
|
||||||
const status = response.entry.status.toString();
|
|
||||||
if (status === 'NOT_CREATED') {
|
|
||||||
this.convertible = true;
|
|
||||||
this.displayable = false;
|
|
||||||
} else if (status === 'CREATED') {
|
|
||||||
this.convertible = false;
|
|
||||||
this.displayable = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.convertible = false;
|
|
||||||
this.displayable = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the component to loading state and send the conversion starting signal to parent component
|
|
||||||
*/
|
|
||||||
convertToPdf(): void {
|
|
||||||
this.isConversionStarted = true;
|
|
||||||
|
|
||||||
this.conversionsubscription = this.renditionsService.convert(this.nodeId, DEFAULT_CONVERSION_ENCODING)
|
|
||||||
.subscribe({
|
|
||||||
error: (error) => { this.isConversionStarted = false; },
|
|
||||||
complete: () => { this.showPDF(); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the PDF rendition of the node
|
|
||||||
*/
|
|
||||||
showPDF(): void {
|
|
||||||
this.renditionUrl = this.renditionsService.getRenditionUrl(this.nodeId, DEFAULT_CONVERSION_ENCODING);
|
|
||||||
this.isConversionStarted = false;
|
|
||||||
this.isConversionFinished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kills the subscription polling if it has been started
|
|
||||||
*/
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
if (this.isConversionStarted) {
|
|
||||||
this.conversionsubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,6 +8,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
line-height: 1.0;
|
line-height: 1.0;
|
||||||
|
border: 1px solid gray;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="adf-viewer__unknown-format-view">
|
||||||
|
<div>
|
||||||
|
<md-icon class="icon">wifi_tethering</md-icon>
|
||||||
|
<div class="label">Document preview could not be loaded.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -0,0 +1,8 @@
|
|||||||
|
.adf-viewer__unknown-format-view {
|
||||||
|
height: 90vh;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
/*!
|
||||||
|
* @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 } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'adf-viewer-unknown-format',
|
||||||
|
templateUrl: 'unknown-format.component.html',
|
||||||
|
styleUrls: ['unknown-format.component.scss']
|
||||||
|
})
|
||||||
|
export class UnknownFormatComponent {
|
||||||
|
}
|
@@ -4,80 +4,151 @@
|
|||||||
[class.adf-viewer-inline-container]="!overlayMode">
|
[class.adf-viewer-inline-container]="!overlayMode">
|
||||||
|
|
||||||
<div class="adf-viewer-content">
|
<div class="adf-viewer-content">
|
||||||
<ng-container *ngIf="overlayMode">
|
<ng-container *ngIf="showToolbar">
|
||||||
<adf-toolbar color="default" class="adf-viewer-toolbar">
|
<adf-toolbar color="default" class="adf-viewer-toolbar">
|
||||||
|
|
||||||
<adf-toolbar-title>
|
<adf-toolbar-title>
|
||||||
<span class="adf-viewer-filename">{{ displayName }}</span>
|
<button *ngIf="allowGoBack"
|
||||||
|
class="adf-viewer-close-button"
|
||||||
|
md-icon-button
|
||||||
|
mdTooltip="Back"
|
||||||
|
(click)="onBackButtonClick()">
|
||||||
|
<md-icon>arrow_back</md-icon>
|
||||||
|
</button>
|
||||||
|
<img [src]="mimeType | adfMimeTypeIcon">
|
||||||
|
<span>{{ displayName }}</span>
|
||||||
</adf-toolbar-title>
|
</adf-toolbar-title>
|
||||||
<button
|
|
||||||
md-icon-button
|
<ng-container *ngIf="allowOpenWith">
|
||||||
class="adf-viewer-close-button"
|
<button md-button [mdMenuTriggerFor]="mnuOpenWith">
|
||||||
mdTooltip="Close and go back"
|
<span>Open with</span>
|
||||||
mdTooltipPosition="before"
|
<md-icon>arrow_drop_down</md-icon>
|
||||||
(click)="close()"
|
</button>
|
||||||
aria-label="Close">
|
<md-menu #mnuOpenWith="mdMenu" [overlapTrigger]="false">
|
||||||
<md-icon>close</md-icon>
|
<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>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<adf-toolbar-divider></adf-toolbar-divider>
|
||||||
|
|
||||||
|
<button *ngIf="allowDownload" md-icon-button mdTooltip="Download" (click)="download()">
|
||||||
|
<md-icon>file_download</md-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button *ngIf="allowPrint" md-icon-button mdTooltip="Print">
|
||||||
|
<md-icon>print</md-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button *ngIf="allowShare" md-icon-button mdTooltip="Share">
|
||||||
|
<md-icon>share</md-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button md-icon-button [mdMenuTriggerFor]="mnuMoreActions" mdTooltip="More actions">
|
||||||
|
<md-icon>more_vert</md-icon>
|
||||||
|
</button>
|
||||||
|
<md-menu #mnuMoreActions="mdMenu">
|
||||||
|
<button md-menu-item>
|
||||||
|
<md-icon>dialpad</md-icon>
|
||||||
|
<span>Action One</span>
|
||||||
|
</button>
|
||||||
|
<button md-menu-item disabled>
|
||||||
|
<md-icon>voicemail</md-icon>
|
||||||
|
<span>Action Two</span>
|
||||||
|
</button>
|
||||||
|
<button md-menu-item>
|
||||||
|
<md-icon>notifications_off</md-icon>
|
||||||
|
<span>Action Three</span>
|
||||||
|
</button>
|
||||||
|
</md-menu>
|
||||||
|
|
||||||
|
<ng-container *ngIf="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>
|
</adf-toolbar>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div class="adf-viewer-layout">
|
<ng-container *ngIf="isLoading">
|
||||||
|
<div class="adf-viewer__loading-screen">
|
||||||
|
<h2>Loading</h2>
|
||||||
|
<div>
|
||||||
|
<md-spinner></md-spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div *ngIf="!isLoading" class="adf-viewer-layout">
|
||||||
<div class="adf-viewer-layout-content">
|
<div class="adf-viewer-layout-content">
|
||||||
<div *ngIf="isLoaded()">
|
<div>
|
||||||
<div class="adf-viewer-content-container">
|
<div class="adf-viewer-content-container" [ngSwitch]="viewerType">
|
||||||
|
|
||||||
<ng-container *ngIf="isPdf()">
|
<ng-container *ngSwitchCase="'pdf'">
|
||||||
<adf-pdf-viewer
|
<adf-pdf-viewer [blobFile]="blobFile" [urlFile]="urlFileContent" [nameFile]="displayName"></adf-pdf-viewer>
|
||||||
[showToolbar]="showToolbar"
|
|
||||||
[blobFile]="blobFile"
|
|
||||||
[urlFile]="urlFileContent"
|
|
||||||
[nameFile]="displayName">
|
|
||||||
</adf-pdf-viewer>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="isImage()">
|
<ng-container *ngSwitchCase="'image'">
|
||||||
<adf-img-viewer
|
<adf-img-viewer [urlFile]="urlFileContent" [nameFile]="displayName" [blobFile]="blobFile"></adf-img-viewer>
|
||||||
[urlFile]="urlFileContent"
|
|
||||||
[nameFile]="displayName"
|
|
||||||
[blobFile]="blobFile">
|
|
||||||
</adf-img-viewer>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="isMedia()">
|
<ng-container *ngSwitchCase="'media'">
|
||||||
<adf-media-player
|
<adf-media-player [urlFile]="urlFileContent" [mimeType]="mimeType" [blobFile]="blobFile" [nameFile]="displayName"></adf-media-player>
|
||||||
[urlFile]="urlFileContent"
|
|
||||||
[mimeType]="mimeType"
|
|
||||||
[blobFile]="blobFile"
|
|
||||||
[nameFile]="displayName">
|
|
||||||
</adf-media-player>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="isText() && !isExternalSupportedExtension()">
|
<ng-container *ngSwitchCase="'text'">
|
||||||
<adf-txt-viewer [urlFile]="urlFileContent" [blobFile]="blobFile"></adf-txt-viewer>
|
<adf-txt-viewer [urlFile]="urlFileContent" [blobFile]="blobFile"></adf-txt-viewer>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<span *ngFor="let extensionTemplate of extensionTemplates">
|
<ng-container *ngSwitchCase="'custom'">
|
||||||
<ng-template
|
<span *ngFor="let extensionTemplate of extensionTemplates">
|
||||||
*ngIf="extensionTemplate.isVisible"
|
<ng-template
|
||||||
[ngTemplateOutlet]="extensionTemplate.template"
|
*ngIf="extensionTemplate.isVisible"
|
||||||
[ngOutletContext]="{ urlFileContent: urlFileContent, extension:extension }">
|
[ngTemplateOutlet]="extensionTemplate.template"
|
||||||
</ng-template>
|
[ngOutletContext]="{ urlFileContent: urlFileContent, extension:extension }">
|
||||||
</span>
|
</ng-template>
|
||||||
|
</span>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<div *ngIf="!supportedExtension()" class="adf-viewer-unknown-content">
|
<ng-container *ngSwitchDefault>
|
||||||
<adf-not-supported-format
|
<adf-viewer-unknown-format></adf-viewer-unknown-format>
|
||||||
*ngIf="!extensionTemplate"
|
</ng-container>
|
||||||
[urlFile]="urlFileContent"
|
|
||||||
[blobFile]="blobFile"
|
|
||||||
[nameFile]="displayName"
|
|
||||||
[showToolbar]="showToolbar"
|
|
||||||
[nodeId]="fileNodeId">
|
|
||||||
</adf-not-supported-format>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<ng-container *ngIf="showInfoDrawer">
|
||||||
|
<div class="adf-viewer__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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
$adf-viewer-background-color: #515151;
|
$adf-viewer-background-color: #f5f5f5;
|
||||||
|
|
||||||
@mixin full-screen() {
|
@mixin full-screen() {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -33,7 +33,7 @@ $adf-viewer-background-color: #515151;
|
|||||||
@include full-screen();
|
@include full-screen();
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -41,6 +41,7 @@ $adf-viewer-background-color: #515151;
|
|||||||
|
|
||||||
.adf-viewer-content {
|
.adf-viewer-content {
|
||||||
@include full-screen();
|
@include full-screen();
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,4 +67,33 @@ $adf-viewer-background-color: #515151;
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__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);
|
||||||
|
border-left: 1px solid rgba(0, 0, 0, 0.07);
|
||||||
|
|
||||||
|
.mat-tab-label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-card {
|
||||||
|
margin: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { SpyLocation } from '@angular/common/testing';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
@@ -25,9 +27,9 @@ import { EventMock } from '../assets/event.mock';
|
|||||||
import { RenderingQueueServices } from '../services/rendering-queue.services';
|
import { RenderingQueueServices } from '../services/rendering-queue.services';
|
||||||
import { ImgViewerComponent } from './imgViewer.component';
|
import { ImgViewerComponent } from './imgViewer.component';
|
||||||
import { MediaPlayerComponent } from './mediaPlayer.component';
|
import { MediaPlayerComponent } from './mediaPlayer.component';
|
||||||
import { NotSupportedFormatComponent } from './notSupportedFormat.component';
|
|
||||||
import { PdfViewerComponent } from './pdfViewer.component';
|
import { PdfViewerComponent } from './pdfViewer.component';
|
||||||
import { TxtViewerComponent } from './txtViewer.component';
|
import { TxtViewerComponent } from './txtViewer.component';
|
||||||
|
import { UnknownFormatComponent } from './unknown-format/unknown-format.component';
|
||||||
import { ViewerComponent } from './viewer.component';
|
import { ViewerComponent } from './viewer.component';
|
||||||
|
|
||||||
declare let jasmine: any;
|
declare let jasmine: any;
|
||||||
@@ -49,12 +51,13 @@ describe('ViewerComponent', () => {
|
|||||||
ViewerComponent,
|
ViewerComponent,
|
||||||
PdfViewerComponent,
|
PdfViewerComponent,
|
||||||
TxtViewerComponent,
|
TxtViewerComponent,
|
||||||
NotSupportedFormatComponent,
|
|
||||||
MediaPlayerComponent,
|
MediaPlayerComponent,
|
||||||
ImgViewerComponent
|
ImgViewerComponent,
|
||||||
|
UnknownFormatComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
RenderingQueueServices
|
RenderingQueueServices,
|
||||||
|
{ provide: Location, useClass: SpyLocation }
|
||||||
]
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
@@ -128,10 +131,6 @@ describe('ViewerComponent', () => {
|
|||||||
expect(element.querySelector('header')).toBeNull();
|
expect(element.querySelector('header')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should Close button be not present if is not overlay mode', () => {
|
|
||||||
expect(element.querySelector('.adf-viewer-close-button')).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should Esc button not hide the viewer if is not overlay mode', () => {
|
it('should Esc button not hide the viewer if is not overlay mode', () => {
|
||||||
EventMock.keyDown(27);
|
EventMock.keyDown(27);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -182,7 +181,7 @@ describe('ViewerComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Exteznsion Type Test', () => {
|
describe('Extension Type Test', () => {
|
||||||
it('should extension file pdf be loaded', (done) => {
|
it('should extension file pdf be loaded', (done) => {
|
||||||
component.urlFile = 'base/src/assets/fake-test-file.pdf';
|
component.urlFile = 'base/src/assets/fake-test-file.pdf';
|
||||||
|
|
||||||
@@ -243,13 +242,13 @@ describe('ViewerComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should the not supported div be loaded if the file is a not supported extension', (done) => {
|
it('should display [unknown format] for unsupported extensions', (done) => {
|
||||||
component.urlFile = 'fake-url-file.unsupported';
|
component.urlFile = 'fake-url-file.unsupported';
|
||||||
component.mimeType = '';
|
component.mimeType = '';
|
||||||
|
|
||||||
component.ngOnChanges(null).then(() => {
|
component.ngOnChanges(null).then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(element.querySelector('adf-not-supported-format')).not.toBeNull();
|
expect(element.querySelector('adf-viewer-unknown-format')).toBeDefined();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -333,17 +332,6 @@ describe('ViewerComponent', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not display the media player if the file identified by mimetype is a media but with not supported extension', (done) => {
|
|
||||||
component.urlFile = 'content';
|
|
||||||
component.mimeType = 'video/avi';
|
|
||||||
|
|
||||||
component.ngOnChanges(null).then(() => {
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(element.querySelector('adf-media-player')).toBeNull();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Events', () => {
|
describe('Events', () => {
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Location } from '@angular/common';
|
||||||
import { Component, EventEmitter, HostListener, Input, OnChanges, OnDestroy, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, HostListener, Input, OnChanges, OnDestroy, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
import { AlfrescoApiService, LogService } from 'ng2-alfresco-core';
|
import { AlfrescoApiService, BaseEvent, LogService, RenditionsService } from 'ng2-alfresco-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-viewer, alfresco-viewer',
|
selector: 'adf-viewer, alfresco-viewer',
|
||||||
@@ -44,30 +45,70 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
showViewer: boolean = true;
|
showViewer: boolean = true;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
showToolbar: boolean = true;
|
showToolbar = true;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
displayName: string;
|
displayName: string = 'Unknown';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowGoBack = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowOpenWith = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowDownload = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowPrint = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowShare = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowInfoDrawer = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
showInfoDrawer = false;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
showViewerChange: EventEmitter<boolean> = new EventEmitter<boolean>();
|
goBack = new EventEmitter<BaseEvent<any>>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
extensionChange: EventEmitter<String> = new EventEmitter<String>();
|
showViewerChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
extensionChange = new EventEmitter<string>();
|
||||||
|
|
||||||
|
viewerType: string = 'unknown';
|
||||||
|
downloadUrl: string = null;
|
||||||
|
fileName: string = 'document';
|
||||||
|
isLoading: boolean = false;
|
||||||
|
|
||||||
extensionTemplates: { template: TemplateRef<any>, isVisible: boolean }[] = [];
|
extensionTemplates: { template: TemplateRef<any>, isVisible: boolean }[] = [];
|
||||||
|
|
||||||
externalExtensions: string[] = [];
|
externalExtensions: string[] = [];
|
||||||
|
|
||||||
urlFileContent: string;
|
urlFileContent: string;
|
||||||
otherMenu: any;
|
otherMenu: any;
|
||||||
extension: string;
|
extension: string;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
loaded: boolean = false;
|
|
||||||
|
|
||||||
constructor(private apiService: AlfrescoApiService,
|
private extensions = {
|
||||||
private logService: LogService) {
|
image: ['png', 'jpg', 'jpeg', 'gif', 'bpm'],
|
||||||
}
|
media: ['wav', 'mp4', 'mp3', 'webm', 'ogg'],
|
||||||
|
text: ['txt', 'xml', 'js', 'html'],
|
||||||
|
pdf: ['pdf']
|
||||||
|
};
|
||||||
|
|
||||||
|
private mimeTypes = [
|
||||||
|
{ mimeType: 'application/x-javascript', type: 'text' },
|
||||||
|
{ mimeType: 'application/pdf', type: 'pdf' }
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private apiService: AlfrescoApiService,
|
||||||
|
private logService: LogService,
|
||||||
|
private location: Location,
|
||||||
|
private renditionService: RenditionsService) {}
|
||||||
|
|
||||||
ngOnChanges(changes) {
|
ngOnChanges(changes) {
|
||||||
if (this.showViewer) {
|
if (this.showViewer) {
|
||||||
@@ -77,28 +118,66 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.blobFile) {
|
if (this.blobFile) {
|
||||||
|
this.isLoading = true;
|
||||||
|
|
||||||
this.mimeType = this.blobFile.type;
|
this.mimeType = this.blobFile.type;
|
||||||
|
this.viewerType = this.getViewerTypeByMimeType(this.mimeType);
|
||||||
|
|
||||||
|
this.allowDownload = false;
|
||||||
|
// TODO: wrap blob into the data url and allow downloading
|
||||||
|
|
||||||
this.extensionChange.emit(this.mimeType);
|
this.extensionChange.emit(this.mimeType);
|
||||||
|
this.isLoading = false;
|
||||||
|
this.scrollTop();
|
||||||
resolve();
|
resolve();
|
||||||
} else if (this.urlFile) {
|
} else if (this.urlFile) {
|
||||||
|
this.isLoading = true;
|
||||||
let filenameFromUrl = this.getFilenameFromUrl(this.urlFile);
|
let filenameFromUrl = this.getFilenameFromUrl(this.urlFile);
|
||||||
this.displayName = filenameFromUrl ? filenameFromUrl : '';
|
this.displayName = filenameFromUrl || 'Unknown';
|
||||||
this.extension = this.getFileExtension(filenameFromUrl);
|
this.extension = this.getFileExtension(filenameFromUrl);
|
||||||
this.extensionChange.emit(this.extension);
|
|
||||||
this.urlFileContent = this.urlFile;
|
this.urlFileContent = this.urlFile;
|
||||||
|
|
||||||
|
this.downloadUrl = this.urlFile;
|
||||||
|
this.fileName = this.displayName;
|
||||||
|
|
||||||
|
this.viewerType = this.getViewerTypeByExtension(this.extension);
|
||||||
|
if (this.viewerType === 'unknown') {
|
||||||
|
this.viewerType = this.getViewerTypeByMimeType(this.mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.extensionChange.emit(this.extension);
|
||||||
|
this.isLoading = false;
|
||||||
|
this.scrollTop();
|
||||||
resolve();
|
resolve();
|
||||||
} else if (this.fileNodeId) {
|
} else if (this.fileNodeId) {
|
||||||
|
this.isLoading = true;
|
||||||
this.apiService.getInstance().nodes.getNodeInfo(this.fileNodeId).then(
|
this.apiService.getInstance().nodes.getNodeInfo(this.fileNodeId).then(
|
||||||
(data: MinimalNodeEntryEntity) => {
|
(data: MinimalNodeEntryEntity) => {
|
||||||
this.mimeType = data.content.mimeType;
|
this.mimeType = data.content.mimeType;
|
||||||
this.displayName = data.name;
|
this.displayName = data.name;
|
||||||
this.urlFileContent = this.apiService.getInstance().content.getContentUrl(data.id);
|
this.urlFileContent = this.apiService.getInstance().content.getContentUrl(data.id);
|
||||||
this.extension = this.getFileExtension(data.name);
|
this.extension = this.getFileExtension(data.name);
|
||||||
|
|
||||||
|
this.fileName = data.name;
|
||||||
|
this.downloadUrl = this.apiService.getInstance().content.getContentUrl(data.id, true);
|
||||||
|
|
||||||
|
this.viewerType = this.getViewerTypeByExtension(this.extension);
|
||||||
|
if (this.viewerType === 'unknown') {
|
||||||
|
this.viewerType = this.getViewerTypeByMimeType(this.mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.viewerType === 'unknown') {
|
||||||
|
this.displayAsPdf(data.id);
|
||||||
|
} else {
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
this.extensionChange.emit(this.extension);
|
this.extensionChange.emit(this.extension);
|
||||||
this.loaded = true;
|
this.scrollTop();
|
||||||
resolve();
|
resolve();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
this.isLoading = false;
|
||||||
reject(error);
|
reject(error);
|
||||||
this.logService.error('This node does not exist');
|
this.logService.error('This node does not exist');
|
||||||
}
|
}
|
||||||
@@ -108,6 +187,79 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollTop() {
|
||||||
|
window.scrollTo(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
getViewerTypeByMimeType(mimeType: string) {
|
||||||
|
if (mimeType) {
|
||||||
|
mimeType = mimeType.toLowerCase();
|
||||||
|
|
||||||
|
if (mimeType.startsWith('image/')) {
|
||||||
|
return 'image';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType.startsWith('text/')) {
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType.startsWith('video/')) {
|
||||||
|
return 'media';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType.startsWith('audio/')) {
|
||||||
|
return 'media';
|
||||||
|
}
|
||||||
|
|
||||||
|
const registered = this.mimeTypes.find(t => t.mimeType === mimeType);
|
||||||
|
if (registered) {
|
||||||
|
return registered.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
getViewerTypeByExtension(extension: string) {
|
||||||
|
if (extension) {
|
||||||
|
extension = extension.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isCustomViewerExtension(extension)) {
|
||||||
|
return 'custom';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.extensions.image.indexOf(extension) >= 0) {
|
||||||
|
return 'image';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.extensions.media.indexOf(extension) >= 0) {
|
||||||
|
return 'media';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.extensions.text.indexOf(extension) >= 0) {
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.extensions.pdf.indexOf(extension) >= 0) {
|
||||||
|
return 'pdf';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackButtonClick() {
|
||||||
|
if (this.overlayMode) {
|
||||||
|
this.close();
|
||||||
|
} else {
|
||||||
|
const event = new BaseEvent<any>();
|
||||||
|
this.goBack.next(event);
|
||||||
|
|
||||||
|
if (!event.defaultPrevented) {
|
||||||
|
this.location.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* close the viewer
|
* close the viewer
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +279,6 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
this.urlFileContent = '';
|
this.urlFileContent = '';
|
||||||
this.displayName = '';
|
this.displayName = '';
|
||||||
this.fileNodeId = null;
|
this.fileNodeId = null;
|
||||||
this.loaded = false;
|
|
||||||
this.extension = null;
|
this.extension = null;
|
||||||
this.mimeType = null;
|
this.mimeType = null;
|
||||||
}
|
}
|
||||||
@@ -157,113 +308,19 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
* @param {string} fileName - file name
|
* @param {string} fileName - file name
|
||||||
* @returns {string} file name extension
|
* @returns {string} file name extension
|
||||||
*/
|
*/
|
||||||
private getFileExtension(fileName: string): string {
|
getFileExtension(fileName: string): string {
|
||||||
return fileName.split('.').pop().toLowerCase();
|
return fileName.split('.').pop().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
isCustomViewerExtension(extension: string): boolean {
|
||||||
* Check if the content is an image through the extension or mime type
|
const extensions = this.externalExtensions || [];
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
public isImage(): boolean {
|
|
||||||
return this.isImageExtension() || this.isImageMimeType();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (extension && extensions.length > 0) {
|
||||||
* Check if the content is a media through the extension or mime type
|
extension = extension.toLowerCase();
|
||||||
*
|
return extensions.indexOf(extension) >= 0;
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
public isMedia(): boolean {
|
|
||||||
return this.isMediaExtension(this.extension) || this.isMediaMimeType();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file is a supported image extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
private isImageExtension(): boolean {
|
|
||||||
return this.extension === 'png' || this.extension === 'jpg' ||
|
|
||||||
this.extension === 'jpeg' || this.extension === 'gif' || this.extension === 'bmp';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file has an image-based mimetype
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
private isMediaMimeType(): boolean {
|
|
||||||
let mimeExtension;
|
|
||||||
if (this.mimeType && this.mimeType.indexOf('/')) {
|
|
||||||
mimeExtension = this.mimeType.substr(this.mimeType.indexOf('/') + 1, this.mimeType.length);
|
|
||||||
}
|
|
||||||
return (this.mimeType && (this.mimeType.indexOf('video/') === 0 || this.mimeType.indexOf('audio/') === 0)) && this.isMediaExtension(mimeExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file is a supported media extension
|
|
||||||
* @param {string} extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
private isMediaExtension(extension: string): boolean {
|
|
||||||
return extension === 'wav' || extension === 'mp4' || extension === 'mp3' || extension === 'WebM' || extension === 'Ogg';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file has an image-based mimetype
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
private isImageMimeType(): boolean {
|
|
||||||
return this.mimeType && this.mimeType.indexOf('image/') === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file is a supported pdf extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
public isPdf(): boolean {
|
|
||||||
return this.extension === 'pdf' || this.mimeType === 'application/pdf';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file is a supported txt extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
public isText(): boolean {
|
|
||||||
return this.extension === 'txt' || this.mimeType === 'text/txt' || this.mimeType === 'text/plain';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the current file is a supported extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
supportedExtension(): boolean {
|
|
||||||
return this.isImage() || this.isPdf() || this.isMedia() || this.isText() || this.isExternalSupportedExtension();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the file is compatible with one of the extension
|
|
||||||
*
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isExternalSupportedExtension(): boolean {
|
|
||||||
let externalType: string;
|
|
||||||
|
|
||||||
if (this.externalExtensions && (this.externalExtensions instanceof Array)) {
|
|
||||||
externalType = this.externalExtensions.find((externalExtension) => {
|
|
||||||
return externalExtension.toLowerCase() === this.extension;
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!externalType;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,12 +335,56 @@ export class ViewerComponent implements OnDestroy, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
download() {
|
||||||
* return true if the data about the node in the ecm are loaded
|
if (this.allowDownload && this.downloadUrl && this.fileName) {
|
||||||
*
|
const link = document.createElement('a');
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
link.style.display = 'none';
|
||||||
isLoaded(): boolean {
|
link.download = this.fileName;
|
||||||
return this.fileNodeId ? this.loaded : true;
|
link.href = this.downloadUrl;
|
||||||
|
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.showPdfRendition(nodeId);
|
||||||
|
} else if (status === 'NOT_CREATED') {
|
||||||
|
this.renditionService.convert(nodeId, 'pdf').subscribe({
|
||||||
|
complete: () => {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.showPdfRendition(nodeId);
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
this.isLoading = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.isLoading = false;
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private showPdfRendition(nodeId: string) {
|
||||||
|
if (nodeId) {
|
||||||
|
this.viewerType = 'pdf';
|
||||||
|
this.urlFileContent = this.renditionService.getRenditionUrl(nodeId, 'pdf');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { SpyLocation } from '@angular/common/testing';
|
||||||
import { ElementRef } from '@angular/core';
|
import { ElementRef } from '@angular/core';
|
||||||
import { Injector } from '@angular/core';
|
import { Injector } from '@angular/core';
|
||||||
import { async, getTestBed, TestBed } from '@angular/core/testing';
|
import { async, getTestBed, TestBed } from '@angular/core/testing';
|
||||||
@@ -28,7 +30,7 @@ export class MockElementRef extends ElementRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ExtensionViewerComponent', () => {
|
describe('ExtensionViewerDirective', () => {
|
||||||
let injector: Injector;
|
let injector: Injector;
|
||||||
let extensionViewerDirective: ExtensionViewerDirective;
|
let extensionViewerDirective: ExtensionViewerDirective;
|
||||||
let viewerComponent: ViewerComponent;
|
let viewerComponent: ViewerComponent;
|
||||||
@@ -37,6 +39,7 @@ describe('ExtensionViewerComponent', () => {
|
|||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [CoreModule],
|
imports: [CoreModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
{ provide: Location, useClass: SpyLocation },
|
||||||
ExtensionViewerDirective,
|
ExtensionViewerDirective,
|
||||||
{provide: ElementRef, useClass: MockElementRef},
|
{provide: ElementRef, useClass: MockElementRef},
|
||||||
ViewerComponent
|
ViewerComponent
|
||||||
|
Reference in New Issue
Block a user