mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
extensibility docs update (#571)
* docs: custom sidebar tabs * update docs * docs update, simplify extension schema * test fixes
This commit is contained in:
parent
c0321fe449
commit
160226094d
@ -24,6 +24,13 @@
|
||||
"unfavorite",
|
||||
"Snackbar",
|
||||
"devtools",
|
||||
"gitter",
|
||||
"jira",
|
||||
"markdownlint",
|
||||
"uploader",
|
||||
"nginx",
|
||||
"docx",
|
||||
"SOLR",
|
||||
|
||||
"unshare",
|
||||
"validators",
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Alfresco Example Content Application
|
||||
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
|
||||
## Introduction
|
||||
|
||||
The Alfresco Content Application is an example application built using
|
||||
@ -287,7 +289,7 @@ The Header & Toolbar section of the viewer contains a number of features that re
|
||||
|
||||
The File Viewer consists of four separate views that handle displaying the content based on four types of content, covering various [file/mime](https://alfresco.github.io/adf-component-catalog/components/ViewerComponent.html#supported-file-formats) types:
|
||||
|
||||
- Document View: PDFs are displayed in the application File Viewer, for other document types (DOCX etc) then a PDF rendition is automatically retrieved.
|
||||
- Document View: PDF files are displayed in the application File Viewer, for other document types (DOCX etc) then a PDF rendition is automatically retrieved.
|
||||
- Image View: JPEG, PNG, GIF, BMP and SVG images are natively displayed in the application File Viewer.
|
||||
- Media View: MP4, MP3, WAV, OGG and WEBM files are played natively application File Viewer. The File Viewer will download, by default, 50MB of the content at a time to ensure a smooth playback of the content.
|
||||
- Text View: TXT, XML, JS, HTML, JSON and TS files are natively displayed as text in the application File Viewer.
|
||||
@ -313,7 +315,7 @@ At the bottom of the content the Viewer Controls allow users to interact with th
|
||||
- Media View:
|
||||
- Play/pause
|
||||
- Timeline position
|
||||
- Audio mute/unmute
|
||||
- Toggle audio
|
||||
- Audio volume
|
||||
- Full screen
|
||||
|
||||
@ -329,7 +331,7 @@ The Properties tab displays the node's metadata info by using the [ContentMetada
|
||||
|
||||

|
||||
|
||||
For more information, please check also the ADF's [ContentMetadataComponent](https://alfresco.github.io/adf-component-catalog/components/ContentMetadataComponent.html).
|
||||
For more information, please check also the [ContentMetadataComponent](https://alfresco.github.io/adf-component-catalog/components/ContentMetadataComponent.html).
|
||||
|
||||
#### Versions tab
|
||||
|
||||
@ -357,7 +359,7 @@ There are 2 ways users can access the Version Manager:
|
||||
|
||||
#### Upload new version
|
||||
|
||||
A new version for the selected file can be added by using this button. Users can upload a new file version using a file that is does not have the same name, or mimetype as the current version, whilst allowing the user to choose the type of version (minor or major) and inputting supporting comments.
|
||||
A new version for the selected file can be added by using this button. Users can upload a new file version using a file that is does not have the same name, or mime type as the current version, whilst allowing the user to choose the type of version (minor or major) and inputting supporting comments.
|
||||
Please also check the [UploadVersionButtonComponent](https://alfresco.github.io/adf-component-catalog/components/UploadVersionButtonComponent.html).
|
||||
|
||||
#### Actions Menu
|
||||
|
@ -2,6 +2,8 @@
|
||||
title: Extending
|
||||
---
|
||||
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
|
||||
<p class="danger">
|
||||
Work is still in progress, the documentation and examples may change.
|
||||
</p>
|
||||
@ -18,6 +20,7 @@ You can create plugins that change, toggle or extend the following areas:
|
||||
|
||||
* Navigation sidebar links and groups
|
||||
* Context Menu
|
||||
* Sidebar (aka Info Drawer)
|
||||
* Toolbar entries
|
||||
* buttons
|
||||
* menu buttons
|
||||
@ -116,9 +119,9 @@ To create a new route, populate the `routes` section with the corresponding entr
|
||||
| **id** | Unique identifier. |
|
||||
| **path** | Runtime path of the route. |
|
||||
| **component** | The main [component](#components) to use for the route. |
|
||||
| *layout* | The layout [component](#components) to use for the route. |
|
||||
| *auth* | List of [authentication guards](#authentication-guards). Defaults to `[ "app.auth" ]`. |
|
||||
| *data* | Custom property bag to carry with the route. |
|
||||
| layout | The layout [component](#components) to use for the route. |
|
||||
| auth | List of [authentication guards](#authentication-guards). Defaults to `[ "app.auth" ]`. |
|
||||
| data | Custom property bag to carry with the route. |
|
||||
|
||||
<p class="tip">
|
||||
Use the `app.layout.main` value for the `layout` property to get the default application layout,
|
||||
@ -150,6 +153,11 @@ You can define the full route schema like in the next example:
|
||||
}
|
||||
```
|
||||
|
||||
<p class="warning">
|
||||
All application routes require at least one authentication guard.
|
||||
If you do not provide a guard the default `['app.auth`]` will be used at runtime.
|
||||
</p>
|
||||
|
||||
### Authentication Guards
|
||||
|
||||
Below is the list of the authentication guards main application registers on startup.
|
||||
@ -539,9 +547,9 @@ on how to register your own entries to be re-used at runtime.
|
||||
|
||||
The rule in the example below evaluates to `true` if all the conditions are met:
|
||||
|
||||
- user has selected node(s)
|
||||
- user is not using **Trashcan** page
|
||||
- user is not using **Libraries** page
|
||||
* user has selected node(s)
|
||||
* user is not using **Trashcan** page
|
||||
* user is not using **Libraries** page
|
||||
|
||||
```json
|
||||
{
|
||||
@ -565,19 +573,443 @@ The rule in the example below evaluates to `true` if all the conditions are met:
|
||||
|
||||
## Application Features
|
||||
|
||||
### Extending Create Menu
|
||||
This section contains application-specific features that may vary depending on the final implementation.
|
||||
|
||||
### Extending Navigation Sidebar
|
||||
The ACA supports the following set of extension points:
|
||||
|
||||
### Extending Toolbar
|
||||
* Create menu
|
||||
* Navigation Bar
|
||||
* Toolbar
|
||||
* Context Menu
|
||||
* Viewer
|
||||
* Sidebar (aka Info Drawer)
|
||||
|
||||
### Extending Context Menu
|
||||
All the customisations are stored in the `features` section of the configuration file:
|
||||
|
||||
### Extending Viewer
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"create": [],
|
||||
"navbar": [],
|
||||
"toolbar": [],
|
||||
"contextMenu": [],
|
||||
"viewer": {
|
||||
"toolbar:": [],
|
||||
"openWith": []
|
||||
},
|
||||
"sidebar": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Other applications or external plugins can utilise different subsets of the configuration above.
|
||||
Also, extra entries can be added to the configuration schema.
|
||||
|
||||
### Content Actions
|
||||
|
||||
Most of the UI elements that operate with content, like toolbar buttons or menus,
|
||||
are based on `ContentActionRef` interface implementation:
|
||||
|
||||
```ts
|
||||
interface ContentActionRef {
|
||||
id: string;
|
||||
type: ContentActionType;
|
||||
|
||||
title?: string;
|
||||
description?: string;
|
||||
order?: number;
|
||||
icon?: string;
|
||||
disabled?: boolean;
|
||||
children?: Array<ContentActionRef>;
|
||||
component?: string;
|
||||
actions?: {
|
||||
click?: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
rules?: {
|
||||
enabled?: string;
|
||||
visible?: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
You can define content actions in the `app.extensions.json` file using the structure above.
|
||||
|
||||
### Create Menu
|
||||
|
||||
Provides extension endpoint for the "NEW" menu options.
|
||||
|
||||
You can populate the menu with an extra entries like in the example below:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"create": [
|
||||
{
|
||||
"id": "app.create.folder",
|
||||
"icon": "create_new_folder",
|
||||
"title": "Create Folder",
|
||||
"actions": {
|
||||
"click": "CREATE_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"enabled": "app.navigation.folder.canCreate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.create.uploadFile",
|
||||
"icon": "file_upload",
|
||||
"title": "Upload Files",
|
||||
"actions": {
|
||||
"click": "UPLOAD_FILES"
|
||||
},
|
||||
"rules": {
|
||||
"enabled": "app.navigation.folder.canUpload"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the [Content Actions](#content-actions) section for more details on supported properties.
|
||||
|
||||
<p class="tip">
|
||||
It is also possible to update or disable existing entries from within the external extension files. You will need to know the `id` of the target element to customise.
|
||||
</p>
|
||||
|
||||
### Navigation Bar
|
||||
|
||||
Navigation bar consists of Link elements (`NavBarLinkRef`) organized into Groups (`NavBarGroupRef`).
|
||||
|
||||
```ts
|
||||
export interface NavBarGroupRef {
|
||||
id: string;
|
||||
items: Array<NavBarLinkRef>;
|
||||
|
||||
order?: number;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export interface NavBarLinkRef {
|
||||
id: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
route: string;
|
||||
|
||||
url?: string; // evaluated at runtime based on route ref
|
||||
description?: string;
|
||||
order?: number;
|
||||
disabled?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
You extensions can perform the following actions at runtime:
|
||||
|
||||
* Register new groups with links
|
||||
* Insert new links into existing groups
|
||||
* Update properties of the existing links
|
||||
* Disable existing links or entire groups
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"navbar": [
|
||||
{
|
||||
"id": "app.navbar.primary",
|
||||
"items": [
|
||||
{
|
||||
"id": "app.navbar.personalFiles",
|
||||
"icon": "folder",
|
||||
"title": "Personal Files",
|
||||
"route": "personal-files"
|
||||
},
|
||||
{
|
||||
"id": "app.navbar.libraries",
|
||||
"icon": "group_work",
|
||||
"title": "Libraries",
|
||||
"route": "libraries"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "app.navbar.secondary",
|
||||
"items": [
|
||||
{
|
||||
"id": "app.navbar.shared",
|
||||
"icon": "people",
|
||||
"title": "Shared",
|
||||
"route": "shared"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Sidebar (Info Drawer)
|
||||
|
||||
You can provide the following customisations for the Sidebar (aka Info Drawer) component:
|
||||
|
||||
* Add extra tabs with custom components
|
||||
* Disable tabs from the main application or extensions
|
||||
* Replace content or properties of existing tabs
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"sidebar": {
|
||||
{
|
||||
"id": "app.sidebar.properties",
|
||||
"order": 100,
|
||||
"title": "Properties",
|
||||
"component": "app.components.tabs.metadata"
|
||||
},
|
||||
{
|
||||
"id": "app.sidebar.comments",
|
||||
"order": 200,
|
||||
"title": "Comments",
|
||||
"component": "app.components.tabs.comments"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The example above renders two tabs:
|
||||
|
||||
* `Properties` tab that references `app.components.tabs.metadata` component
|
||||
* `Comments` tab that references `app.components.tabs.comments` component
|
||||
|
||||
All corresponding components must be registered for runtime use.
|
||||
|
||||
<p class="tip">
|
||||
See [Registration](#registration) section for more details
|
||||
on how to register your own entries to be re-used at runtime.
|
||||
</p>
|
||||
|
||||
#### Tab properties
|
||||
|
||||
| Name | Description |
|
||||
| --- | --- |
|
||||
| **id** | Unique identifier. |
|
||||
| **component** | The main [component](#components) to use for the route. |
|
||||
| **title** | Tab title or resource key. |
|
||||
| icon | Tab icon |
|
||||
| disabled | Toggles disabled state. Can be assigned from other plugins. |
|
||||
| order | The order of the element. |
|
||||
|
||||
### Toolbar
|
||||
|
||||
The toolbar extension point is represented by an array of Content Action references.
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"toolbar": [
|
||||
{
|
||||
"id": "app.toolbar.preview",
|
||||
"title": "View",
|
||||
"icon": "open_in_browser",
|
||||
"actions": {
|
||||
"click": "VIEW_FILE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canViewFile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.download",
|
||||
"title": "Download",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The content actions are applied to the toolbars for the following Views:
|
||||
|
||||
* Personal Files
|
||||
* Libraries
|
||||
* Shared
|
||||
* Recent Files
|
||||
* Favorites
|
||||
* Trash
|
||||
* Search Results
|
||||
|
||||
### Context Menu
|
||||
|
||||
Context Menu extensibility is similar to the one of the Toolbar.
|
||||
You may want to define a list of content actions backed by Rules and wired with Application Actions.
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"contextMenu": [
|
||||
{
|
||||
"id": "app.context.menu.download",
|
||||
"order": 100,
|
||||
"title": "Download",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that you can re-use any rules and evaluators available.
|
||||
|
||||
In the example above, the context menu action `Download` utilizes the `app.toolbar.canDownload` rule,
|
||||
declared in the `rules` section:
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"id": "app.toolbar.canDownload",
|
||||
"type": "core.every",
|
||||
"parameters": [
|
||||
{ "type": "rule", "value": "app.selection.canDownload" },
|
||||
{ "type": "rule", "value": "app.navigation.isNotTrashcan" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Viewer
|
||||
|
||||
Viewer component in ACA supports the following extension points:
|
||||
|
||||
* `More` toolbar actions
|
||||
* `Open With` actions
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"viewer": {
|
||||
"toolbar:": [],
|
||||
"openWith": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Toolbar actions
|
||||
|
||||
The ADF Viewer component allows providing custom entries for the `More` menu button on the toolbar.
|
||||
The ACA provides an extension point for this menu that you can utilise to populate custom menu items:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"features": {
|
||||
"viewer": {
|
||||
"toolbar:": [
|
||||
{
|
||||
"id": "app.viewer.share",
|
||||
"order": 300,
|
||||
"title": "Share",
|
||||
"icon": "share",
|
||||
"actions": {
|
||||
"click": "SHARE_NODE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.file.canShare"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Open With actions
|
||||
|
||||
#### Toolbar actions
|
||||
You can provide a list of `Open With` actions to render with every instance of the Viewer.
|
||||
|
||||
In the following example, we create a simple `Snackbar` action reference,
|
||||
and invoke it from the custom `Open With` menu entry called `Snackbar`.
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
|
||||
"actions": [
|
||||
{
|
||||
"id": "plugin1.actions.info",
|
||||
"type": "SNACKBAR_INFO",
|
||||
"payload": "I'm a nice little popup raised by extension."
|
||||
},
|
||||
],
|
||||
|
||||
"features": {
|
||||
"viewer": {
|
||||
"openWith": [
|
||||
{
|
||||
"id": "plugin1.viewer.openWith.action1",
|
||||
"type": "button",
|
||||
"icon": "build",
|
||||
"title": "Snackbar",
|
||||
"actions": {
|
||||
"click": "plugin1.actions.info"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As with other content actions, custom plugins can disable, update or extend `Open With` actions.
|
||||
|
||||
## Registration
|
||||
|
||||
@ -699,7 +1131,6 @@ extensions.setEvaluators({
|
||||
Now, the `plugin1.rules.hasSelection` evaluator can be used as an inline rule reference,
|
||||
or part of the composite rule like `core.every`.
|
||||
|
||||
|
||||
<p class="tip">
|
||||
See [Registration](#registration) section for more details
|
||||
on how to register your own entries to be re-used at runtime.
|
||||
|
@ -482,7 +482,7 @@ In the `app.config.json` define a link entry which will point to the custom page
|
||||
{
|
||||
"icon": "work",
|
||||
"label": "Link",
|
||||
"title": "My custome link",
|
||||
"title": "My custom link",
|
||||
"route": {
|
||||
"url": "/custom-route"
|
||||
}
|
||||
|
@ -332,8 +332,8 @@
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"actions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"toolbar": {
|
||||
"description": "Toolbar entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
@ -352,23 +352,17 @@
|
||||
"items": { "$ref": "#/definitions/sidebarTabRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"content": {
|
||||
"description": "Main application content extensions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"actions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"contextActions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
"toolbar": {
|
||||
"description": "Toolbar entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"contextMenu": {
|
||||
"description": "Context menu entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export class ContextMenuComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
.subscribe(selection => {
|
||||
if (selection.count) {
|
||||
this.selection = selection;
|
||||
this.actions = this.extensions.getAllowedContentContextActions();
|
||||
this.actions = this.extensions.getAllowedContextMenuActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
documentDisplayMode$: Observable<string>;
|
||||
sharedPreviewUrl$: Observable<string>;
|
||||
actions: Array<ContentActionRef> = [];
|
||||
viewerActions: Array<ContentActionRef> = [];
|
||||
viewerToolbarActions: Array<ContentActionRef> = [];
|
||||
canUpdateNode = false;
|
||||
canUpload = false;
|
||||
|
||||
@ -76,8 +76,8 @@ export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(selection => {
|
||||
this.selection = selection;
|
||||
this.actions = this.extensions.getAllowedContentActions();
|
||||
this.viewerActions = this.extensions.getViewerActions();
|
||||
this.actions = this.extensions.getAllowedToolbarActions();
|
||||
this.viewerToolbarActions = this.extensions.getViewerToolbarActions();
|
||||
this.canUpdateNode = this.selection.count === 1 && this.content.canUpdateNode(selection.first);
|
||||
});
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
</adf-viewer-open-with>
|
||||
|
||||
<adf-viewer-more-actions>
|
||||
<ng-container *ngFor="let action of viewerActions; trackBy: trackByActionId">
|
||||
<ng-container *ngFor="let action of viewerToolbarActions; trackBy: trackByActionId">
|
||||
<aca-toolbar-action type="menu-item" [entry]="action"></aca-toolbar-action>
|
||||
</ng-container>
|
||||
</adf-viewer-more-actions>
|
||||
|
@ -42,13 +42,11 @@ export interface ExtensionConfig {
|
||||
create?: Array<ContentActionRef>;
|
||||
viewer?: {
|
||||
openWith?: Array<ContentActionRef>;
|
||||
actions?: Array<ContentActionRef>;
|
||||
toolbar?: Array<ContentActionRef>;
|
||||
};
|
||||
navbar?: Array<NavBarGroupRef>;
|
||||
sidebar?: Array<SidebarTabRef>;
|
||||
content?: {
|
||||
actions?: Array<ContentActionRef>;
|
||||
contextActions?: Array<ContentActionRef>
|
||||
};
|
||||
toolbar?: Array<ContentActionRef>;
|
||||
contextMenu?: Array<ContentActionRef>;
|
||||
};
|
||||
}
|
||||
|
@ -290,26 +290,24 @@ describe('ExtensionService', () => {
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
content: {
|
||||
actions: [
|
||||
{
|
||||
id: 'aca:toolbar/separator-1',
|
||||
order: 1,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action1',
|
||||
},
|
||||
{
|
||||
id: 'aca:toolbar/separator-2',
|
||||
order: 2,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action2'
|
||||
}
|
||||
]
|
||||
}
|
||||
toolbar: [
|
||||
{
|
||||
id: 'aca:toolbar/separator-1',
|
||||
order: 1,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action1',
|
||||
},
|
||||
{
|
||||
id: 'aca:toolbar/separator-2',
|
||||
order: 2,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action2'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
expect(extensions.contentActions.length).toBe(2);
|
||||
expect(extensions.toolbarActions.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should sort content actions by order', () => {
|
||||
@ -317,30 +315,28 @@ describe('ExtensionService', () => {
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
content: {
|
||||
actions: [
|
||||
{
|
||||
id: 'aca:toolbar/separator-2',
|
||||
order: 2,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action2'
|
||||
},
|
||||
{
|
||||
id: 'aca:toolbar/separator-1',
|
||||
order: 1,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action1'
|
||||
}
|
||||
]
|
||||
}
|
||||
toolbar: [
|
||||
{
|
||||
id: 'aca:toolbar/separator-2',
|
||||
order: 2,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action2'
|
||||
},
|
||||
{
|
||||
id: 'aca:toolbar/separator-1',
|
||||
order: 1,
|
||||
type: ContentActionType.separator,
|
||||
title: 'action1'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
expect(extensions.contentActions.length).toBe(2);
|
||||
expect(extensions.contentActions[0].id).toBe(
|
||||
expect(extensions.toolbarActions.length).toBe(2);
|
||||
expect(extensions.toolbarActions[0].id).toBe(
|
||||
'aca:toolbar/separator-1'
|
||||
);
|
||||
expect(extensions.contentActions[1].id).toBe(
|
||||
expect(extensions.toolbarActions[1].id).toBe(
|
||||
'aca:toolbar/separator-2'
|
||||
);
|
||||
});
|
||||
|
@ -38,6 +38,7 @@ import { ActionRef, ContentActionRef, ContentActionType } from './action.extensi
|
||||
import * as core from './evaluators/core.evaluators';
|
||||
import { NodePermissionService } from '../services/node-permission.service';
|
||||
import { SidebarTabRef } from './sidebar.extensions';
|
||||
import { ProfileResolver } from '../services/profile.resolver';
|
||||
|
||||
@Injectable()
|
||||
export class ExtensionService implements RuleContext {
|
||||
@ -53,9 +54,9 @@ export class ExtensionService implements RuleContext {
|
||||
routes: Array<RouteRef> = [];
|
||||
actions: Array<ActionRef> = [];
|
||||
|
||||
contentActions: Array<ContentActionRef> = [];
|
||||
viewerActions: Array<ContentActionRef> = [];
|
||||
contentContextmenuActions: Array<ContentActionRef> = [];
|
||||
toolbarActions: Array<ContentActionRef> = [];
|
||||
viewerToolbarActions: Array<ContentActionRef> = [];
|
||||
contextMenuActions: Array<ContentActionRef> = [];
|
||||
openWithActions: Array<ContentActionRef> = [];
|
||||
createActions: Array<ContentActionRef> = [];
|
||||
navbar: Array<NavBarGroupRef> = [];
|
||||
@ -133,9 +134,9 @@ export class ExtensionService implements RuleContext {
|
||||
this.rules = this.loadRules(config);
|
||||
this.actions = this.loadActions(config);
|
||||
this.routes = this.loadRoutes(config);
|
||||
this.contentActions = this.loadContentActions(config);
|
||||
this.viewerActions = this.loadViewerActions(config);
|
||||
this.contentContextmenuActions = this.loadContentContextMenuActions(config);
|
||||
this.toolbarActions = this.loadToolbarActions(config);
|
||||
this.viewerToolbarActions = this.loadViewerToolbarActions(config);
|
||||
this.contextMenuActions = this.loadContextMenuActions(config);
|
||||
this.openWithActions = this.loadViewerOpenWith(config);
|
||||
this.createActions = this.loadCreateActions(config);
|
||||
this.navbar = this.loadNavBar(config);
|
||||
@ -168,27 +169,27 @@ export class ExtensionService implements RuleContext {
|
||||
return [];
|
||||
}
|
||||
|
||||
protected loadContentActions(config: ExtensionConfig) {
|
||||
if (config && config.features && config.features.content) {
|
||||
return (config.features.content.actions || [])
|
||||
protected loadToolbarActions(config: ExtensionConfig) {
|
||||
if (config && config.features && config.features.toolbar) {
|
||||
return (config.features.toolbar || [])
|
||||
.sort(this.sortByOrder)
|
||||
.map(this.setActionDefaults);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
protected loadViewerActions(config: ExtensionConfig): Array<ContentActionRef> {
|
||||
protected loadViewerToolbarActions(config: ExtensionConfig): Array<ContentActionRef> {
|
||||
if (config && config.features && config.features.viewer) {
|
||||
return (config.features.viewer.actions || [])
|
||||
return (config.features.viewer.toolbar || [])
|
||||
.sort(this.sortByOrder)
|
||||
.map(this.setActionDefaults);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
protected loadContentContextMenuActions(config: ExtensionConfig): Array<ContentActionRef> {
|
||||
if (config && config.features && config.features.content) {
|
||||
return (config.features.content.contextActions || [])
|
||||
protected loadContextMenuActions(config: ExtensionConfig): Array<ContentActionRef> {
|
||||
if (config && config.features && config.features.contextMenu) {
|
||||
return (config.features.contextMenu || [])
|
||||
.sort(this.sortByOrder)
|
||||
.map(this.setActionDefaults);
|
||||
}
|
||||
@ -312,6 +313,7 @@ export class ExtensionService implements RuleContext {
|
||||
component: this.getComponentById(route.layout || this.defaults.layout),
|
||||
canActivateChild: guards,
|
||||
canActivate: guards,
|
||||
resolve: { profile: ProfileResolver },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
@ -342,8 +344,8 @@ export class ExtensionService implements RuleContext {
|
||||
}
|
||||
|
||||
// evaluates content actions for the selection and parent folder node
|
||||
getAllowedContentActions(): Array<ContentActionRef> {
|
||||
return this.contentActions
|
||||
getAllowedToolbarActions(): Array<ContentActionRef> {
|
||||
return this.toolbarActions
|
||||
.filter(this.filterEnabled)
|
||||
.filter(action => this.filterByRules(action))
|
||||
.map(action => {
|
||||
@ -364,14 +366,14 @@ export class ExtensionService implements RuleContext {
|
||||
.reduce(this.reduceSeparators, []);
|
||||
}
|
||||
|
||||
getViewerActions(): Array<ContentActionRef> {
|
||||
return this.viewerActions
|
||||
getViewerToolbarActions(): Array<ContentActionRef> {
|
||||
return this.viewerToolbarActions
|
||||
.filter(this.filterEnabled)
|
||||
.filter(action => this.filterByRules(action));
|
||||
}
|
||||
|
||||
getAllowedContentContextActions(): Array<ContentActionRef> {
|
||||
return this.contentContextmenuActions
|
||||
getAllowedContextMenuActions(): Array<ContentActionRef> {
|
||||
return this.contextMenuActions
|
||||
.filter(this.filterEnabled)
|
||||
.filter(action => this.filterByRules(action));
|
||||
}
|
||||
|
@ -237,400 +237,398 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"content": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "app.toolbar.preview",
|
||||
"order": 100,
|
||||
"title": "APP.ACTIONS.VIEW",
|
||||
"icon": "open_in_browser",
|
||||
"actions": {
|
||||
"click": "VIEW_FILE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canViewFile"
|
||||
}
|
||||
"toolbar": [
|
||||
{
|
||||
"id": "app.toolbar.preview",
|
||||
"order": 100,
|
||||
"title": "APP.ACTIONS.VIEW",
|
||||
"icon": "open_in_browser",
|
||||
"actions": {
|
||||
"click": "VIEW_FILE"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.download",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.DOWNLOAD",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canViewFile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.download",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.DOWNLOAD",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.editFolder",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.EDIT",
|
||||
"icon": "create",
|
||||
"actions": {
|
||||
"click": "EDIT_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canEditFolder"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.editFolder",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.EDIT",
|
||||
"icon": "create",
|
||||
"actions": {
|
||||
"click": "EDIT_FOLDER"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.purgeDeletedNodes",
|
||||
"order": 400,
|
||||
"title": "APP.ACTIONS.DELETE_PERMANENT",
|
||||
"icon": "delete_forever",
|
||||
"actions": {
|
||||
"click": "PURGE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canEditFolder"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.purgeDeletedNodes",
|
||||
"order": 400,
|
||||
"title": "APP.ACTIONS.DELETE_PERMANENT",
|
||||
"icon": "delete_forever",
|
||||
"actions": {
|
||||
"click": "PURGE_DELETED_NODES"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.restoreDeletedNodes",
|
||||
"order": 500,
|
||||
"title": "APP.ACTIONS.RESTORE",
|
||||
"icon": "restore",
|
||||
"actions": {
|
||||
"click": "RESTORE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.restoreDeletedNodes",
|
||||
"order": 500,
|
||||
"title": "APP.ACTIONS.RESTORE",
|
||||
"icon": "restore",
|
||||
"actions": {
|
||||
"click": "RESTORE_DELETED_NODES"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.createLibrary",
|
||||
"order": 600,
|
||||
"title": "Create Library",
|
||||
"icon": "create_new_folder",
|
||||
"actions": {
|
||||
"click": "CREATE_LIBRARY"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.isLibraries"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.createLibrary",
|
||||
"order": 600,
|
||||
"title": "Create Library",
|
||||
"icon": "create_new_folder",
|
||||
"actions": {
|
||||
"click": "CREATE_LIBRARY"
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.info",
|
||||
"type": "custom",
|
||||
"order": 700,
|
||||
"component": "app.toolbar.toggleInfoDrawer",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.info"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.more",
|
||||
"type": "menu",
|
||||
"order": 10000,
|
||||
"icon": "more_vert",
|
||||
"title": "APP.ACTIONS.MORE",
|
||||
"children": [
|
||||
{
|
||||
"id": "app.toolbar.favorite",
|
||||
"comment": "workaround for Recent Files and Search API issue",
|
||||
"type": "custom",
|
||||
"order": 100,
|
||||
"component": "app.toolbar.toggleFavorite",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canToggle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.favorite.add",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"icon": "star_border",
|
||||
"actions": {
|
||||
"click": "ADD_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canAdd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.favorite.remove",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"icon": "star",
|
||||
"actions": {
|
||||
"click": "REMOVE_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canRemove"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.copy",
|
||||
"order": 400,
|
||||
"title": "APP.ACTIONS.COPY",
|
||||
"icon": "content_copy",
|
||||
"actions": {
|
||||
"click": "COPY_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canCopyNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.move",
|
||||
"order": 500,
|
||||
"title": "APP.ACTIONS.MOVE",
|
||||
"icon": "library_books",
|
||||
"actions": {
|
||||
"click": "MOVE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.share",
|
||||
"order": 600,
|
||||
"title": "APP.ACTIONS.SHARE",
|
||||
"icon": "share",
|
||||
"actions": {
|
||||
"click": "SHARE_NODE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.file.canShare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.unshare",
|
||||
"order": 700,
|
||||
"title": "APP.ACTIONS.UNSHARE",
|
||||
"icon": "stop_screen_share",
|
||||
"actions": {
|
||||
"click": "UNSHARE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canUnshare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.delete",
|
||||
"order": 800,
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.deleteLibrary",
|
||||
"order": 900,
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_LIBRARY"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.library"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.versions",
|
||||
"order": 1000,
|
||||
"title": "APP.ACTIONS.VERSIONS",
|
||||
"icon": "history",
|
||||
"actions": {
|
||||
"click": "MANAGE_VERSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.permissions",
|
||||
"order": 1100,
|
||||
"title": "APP.ACTIONS.PERMISSIONS",
|
||||
"icon": "settings_input_component",
|
||||
"actions": {
|
||||
"click": "MANAGE_PERMISSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.permissions"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.navigation.isLibraries"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.info",
|
||||
"type": "custom",
|
||||
"order": 700,
|
||||
"component": "app.toolbar.toggleInfoDrawer",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.info"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.more",
|
||||
"type": "menu",
|
||||
"order": 10000,
|
||||
"icon": "more_vert",
|
||||
"title": "APP.ACTIONS.MORE",
|
||||
"children": [
|
||||
{
|
||||
"id": "app.toolbar.favorite",
|
||||
"comment": "workaround for Recent Files and Search API issue",
|
||||
"type": "custom",
|
||||
"order": 100,
|
||||
"component": "app.toolbar.toggleFavorite",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canToggle"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.favorite.add",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"icon": "star_border",
|
||||
"actions": {
|
||||
"click": "ADD_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canAdd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.favorite.remove",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"icon": "star",
|
||||
"actions": {
|
||||
"click": "REMOVE_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canRemove"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.copy",
|
||||
"order": 400,
|
||||
"title": "APP.ACTIONS.COPY",
|
||||
"icon": "content_copy",
|
||||
"actions": {
|
||||
"click": "COPY_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canCopyNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.move",
|
||||
"order": 500,
|
||||
"title": "APP.ACTIONS.MOVE",
|
||||
"icon": "library_books",
|
||||
"actions": {
|
||||
"click": "MOVE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.share",
|
||||
"order": 600,
|
||||
"title": "APP.ACTIONS.SHARE",
|
||||
"icon": "share",
|
||||
"actions": {
|
||||
"click": "SHARE_NODE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.file.canShare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.unshare",
|
||||
"order": 700,
|
||||
"title": "APP.ACTIONS.UNSHARE",
|
||||
"icon": "stop_screen_share",
|
||||
"actions": {
|
||||
"click": "UNSHARE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canUnshare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.delete",
|
||||
"order": 800,
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.deleteLibrary",
|
||||
"order": 900,
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_LIBRARY"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.library"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.versions",
|
||||
"order": 1000,
|
||||
"title": "APP.ACTIONS.VERSIONS",
|
||||
"icon": "history",
|
||||
"actions": {
|
||||
"click": "MANAGE_VERSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.toolbar.permissions",
|
||||
"order": 1100,
|
||||
"title": "APP.ACTIONS.PERMISSIONS",
|
||||
"icon": "settings_input_component",
|
||||
"actions": {
|
||||
"click": "MANAGE_PERMISSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.permissions"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"contextMenu": [
|
||||
{
|
||||
"id": "app.context.menu.download",
|
||||
"order": 100,
|
||||
"title": "APP.ACTIONS.DOWNLOAD",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
],
|
||||
"contextActions": [
|
||||
{
|
||||
"id": "app.contextmenu.download",
|
||||
"order": 100,
|
||||
"title": "APP.ACTIONS.DOWNLOAD",
|
||||
"icon": "get_app",
|
||||
"actions": {
|
||||
"click": "DOWNLOAD_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canDownload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.preview",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.VIEW",
|
||||
"icon": "open_in_browser",
|
||||
"actions": {
|
||||
"click": "VIEW_FILE"
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.preview",
|
||||
"order": 200,
|
||||
"title": "APP.ACTIONS.VIEW",
|
||||
"icon": "open_in_browser",
|
||||
"actions": {
|
||||
"click": "VIEW_FILE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canViewFile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.editFolder",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.EDIT",
|
||||
"icon": "create",
|
||||
"actions": {
|
||||
"click": "EDIT_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canEditFolder"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.share",
|
||||
"title": "APP.ACTIONS.SHARE",
|
||||
"order": 400,
|
||||
"icon": "share",
|
||||
"actions": {
|
||||
"click": "SHARE_NODE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.file.canShare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.favorite.add",
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"order": 500,
|
||||
"icon": "star_border",
|
||||
"actions": {
|
||||
"click": "ADD_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canAdd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.favorite.remove",
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"order": 600,
|
||||
"icon": "star",
|
||||
"actions": {
|
||||
"click": "REMOVE_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canRemove"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.favorite",
|
||||
"comment": "workaround for Recent Files and Search API issue",
|
||||
"type": "custom",
|
||||
"order": 501,
|
||||
"component": "app.toolbar.toggleFavorite",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canToggle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.copy",
|
||||
"title": "APP.ACTIONS.COPY",
|
||||
"order": 700,
|
||||
"icon": "content_copy",
|
||||
"actions": {
|
||||
"click": "COPY_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canCopyNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.move",
|
||||
"title": "APP.ACTIONS.MOVE",
|
||||
"order": 800,
|
||||
"icon": "library_books",
|
||||
"actions": {
|
||||
"click": "MOVE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.delete",
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"order": 900,
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.versions",
|
||||
"title": "APP.ACTIONS.VERSIONS",
|
||||
"order": 1000,
|
||||
"icon": "history",
|
||||
"actions": {
|
||||
"click": "MANAGE_VERSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.permissions",
|
||||
"title": "APP.ACTIONS.PERMISSIONS",
|
||||
"icon": "settings_input_component",
|
||||
"order": 1100,
|
||||
"actions": {
|
||||
"click": "MANAGE_PERMISSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.permissions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.purgeDeletedNodes",
|
||||
"order": 1200,
|
||||
"title": "APP.ACTIONS.DELETE_PERMANENT",
|
||||
"icon": "delete_forever",
|
||||
"actions": {
|
||||
"click": "PURGE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.contextmenu.restoreDeletedNodes",
|
||||
"order": 1300,
|
||||
"title": "APP.ACTIONS.RESTORE",
|
||||
"icon": "restore",
|
||||
"actions": {
|
||||
"click": "RESTORE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canViewFile"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.editFolder",
|
||||
"order": 300,
|
||||
"title": "APP.ACTIONS.EDIT",
|
||||
"icon": "create",
|
||||
"actions": {
|
||||
"click": "EDIT_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canEditFolder"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.share",
|
||||
"title": "APP.ACTIONS.SHARE",
|
||||
"order": 400,
|
||||
"icon": "share",
|
||||
"actions": {
|
||||
"click": "SHARE_NODE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.file.canShare"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.favorite.add",
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"order": 500,
|
||||
"icon": "star_border",
|
||||
"actions": {
|
||||
"click": "ADD_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canAdd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.favorite.remove",
|
||||
"title": "APP.ACTIONS.FAVORITE",
|
||||
"order": 600,
|
||||
"icon": "star",
|
||||
"actions": {
|
||||
"click": "REMOVE_FAVORITE"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canRemove"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.favorite",
|
||||
"comment": "workaround for Recent Files and Search API issue",
|
||||
"type": "custom",
|
||||
"order": 501,
|
||||
"component": "app.toolbar.toggleFavorite",
|
||||
"rules": {
|
||||
"visible": "app.toolbar.favorite.canToggle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.copy",
|
||||
"title": "APP.ACTIONS.COPY",
|
||||
"order": 700,
|
||||
"icon": "content_copy",
|
||||
"actions": {
|
||||
"click": "COPY_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.canCopyNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.move",
|
||||
"title": "APP.ACTIONS.MOVE",
|
||||
"order": 800,
|
||||
"icon": "library_books",
|
||||
"actions": {
|
||||
"click": "MOVE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.delete",
|
||||
"title": "APP.ACTIONS.DELETE",
|
||||
"order": 900,
|
||||
"icon": "delete",
|
||||
"actions": {
|
||||
"click": "DELETE_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.selection.canDelete"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.versions",
|
||||
"title": "APP.ACTIONS.VERSIONS",
|
||||
"order": 1000,
|
||||
"icon": "history",
|
||||
"actions": {
|
||||
"click": "MANAGE_VERSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.permissions",
|
||||
"title": "APP.ACTIONS.PERMISSIONS",
|
||||
"icon": "settings_input_component",
|
||||
"order": 1100,
|
||||
"actions": {
|
||||
"click": "MANAGE_PERMISSIONS"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.permissions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.purgeDeletedNodes",
|
||||
"order": 1200,
|
||||
"title": "APP.ACTIONS.DELETE_PERMANENT",
|
||||
"icon": "delete_forever",
|
||||
"actions": {
|
||||
"click": "PURGE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "app.context.menu.restoreDeletedNodes",
|
||||
"order": 1300,
|
||||
"title": "APP.ACTIONS.RESTORE",
|
||||
"icon": "restore",
|
||||
"actions": {
|
||||
"click": "RESTORE_DELETED_NODES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.trashcan.hasSelection"
|
||||
}
|
||||
}
|
||||
],
|
||||
"viewer": {
|
||||
"actions": [
|
||||
"toolbar": [
|
||||
{
|
||||
"id": "app.viewer.favorite.add",
|
||||
"order": 100,
|
||||
|
@ -332,8 +332,8 @@
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"actions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"toolbar": {
|
||||
"description": "Toolbar entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
@ -352,23 +352,17 @@
|
||||
"items": { "$ref": "#/definitions/sidebarTabRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"content": {
|
||||
"description": "Main application content extensions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"actions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"contextActions": {
|
||||
"description": "Content actions (toolbar, context menus, etc.)",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
"toolbar": {
|
||||
"description": "Toolbar entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
},
|
||||
"contextMenu": {
|
||||
"description": "Context menu entries",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,78 +50,76 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"content": {
|
||||
"actions": [
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.createFolder",
|
||||
"type": "button",
|
||||
"order": 10,
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.CREATE_FOLDER",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER",
|
||||
"icon": "create_new_folder",
|
||||
"actions": {
|
||||
"click": "CREATE_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canCreate"
|
||||
}
|
||||
"toolbar": [
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.createFolder",
|
||||
"type": "button",
|
||||
"order": 10,
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.CREATE_FOLDER",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.CREATE_FOLDER",
|
||||
"icon": "create_new_folder",
|
||||
"actions": {
|
||||
"click": "CREATE_FOLDER"
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.uploadFile",
|
||||
"order": 11,
|
||||
"type": "button",
|
||||
"icon": "file_upload",
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES",
|
||||
"actions": {
|
||||
"click": "UPLOAD_FILES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canUpload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.uploadFolder",
|
||||
"order": 12,
|
||||
"type": "button",
|
||||
"icon": "cloud_upload",
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS",
|
||||
"actions": {
|
||||
"click": "UPLOAD_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canUpload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "plugin1.toolbar.menu1",
|
||||
"type": "menu",
|
||||
"icon": "storage",
|
||||
"order": 300,
|
||||
"children": [
|
||||
{
|
||||
"id": "plugin1.toolbar.menu1.settings",
|
||||
"type": "button",
|
||||
"title": "Settings",
|
||||
"icon": "settings_applications",
|
||||
"actions": {
|
||||
"click": "plugin1.actions.settings"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "plugin1.toolbar.separator3",
|
||||
"order": 301,
|
||||
"type": "separator"
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canCreate"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.uploadFile",
|
||||
"order": 11,
|
||||
"type": "button",
|
||||
"icon": "file_upload",
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FILE",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FILES",
|
||||
"actions": {
|
||||
"click": "UPLOAD_FILES"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canUpload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "app.toolbar.uploadFolder",
|
||||
"order": 12,
|
||||
"type": "button",
|
||||
"icon": "cloud_upload",
|
||||
"title": "APP.NEW_MENU.MENU_ITEMS.UPLOAD_FOLDER",
|
||||
"description": "APP.NEW_MENU.TOOLTIPS.UPLOAD_FOLDERS",
|
||||
"actions": {
|
||||
"click": "UPLOAD_FOLDER"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.navigation.folder.canUpload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "plugin1.toolbar.menu1",
|
||||
"type": "menu",
|
||||
"icon": "storage",
|
||||
"order": 300,
|
||||
"children": [
|
||||
{
|
||||
"id": "plugin1.toolbar.menu1.settings",
|
||||
"type": "button",
|
||||
"title": "Settings",
|
||||
"icon": "settings_applications",
|
||||
"actions": {
|
||||
"click": "plugin1.actions.settings"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"disabled": true,
|
||||
"id": "plugin1.toolbar.separator3",
|
||||
"order": 301,
|
||||
"type": "separator"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user