Skip to content

Commit

Permalink
[ACS-6620] Proper viewer extension template projection to viewer rend…
Browse files Browse the repository at this point in the history
…erer (#9273)

* [ACS-6620] Proper viewer extension template projection to viewer renderer

* [ACS-6620] Use extensions instead of content for viewer config

* [ACS-6620] Lint fix
  • Loading branch information
MichalKinas authored Jan 25, 2024
1 parent 5ec8228 commit 2c627f1
Show file tree
Hide file tree
Showing 17 changed files with 267 additions and 113 deletions.
2 changes: 1 addition & 1 deletion demo-shell/src/assets/app.extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

"features": {
"viewer": {
"content": []
"extensions": []
},

"documentList": {
Expand Down
57 changes: 29 additions & 28 deletions docs/content-services/components/alfresco-viewer.component.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,47 +237,48 @@ The Viewer supports dynamically-loaded viewer preview extensions, to know more a

#### Code extension mechanism]

You can define your own custom handler to handle other file formats that are not yet supported by
You can define your own custom handler to override supported file formats or handle other file formats that are not yet supported by
the [Alfresco Viewer component](viewer.component.md). Below is an example that shows how to use the `adf-viewer-extension`
to handle 3D data files:

```html
<adf-alfresco-viewer [nodeId]="nodeId">

<adf-viewer-extension [supportedExtensions]="['obj','3ds']" #extension>
<ng-template let-urlFileContent="urlFileContent" let-extension="extension">
<threed-viewer
[urlFile]="urlFileContent"
[extension]="extension">
</threed-viewer>
</ng-template>
</adf-viewer-extension>

<ng-template #viewerExtensions>
<adf-viewer-extension [supportedExtensions]="['obj','3ds']" #extension>
<ng-template let-urlFileContent="urlFileContent" let-extension="extension">
<threed-viewer
[urlFile]="urlFileContent"
[extension]="extension">
</threed-viewer>
</ng-template>
</adf-viewer-extension>
</ng-template>
</adf-alfresco-viewer>
```

Note: you need to add the `ng2-3d-editor` dependency to your `package.json` file to make the example above work.

You can define multiple `adf-viewer-extension` templates if required:
You need to keep all instances of `adf-viewer-extension` inside `viewerExtensions` template, also you can define multiple `adf-viewer-extension` templates if required:

```html
<adf-alfresco-viewer [nodeId]="nodeId">

<adf-viewer-extension [supportedExtensions]="['xls','xlsx']" #extension>
<ng-template let-urlFileContent="urlFileContent">
<my-custom-xls-component
urlFileContent="urlFileContent">
</my-custom-xls-component>
</ng-template>
</adf-viewer-extension>

<adf-viewer-extension [supportedExtensions]="['txt']" #extension>
<ng-template let-urlFileContent="urlFileContent" >
<my-custom-txt-component
urlFileContent="urlFileContent">
</my-custom-txt-component>
</ng-template>
</adf-viewer-extension>
<ng-template #viewerExtensions>
<adf-viewer-extension [supportedExtensions]="['xls','xlsx']" #extension>
<ng-template let-urlFileContent="urlFileContent">
<my-custom-xls-component
urlFileContent="urlFileContent">
</my-custom-xls-component>
</ng-template>
</adf-viewer-extension>

<adf-viewer-extension [supportedExtensions]="['txt']" #extension>
<ng-template let-urlFileContent="urlFileContent" >
<my-custom-txt-component
urlFileContent="urlFileContent">
</my-custom-txt-component>
</ng-template>
</adf-viewer-extension>
</ng-template>
</adf-alfresco-viewer>
```

Expand Down
48 changes: 22 additions & 26 deletions docs/core/components/viewer-render.component.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Using with file [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob):
| thumbnailsTemplate | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | The template for the pdf thumbnails. |
| tracks | [`Track`](../../../lib/core/src/lib/viewer/models/viewer.model.ts)`[]` | \[] | media subtitles for the media player |
| urlFile | `string` | "" | If you want to load an external file that does not come from ACS you can use this URL to specify where to load the file from. |
| viewerTemplateExtensions | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | Template containing ViewerExtensionDirective instances providing different viewer extensions based on supported file extension. |

### Events

Expand Down Expand Up @@ -200,34 +201,13 @@ The [Viewer render component](viewer.component.md) should now be able to display

The Viewer supports dynamically-loaded viewer preview extensions, to know more about it [Preview Extension component](../../extensions/components/preview-extension.component.md). This

#### Code extension mechanism]
#### Code extension mechanism

You can define your own custom handler to handle other file formats that are not yet supported by
the [Viewer render component](viewer.component.md). Below is an example that shows how to use the `adf-viewer-render-extension`
to handle 3D data files:

```html
<adf-viewer-render [nodeId]="nodeId">

<adf-viewer-extension [supportedExtensions]="['obj','3ds']" #extension>
<ng-template let-urlFileContent="urlFileContent" let-extension="extension">
<threed-viewer
[urlFile]="urlFileContent"
[extension]="extension">
</threed-viewer>
</ng-template>
</adf-viewer-extension>

</adf-viewer-render>
```

Note: you need to add the `ng2-3d-editor` dependency to your `package.json` file to make the example above work.

You can define multiple `adf-viewer-render-extension` templates if required:

```html
<adf-viewer-render [nodeId]="nodeId">
You can define your own custom handler to override supported file formats or handle other file formats that are not yet supported by
the [Viewer render component](viewer.component.md). In order to do that first you need to define a template containing at least one `adf-viewer-extension`:

```html
<ng-template #viewerExtensions>
<adf-viewer-extension [supportedExtensions]="['xls','xlsx']" #extension>
<ng-template let-urlFileContent="urlFileContent">
<my-custom-xls-component
Expand All @@ -243,6 +223,22 @@ You can define multiple `adf-viewer-render-extension` templates if required:
</my-custom-txt-component>
</ng-template>
</adf-viewer-render-extension>
</ng-template>
```

Next in your component you need to get a reference of created template

```ts
@ViewChild('viewerExtensions')
viewerTemplateExtensions: TemplateRef<any>;
```

and pass it via `viewerTemplateExtensions` input:

```html
<adf-viewer-render>
...
[viewerTemplateExtensions]="viewerTemplateExtensions"
</adf-viewer-render>
```

Expand Down
59 changes: 30 additions & 29 deletions docs/core/components/viewer.component.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ See the [Custom layout](#custom-layout) section for full details of all availabl
| sidebarRightTemplateContext | | null | Context object available for binding by the local sidebarRightTemplate with let declarations. |
| tracks | [`Track`](../../../lib/core/src/lib/viewer/models/viewer.model.ts)`[]` | \[] | media subtitles for the media player |
| urlFile | `string` | "" | If you want to load an external file that does not come from ACS you can use this URL to specify where to load the file from. |
| viewerExtensions | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | Template containing ViewerExtensionDirective instances providing different viewer extensions based on supported file extension. |

### Events

Expand Down Expand Up @@ -209,47 +210,47 @@ The Viewer supports dynamically-loaded viewer preview extensions, to know more a

#### Code extension mechanism]

You can define your own custom handler to handle other file formats that are not yet supported by
You can define your own custom handler to override supported file formats or handle other file formats that are not yet supported by
the [Viewer component](viewer.component.md). Below is an example that shows how to use the `adf-viewer-extension`
to handle 3D data files:

```html
<adf-viewer [urlFile]="urlFile">

<adf-viewer-extension [supportedExtensions]="['obj','3ds']" #extension>
<ng-template let-urlFileContent="urlFileContent" let-extension="extension">
<threed-viewer
[urlFile]="urlFileContent"
[extension]="extension">
</threed-viewer>
</ng-template>
</adf-viewer-extension>

<ng-template #viewerExtensions>
<adf-viewer-extension [supportedExtensions]="['obj','3ds']" #extension>
<ng-template let-urlFileContent="urlFileContent" let-extension="extension">
<threed-viewer
[urlFile]="urlFileContent"
[extension]="extension">
</threed-viewer>
</ng-template>
</adf-viewer-extension>
</ng-template>
</adf-viewer>
```

Note: you need to add the `ng2-3d-editor` dependency to your `package.json` file to make the example above work.

You can define multiple `adf-viewer-extension` templates if required:

You need to keep all instances of `adf-viewer-extension` inside `viewerExtensions` template, also you can define multiple `adf-viewer-extension` templates if required:
```html
<adf-viewer [urlFile]="urlFile">

<adf-viewer-extension [supportedExtensions]="['xls','xlsx']" #extension>
<ng-template let-urlFileContent="urlFileContent">
<my-custom-xls-component
urlFileContent="urlFileContent">
</my-custom-xls-component>
</ng-template>
</adf-viewer-extension>

<adf-viewer-extension [supportedExtensions]="['txt']" #extension>
<ng-template let-urlFileContent="urlFileContent" >
<my-custom-txt-component
urlFileContent="urlFileContent">
</my-custom-txt-component>
</ng-template>
</adf-viewer-extension>
<ng-template #viewerExtensions>
<adf-viewer-extension [supportedExtensions]="['xls','xlsx']" #extension>
<ng-template let-urlFileContent="urlFileContent">
<my-custom-xls-component
urlFileContent="urlFileContent">
</my-custom-xls-component>
</ng-template>
</adf-viewer-extension>

<adf-viewer-extension [supportedExtensions]="['txt']" #extension>
<ng-template let-urlFileContent="urlFileContent" >
<my-custom-txt-component
urlFileContent="urlFileContent">
</my-custom-txt-component>
</ng-template>
</adf-viewer-extension>
</ng-template>
</adf-viewer>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
[urlFile]="urlFileContent"
[tracks]="tracks"
[readOnly]="readOnly"
[viewerExtensions]="viewerExtensions"
(downloadFile)="onDownloadFile()"
(navigateBefore)="onNavigateBeforeClick($event)"
(navigateNext)="onNavigateNextClick($event)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit, OnDestroy {
@ContentChild(ViewerOpenWithComponent)
openWith: ViewerOpenWithComponent;

@ContentChild('viewerExtensions', { static: false })
viewerExtensions: TemplateRef<any>;

/** Node Id of the file to load. */
@Input()
nodeId: string = null;
Expand Down
17 changes: 10 additions & 7 deletions lib/core/src/lib/viewer/components/viewer-render.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ <h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
</adf-preview-extension>
</ng-container>

<span class="adf-viewer-render-custom-content"
*ngFor="let extensionTemplate of extensionTemplates">
<ng-template *ngIf="extensionTemplate.isVisible"
[ngTemplateOutlet]="extensionTemplate.template"
[ngTemplateOutletContext]="{ urlFile: urlFile, extension:extension }">
</ng-template>
</span>
<ng-container *ngFor="let extensionTemplate of extensionTemplates">
<span *ngIf="extensionTemplate.isVisible" class="adf-viewer-render-custom-content">
<ng-template [ngTemplateOutlet]="extensionTemplate.template"
[ngTemplateOutletContext]="{ urlFile: urlFile, extension: extension }">
</ng-template>
</span>
</ng-container>
</ng-container>

<ng-container *ngSwitchDefault>
Expand All @@ -94,3 +94,6 @@ <h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
</div>
</div>
</div>
<ng-container *ngIf="viewerTemplateExtensions">
<ng-template [ngTemplateOutlet]="viewerTemplateExtensions" [ngTemplateOutletInjector]="injector"></ng-template>
</ng-container>
56 changes: 53 additions & 3 deletions lib/core/src/lib/viewer/components/viewer-render.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import { Location } from '@angular/common';
import { SpyLocation } from '@angular/common/testing';
import { Component, ViewChild } from '@angular/core';
import { Component, TemplateRef, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RenderingQueueServices } from '../services/rendering-queue.services';
import { ViewerRenderComponent } from './viewer-render.component';
Expand All @@ -33,8 +33,20 @@ import { By } from '@angular/platform-browser';
@Component({
selector: 'adf-double-viewer',
template: `
<adf-viewer-render [urlFile]="urlFileViewer1" #viewer1></adf-viewer-render>
<adf-viewer-render [urlFile]="urlFileViewer1" [viewerTemplateExtensions]="viewerTemplateExtensions" #viewer1></adf-viewer-render>
<adf-viewer-render [urlFile]="urlFileViewer2" #viewer2></adf-viewer-render>
<ng-template #viewerExtension>
<adf-viewer-extension [supportedExtensions]="['json']">
<ng-template>
<h1>JSON Viewer</h1>
</ng-template>
</adf-viewer-extension>
<adf-viewer-extension [supportedExtensions]="['test']">
<ng-template>
<h1>Test Viewer</h1>
</ng-template>
</adf-viewer-extension>
</ng-template>
`
})
class DoubleViewerComponent {
Expand All @@ -44,6 +56,9 @@ class DoubleViewerComponent {
@ViewChild('viewer2')
viewer2: ViewerRenderComponent;

@ViewChild('viewerExtension', { static: true })
viewerTemplateExtensions: TemplateRef<any>;

urlFileViewer1: string;
urlFileViewer2: string;

Expand Down Expand Up @@ -261,6 +276,42 @@ describe('ViewerComponent', () => {
});
});

describe('Custom viewer extension template', () => {
const getCustomViewerContent = (customFixture: ComponentFixture<DoubleViewerComponent>): HTMLHeadingElement =>
customFixture.debugElement.query(By.css('.adf-viewer-render-custom-content h1')).nativeElement;

it('should render provided custom template when file type matches supported extensions', async () => {
const fixtureCustom = TestBed.createComponent(DoubleViewerComponent);
fixtureCustom.detectChanges();
await fixtureCustom.whenStable();

const customComponent = fixtureCustom.componentInstance.viewer1;
fixtureCustom.componentInstance.urlFileViewer1 = 'fake-url-file.json';
customComponent.ngOnChanges();

fixtureCustom.detectChanges();
await fixtureCustom.whenStable();

let customContent = getCustomViewerContent(fixtureCustom);
expect(customComponent.extensionsSupportedByTemplates).toEqual(['json', 'test']);
expect(customComponent.extensionTemplates.length).toBe(2);
expect(customComponent.extensionTemplates[0].isVisible).toBeTrue();
expect(customComponent.extensionTemplates[1].isVisible).toBeFalse();
expect(customContent.innerText).toBe('JSON Viewer');

fixtureCustom.componentInstance.urlFileViewer1 = 'fake-url-file.test';
customComponent.ngOnChanges();

fixtureCustom.detectChanges();
await fixtureCustom.whenStable();

customContent = getCustomViewerContent(fixtureCustom);
expect(customComponent.extensionTemplates[0].isVisible).toBeFalse();
expect(customComponent.extensionTemplates[1].isVisible).toBeTrue();
expect(customContent.innerText).toBe('Test Viewer');
});
});

describe('MimeType handling', () => {
it('should display an image file identified by mimetype when the filename has no extension', (done) => {
component.urlFile = 'fake-content-img';
Expand Down Expand Up @@ -338,7 +389,6 @@ describe('ViewerComponent', () => {
expect(element.querySelector('adf-pdf-viewer')).not.toBeNull();
done();
});

}, 25000);

it('should display a PDF file identified by mimetype when the file extension is wrong', (done) => {
Expand Down
Loading

0 comments on commit 2c627f1

Please sign in to comment.