[ACA-2364] support 'canPreview' rule for the Viewer (#1102)

* support `canPreview` rule for the Viewer

* update plint settings

* update prettier settings for plint

* test fixes

* update config
This commit is contained in:
Denys Vuika 2019-05-10 15:08:00 +01:00 committed by GitHub
parent d5f8699976
commit d8e3b9ada0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 4 deletions

10
.github/plint.yml vendored
View File

@ -2,11 +2,21 @@ modules:
- pr.prettier
- pr.spellcheck
prettier:
exclude:
- '*.json'
spellcheck:
dictionaries:
- html
- en-gb
- en_US
words:
- plint
- ngrx
- qshare
- snackbar
- exif
- docx
exclude:
- src/assets/app.extensions.json

View File

@ -363,6 +363,7 @@ Viewer component in ACA supports the following extension points:
- Toolbar actions
- `More` toolbar actions
- `Open With` actions
- Rules
```json
{
@ -547,6 +548,35 @@ and invoke it from the custom `Open With` menu entry called `Snackbar`.
As with other content actions, custom plugins can disable, update or extend `Open With` actions.
### Rules
You can provide global rules for the Viewer by utilizing the `features.viewer.rules` object:
```ts
export interface ViewerRules {
/**
* Checks if user can preview the node.
*/
canPreview?: string;
}
```
For example:
```json
{
"features": {
"viewer": {
"rules": {
"canPreview": "customRule"
}
}
}
}
```
The rule should return `true` if node preview is allowed, otherwise `false`.
## Content metadata presets
The content metadata presets are needed by the [Content Metadata Component](https://www.alfresco.com/abn/adf/docs/content-services/content-metadata-card.component/) to render the properties of metadata aspects for a given node.

View File

@ -684,6 +684,16 @@
"description": "Viewer component extensions",
"type": "object",
"properties": {
"rules": {
"description": "Viewer rules",
"type": "object",
"properties": {
"canPreview": {
"description": "Controls whether preview is enabled for particular node",
"type": "string"
}
}
},
"openWith": {
"description": "The [Open With] menu extensions",
"type": "array",

View File

@ -53,7 +53,8 @@ import {
} from '@alfresco/adf-extensions';
import { AppConfigService, AuthenticationService } from '@alfresco/adf-core';
import { BehaviorSubject, Observable } from 'rxjs';
import { RepositoryInfo } from '@alfresco/js-api';
import { RepositoryInfo, NodeEntry } from '@alfresco/js-api';
import { ViewerRules } from './viewer.rules';
@Injectable({
providedIn: 'root'
@ -76,6 +77,7 @@ export class AppExtensionService implements RuleContext {
navbar: Array<NavBarGroupRef> = [];
sidebar: Array<SidebarTabRef> = [];
contentMetadata: any;
viewerRules: ViewerRules = {};
documentListPresets: {
files: Array<DocumentListPresetRef>;
@ -184,6 +186,10 @@ export class AppExtensionService implements RuleContext {
searchLibraries: this.getDocumentListPreset(config, 'search-libraries')
};
if (config.features && config.features.viewer) {
this.viewerRules = <ViewerRules>(config.features.viewer['rules'] || {});
}
this.registerIcons(config);
const references = (config.$references || [])
@ -504,7 +510,37 @@ export class AppExtensionService implements RuleContext {
}
}
// todo: move to ADF/RuleService
isRuleDefined(ruleId: string): boolean {
return ruleId && this.getEvaluator(ruleId) ? true : false;
}
// todo: move to ADF/RuleService
evaluateRule(ruleId: string, ...args: any[]): boolean {
const evaluator = this.getEvaluator(ruleId);
if (evaluator) {
return evaluator(this, ...args);
}
return false;
}
getEvaluator(key: string): RuleEvaluator {
return this.extensions.getEvaluator(key);
}
canPreviewNode(node: NodeEntry) {
const rules = this.viewerRules;
if (this.isRuleDefined(rules.canPreview)) {
const canPreview = this.evaluateRule(rules.canPreview, node);
if (!canPreview) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,31 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2019 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export interface ViewerRules {
/**
* Checks if user can preview the node.
*/
canPreview?: string;
}

View File

@ -37,6 +37,7 @@ import {
} from '@alfresco/aca-shared/store';
import { Router } from '@angular/router';
import { Store, createSelector } from '@ngrx/store';
import { AppExtensionService } from '../../extensions/extension.service';
export const fileToPreview = createSelector(
getAppSelection,
@ -54,7 +55,8 @@ export class ViewerEffects {
constructor(
private store: Store<AppStore>,
private actions$: Actions,
private router: Router
private router: Router,
private extensions: AppExtensionService
) {}
@Effect({ dispatch: false })
@ -94,7 +96,10 @@ export class ViewerEffects {
if (action.payload && action.payload.entry) {
const { id, nodeId, isFile } = <any>action.payload.entry;
if (isFile || nodeId) {
if (
this.extensions.canPreviewNode(action.payload) &&
(isFile || nodeId)
) {
this.displayPreview(nodeId || id, action.parentId);
}
} else {
@ -105,7 +110,10 @@ export class ViewerEffects {
if (result.selection && result.selection.file) {
const { id, nodeId, isFile } = <any>result.selection.file.entry;
if (isFile || nodeId) {
if (
this.extensions.canPreviewNode(action.payload) &&
(isFile || nodeId)
) {
const parentId = result.folder ? result.folder.id : null;
this.displayPreview(nodeId || id, parentId);
}