* fix upload area snackbar behaviour

* SASS support for components

ability to use '.scss' files from within components

* [ADF-610] Upload button and DnD area should not upload hidden files and folders (#1908)

[ADF-610]  upload cleanup
- more strongly typing
- api improvements

* Upload cleanup and api improvements

- remove old unused settings (formFields variable)
- individual options for uploaded files (i.e. versioning)
- upload button and drag-and-drop area now set individual settings for file versioning

* exclude hidden files from upload

* [ADF-640] reload document list on folder upload (#1895)

* reload document list on folder upload

- extend UploadService with 'folderCreated' event to be able reacting on folder uploads globally
- extend Demo Shell to reload document list on UploadService events (folderCreated)

* readme updates

* [ADF-621] show drop effect on folders only (#1897)

* show drop effect on folders only

- fix `hasValue` api for data rows (avoid 'false' value to be evaluated as missing value)
- support for evaluating drop support for rows
- document list enables upload zones for folders only

* api improvements as per code review

* [ADF-242] Fixed behaviour for saving/deleting reports (#1905)

* [ADF-242] - fix for deleting - saving a report

* [ADF - 242] added test for fixed feature on reports save - delete

* Added translation key

* [ADF-604] Upgrade @angular/material to latest version (#1909)

* update dependencies and module imports

* fix template warnings and fix import issues

* migrate Activiti Form to MdTabsModule

* fix unit tests

* fix tests

* fix unit tests

* fix unit tests

* disable test that fails only on travis

* upgrade activiti form component to angular/material

* fix test (remove MDL class check)

* [ADF-613] Add plain text viewer (#1873)

* add plain text viewer

* different devices optimizations

* returns types

* [ADF-573] support for toggling enabled state (#1912)

* [ADF-602] Accordion component - Add basic documentation (#1913)

* Add basic documentation Accordion component

* Update README.md

* [ADF-680] Added previous page check when page has no more elements (#1911)

* [ADF-242] - fix for deleting - saving a report

* [ADF - 242] added test for fixed feature on reports save - delete

* [ADF-680] - Fixed behaviour when deleting all files on last page of document list

* Start adding test for documentlist check

* Added test for check double page load

* [ADF-680] - removed commented test code

* [ADF-680] Added changes from peer review

* [ADF-680] added return type

* [ADF-667] selection mode and row styles (#1914)

* selection mode and row styles

- single/multiple/none selection modes for DataTable component (and Document List)
- support for custom row styles (inline and classname values)
- fix karma config (material themes)
- readme updates
- package-lock.json files for NPM5 support
- updated DataTable demo to demonstrate selection modes and row styles

* remove package lock files

* move demo projects to webpack (#1915)

* wav and Mp3 enabling viewer (#1916)

* add option only demo shell version change for update version script

* ADF-402 add the show diagram button (#1917)

* [ADF-707] Ability to select a row on a dynamic table (#1921)

* [ADF-710] Create an Process Attachment List component (#1919)

* added new component to list the process attachments with view, download and delete functionality

* added unit test cases for activit-process-attachment-list component

* exported new process attachment list component

* added documentation for process-attachment-list component

* [ADF-712] Task Attachment - Provide a way to attach a new content (#1898)

* create button, download, view functionality added in task attachment list component

* created sevice to attach document to task

* added new component to create/uplaod attachment to task

* added new component to create/uplaod attachment to task

* added test case for create task attachment component

* added test case for create task attachment component

* added input to block upload document  to ECM

* fixed create task attachment spec file issue

* changed alfresco-upload to alfresco-core upload directive

* removed attachCreate button and emitter from task-attachment-list

* removed uploadToEcm input and checkValidity method from alfresco-upload

* added documentation for task-attachment-list and create-task-attachment components

* [ADF-696] Entire accordion group header should be clickable (#1918)

* #ADF-696 Added new input to show/hide expand icon, click event is activated for the complete heading

* #ADF-696 tslint fix

* #ADF-696 Added documentation for new input and removed unwanted div

* [ADF-721] Fix translation reference for dev task (#1923)

* move translation files in the bundles folder

* fix after review
ripristinate tslint and remove override tsconfig

* [ADF-709] add autofocus when a new row is added on dynamic table widget (#1927)

* [ADF-709] add autofocus when a new row is added on dynamic table widget

* [ADF-709] removed wrong reference for template

* [ADF-713] Process Attachment - Provide a way to attach a new content (#1920)

* added service to get all the related content of the process instance

* added new component to create/upload attachment for process instance

* added unit test cases for create-process-attachment component

* exported create-process-attachment component

* added documentation for create-process-attachment component

* Add data-automation-id to multi select checkbox (#1924)

* [ADF-571] upload feature rework (#1922)

* upload feature rework

lots of improvements for upload dialog and underlying services

* readme update

- readme cleanup
- remove some old comments from code
- update readme with new events for Upload Service

* restore prerequisites section in readme

* fix i18n issue with webpack

* exported report and chart models (#1925)

* fix file upload bug (#1928)

- proper extraction of File objects from the FileList

* lock files for npm 5 (#1930)

add lock files for npm v5; does nothing for earlier versions, so is not harmful

* Source Mapping is not working on test debugging (#1931)

* coverage single components run fix

* remove spec.ts from coverage

* make the coverage and the istanbul-instrumenter-loader works only over the console test because a problem on the remapping for the browser test

* move tslint on the main folder of any component

* remove build:w from readme

* stop build tslint error also in spec files

* clear karma file from unnecessary files

* add set -f for build all script in order to accept *

* fix lint problem and failing tests

* fix failing test search component

* add loader test for viewer

* fix tslint error userinfo

* --max_old_space_size=2048 remove

* fix tslint error uploader unused EventEmitter

* remove spec|index|.*mock|.*model|.*event from coverage

* move coverage separate file and get component to calculate coverage as input

* remove old 'banned' demo from login screen (#1929)

* add sleep time flag in publish script

* rollback demo tag

* fix pacakge.json tag

* [ADF-686] add blobFile as input (#1933)

* coverage fix (#1934)

* [ADF-702] Task/Process Filter - Provide a way to change the default filter (#1932)

* [ADF-702] Task/Process Filter - Provide a way to change the default filter

* Provide a way to select a custom menu filter

* Improve activiti process filter

* Add internal link

* Change link name

* add link

* [ADF-744] Attachment List is not displayed within Processes. (#1937)

* Use the adf process attachment list indise demo shell

* Change documentation

* support for healdess chrome (#1939)

* #ADF-696 Now accordion opens/closes on click of group header along with emitting heading click event (#1936)

* add info and link on current last git commit (#1940)

* [ADF-754] toolbar component (#1938)

* toolbar component

- simple toolbar component (core lib)
- readme updates (core lib)
- update demo shell with toolbar component demo (document list)

* update unit tests

* [ADF-763] Add Chrome default browser for karma chrome launcher for Chrome versi… (#1941)

* Add Chrome default browser for karma chrome launcher for Chrome version<59

* Fixing intermittently failing test in ng2-activiti-analytics component

* Adding new icon (sent) for Bootstrap to Material icon mapping (#1943)

* fix blob input in text viewer (#1942)

* GitHub issue & pull request template change (#1945)

* Update ISSUE_TEMPLATE.md

* Update PULL_REQUEST_TEMPLATE.md

* [ADF-689] Fix alfresco-document-menu-action styling (z-index) (#1944)

* fix translation wrong folder creation issue

* [ADF-773] Fix datatable custom template render (#1947)

* [ADF-780] centralised call for process filters api (#1950)

* [ADF-780] centralised call for process filters api

* [ADF-780] updated conversion to string

* [ADF-741] Add the create task attachment component to the demo shell (#1946)

* Add the create task attachment component to the demo shell

* Add translation keys

* Add return to methods

* fix thumbnail task process list (#1951)

* [ADF-643] upload enhancements (#1949)

* rework folder uploading

- flatterns hierarchy on folder upload
- performs a single traversal for the entire folder heirarchy and ends with a comple file list
- allows now dropping folders on existing folders
- overall code improvements

* fix unit tests

* readme updates

* clean old and unused code

* code cleanup

* limit concurrent uploads

* update code as per review

* fix upload button for Safari

* fixes for Safari

- Safari compatibility
- code updates based on review

* fix code

* fix unit tests

* [ADF-589] Login component different bug fixes (#1953)

* Basic style changes

* Further design changes

* Responsive design fixes

* Different sign in button style for the different login steps

* #ADF-780 Fixed getProcessFilterByName to get the correct filter for the given appId and name (#1952)

* fix issues with the require keyword (angular cli) (#1954)

* [ADF-799] add HappyPack to webpack conf (#1956)

* update npm5 lock files

* [ADF-740] Add button for process attachment list (#1955)

* [ADF-740] adding button to allow user to upload related content on process instance

* [ADF-740] add button for attachment content list for process

* changed locatin for translation

* [ADF-740] added test for add button for process attach

* [ADF-740] added PR request changes

* [ADF-802] fix error on uploading file to attachment list (#1957)

* [ADF-802] fix error on uploading file to attachment list

* [ADF-802] improved for loop

* [ADF-797] remove dist folder from npm distributed package , leave src and bundles (#1961)

* [ADF-804] webpack proxy setup to avoid CORS problem (#1960)

* package lock update

* update travis to node 8 (#1965)

* upload service exposes created nodes (#1964)

* [ADF-591] documentation refinements (#1959)

* refine ng2-activiti-analytics

* refine ng2-activiti-diagrams docs

* refine ng2-activiti-form

* refine ng2-activiti-processlist

* refine ng2-activiti-tasklist

* refine ng2-alfresco-core

* refine ng2-alfresco-datatable

* refine ng2-alfresco-datatable

* refine gn2-alfresco-login

* refine ng2-alfresco-search

* refine ng2-alfresco-social

* refine ng2-alfresco-tag

* refine ng2-alfresco-upload

* refine ng2-alfresco-userinfo

* refine ng2-alfresco-viewer

* refine ng2-alfresco-webscript

* various readme cleanups

* fix builds related to node-sass library (#1966)

* update dependencies and remove old lock files

* update sass loader

* updated lock files

* [ADF-578] Remember me functionality (#1962)

* Remember me functionality

* Happy pack to ng2-components' package.json

* Build fix

* Adding tabindices to viewer control elements (#1968)

* karma conf all single browser

* Fix current page number issue (#1970)

* [ADF-524] Datatable loading state (#1958)

* loading state datatable

* modify readme after review

* [ADF-78]  Update CORS help (#1973)

* Fix host configuration in demo-shell when no port is present (#1971)

* remove brachet

* [ADF-494] fixed readonly rendering for forms (#1972)

* [ADF-494] improved disabling for form

* [ADF-494] fixed readonly rendering for forms

* [ADF-814] application configuration service (#1969)

* app configuration service

* api improvements and readme update

* extend readme and add defaults

* unit tests for app config service

* [ADF-716] Task Header - Use a custom view inside the component (#1967)

* Use a generic custom view inside the task header

* Move the component into core component and change name

* Missing file

* Fix unit test

* fix unit test component name

* fix issue with shared Code settings

- remove obsolete rules for .js/.ts
- hide .happypack folder in the project tree

* [ADF-810] fix default value radio button (#1975)

* [ADF-510] Drag&Drop check permission to allow user to upload a file (#1948)

* [ADF-510] added permission check for drag&drop

* Improved code for drag and drop side

* Added test for drag and drop upload area changes

* Added test for document list permissions check

* [ADF-510] rebased branch after changes applied to upload

* [ADF-510] rebased branch and fixed tests

* [ADF-717] upgrade i18n and charting dependencies (#1976)

* remove app-specific polyfill dependencies

remove polyfill dependencies never used by component libraries

* upgrade i18n dependencies

* upgrade ng2-charts dependency

* fix unit tests

* update demo projects

* [ADF-524] Fix empty state after the loading introduction (#1980)

* fix empty state after the loading introduction

* Update document-list.component.spec.ts

remove typo

* [ADF-838] Table of content automatic creation (#1981)

* readonly value set

* Table of content automatic creation (#1982)

* add missing intl dependency for demo shell (#1984)

* [ADF-833] DataTable -  improve the single and double click event (#1979)

* Improve the single and double click event

* Fix unit test

* Task header basic documentation (#1985)

* Disable upload attachment when the task is completed (#1987)

* [ADF-847] upgrade to use application configuration service (#1986)

* migrate core lib to use server-side app config

* fix unit tests

* update Search tests

- update tests
- upgrade tests to use TestBed

* update UserInfo tests

* update Social tests

* update tests

* update unit tests

* cleanup old code

* update about page

* update demo shell readme

* dev and prod configurations

* updated package-lock file and removed duplicates in package.json

* [ADF-851] execute-outcome event for form service (#1989)

* execute-outcome event for form service

* readme updates

* fix loading state excluding other state during the loading (#1991)

* Fix compilation error (#1993)

* [ADF-883] Fix build errors (#1992)

* [ADF-793] Ability to create PDF renditions in case of non supported formats (#1994)

* Style changes and button

* Convert to PDF button

* Convert to PDF button part II.

* Convert within the Not Supported Format component

* Rendition loading skeleton

* Conversion is working.

* Convert button behaviour tests

* Rebasing fix.

* app settings page (#1997)

- custom app setttings service to use isolated storage (demo shell)
- restore settings UI
- redirect angular and rxjs to the same version as components use.

* [ADF-822] Added the npm-prepublish script (#1978)

* added the npm prepublish script

* changed permissions to prepublish script

* changed to npm run prepublish

* prepare the pr

* removed useless code to the script

* remove flags lib from demo shell (#1983)

* remove flags lib from demo shell

greatly reduce demo shell webpack resources by switching off flags (only 3 icons were displayed in the past)

* merge package.json

* add icons

* Fix typo error

* [ADF-794] Add people assignment component (#1977)

* Add people component

* exported people service

* added people-list component to show the involved user list

* changed people-search component layout

* changed people-list usage in people component

* changed people-list data table from custom template to data adapter

* changes people-search component related to people-list

* changes in activiti-people related to people-list and people-search component

* changed data adapter to direct data column setting to data-table

* removed ngChanges and added User and UserEvent models

* added User and UserEvent model in emitter and other emitter handler

* added user event model

* changed activiti-people component with latest UX changes

* addedand changed translate keys to the components

* added hasUser method to check the condition in html

* fixed tslint issue and test case issue in activiti-people component

* added test case for actviti-people-list component

* test case added for activiti-people-search component

* changed activiti-people test cases according to latest UX changes

* added description for activiti-people component

* changed test case to fix component.upgradeElement issue

* changes requested by Vito Albano #1

* splitted getDisplayUser into getDisplayUser and getInitialUsername

* introduce check type definition

* [ADF-897] - ActivitiPeopleList - use the adf prefix (#2001)

* Use the adf as prexif instead of activiti

* Fix typo

* Fix wrong import

* support binding [form] data directly (#1996)

- ability to bind [form] data directly inside `<activiti-form>` component
- ability to parse forms with FormService
- demo of the custom form in demo shell

* [ADF-778] cancel window for upload dialog shows only on complete (#2003)

* [ADF-778] Added new behaviour to upload dialog

* [ADF-778] cancel window for upload dialog shows only on complete

* [ADF-778] changed variable name to showCloseButton

* Create task/process attachment Compilation error (#2004)

* fix tslint errors

minor fix for "Unnecessary semicolon" TSLint rule

* [ADF-842] Fixed type for taskdetails (#2009)

* fix type definition (#2002)

* Use the activiti people with the new look and feel inside the demo shell (#2008)

* add rxjs and @angular in tsconfig.json

* [ADF-843] Form events bus (#1990)

* form events bus

* event test bus fix

* fix test after code review

* fix types errors

* change to public formservice

* make optional formservice

* [ADF-915] Add option to change the JS-API with different version in the update package

* Missing keys (#2011)

* [ADF-845] breadcrumb root option added and style review (#1999)

* breadcrumb root option added and style review

* new breadcrumbs

* split onchange in a method

* update readme with a note for old pefix tag

* fix tslint errors

* fix breadcrumb test

* [ADF-922] Regenerate package-lock.json files for every package and create script for doing that in the future (#2012)

* Updated package-lock.json files

* npm-relock-pkgs.sh

* Update README.md

* Fix ng2-alfresco-search sass problem

* SASS version update (#2013)

* sass update

* update sass loader

* vjsapi option prepublish

* prepublish script deprecation in favour of prepublishOnly node 8 (#2010)

* modify prePublish script with preoPublishOnly

* install rimraf globally

* fix clean scripts demo folders

* move appveyor to node 8

* Appveyor test (#1998)

* reduce memory

* remove max-old-space

* remove increase memory

* create new TaskDetailsModel in loadNextTask (#2017)

* Fix readme document list

* [ADF-907] - Form reacts to data added in input (#2016)

* [ADF-907] Enable activiti form to react on value data changes

* [ADF-907] - Form reacts to data added in input]

* [ADF - 907] added mock json for form

* [ADF-907] added new event of the form to the event list

* [ADF - 907] Added return column to README

* [ADF - 907] Added return column to README

* Script add pkg and clean update

* install globally pkg pre build

* Fix upload related content (#2019)

* regeneration TOC and add automatic list component generator (#2022)

* Fix upload process attachment (#2024)

* update typescript (#2026)

* update viewer readme

* fix type definition variables

* NgZone type passed parameter

* fix tslint error in tasklist

* Add screenshot (#2028)

* fix search miss typing

* bump version 1.6.0 (#2027)
This commit is contained in:
Eugenio Romano
2017-06-29 15:57:37 +01:00
committed by GitHub
parent c6f6227da7
commit b15ab3b988
822 changed files with 168022 additions and 13865 deletions

View File

@@ -8,13 +8,13 @@ dist
src/**/*.js
src/**/*.js.map
src/**/*.d.ts
demo/**/*.js
demo/**/*.js.map
demo/**/*.d.ts
index.js
index.js.map
index.js.map.gitignore
!systemjs.config.js
*.tgz
/package/
/bundles/
index.d.ts
/.happypack

View File

@@ -6,6 +6,7 @@ demo/localTestFile.pdf
coverage/
demo/
dist/
node_modules
typings/
fonts/
@@ -17,5 +18,6 @@ fonts/
/karma.conf.js
/gulpfile.ts
/.npmignore
/.happypack
*.tgz

View File

@@ -1,36 +1,25 @@
# Alfresco File Viewer Component for Angular 2
# Alfresco File Viewer Component
<p>
<a title='Build Status Travis' href="https://travis-ci.org/Alfresco/alfresco-ng2-components">
<img src='https://travis-ci.org/Alfresco/alfresco-ng2-components.svg?branch=master' alt='travis
Status' />
</a>
<a title='Build Status AppVeyor' href="https://ci.appveyor.com/project/alfresco/alfresco-ng2-components">
<img src='https://ci.appveyor.com/api/projects/status/github/Alfresco/alfresco-ng2-components' alt='travis
Status' />
</a>
<a href='https://codecov.io/gh/Alfresco/alfresco-ng2-components'>
<img src='https://img.shields.io/codecov/c/github/Alfresco/alfresco-ng2-components/master.svg?maxAge=2592000' alt='Coverage Status' />
</a>
<a href='https://www.npmjs.com/package/ng2-alfresco-viewer'>
<img src='https://img.shields.io/npm/dt/ng2-alfresco-viewer.svg' alt='npm downloads' />
</a>
<a href='https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE'>
<img src='https://img.shields.io/hexpm/l/plug.svg' alt='license' />
</a>
<a href='https://www.alfresco.com/'>
<img src='https://img.shields.io/badge/style-component-green.svg?label=alfresco' alt='alfresco component' />
</a>
<a href='https://angular.io/'>
<img src='https://img.shields.io/badge/style-2-red.svg?label=angular' alt='angular 2' />
</a>
<a href='https://www.typescriptlang.org/docs/tutorial.html'>
<img src='https://img.shields.io/badge/style-lang-blue.svg?label=typescript' alt='typescript' />
</a>
<a href='https://www.alfresco.com/'>
<img src='https://img.shields.io/badge/style-%3E5.0.0-blue.svg?label=node%20version' alt='node version' />
</a>
</p>
<!-- markdown-toc start - Don't edit this section. npm run toc to generate it-->
<!-- toc -->
- [Prerequisites](#prerequisites)
- [Install](#install)
- [Basic usage](#basic-usage)
- [Properties](#properties)
- [Supported file formats](#supported-file-formats)
- [PDF Conversion](#pdf-conversion)
- [Custom extension handler](#custom-extension-handler)
- [Build from sources](#build-from-sources)
- [NPM scripts](#npm-scripts)
- [Demo](#demo)
- [License](#license)
<!-- tocstop -->
<!-- markdown-toc end -->
See it live: [Viewer Quickstart](https://embed.plnkr.co/iTuG1lFIXfsP95l6bDW6/)
@@ -39,196 +28,67 @@ See it live: [Viewer Quickstart](https://embed.plnkr.co/iTuG1lFIXfsP95l6bDW6/)
Before you start using this development framework, make sure you have installed all required software and done all the
necessary configuration [prerequisites](https://github.com/Alfresco/alfresco-ng2-components/blob/master/PREREQUISITES.md).
> If you plan using this component with projects generated by Angular CLI, please refer to the following article: [Using ADF with Angular CLI](https://github.com/Alfresco/alfresco-ng2-components/wiki/Angular-CLI)
## Install
Follow the 3 steps below:
```sh
npm install ng2-alfresco-viewer
```
1. Npm
## Basic usage
```sh
npm install ng2-alfresco-viewer --save
```
2. Html
Include these dependencies in your index.html page:
```html
<!-- Google Material Design Lite -->
<link rel="stylesheet" href="node_modules/material-design-lite/material.min.css">
<script src="node_modules/material-design-lite/material.min.js"></script>
<link rel="stylesheet" href="node_modules/material-design-icons/iconfont/material-icons.css">
<!-- Load the Angular Material 2 stylesheet -->
<link href="node_modules/@angular/material/core/theming/prebuilt/deeppurple-amber.css" rel="stylesheet">
<!-- Polyfill(s) for Safari (pre-10.x) -->
<script src="node_modules/intl/dist/Intl.min.js"></script>
<script src="node_modules/intl/locale-data/jsonp/en.js"></script>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/dom4/1.8.3/dom4.js"></script>
<script src="node_modules/element.scrollintoviewifneeded-polyfill/index.js"></script>
<!-- Polyfill(s) for dialogs -->
<script src="node_modules/dialog-polyfill/dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="node_modules/dialog-polyfill/dialog-polyfill.css" />
<style>._dialog_overlay { position: static !important; } </style>
<!-- Modules -->
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- Polyfill(s) for pdf support -->
<script src="node_modules/pdfjs-dist/web/compatibility.js"></script>
<script src="node_modules/pdfjs-dist/build/pdf.js"></script>
<script src="node_modules/pdfjs-dist/build/pdf.worker.js"></script>
<script src="node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
```
3. SystemJs
Add the following components to your systemjs.config.js file:
- ng2-translate
- alfresco-js-api
- ng2-alfresco-core
- ng2-alfresco-viewer
Please refer to the following example file: [systemjs.config.js](demo/systemjs.config.js) .
#### Basic usage with node id
Using with node id:
```html
<alfresco-viewer [overlayMode]="true" [urlFile]="'filename.pdf'"></alfresco-viewer>
<alfresco-viewer
[showViewer]="true"
[overlayMode]="true"
[fileNodeId]="'d367023a-7ebe-4f3a-a7d0-4f27c43f1045'">
</alfresco-viewer>
```
Example of an App that declares the file viewer component :
```ts
import { NgModule, Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { ViewerModule } from 'ng2-alfresco-viewer';
@Component({
selector: 'alfresco-app-demo',
template: `
<alfresco-viewer
[showViewer]="true"
[overlayMode]="true"
[fileNodeId]="'d367023a-7ebe-4f3a-a7d0-4f27c43f1045'">
</alfresco-viewer>`
})
class MyDemoApp {
constructor(private authService: AlfrescoAuthenticationService,
private settingsService: AlfrescoSettingsService) {
settingsService.ecmHost = 'http://localhost:8080';
this.authService.login('admin', 'admin').subscribe(
ticket => console.log(ticket),
error => console.log(error)
);
}
}
@NgModule({
imports: [
BrowserModule,
CoreModule.forRoot(),
ViewerModule.forRoot()
],
declarations: [ MyDemoApp ],
bootstrap: [ MyDemoApp ]
})
export class AppModule { }
platformBrowserDynamic().bootstrapModule(AppModule);
```
#### Basic usage with urlFile
Using with file url:
```html
<alfresco-viewer [overlayMode]="true" [urlFile]="'filename.pdf'"></alfresco-viewer>
<alfresco-viewer
[overlayMode]="true"
[urlFile]="'filename.pdf'">
</alfresco-viewer>
```
Example of an App that declares the file viewer component :
## Properties
```ts
import { NgModule, Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { ViewerModule } from 'ng2-alfresco-viewer';
| Attribute | Options | Default | Description |
| --- | --- | --- | --- |
| fileNodeId | string | | Node Id of the file to load the file |
| urlFile | string | | If you want load an external file that not comes from the ECM you can use this Url where to load the file |
| urlBlob | Blob | | If you want load a Blob File |
| overlayMode | boolean | false | if `true` Show the Viewer full page over the present content otherwise will fit the parent div |
| showViewer | boolean | true | Hide or show the viewer |
| showToolbar | boolean | true | Hide or show the toolbars |
| displayName | string | | You can specify the name of the file |
@Component({
selector: 'alfresco-app-demo',
template: `
<alfresco-viewer
[showViewer]="true"
[overlayMode]="true"
[urlFile]="'localTestFile.pdf'">
</alfresco-viewer>`
})
class MyDemoApp {
## Supported file formats
constructor(private authService: AlfrescoAuthenticationService,
private settingsService: AlfrescoSettingsService) {
settingsService.ecmHost = 'http://localhost:8080';
this.authService.login('admin', 'admin').subscribe(
ticket => console.log(ticket),
error => console.log(error)
);
}
}
@NgModule({
imports: [
BrowserModule,
CoreModule.forRoot(),
ViewerModule.forRoot()
],
declarations: [ MyDemoApp ],
bootstrap: [ MyDemoApp ]
})
export class AppModule { }
platformBrowserDynamic().bootstrapModule(AppModule);
```
#### Options
| Attribute | Options | Default | Description | Mandatory
| --- | --- | --- | --- | --- |
| `fileNodeId` | *string* | | Node Id of the file to load the file |
| `urlFile` | *string* | | If you want load an external file that not comes from the ECM you can use this Url where to load the file |
| `urlBlob` | *Blob* | | If you want load a Blob File |
| `overlayMode` | *boolean* | `false` | if true Show the Viewer full page over the present content otherwise will fit the parent div |
| `showViewer` | *boolean* | `true` | Hide or show the viewer |
| `showToolbar` | *boolean* | `true` | Hide or show the toolbars |
| `displayName` | *string* | | You can specify the name of the file |
#### Supported file formats
| Type | extensions |
| Type | Extension |
| --- | --- |
| Media | Mp4, WebM, Ogv |
| Media | wav, Mp3, Mp4, WebM, Ogv |
| Images | png, jpg, jpeg, gif, bmp |
| Text | pdf |
| Text | pdf, txt |
# Custom extension handler
## PDF Conversion
![Rendition](docs/assets/renditions.png)
Note for unsupported extension the viewer will offer the possibility to convert it in PDF is that kind of extension is supported by the [content service renditions service](https://community.alfresco.com/docs/DOC-5879-rendition-service)
## Custom extension handler
If you want handle other file formats that are not yet supported by the ng2-alfresco-viewer you can define your own custom handler.
Below you can find an example where with the use of ```extension-viewer``` if you can handle 3d files
Below you can find an example where with the use of `extension-viewer` if you can handle 3d files
```html
<alfresco-viewer
@@ -250,7 +110,7 @@ Below you can find an example where with the use of ```extension-viewer``` if yo
Note: you need adding `ng2-3d-editor` dependency to your `package.json` file to make example above work.
It is possible to define multiple ```extension-viewer``` templates:
It is possible to define multiple `extension-viewer` templates:
```html
<alfresco-viewer
@@ -278,49 +138,15 @@ It is possible to define multiple ```extension-viewer``` templates:
## Build from sources
Alternatively you can build component from sources with the following commands:
You can build component from sources with the following commands:
```sh
npm install
npm run build
```
### Build the files and keep watching for changes
```sh
$ npm run build:w
```
## Running unit tests
```sh
npm test
```
### Running unit tests in browser
```sh
npm test-browser
```
This task rebuilds all the code, runs tslint, license checks and other quality check tools
before performing unit testing.
### Code coverage
```sh
npm run coverage
```
## Demo
If you want have a demo of how the component works, please check the demo folder :
```sh
cd demo
npm install
npm start
```
> The `build` task rebuilds all the code, runs tslint, license checks
> and other quality check tools before performing unit testing.
## NPM scripts
@@ -331,6 +157,16 @@ npm start
| npm run test-browser | Run unit tests in the browser
| npm run coverage | Run unit tests and display code coverage report |
## Demo
Please check the demo folder for a demo project
```sh
cd demo
npm install
npm start
```
## License
[Apache Version 2.0](https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE)
[Apache Version 2.0](https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE)

View File

@@ -0,0 +1,35 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-source-map',
externals: [
/^\@angular\//,
/^rxjs\//,
'moment',
'raphael',
'ng2-charts',
'alfresco-js-api',
'ng2-alfresco-core',
'ng2-alfresco-datatable',
'ng2-activiti-analytics',
'ng2-activiti-diagrams',
'ng2-activiti-form',
"ng2-activiti-tasklist",
'ng2-alfresco-documentlist'
],
output: {
filename: './bundles/[name].js',
library: '[name]',
libraryTarget: 'umd',
chunkFilename: '[id].chunk.js'
},
entry: {
"ng2-alfresco-viewer": "./index.ts"
}
});

View File

@@ -2,6 +2,11 @@ const webpack = require('webpack');
const helpers = require('./helpers');
const fs = require('fs');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
var HappyPack = require('happypack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = {
@@ -12,22 +17,14 @@ module.exports = {
}
},
// require those dependencies but don't bundle them
externals: [
/^\@angular\//,
/^rxjs\//,
'moment',
'raphael',
'ng2-charts',
'alfresco-js-api',
'ng2-alfresco-core',
'ng2-alfresco-datatable',
'ng2-activiti-analytics',
'ng2-activiti-diagrams',
'ng2-activiti-form',
"ng2-activiti-tasklist",
'ng2-alfresco-documentlist'
],
resolve: {
alias: {
"ng2-alfresco-core": helpers.root('../ng2-alfresco-core/index.ts')
},
extensions: ['.ts', '.js'],
symlinks: false,
modules: [helpers.root('../../ng2-components'), helpers.root('node_modules')]
},
module: {
rules: [
@@ -37,37 +34,37 @@ module.exports = {
loader: 'source-map-loader',
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
enforce: 'pre',
test: /\.ts$/,
use: 'source-map-loader',
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
enforce: 'pre',
test: /\.ts$/,
loader: 'tslint-loader',
options: {
emitErrors: true,
configFile: path.resolve(__dirname, './assets/tslint.json')
failOnHint: true
},
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.ts$/,
use: ['ts-loader', 'angular2-template-loader'],
loader: ['happypack/loader?id=ts', 'angular2-template-loader'],
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.html$/,
loader: 'html-loader',
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
exclude: [/node_modules/, /bundles/, /dist/, /demo/, /assets/]
},
{
test: /\.css$/,
loader: ['to-string-loader', 'css-loader'],
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},{
exclude: [/node_modules/, /bundles/, /dist/, /demo/, /assets/]
},
{
test: /\.component.scss$/,
use: ['to-string-loader', 'raw-loader', 'sass-loader'],
exclude: [/node_modules/, /bundles/, /dist/, /demo/, /assets/]
},
{
enforce: 'pre',
test: /\.ts$/,
loader: 'license-check',
@@ -75,7 +72,7 @@ module.exports = {
emitErrors: true,
licenseFile: path.resolve(__dirname, './assets/license_header.txt')
},
exclude: [/node_modules/, /bundles/, /dist/, /demo/, /rendering-queue.services.ts/ ],
exclude: [/node_modules/, /bundles/, /dist/, /demo/, /rendering-queue.services.ts/, /assets/]
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
@@ -95,15 +92,29 @@ module.exports = {
]
},
resolve: {
extensions: ['.ts', '.js'],
symlinks: false,
modules: [
'../ng2-components', 'node_modules'
]
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new HappyPack({
id: 'ts',
threads: 8,
loaders: [
{
path: 'ts-loader',
query: {
happyPackMode: true,
"compilerOptions": {
"paths": {}
}
}
}
]
}),
new CopyWebpackPlugin([{
from: `src/i18n/`,
to: `bundles/assets/${path.basename(helpers.root(''))}/i18n/`
}]),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.BannerPlugin(fs.readFileSync(path.resolve(__dirname, './assets/license_header_add.txt'), 'utf8')),
@@ -112,11 +123,19 @@ module.exports = {
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'),
{}
)
),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
],
devtool: 'cheap-module-source-map',
node: {
fs: 'empty',
module: false

View File

@@ -0,0 +1,22 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const testConfig = require('./webpack.test.js');
const helpers = require('./helpers');
module.exports = webpackMerge(testConfig, {
module: {
rules: [
{
enforce: 'post',
test: /^(?!(.*spec|index|.*mock|.*model|.*event)).*\.ts?$/,
include: [helpers.root('src')],
loader: 'istanbul-instrumenter-loader',
exclude: [
/node_modules/,
/test/
]
}
]
}
});

View File

@@ -1,43 +1,15 @@
const webpack = require('webpack');
const helpers = require('./helpers');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = {
module.exports = webpackMerge(commonConfig, {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js'],
symlinks: false,
modules: [helpers.root('../ng2-components'), helpers.root('node_modules')]
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.ts$/,
loaders: ['ts-loader?' + JSON.stringify({ transpileOnly: true}), 'angular2-template-loader'],
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.html$/,
loader: 'html-loader',
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.css$/,
loader: ['to-string-loader', 'css-loader'],
exclude: [/node_modules/, /bundles/, /dist/, /demo/]
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico|pdf)$/,
test: /\.(txt|pdf)$/,
loader: 'file-loader',
query: {
name: '[path][name].[ext]',
@@ -45,41 +17,8 @@ module.exports = {
return url.replace('src', 'dist');
}
}
},
{
enforce: 'post',
test: /\.ts$/,
loader: 'istanbul-instrumenter-loader',
exclude: [
/node_modules/,
/test/
]
}
]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'),
{}
),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
],
node: {
fs: 'empty',
module: false
}
};
});

View File

@@ -0,0 +1,10 @@
var path = require('path');
var _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;

View File

@@ -0,0 +1,133 @@
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const helpers = require('./helpers');
const path = require('path');
const alfrescoLibs = [
'ng2-alfresco-viewer'
];
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'dist': './src/main.ts'
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
include: [helpers.root('src'), helpers.root('../ng2-components')],
loader: 'source-map-loader',
exclude: [ /node_modules/, /public/, /resources/, /dist/]
},
{
test: /\.ts$/,
include: [helpers.root('src'), helpers.root('..')],
loader: [
'ts-loader',
'angular2-template-loader'
],
exclude: [ /node_modules/, /public/, /resources/, /dist/]
},
{
enforce: 'pre',
test: /\.ts$/,
loader: 'tslint-loader',
include: [helpers.root('src')],
options: {
emitErrors: true
},
exclude: [ /node_modules/, /public/, /resources/, /dist/]
},
{
enforce: 'pre',
test: /\.ts$/,
use: 'source-map-loader',
exclude: [ /public/, /resources/, /dist/]
},
{
test: /\.html$/,
loader: 'html-loader',
exclude: [ /node_modules/, /public/, /resources/, /dist/]
},
{
test: /\.css$/,
exclude: [helpers.root('src'), helpers.root('../ng2-components')],
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader?sourceMap'
})
},
{
test: /\.css$/,
include: [helpers.root('src'), helpers.root('../ng2-components')],
loader: 'raw-loader'
},
{
test: /\.component.scss$/,
use: ['to-string-loader', 'raw-loader', 'sass-loader']
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
}
]
},
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new HtmlWebpackPlugin({
template: './index.html'
}),
new CopyWebpackPlugin([
... alfrescoLibs.map(lib => {
return {
context: `../ng2-components/${lib}/bundles/assets/` ,
from: '**/*',
to: `assets/`
}
}),
{
context: 'resources/i18n',
from: '**/*.json',
to: 'resources/i18n'
},
... alfrescoLibs.map(lib => {
return {
context: 'node_modules',
from: `${lib}/src/i18n/*.json`,
to: 'node_modules'
}
})
]),
new webpack.optimize.CommonsChunkPlugin({
name: ['src', 'vendor', 'polyfills']
})
],
devServer: {
contentBase: helpers.root('dist'),
compress: true,
port: 3000,
historyApiFallback: true,
host: '0.0.0.0',
inline: true
},
node: {
fs: 'empty'
}
};

View File

@@ -0,0 +1,36 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
const path = require('path');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
resolve: {
alias: {
"ng2-alfresco-core$": path.resolve(__dirname, '../../ng2-alfresco-core/index.ts'),
"ng2-alfresco-viewer$": path.resolve(__dirname, '../../ng2-alfresco-viewer/index.ts')
},
extensions: ['.ts', '.js'],
modules: [path.resolve(__dirname, '../node_modules')]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
]
});

View File

@@ -0,0 +1,65 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const alfrescoLibs = [
'ng2-alfresco-viewer'
];
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
resolve: {
extensions: ['.ts', '.js'],
modules: [helpers.root('node_modules')]
},
plugins: [
new CopyWebpackPlugin([
... alfrescoLibs.map(lib => {
return {
context: `node_modules/${lib}/bundles/assets/` ,
from: '**/*',
to: `assets/`
}
})
]),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
mangle: {
keep_fnames: true
},
compress: {
warnings: false
},
output: {
comments: false
},
sourceMap: true
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
]
});

View File

@@ -5,41 +5,7 @@
<title>Angular 2 Viewer - Demo</title>
<base href="./">
<!-- Google Material Design Lite -->
<link rel="stylesheet" href="node_modules/material-design-lite/material.min.css">
<script src="node_modules/material-design-lite/material.min.js"></script>
<link rel="stylesheet" href="node_modules/material-design-icons/iconfont/material-icons.css">
<!-- Polyfill(s) for Safari (pre-10.x) -->
<script src="node_modules/intl/dist/Intl.min.js"></script>
<script src="node_modules/intl/locale-data/jsonp/en.js"></script>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/dom4/1.8.3/dom4.js"></script>
<script src="node_modules/element.scrollintoviewifneeded-polyfill/index.js"></script>
<!-- Polyfill(s) for dialogs -->
<script src="node_modules/dialog-polyfill/dialog-polyfill.js"></script>
<link rel="stylesheet" type="text/css" href="node_modules/dialog-polyfill/dialog-polyfill.css" />
<style>._dialog_overlay { position: static !important; } </style>
<!-- Modules -->
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- Polyfill(s) for pdf support -->
<script src="node_modules/pdfjs-dist/web/compatibility.js"></script>
<script src="node_modules/pdfjs-dist/build/pdf.js"></script>
<script src="node_modules/pdfjs-dist/build/pdf.worker.js"></script>
<script src="node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
@@ -47,3 +13,4 @@
</body>
</html>

View File

@@ -0,0 +1,79 @@
{
"name": "ng2-alfresco-viewer-demo",
"version": "0.1.0",
"lockfileVersion": 1,
"dependencies": {
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"rimraf": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
"integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
}
}

View File

@@ -3,19 +3,16 @@
"description": "Alfresco Angular2 Viewer - Demo",
"version": "0.1.0",
"author": "Alfresco Software, Ltd.",
"main": "index.js",
"scripts": {
"clean": "npm run clean-build && rimraf dist node_modules typings dist",
"clean-build" : "rimraf 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts'",
"postinstall": "npm run build",
"start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ",
"server": "wsrv -o -s -l",
"build": "npm run tslint && npm run clean-build && npm run tsc",
"build:w": "npm run tslint && rimraf dist && npm run tsc:w",
"travis": "npm link ng2-alfresco-core ng2-alfresco-viewer",
"tsc": "tsc",
"tsc:w": "tsc -w",
"tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts -e '{,**/}**.d.ts'"
"build": "rimraf dist && npm run webpack -- --config config/webpack.prod.js --progress --profile --bail",
"build:dev": "rimraf dist && npm run webpack -- --config config/webpack.dev.js --progress --profile --bail",
"start:dist": "wsrv -s dist/ -p 3000 -a 0.0.0.0",
"start": "npm run webpack-dev-server -- --config config/webpack.prod.js --progress --content-base app/",
"start:dev": "npm run webpack-dev-server -- --config config/webpack.dev.js --progress --content-base app/",
"clean": "npm run clean-build && rimraf dist node_modules typings dist",
"clean-build": "rimraf 'app/{,**/}**.js' 'app/{,**/}**.js.map' 'app/{,**/}**.d.ts'",
"webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
"webpack": "webpack"
},
"license": "Apache-2.0",
"dependencies": {
@@ -28,34 +25,77 @@
"@angular/platform-browser": "~4.0.0",
"@angular/platform-browser-dynamic": "~4.0.0",
"@angular/router": "~4.0.0",
"@angular/material": "2.0.0-beta.1",
"alfresco-js-api": "~1.5.0",
"alfresco-js-api": "~1.6.0",
"core-js": "2.4.1",
"hammerjs": "2.0.8",
"ng2-alfresco-core": "1.5.0",
"ng2-translate": "5.0.0",
"ng2-alfresco-core": "1.6.0",
"@ngx-translate/core": "^7.0.0",
"reflect-metadata": "0.1.10",
"rxjs": "5.1.0",
"systemjs": "0.19.27",
"zone.js": "0.7.6",
"intl": "1.2.4",
"dialog-polyfill": "0.4.7",
"element.scrollintoviewifneeded-polyfill": "1.0.1",
"material-design-icons": "2.2.3",
"material-design-lite": "1.2.1",
"ng2-alfresco-viewer": "1.5.0",
"ng2-alfresco-viewer": "1.6.0",
"pdfjs-dist": "1.5.404"
},
"devDependencies": {
"@types/jasmine": "^2.2.33",
"@types/node": "^6.0.42",
"concurrently": "^2.2.0",
"rimraf": "2.5.2",
"tslint": "3.15.1",
"typescript": "^2.0.3",
"wsrv": "^0.1.5"
"@types/hammerjs": "^2.0.34",
"@types/jasmine": "2.5.35",
"@types/node": "6.0.45",
"angular2-template-loader": "^0.6.2",
"autoprefixer": "^6.5.4",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.23.1",
"css-to-string-loader": "^0.1.2",
"cssnano": "^3.8.1",
"extract-text-webpack-plugin": "^2.0.0-rc.3",
"file-loader": "0.11.1",
"html-loader": "^0.4.4",
"html-webpack-plugin": "^2.28.0",
"istanbul-instrumenter-loader": "0.2.0",
"jasmine-ajax": "^3.2.0",
"jasmine-core": "2.4.1",
"karma": "^0.13.22",
"karma-chrome-launcher": "~1.0.1",
"karma-coverage": "^1.1.1",
"karma-jasmine": "~1.0.2",
"karma-jasmine-ajax": "^0.1.13",
"karma-jasmine-html-reporter": "0.2.0",
"karma-mocha-reporter": "^2.2.2",
"karma-remap-istanbul": "^0.6.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-systemjs": "^0.16.0",
"karma-webpack": "^2.0.2",
"loader-utils": "^1.1.0",
"merge-stream": "^1.0.1",
"node-sass": "^3.13.1",
"null-loader": "^0.1.1",
"package-json-merge": "0.0.1",
"raw-loader": "^0.5.1",
"remap-istanbul": "^0.6.3",
"rimraf": "^2.6.1",
"run-sequence": "^1.2.2",
"sass-loader": "6.0.2",
"script-loader": "0.7.0",
"source-map-loader": "^0.1.6",
"style-loader": "^0.13.1",
"systemjs-builder": "^0.15.34",
"to-string-loader": "^1.1.4",
"traceur": "^0.0.91",
"ts-loader": "^2.0.0",
"ts-node": "^1.7.0",
"tslint": "^4.4.2",
"tslint-loader": "^3.3.0",
"typescript": "^2.1.6",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0",
"webpack-merge": "2.6.1",
"wsrv": "^0.1.7"
},
"contributors": [
{

View File

@@ -0,0 +1,17 @@
import 'core-js/es6';
import 'core-js/es7/reflect';
import 'intl';
require('zone.js/dist/zone'); // IE 8-11
require('element.scrollintoviewifneeded-polyfill'); // IE/FF
if (process.env.ENV === 'production') {
// Production
} else {
// Development
Error['stackTraceLimit'] = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}

View File

@@ -0,0 +1,38 @@
// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
// RxJS
import 'rxjs';
// hammerjs
import 'hammerjs';
// Alfresco
import 'alfresco-js-api';
import 'ng2-alfresco-viewer';
// Google Material Design Lite
import 'material-design-lite/material.js';
import 'material-design-lite/dist/material.orange-blue.min.css';
import 'material-design-icons/iconfont/material-icons.css';
// Polyfill(s) for dialogs
require('script-loader!dialog-polyfill/dialog-polyfill');
import 'dialog-polyfill/dialog-polyfill.css';
require('pdfjs-dist/web/compatibility.js');
// Setting worker path to worker bundle.
let pdfjsLib = require('pdfjs-dist');
if (process.env.ENV === 'production') {
pdfjsLib.PDFJS.workerSrc = './pdf.worker.js';
} else {
pdfjsLib.PDFJS.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js';
}
require('pdfjs-dist/web/pdf_viewer.js');

View File

@@ -1,53 +0,0 @@
/**
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'src',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/material': 'npm:@angular/material/bundles/material.umd.js',
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.min.js',
'@angular/animations/browser':'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'ng2-translate': 'npm:ng2-translate',
'alfresco-js-api': 'npm:alfresco-js-api/dist',
'ng2-alfresco-core': 'npm:ng2-alfresco-core',
'ng2-alfresco-viewer': 'npm:ng2-alfresco-viewer'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
'ng2-translate': { defaultExtension: 'js' },
'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'},
'ng2-alfresco-core': {main: './bundles/ng2-alfresco-core.js', defaultExtension: 'js'},
'ng2-alfresco-viewer': {main: './bundles/ng2-alfresco-viewer.js', defaultExtension: 'js'}
}
});
})(this);

View File

@@ -1,5 +1,6 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
@@ -16,6 +17,7 @@
"noFallthroughCasesInSwitch": true,
"removeComments": true,
"declaration": true,
"outDir": "./dist",
"lib": [
"es2015",
"dom"
@@ -23,7 +25,9 @@
"suppressImplicitAnyIndexErrors": true
},
"exclude": [
"node_modules"
"demo",
"node_modules",
"dist"
],
"angularCompilerOptions": {
"strictMetadataEmit": false,

View File

@@ -1,121 +1,118 @@
{
"rules": {
"align": [
true,
"parameters",
"arguments",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space",
"check-lowercase"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"max-line-length": [
true,
180
],
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": false,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-constructor-vars": false,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-require-imports": false,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": true,
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-strict": false,
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-type",
"check-module",
"check-decl"
]
}
"rules": {
"align": [
true,
"parameters",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"max-line-length": [
true,
180
],
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-arg": true,
"no-bitwise": false,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-constructor-vars": false,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-require-imports": false,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": false,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": true,
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-strict": false,
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-type",
"check-module",
"check-decl"
]
}
}

View File

@@ -0,0 +1 @@
module.exports = require('./config/webpack.dev.js');

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;AAWH,sCAA8D;AAC9D,uDAA+C;AAE/C,sEAAoE;AACpE,oFAAiF;AACjF,4EAA0E;AAC1E,gFAA8E;AAC9E,8FAAmF;AACnF,4EAA0E;AAC1E,0FAAuF;AAEvF,uDAAkD;AAClD,6DAAwD;AACxD,0DAAqD;AACrD,4DAAuD;AACvD,mEAA8D;AAC9D,0DAAqD;AAExC,QAAA,iBAAiB,GAAU;IACpC,kCAAe;IACf,wCAAkB;IAClB,4CAAoB;IACpB,iDAAkB;IAClB,wCAAkB;IAClB,qDAAwB;CAC3B,CAAC;AAEW,QAAA,gBAAgB,GAAU;IACnC,iDAAsB;CACzB,CAAC;AAgBF,IAAa,YAAY;IAAzB;IASA,CAAC;IARU,oBAAO,GAAd;QACI,MAAM,CAAC;YACH,QAAQ,EAAE,cAAY;YACtB,SAAS,EACF,wBAAgB,QACtB;SACJ,CAAC;IACN,CAAC;IACL,mBAAC;AAAD,CAAC,AATD,IASC;AATY,YAAY;IAdxB,eAAQ,CAAC;QACN,OAAO,EAAE;YACL,8BAAU;SACb;QACD,YAAY,EACL,yBAAiB,QACvB;QACD,SAAS,EACF,wBAAgB,QACtB;QACD,OAAO,EACA,yBAAiB,QACvB;KACJ,CAAC;GACW,YAAY,CASxB;AATY,oCAAY"}

View File

@@ -33,7 +33,9 @@ import { ImgViewerComponent } from './src/components/imgViewer.component';
import { MediaPlayerComponent } from './src/components/mediaPlayer.component';
import { NotSupportedFormat } from './src/components/notSupportedFormat.component';
import { PdfViewerComponent } from './src/components/pdfViewer.component';
import { TxtViewerComponent } from './src/components/txtViewer.component';
import { ExtensionViewerDirective } from './src/directives/extension-viewer.directive';
import { MdIconModule, MdButtonModule, MdProgressSpinnerModule } from '@angular/material';
export * from './src/components/viewer.component';
export * from './src/services/rendering-queue.services';
@@ -41,10 +43,12 @@ export * from './src/components/imgViewer.component';
export * from './src/components/mediaPlayer.component';
export * from './src/components/notSupportedFormat.component';
export * from './src/components/pdfViewer.component';
export * from './src/components/txtViewer.component';
export const VIEWER_DIRECTIVES: any[] = [
ViewerComponent,
ImgViewerComponent,
TxtViewerComponent,
MediaPlayerComponent,
NotSupportedFormat,
PdfViewerComponent,
@@ -57,7 +61,10 @@ export const VIEWER_PROVIDERS: any[] = [
@NgModule({
imports: [
CoreModule
CoreModule,
MdIconModule,
MdButtonModule,
MdProgressSpinnerModule
],
declarations: [
...VIEWER_DIRECTIVES

View File

@@ -8,18 +8,12 @@ module.exports = function (config) {
files: [
'./node_modules/hammerjs/hammer.js',
{pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: false},
//diagrams
'./node_modules/chart.js/dist/Chart.js',
'./node_modules/alfresco-js-api/dist/alfresco-js-api.js',
'./node_modules/raphael/raphael.js',
'./node_modules/moment/min/moment.min.js',
'./node_modules/md-date-time-picker/dist/js/mdDateTimePicker.js',
{pattern: './node_modules/ng2-translate/**/*.js', included: false, watched: false},
{pattern: './node_modules/ng2-charts/**/*.js', included: false, served: true, watched: false},
{pattern: './node_modules/md-date-time-picker/**/*.js', included: false, served: true, watched: false},
{pattern: './node_modules/moment/**/*.js', included: false, served: true, watched: false},
// pdf-js
{pattern: './node_modules/pdfjs-dist/build/pdf.js', included: true, watched: false},
@@ -27,11 +21,11 @@ module.exports = function (config) {
{pattern: './node_modules/pdfjs-dist/web/pdf_viewer.js', included: true, watched: false},
{pattern: 'karma-test-shim.js', watched: false},
{pattern: './src/**/*.*', included: false, served: true, watched: false}
{pattern: './src/**/*.ts', included: false, served: true, watched: false}
],
webpack: webpackConfig,
webpack: (config.mode === 'coverage') ? require('./webpack.coverage') : require('./webpack.test'),
webpackMiddleware: {
stats: 'errors-only'

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,17 @@
{
"name": "ng2-alfresco-viewer",
"description": "Alfresco documents viewer",
"version": "1.5.0",
"version": "1.6.0",
"author": "Alfresco Software, Ltd.",
"scripts": {
"clean": "rimraf dist node_modules typings bundles coverage .npmrc",
"clean-lock": "rimraf package-lock.json",
"rimraf": "rimraf",
"build": "webpack --config webpack.build.js --progress --profile --bail",
"test": "karma start karma.conf.js --reporters mocha,coverage --single-run --component",
"test": "karma start karma.conf.js --reporters mocha,coverage --single-run --mode coverage",
"test-browser": "karma start karma.conf.js --reporters kjhtml --component",
"coverage": "npm run test && wsrv -o -p 9875 ./coverage/report",
"prepublish" : "npm run build"
"prepublishOnly": "npm run build"
},
"main": "bundles/ng2-alfresco-viewer.js",
"repository": {
@@ -45,13 +46,12 @@
"@angular/platform-browser": "~4.0.0",
"@angular/platform-browser-dynamic": "~4.0.0",
"@angular/router": "~4.0.0",
"@angular/material": "2.0.0-beta.1",
"alfresco-js-api": "~1.5.0",
"@angular/material": "2.0.0-beta.6",
"alfresco-js-api": "~1.6.0",
"core-js": "2.4.1",
"hammerjs": "2.0.8",
"ng2-alfresco-core": "1.5.0",
"ng2-translate": "5.0.0",
"ng2-alfresco-core": "1.6.0",
"@ngx-translate/core": "^7.0.0",
"pdfjs-dist": "1.5.404",
"reflect-metadata": "0.1.10",
"rxjs": "5.1.0",
@@ -70,6 +70,8 @@
"cssnano": "^3.8.1",
"extract-text-webpack-plugin": "^2.0.0-rc.3",
"file-loader": "0.11.1",
"fork-ts-checker-webpack-plugin": "^0.2.3",
"happypack": "3.0.0",
"html-loader": "^0.4.4",
"html-webpack-plugin": "^2.28.0",
"istanbul-instrumenter-loader": "0.2.0",
@@ -88,12 +90,14 @@
"karma-webpack": "^2.0.2",
"loader-utils": "^1.1.0",
"merge-stream": "^1.0.1",
"node-sass": "^4.5.3",
"null-loader": "^0.1.1",
"package-json-merge": "0.0.1",
"raw-loader": "^0.5.1",
"remap-istanbul": "^0.6.3",
"rimraf": "^2.5.4",
"rimraf": "^2.6.1",
"run-sequence": "^1.2.2",
"sass-loader": "^6.0.5",
"script-loader": "0.7.0",
"source-map-loader": "^0.1.6",
"style-loader": "^0.13.1",
@@ -104,7 +108,7 @@
"ts-node": "^1.7.0",
"tslint": "^4.4.2",
"tslint-loader": "^3.3.0",
"typescript": "^2.1.6",
"typescript": "^2.3.4",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0",
"webpack-merge": "2.6.1",

View File

@@ -0,0 +1 @@
Text example

View File

@@ -29,7 +29,7 @@ export class ImgViewerComponent implements OnChanges {
urlFile: string;
@Input()
blobFile: any;
blobFile: Blob;
@Input()
nameFile: string;

View File

@@ -64,28 +64,28 @@ describe('Test ng2-alfresco-viewer Media player component ', () => {
fixture.detectChanges();
});
it('If no url or no blob are passed should thrown an error', () => {
it('should thrown an error If no url or no blob are passed', () => {
let change = new SimpleChange(null, null, true);
expect(() => {
component.ngOnChanges({ 'blobFile': change });
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
it('should not thrown an error If url is passed', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
it('should not thrown an error If url is passed', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If blob is passed should not thrown an error', () => {
it('should not thrown an error If blob is passed', () => {
let blob = createFakeBlob();
spyOn(service, 'createTrustedUrl').and.returnValue('fake-blob-url');

View File

@@ -1,23 +1,48 @@
.viewer-download-text {
text-align: center;
word-wrap: break-word;
}
.viewer-margin-cloud-download{
margin-right: 20px;
.unsupported-container {
width: 600px;
}
.viewer-margin {
margin: auto !important;
}
.center-element {
padding: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.full_width{
width :95% !important;
.viewer-download-text {
text-align: center;
word-wrap: break-word;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.viewer-download-text h4 {
margin: 0;
}
.adf-conversion-spinner {
margin: 16px 0;
}
.viewer-margin >>> .adf-conversion-spinner.mat-spinner path {
stroke: #00BFD4;
}
.button-container {
display: flex;
align-items: center;
justify-content: space-around;
}
.button-container button {
line-height: 40px;
}
.viewer-button-icon {
margin-right: 10px;
margin-top: -5px;
}

View File

@@ -1,12 +1,21 @@
<section class="section--center mdl-grid mdl-grid--no-spacing">
<section *ngIf="!isConversionFinished" class="unsupported-container">
<div class="viewer-margin mdl-card mdl-cell mdl-cell--9-col-desktop mdl-cell--6-col-tablet mdl-cell--4-col-phone mdl-shadow--2dp">
<div class="viewer-download-text mdl-card__supporting-text viewer-margin">
<div *ngIf="!isConversionStarted" class="viewer-download-text mdl-card__supporting-text">
<h4>File '<span>{{nameFile}}</span>' is of an unsupported format</h4>
</div>
<div class="center-element mdl-card__actions">
<button id="viewer-download-button" aria-label="Download" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="download()">
<i class="viewer-margin-cloud-download material-icons">cloud_download</i> Download
<md-spinner *ngIf="isConversionStarted" id="conversion-spinner" class="adf-conversion-spinner" color="primary"></md-spinner>
<div class="button-container mdl-card__actions">
<button md-button id="viewer-download-button" aria-label="Download" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" (click)="download()">
<md-icon class="viewer-button-icon">cloud_download</md-icon> Download
</button>
<button md-button *ngIf="convertible" [disabled]="isConversionStarted" id="viewer-convert-button" aria-label="Convert to PDF" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="convertToPdf()">
<md-icon class="viewer-button-icon">insert_drive_file</md-icon> Convert to PDF
</button>
<button md-button *ngIf="displayable" id="viewer-display-button" aria-label="Show PDF" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" (click)="showPDF()">
<md-icon class="viewer-button-icon">insert_drive_file</md-icon> Show PDF
</button>
</div>
</div>
</section>
<pdf-viewer *ngIf="isConversionFinished" id="pdf-rendition-viewer" [showToolbar]="showToolbar" [urlFile]="renditionUrl" [nameFile]="nameFile"></pdf-viewer>

View File

@@ -17,47 +17,85 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { NotSupportedFormat } from './notSupportedFormat.component';
import { PdfViewerComponent } from './pdfViewer.component';
import { DebugElement } from '@angular/core';
import { MdIconModule, MdButtonModule, MdProgressSpinnerModule } from '@angular/material';
import { Subject } from 'rxjs';
import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
CoreModule,
ContentService,
AlfrescoApiService,
CoreModule
LogService,
RenditionsService
} from 'ng2-alfresco-core';
type RenditionResponse = {
entry: {
status: string
}
};
describe('Test ng2-alfresco-viewer Not Supported Format View component', () => {
const nodeId = 'not-supported-node-id';
let component: NotSupportedFormat;
let service: ContentService;
let fixture: ComponentFixture<NotSupportedFormat>;
let debug: DebugElement;
let element: HTMLElement;
let renditionsService: RenditionsService;
let renditionSubject: Subject<RenditionResponse>,
conversionSubject: Subject<any>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
CoreModule
CoreModule,
MdIconModule,
MdButtonModule,
MdProgressSpinnerModule
],
declarations: [
NotSupportedFormat,
PdfViewerComponent
],
declarations: [NotSupportedFormat],
providers: [
AlfrescoSettingsService,
AlfrescoAuthenticationService,
AlfrescoApiService
AlfrescoApiService,
ContentService,
RenditionsService,
LogService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NotSupportedFormat);
service = fixture.debugElement.injector.get(ContentService);
debug = fixture.debugElement;
element = fixture.nativeElement;
component = fixture.componentInstance;
fixture.detectChanges();
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', () => {
it('Download button should be present', () => {
beforeEach(() => {
fixture.detectChanges();
});
it('should be present Download button', () => {
expect(element.querySelector('#viewer-download-button')).not.toBeNull();
});
@@ -66,16 +104,131 @@ describe('Test ng2-alfresco-viewer Not Supported Format View component', () => {
fixture.detectChanges();
expect(element.querySelector('h4 span').innerHTML).toEqual('Example Content.xls');
});
it('should NOT show loading spinner by default', () => {
expect(element.querySelector('#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('#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('#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('#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('#viewer-convert-button')).toBeNull();
});
}));
});
describe('User Interaction', () => {
it('Click on Download button should call download method', () => {
spyOn(window, 'open');
let downloadButton: any = element.querySelector('#viewer-download-button');
downloadButton.click();
beforeEach(() => {
fixture.detectChanges();
});
expect(window.open).toHaveBeenCalled();
describe('Download', () => {
it('should call download method if Click on Download button', () => {
spyOn(window, 'open');
component.urlFile = 'test';
let downloadButton: any = element.querySelector('#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('#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('#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('#viewer-convert-button');
expect(element.querySelector('#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('#viewer-convert-button');
expect(element.querySelector('#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('#pdf-rendition-viewer')).not.toBeNull('Pdf rendition should be shown.');
});
});
});
});

View File

@@ -15,14 +15,18 @@
* limitations under the License.
*/
import { Component, Input } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { ContentService, RenditionsService } from 'ng2-alfresco-core';
import { AlfrescoApiService } from 'ng2-alfresco-core';
const DEFAULT_CONVERSION_ENCODING = 'pdf';
@Component({
selector: 'not-supported-format',
templateUrl: './notSupportedFormat.component.html',
styleUrls: ['./notSupportedFormat.component.css']
})
export class NotSupportedFormat {
export class NotSupportedFormat implements OnInit {
@Input()
nameFile: string;
@@ -30,10 +34,87 @@ export class NotSupportedFormat {
@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;
constructor(
private contentService: ContentService,
private renditionsService: RenditionsService,
private apiService: AlfrescoApiService
) {}
/**
* Download file opening it in a new window
*/
download() {
window.open(this.urlFile);
if (this.urlFile) {
window.open(this.urlFile);
} else {
this.contentService.downloadBlob(this.blobFile, this.nameFile);
}
}
ngOnInit() {
if (this.nodeId) {
this.checkRendition();
}
}
/**
* 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: any) => {
if (response.entry.status === 'NOT_CREATED') {
this.convertible = true;
this.displayable = false;
} else if (response.entry.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.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.apiService.getInstance().content.getRenditionUrl(this.nodeId, DEFAULT_CONVERSION_ENCODING);
this.isConversionStarted = false;
this.isConversionFinished = true;
}
}

View File

@@ -14,7 +14,7 @@
<!-- Pagination toolbar start -->
<div *ngIf="showToolbar" id="viewer-toolbar-pagination" class="viewer-toolbar-pagination mdl-cell--hide-tablet mdl-cell--hide-phone">
<div id="viewer-previous-page-button" aria-label="arrow left" class="button-page left" (click)="previousPage()">
<div id="viewer-previous-page-button" aria-label="arrow left" class="button-page left" (click)="previousPage()" tabindex="0">
<i class="icon material-icons">keyboard_arrow_left</i>
</div>
@@ -24,7 +24,7 @@
<div id="viewer-total-pages" class="left viewer-total-pages">/ {{totalPages}}</div>
</div>
<div id="viewer-next-page-button" aria-label="arrow right" class="button-page left" (click)="nextPage()" >
<div id="viewer-next-page-button" aria-label="arrow right" class="button-page left" (click)="nextPage()" tabindex="0">
<i class="icon material-icons" >keyboard_arrow_right</i>
</div>
</div>
@@ -32,13 +32,13 @@
<!-- Command toolbar start -->
<div *ngIf="showToolbar" id="viewer-toolbar-command" class="viewer-toolbar-command">
<div id="viewer-scale-page-button" aria-label="zoom out map" class="button-page left" (click)="pageFit()">
<div id="viewer-scale-page-button" aria-label="zoom out map" class="button-page left" (click)="pageFit()" tabindex="0">
<i class="icon material-icons">zoom_out_map</i>
</div>
<div id="viewer-zoom-in-button" aria-label="zoom in" class="button-page left" (click)="zoomIn()">
<div id="viewer-zoom-in-button" aria-label="zoom in" class="button-page left" (click)="zoomIn()" tabindex="0">
<i class="icon material-icons">zoom_in</i>
</div>
<div id="viewer-zoom-out-button" aria-label="zoom out" class="button-page left" (click)="zoomOut()">
<div id="viewer-zoom-out-button" aria-label="zoom out" class="button-page left" (click)="zoomOut()" tabindex="0">
<i class="icon material-icons">zoom_out</i>
</div>
</div>

View File

@@ -84,7 +84,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
fixture.detectChanges();
});
it('If urlfile is not present should thrown an error ', () => {
it('should thrown an error If urlfile is not present', () => {
component.urlFile = undefined;
fixture.detectChanges();
@@ -94,21 +94,21 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('Canvas should be present', () => {
it('should Canvas be present', () => {
expect(element.querySelector('#viewer-viewerPdf')).not.toBeNull();
expect(element.querySelector('#viewer-pdf-container')).not.toBeNull();
});
it('Loader should be present', () => {
it('should Loader be present', () => {
expect(element.querySelector('#loader-container')).not.toBeNull();
});
it('Next an Previous Buttons should be present', () => {
it('should Next an Previous Buttons be present', () => {
expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull();
expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
});
it('Input Page elements should be present', () => {
it('should Input Page elements be present', () => {
expect(element.querySelector('#viewer-pagenumber-input')).toBeDefined();
expect(element.querySelector('#viewer-total-pages')).toBeDefined();
@@ -116,7 +116,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
});
it('Toolbar should be hide if showToolbar is false', () => {
it('should Toolbar be hide if showToolbar is false', () => {
component.showToolbar = false;
fixture.detectChanges();
@@ -135,28 +135,28 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
fixture.detectChanges();
});
it('If blobFile is not present should thrown an error ', () => {
it('should If blobFile is not present thrown an error ', () => {
component.blobFile = undefined;
expect(() => {
component.ngOnChanges(null);
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('Canvas should be present', () => {
it('should Canvas be present', () => {
expect(element.querySelector('#viewer-viewerPdf')).not.toBeNull();
expect(element.querySelector('#viewer-pdf-container')).not.toBeNull();
});
it('Loader should be present', () => {
it('should Loader be present', () => {
expect(element.querySelector('#loader-container')).not.toBeNull();
});
it('Next an Previous Buttons should be present', () => {
it('should Next an Previous Buttons be present', () => {
expect(element.querySelector('#viewer-previous-page-button')).not.toBeNull();
expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
});
it('Input Page elements should be present', () => {
it('should Input Page elements be present', () => {
expect(element.querySelector('#viewer-pagenumber-input')).toBeDefined();
expect(element.querySelector('#viewer-total-pages')).toBeDefined();
@@ -164,7 +164,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
});
it('Toolbar should be hide if showToolbar is false', () => {
it('should Toolbar be hide if showToolbar is false', () => {
component.showToolbar = false;
fixture.detectChanges();
@@ -182,7 +182,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
component.inputPage('1');
});
it('Total number of pages should be loaded', (done) => {
it('should Total number of pages be loaded', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -193,7 +193,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
}, 5000);
it('right arrow should move to the next page', (done) => {
it('should right arrow move to the next page', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -207,7 +207,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
}, 5000);
it('nextPage should move to the next page', (done) => {
it('should nextPage move to the next page', (done) => {
let nextPageButton: any = element.querySelector('#viewer-next-page-button');
component.ngOnChanges(null).then(() => {
@@ -223,7 +223,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('left arrow should move to the previous page', (done) => {
it('should left arrow move to the previous page', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -239,7 +239,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('previous page should move to the previous page', (done) => {
it('should previous page move to the previous page', (done) => {
let previousPageButton: any = element.querySelector('#viewer-previous-page-button');
let nextPageButton: any = element.querySelector('#viewer-next-page-button');
@@ -258,7 +258,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('previous page should not move to the previous page if is page 1', (done) => {
it('should previous page not move to the previous page if is page 1', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -272,7 +272,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('Input page should move to the inserted page', (done) => {
it('should Input page move to the inserted page', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -293,7 +293,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
fixture.detectChanges();
});
it('In should increment the scale value', (done) => {
it('should zoom in increment the scale value', (done) => {
let zoomInButton: any = element.querySelector('#viewer-zoom-in-button');
component.ngOnChanges(null).then(() => {
@@ -306,7 +306,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('Out should decrement the scale value', (done) => {
it('should zoom out decrement the scale value', (done) => {
let zoomOutButton: any = element.querySelector('#viewer-zoom-out-button');
component.ngOnChanges(null).then(() => {
@@ -319,7 +319,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
});
});
it('fit-in button should toggle page-fit and auto scale mode', (done) => {
it('should fit-in button toggle page-fit and auto scale mode', (done) => {
let fitPage: any = element.querySelector('#viewer-scale-page-button');
component.ngOnChanges(null).then(() => {
@@ -341,8 +341,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
fixture.detectChanges();
component.inputPage('1');
});
it('resize event should trigger setScaleUpdatePages', (done) => {
it('should resize event trigger setScaleUpdatePages', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@@ -362,8 +361,7 @@ describe('Test ng2-alfresco-viewer PdfViewer component', () => {
component.urlFile = require('../assets/fake-test-file.pdf');
fixture.detectChanges();
});
it('scroll page should return the current page', (done) => {
it('should scroll page return the current page', (done) => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {

View File

@@ -161,7 +161,7 @@ export class PdfViewerComponent {
heigthContainer = documentContainer.clientHeight;
}
let currentPage = this.pdfViewer._pages[this.pdfViewer._currentPageNumber];
let currentPage = this.pdfViewer._pages[this.pdfViewer._currentPageNumber - 1];
let padding = 20;
let pageWidthScale = (widthContainer - padding) / currentPage.width * currentPage.scale;

View File

@@ -0,0 +1,11 @@
.adf-txt-viewer-margin {
margin: auto !important;
overflow: auto;
font-size: 1em;
padding: 20px;
max-width: 70%;
}
.full_width{
width :95% !important;
}

View File

@@ -0,0 +1,6 @@
<section class="section--center mdl-grid mdl-grid--no-spacing">
<pre id="adf-viewer-text-container"class="adf-txt-viewer-margin mdl-card mdl-cell mdl-cell--12-col-desktop mdl-cell--12-col-tablet mdl-cell--2-col-phone mdl-shadow--2dp">
{{content}}
</pre>
</section>

View File

@@ -0,0 +1,88 @@
/*!
* @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 { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { TxtViewerComponent } from './txtViewer.component';
import { DebugElement, SimpleChange } from '@angular/core';
import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
AlfrescoApiService,
CoreModule
} from 'ng2-alfresco-core';
describe('Test ng2-alfresco-viewer Text View component', () => {
let component: TxtViewerComponent;
let fixture: ComponentFixture<TxtViewerComponent>;
let debug: DebugElement;
let element: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
CoreModule
],
declarations: [TxtViewerComponent],
providers: [
AlfrescoSettingsService,
AlfrescoAuthenticationService,
AlfrescoApiService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TxtViewerComponent);
debug = fixture.debugElement;
element = fixture.nativeElement;
component = fixture.componentInstance;
});
describe('View', () => {
it('Should text container be present with urlfile', (done) => {
fixture.detectChanges();
let urlFile = require('../assets/fake-test-file.txt');
let change = new SimpleChange(null, urlFile, true);
component.ngOnChanges({ 'urlFile': change }).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#adf-viewer-text-container').textContent).toContain('example');
done();
});
});
});
it('Should text container be present with Blob file', (done) => {
let blobFile = new Blob(['text example'], {type: 'text/txt'});
let change = new SimpleChange(null, blobFile, true);
component.ngOnChanges({ 'blobFile': change }).then(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(element.querySelector('#adf-viewer-text-container').textContent).toContain('example');
done();
});
});
});
});
});

View File

@@ -0,0 +1,89 @@
/*!
* @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 } from '@angular/core';
import { SimpleChanges } from '@angular/core';
import { Http, Response, RequestOptions, ResponseContentType } from '@angular/http';
import 'rxjs/add/operator/toPromise';
@Component({
selector: 'txt-viewer',
templateUrl: './txtViewer.component.html',
styleUrls: ['./txtViewer.component.css']
})
export class TxtViewerComponent {
@Input()
urlFile: any;
@Input()
blobFile: Blob;
content: string;
constructor(private http: Http) {
}
ngOnChanges(changes: SimpleChanges): Promise<any> {
let blobFile = changes['blobFile'];
if (blobFile && blobFile.currentValue) {
return this.readBlob(blobFile.currentValue);
}
let urlFile = changes['urlFile'];
if (urlFile && urlFile.currentValue) {
return this.getUrlContent(urlFile.currentValue);
}
if (!this.urlFile && !this.blobFile) {
throw new Error('Attribute urlFile or blobFile is required');
}
}
private getUrlContent(url: string): Promise<any> {
return new Promise((resolve, reject) => {
this.http.get(url, new RequestOptions({
responseType: ResponseContentType.Text
})).toPromise().then(
(res: Response) => {
this.content = res.text();
resolve();
}, (event) => {
reject(event);
});
});
}
private readBlob(blob: Blob): Promise<any> {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
this.content = reader.result;
resolve();
};
reader.onerror = (error: ErrorEvent) => {
reject(error);
};
reader.readAsText(blob);
});
}
}

View File

@@ -51,14 +51,26 @@
<media-player [urlFile]="urlFileContent" [mimeType]="mimeType" [blobFile]="blobFile"
[nameFile]="displayName"></media-player>
</div>
<div class="center-element" *ngIf="isText()">
<txt-viewer [urlFile]="urlFileContent" [blobFile]="blobFile" ></txt-viewer>
</div>
<span *ngFor="let extensionTemplate of extensionTemplates">
<template [ngTemplateOutlet]="extensionTemplate.template" *ngIf="extensionTemplate.isVisible"
[ngOutletContext]="{ urlFileContent: urlFileContent, extension:extension }"></template>
<ng-template
*ngIf="extensionTemplate.isVisible"
[ngTemplateOutlet]="extensionTemplate.template"
[ngOutletContext]="{ urlFileContent: urlFileContent, extension:extension }">
</ng-template>
</span>
<div *ngIf="!supportedExtension()">
<not-supported-format *ngIf="!extensionTemplate" [urlFile]="urlFileContent" [nameFile]="displayName"></not-supported-format>
<not-supported-format *ngIf="!extensionTemplate"
[urlFile]="urlFileContent"
[blobFile]="blobFile"
[nameFile]="displayName"
[showToolbar]="showToolbar"
[nodeId]="fileNodeId">
</not-supported-format>
</div>
<!-- End View Switch -->

View File

@@ -17,6 +17,7 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { PdfViewerComponent } from './pdfViewer.component';
import { TxtViewerComponent } from './txtViewer.component';
import { NotSupportedFormat } from './notSupportedFormat.component';
import { MediaPlayerComponent } from './mediaPlayer.component';
import { ImgViewerComponent } from './imgViewer.component';
@@ -28,7 +29,8 @@ import {
AlfrescoAuthenticationService,
AlfrescoSettingsService,
AlfrescoApiService,
CoreModule
CoreModule,
RenditionsService
} from 'ng2-alfresco-core';
declare let jasmine: any;
@@ -48,6 +50,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
declarations: [
ViewerComponent,
PdfViewerComponent,
TxtViewerComponent,
NotSupportedFormat,
MediaPlayerComponent,
ImgViewerComponent
@@ -56,7 +59,8 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
AlfrescoSettingsService,
AlfrescoAuthenticationService,
AlfrescoApiService,
RenderingQueueServices
RenderingQueueServices,
RenditionsService
]
}).compileComponents();
}));
@@ -72,6 +76,8 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
component.showToolbar = true;
component.urlFile = 'base/src/assets/fake-test-file.pdf';
component.mimeType = 'application/pdf';
component.ngOnChanges(null);
fixture.detectChanges();
});
@@ -88,39 +94,39 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
fixture.detectChanges();
});
it('shadow overlay should be present if is overlay mode', () => {
it('should shadow overlay be present if is overlay mode', () => {
expect(element.querySelector('#viewer-shadow-transparent')).not.toBeNull();
});
it('header should be present if is overlay mode', () => {
it('should header be present if is overlay mode', () => {
expect(element.querySelector('header')).not.toBeNull();
});
it('Name File should be present if is overlay mode ', () => {
it('should Name File be present if is overlay mode ', () => {
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('fake-test-file.pdf');
});
});
it('Close button should be present if overlay mode', () => {
it('should Close button be present if overlay mode', () => {
expect(element.querySelector('#viewer-close-button')).not.toBeNull();
});
it('Click on close button should hide the viewer', () => {
it('should Click on close button hide the viewer', () => {
let closebutton: any = element.querySelector('#viewer-close-button');
closebutton.click();
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
it('Esc button should hide the viewer', () => {
it('should Esc button hide the viewer', () => {
EventMock.keyDown(27);
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).toBeNull();
});
it('all-space class should not be present if is in overlay mode', () => {
it('should all-space class not be present if is in overlay mode', () => {
expect(element.querySelector('#viewer').getAttribute('class')).toEqual('');
});
});
@@ -132,15 +138,15 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
fixture.detectChanges();
});
it('header should be NOT be present if is not overlay mode', () => {
it('should header be NOT be present if is not overlay mode', () => {
expect(element.querySelector('header')).toBeNull();
});
it('Close button should be not present if is not overlay mode', () => {
it('should Close button be not present if is not overlay mode', () => {
expect(element.querySelector('#viewer-close-button')).toBeNull();
});
it('Esc button should 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);
fixture.detectChanges();
expect(element.querySelector('#viewer-main-container')).not.toBeNull();
@@ -153,7 +159,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
describe('Attribute', () => {
it('Url or fileNodeId File should be mandatory', () => {
it('should Url or fileNodeId be mandatory', () => {
component.showViewer = true;
component.fileNodeId = undefined;
component.urlFile = undefined;
@@ -163,7 +169,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
}).toThrow();
});
it('If FileNodeId is present should not be thrown any error ', () => {
it('should FileNodeId present not thrown any error ', () => {
component.showViewer = true;
component.fileNodeId = 'file-node-id';
component.urlFile = undefined;
@@ -173,7 +179,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
}).not.toThrow();
});
it('If urlFile is present should not be thrown any error ', () => {
it('should urlFile present not thrown any error ', () => {
component.showViewer = true;
component.fileNodeId = undefined;
@@ -182,11 +188,11 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
}).not.toThrow();
});
it('showViewer default value should be true', () => {
it('should showViewer default value be true', () => {
expect(component.showViewer).toBe(true);
});
it('if showViewer value is false the viewer should be hide', () => {
it('should viewer be hide if showViewer value is false', () => {
component.showViewer = false;
fixture.detectChanges();
@@ -194,8 +200,8 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
});
describe('Extension Type Test', () => {
it('if extension file is a pdf the pdf viewer should be loaded', (done) => {
describe('Exteznsion Type Test', () => {
it('should extension file pdf be loaded', (done) => {
component.urlFile = 'base/src/assets/fake-test-file.pdf';
component.ngOnChanges(null).then(() => {
@@ -205,7 +211,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
});
it('if extension file is a image the img viewer should be loaded', (done) => {
it('should extension file png be loaded', (done) => {
component.urlFile = 'fake-url-file.png';
component.ngOnChanges(null).then(() => {
@@ -215,7 +221,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
});
it('if extension file is a video the the media player should be loaded', (done) => {
it('should extension file mp4 be loaded', (done) => {
component.urlFile = 'fake-url-file.mp4';
component.ngOnChanges(null).then(() => {
@@ -225,8 +231,39 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
});
it('if extension file is a not supported the not supported div should be loaded', (done) => {
it('should extension file mp3 be loaded', (done) => {
component.urlFile = 'fake-url-file.mp3';
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
expect(element.querySelector('media-player')).not.toBeNull();
done();
});
});
it('should extension file wav be loaded', (done) => {
component.urlFile = 'fake-url-file.wav';
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
expect(element.querySelector('media-player')).not.toBeNull();
done();
});
});
it('should extension file txt be loaded', (done) => {
component.urlFile = 'fake-url-file.txt';
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
expect(element.querySelector('txt-viewer')).not.toBeNull();
done();
});
});
it('should the not supported div be loaded if the file is a not supported extension', (done) => {
component.urlFile = 'fake-url-file.unsupported';
component.mimeType = '';
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
@@ -293,6 +330,17 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
});
it('should display the txt viewer if the file identified by mimetype is a txt when the filename has wrong extension', (done) => {
component.urlFile = 'content.bin';
component.mimeType = 'text/txt';
component.ngOnChanges(null).then(() => {
fixture.detectChanges();
expect(element.querySelector('txt-viewer')).not.toBeNull();
done();
});
});
it('should display the media player if the file identified by mimetype is a media when the filename has no extension', (done) => {
component.urlFile = 'content';
component.mimeType = 'video/mp4';
@@ -317,7 +365,7 @@ describe('Test ng2-alfresco-viewer ViewerComponent', () => {
});
describe('Events', () => {
it('if extension change exextensionChange event should be fired ', (done) => {
it('should if the extension change extension Change event be fired ', (done) => {
component.extensionChange.subscribe((fileExtension) => {
expect(fileExtension).toEqual('png');

View File

@@ -79,8 +79,8 @@ export class ViewerComponent {
if (!this.urlFile && !this.blobFile && !this.fileNodeId) {
throw new Error('Attribute urlFile or fileNodeId or blobFile is required');
}
return new Promise((resolve, reject) => {
let alfrescoApi = this.apiService.getInstance();
if (this.blobFile) {
this.mimeType = this.blobFile.type;
this.extensionChange.emit(this.mimeType);
@@ -93,10 +93,10 @@ export class ViewerComponent {
this.urlFileContent = this.urlFile;
resolve();
} else if (this.fileNodeId) {
alfrescoApi.nodes.getNodeInfo(this.fileNodeId).then((data: MinimalNodeEntryEntity) => {
this.apiService.getInstance().nodes.getNodeInfo(this.fileNodeId).then((data: MinimalNodeEntryEntity) => {
this.mimeType = data.content.mimeType;
this.displayName = data.name;
this.urlFileContent = alfrescoApi.content.getContentUrl(data.id);
this.urlFileContent = this.apiService.getInstance().content.getContentUrl(data.id);
this.extension = this.getFileExtension(data.name);
this.extensionChange.emit(this.extension);
this.loaded = true;
@@ -145,7 +145,7 @@ export class ViewerComponent {
* @param {string} url - url file
* @returns {string} name file
*/
getFilenameFromUrl(url: string) {
getFilenameFromUrl(url: string): string {
let anchor = url.indexOf('#');
let query = url.indexOf('?');
let end = Math.min(
@@ -160,7 +160,7 @@ export class ViewerComponent {
* @param {string} fileName - file name
* @returns {string} file name extension
*/
private getFileExtension(fileName: string) {
private getFileExtension(fileName: string): string {
return fileName.split('.').pop().toLowerCase();
}
@@ -169,7 +169,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isImage() {
private isImage(): boolean {
return this.isImageExtension() || this.isImageMimeType();
}
@@ -178,7 +178,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isMedia() {
private isMedia(): boolean {
return this.isMediaExtension(this.extension) || this.isMediaMimeType();
}
@@ -187,7 +187,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isImageExtension() {
private isImageExtension(): boolean {
return this.extension === 'png' || this.extension === 'jpg' ||
this.extension === 'jpeg' || this.extension === 'gif' || this.extension === 'bmp';
}
@@ -197,12 +197,12 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isMediaMimeType() {
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.isMediaExtension(mimeExtension);
return (this.mimeType && (this.mimeType.indexOf('video/') === 0 || this.mimeType.indexOf('audio/') === 0)) && this.isMediaExtension(mimeExtension);
}
/**
@@ -211,8 +211,8 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isMediaExtension(extension: string) {
return extension === 'mp4' || extension === 'WebM' || extension === 'Ogg';
private isMediaExtension(extension: string): boolean {
return extension === 'wav' || extension === 'mp4' || extension === 'mp3' || extension === 'WebM' || extension === 'Ogg';
}
/**
@@ -220,7 +220,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isImageMimeType() {
private isImageMimeType(): boolean {
return this.mimeType && this.mimeType.indexOf('image/') === 0;
}
@@ -229,17 +229,26 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isPdf() {
private isPdf(): boolean {
return this.extension === 'pdf' || this.mimeType === 'application/pdf';
}
/**
* check if the current file is a supported txt extension
*
* @returns {boolean}
*/
private 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() {
return this.isImage() || this.isPdf() || this.isMedia() || this.isExternalSupportedExtension();
supportedExtension(): boolean {
return this.isImage() || this.isPdf() || this.isMedia() || this.isText() || this.isExternalSupportedExtension();
}
/**
@@ -247,7 +256,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
isExternalSupportedExtension() {
isExternalSupportedExtension(): boolean {
let externalType: string;
if (this.externalExtensions && (this.externalExtensions instanceof Array)) {
@@ -274,8 +283,6 @@ export class ViewerComponent {
/**
* Check if in the document there are scrollable main area and disable it
*
* @returns {boolean}
*/
private blockOtherScrollBar() {
let mainElements: any = document.getElementsByTagName('main');
@@ -286,9 +293,7 @@ export class ViewerComponent {
}
/**
* Check if in the document there are scrollable main area and renable it
*
* @returns {boolean}
* Check if in the document there are scrollable main area and re-enable it
*/
private unblockOtherScrollBar() {
let mainElements: any = document.getElementsByTagName('main');
@@ -303,7 +308,7 @@ export class ViewerComponent {
*
* @returns {boolean}
*/
private isParentElementHeaderBar() {
private isParentElementHeaderBar(): boolean {
return !!this.closestElement(this.element.nativeElement, 'header');
}
@@ -313,7 +318,7 @@ export class ViewerComponent {
* @param {string} nodeName
* @returns {HTMLElement}
*/
private closestElement(element: HTMLElement, nodeName: string) {
private closestElement(element: HTMLElement, nodeName: string): HTMLElement {
let parent = element.parentElement;
if (parent) {
if (parent.nodeName.toLowerCase() === nodeName) {
@@ -340,8 +345,10 @@ export class ViewerComponent {
/**
* return true if the data about the node in the ecm are loaded
*
* @returns {boolean}
*/
isLoaded() {
isLoaded(): boolean {
return this.fileNodeId ? this.loaded : true;
}
}

View File

@@ -0,0 +1,3 @@
{
}

View File

@@ -35,7 +35,9 @@
"ng2-alfresco-viewer": ["../ng2-alfresco-viewer/"],
"ng2-alfresco-webscript": ["../ng2-alfresco-webscript/"],
"ng2-alfresco-userinfo": ["../ng2-alfresco-userinfo"],
"alfresco-js-api": ["../node_modules/alfresco-js-api/"]
"alfresco-js-api": ["./node_modules/alfresco-js-api/"],
"@angular/*": ["./node_modules/@angular/*"],
"rxjs/*": ["./node_modules/rxjs/*"]
},
"lib": [
"es2015",

View File

@@ -1,17 +1 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./config/webpack.common.js');
module.exports = webpackMerge(commonConfig, {
output: {
filename: './bundles/[name].js',
library: '[name]',
libraryTarget: 'umd',
chunkFilename: '[id].chunk.js'
},
entry: {
"ng2-alfresco-viewer": "./index.ts"
}
});
module.exports = require('./config/webpack.build.js');

View File

@@ -0,0 +1 @@
module.exports = require('./config/webpack.coverage.js');

View File

@@ -1,8 +1 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const testConfig = require('./config/webpack.test.js');
module.exports = webpackMerge(testConfig, {
});
module.exports = require('./config/webpack.test.js');