mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-09-17 14:21:14 +00:00
[ACA-1646] "dev tools" extension (#567)
* dev tools extension project * code editor integration * latest editor, offline setup * override extension config (session only) * schema support * wire external plugins with experimental flag * update package scripts * sidebar extensions scaffold * propagate extension tabs to info drawer * separate tab components for info drawer * extensibility for info drawer * support tab icons
This commit is contained in:
@@ -5,5 +5,5 @@ LABEL maintainer="Denys Vuika <denys.vuika@alfresco.com>"
|
|||||||
COPY nginx.conf /etc/nginx/nginx.conf
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
COPY dist/ .
|
COPY dist/app/ .
|
||||||
|
|
||||||
|
58
angular.json
58
angular.json
@@ -11,7 +11,7 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist",
|
"outputPath": "dist/app",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
@@ -45,6 +45,16 @@
|
|||||||
"glob": "pdf.worker.js",
|
"glob": "pdf.worker.js",
|
||||||
"input": "node_modules/pdfjs-dist/build",
|
"input": "node_modules/pdfjs-dist/build",
|
||||||
"output": "/"
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "node_modules/monaco-editor/min",
|
||||||
|
"output": "./assets/monaco"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"glob": "**/*.js",
|
||||||
|
"input": "node_modules/@ngstack/code-editor/workers",
|
||||||
|
"output": "./assets/workers"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
@@ -106,9 +116,9 @@
|
|||||||
"karmaConfig": "./karma.conf.js",
|
"karmaConfig": "./karma.conf.js",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"stylePreprocessorOptions": {
|
"stylePreprocessorOptions": {
|
||||||
"includePaths": [
|
"includePaths": [
|
||||||
"src/app/ui"
|
"src/app/ui"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
"scripts": [
|
"scripts": [
|
||||||
@@ -188,6 +198,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"aca-dev-tools": {
|
||||||
|
"root": "projects/aca-dev-tools",
|
||||||
|
"sourceRoot": "projects/aca-dev-tools/src",
|
||||||
|
"projectType": "library",
|
||||||
|
"prefix": "lib",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "projects/aca-dev-tools/tsconfig.lib.json",
|
||||||
|
"project": "projects/aca-dev-tools/ng-package.json"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"project": "projects/aca-dev-tools/ng-package.prod.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "projects/aca-dev-tools/src/test.ts",
|
||||||
|
"tsConfig": "projects/aca-dev-tools/tsconfig.spec.json",
|
||||||
|
"karmaConfig": "projects/aca-dev-tools/karma.conf.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"projects/aca-dev-tools/tsconfig.lib.json",
|
||||||
|
"projects/aca-dev-tools/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultProject": "alfresco-content-app",
|
"defaultProject": "alfresco-content-app",
|
||||||
|
@@ -228,6 +228,46 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sidebarTabRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "component"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique identifier for the navigation group",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "Element title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"component": {
|
||||||
|
"description": "Component id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"description": "Material icon name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"description": "Toggles disabled state",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"description": "Element order",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"description": "Element rules",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"visible": {
|
||||||
|
"description": "Rule to evaluate the visibility state",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -306,6 +346,12 @@
|
|||||||
"items": { "$ref": "#/definitions/navBarGroupRef" },
|
"items": { "$ref": "#/definitions/navBarGroupRef" },
|
||||||
"minItems": 1
|
"minItems": 1
|
||||||
},
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"description": "Sidebar extensions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/sidebarTabRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"description": "Main application content extensions",
|
"description": "Main application content extensions",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
1101
package-lock.json
generated
1101
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@@ -4,15 +4,12 @@
|
|||||||
"license": "LGPL-3.0",
|
"license": "LGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "npm run server-versions && ng serve --open",
|
"start": "npm run server-versions && ng build aca-dev-tools && ng serve --open",
|
||||||
"start:prod": "npm run server-versions && ng serve --prod --open",
|
"start:prod": "npm run server-versions && ng serve --prod --open",
|
||||||
"build": "npm run server-versions && ng build --prod",
|
"build": "npm run server-versions && ng build aca-dev-tools --prod && ng build --prod",
|
||||||
"build:prod": "npm run server-versions && ng build --prod",
|
"build:dev": "npm run server-versions && ng build aca-dev-tools && ng build",
|
||||||
"build:dev": "npm run server-versions && ng build",
|
"test": "ng test alfresco-content-app --code-coverage",
|
||||||
"build:tomcat": "npm run server-versions && ng build --base-href ./",
|
"test:ci": "ng test alfresco-content-app --code-coverage --watch=false && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage",
|
||||||
"build:electron": "npm run server-versions && ng build --output-path www --base-href ./",
|
|
||||||
"test": "ng test --code-coverage",
|
|
||||||
"test:ci": "ng test --code-coverage --watch=false && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage",
|
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0",
|
"server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0",
|
||||||
"_e2e": "ng e2e",
|
"_e2e": "ng e2e",
|
||||||
@@ -21,7 +18,7 @@
|
|||||||
"start:docker": "docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000",
|
"start:docker": "docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000",
|
||||||
"stop:docker": "docker-compose stop",
|
"stop:docker": "docker-compose stop",
|
||||||
"e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker",
|
"e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker",
|
||||||
"spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts'"
|
"spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts' 'projects/**/*.ts'"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -46,6 +43,7 @@
|
|||||||
"@ngrx/router-store": "^6.1.0",
|
"@ngrx/router-store": "^6.1.0",
|
||||||
"@ngrx/store": "^6.1.0",
|
"@ngrx/store": "^6.1.0",
|
||||||
"@ngrx/store-devtools": "^6.1.0",
|
"@ngrx/store-devtools": "^6.1.0",
|
||||||
|
"@ngstack/code-editor": "^0.4.3",
|
||||||
"@ngx-translate/core": "^10.0.2",
|
"@ngx-translate/core": "^10.0.2",
|
||||||
"alfresco-js-api": "2.5.0",
|
"alfresco-js-api": "2.5.0",
|
||||||
"core-js": "^2.5.7",
|
"core-js": "^2.5.7",
|
||||||
@@ -53,6 +51,7 @@
|
|||||||
"minimatch-browser": "^1.0.0",
|
"minimatch-browser": "^1.0.0",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"moment-es6": "1.0.0",
|
"moment-es6": "1.0.0",
|
||||||
|
"monaco-editor": "^0.14.2",
|
||||||
"pdfjs-dist": "2.0.303",
|
"pdfjs-dist": "2.0.303",
|
||||||
"rxjs": "^6.2.2",
|
"rxjs": "^6.2.2",
|
||||||
"web-animations-js": "2.3.1",
|
"web-animations-js": "2.3.1",
|
||||||
@@ -60,6 +59,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~0.7.0",
|
"@angular-devkit/build-angular": "~0.7.0",
|
||||||
|
"@angular-devkit/build-ng-packagr": "~0.7.0",
|
||||||
"@angular/cli": "^6.1.3",
|
"@angular/cli": "^6.1.3",
|
||||||
"@angular/compiler-cli": "6.1.2",
|
"@angular/compiler-cli": "6.1.2",
|
||||||
"@angular/language-service": "6.1.2",
|
"@angular/language-service": "6.1.2",
|
||||||
@@ -82,10 +82,13 @@
|
|||||||
"karma-coverage-istanbul-reporter": "^1.2.1",
|
"karma-coverage-istanbul-reporter": "^1.2.1",
|
||||||
"karma-jasmine": "~1.1.0",
|
"karma-jasmine": "~1.1.0",
|
||||||
"karma-jasmine-html-reporter": "^0.2.2",
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
|
"ng-packagr": "^3.0.0",
|
||||||
"protractor": "5.3.2",
|
"protractor": "5.3.2",
|
||||||
"rimraf": "2.6.2",
|
"rimraf": "2.6.2",
|
||||||
"selenium-webdriver": "4.0.0-alpha.1",
|
"selenium-webdriver": "4.0.0-alpha.1",
|
||||||
"ts-node": "~4.1.0",
|
"ts-node": "~4.1.0",
|
||||||
|
"tsickle": ">=0.29.0",
|
||||||
|
"tslib": "^1.9.0",
|
||||||
"tslint": "~5.11.0",
|
"tslint": "~5.11.0",
|
||||||
"typescript": "^2.9.2",
|
"typescript": "^2.9.2",
|
||||||
"wait-on": "2.1.0"
|
"wait-on": "2.1.0"
|
||||||
|
31
projects/aca-dev-tools/karma.conf.js
Normal file
31
projects/aca-dev-tools/karma.conf.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
dir: require('path').join(__dirname, '../../coverage'),
|
||||||
|
reports: ['html', 'lcovonly'],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false
|
||||||
|
});
|
||||||
|
};
|
8
projects/aca-dev-tools/ng-package.json
Normal file
8
projects/aca-dev-tools/ng-package.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../dist/aca-dev-tools",
|
||||||
|
"deleteDestPath": false,
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public_api.ts"
|
||||||
|
}
|
||||||
|
}
|
7
projects/aca-dev-tools/ng-package.prod.json
Normal file
7
projects/aca-dev-tools/ng-package.prod.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../dist/aca-dev-tools",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public_api.ts"
|
||||||
|
}
|
||||||
|
}
|
9
projects/aca-dev-tools/package.json
Normal file
9
projects/aca-dev-tools/package.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "aca-dev-tools",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^6.0.0",
|
||||||
|
"@angular/core": "^6.0.0",
|
||||||
|
"@ngstack/code-editor": "^0.4.1"
|
||||||
|
}
|
||||||
|
}
|
39
projects/aca-dev-tools/src/lib/aca-dev-tools.component.html
Normal file
39
projects/aca-dev-tools/src/lib/aca-dev-tools.component.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<div class="inner-layout">
|
||||||
|
<div class="inner-layout__header">
|
||||||
|
<adf-breadcrumb root="app.extensions.json"></adf-breadcrumb>
|
||||||
|
<adf-toolbar class="inline">
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
color="primary"
|
||||||
|
title="Save changes"
|
||||||
|
(click)="saveChanges()">
|
||||||
|
<mat-icon>save_alt</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
color="primary"
|
||||||
|
title="Revert changes"
|
||||||
|
(click)="revertChanges()">
|
||||||
|
<mat-icon>history</mat-icon>
|
||||||
|
</button>
|
||||||
|
</adf-toolbar>
|
||||||
|
</div>
|
||||||
|
<div class="inner-layout__content">
|
||||||
|
<div class="inner-layout__panel">
|
||||||
|
|
||||||
|
<div fxLayout="column" fxFill>
|
||||||
|
<div fxLayout fxFlex>
|
||||||
|
<div fxFlex="100">
|
||||||
|
<ng-container *ngIf="model">
|
||||||
|
<ngs-code-editor
|
||||||
|
[codeModel]="model"
|
||||||
|
(valueChanged)="onCodeChanged($event)">
|
||||||
|
</ngs-code-editor>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
23
projects/aca-dev-tools/src/lib/aca-dev-tools.component.scss
Normal file
23
projects/aca-dev-tools/src/lib/aca-dev-tools.component.scss
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.lib-aca-dev-tools {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ngs-code-editor {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
// border: 1px solid grey;
|
||||||
|
// min-height: 400px;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AcaDevToolsComponent } from './aca-dev-tools.component';
|
||||||
|
|
||||||
|
describe('AcaDevToolsComponent', () => {
|
||||||
|
let component: AcaDevToolsComponent;
|
||||||
|
let fixture: ComponentFixture<AcaDevToolsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AcaDevToolsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AcaDevToolsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
72
projects/aca-dev-tools/src/lib/aca-dev-tools.component.ts
Normal file
72
projects/aca-dev-tools/src/lib/aca-dev-tools.component.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { CodeModel } from '@ngstack/code-editor';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { forkJoin } from 'rxjs';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'lib-aca-dev-tools',
|
||||||
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
host: { class: 'lib-aca-dev-tools' },
|
||||||
|
templateUrl: './aca-dev-tools.component.html',
|
||||||
|
styleUrls: ['./aca-dev-tools.component.scss']
|
||||||
|
})
|
||||||
|
export class AcaDevToolsComponent implements OnInit {
|
||||||
|
model: CodeModel = null;
|
||||||
|
|
||||||
|
private code: string;
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute, private http: HttpClient) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
const routeData = this.route.snapshot.data;
|
||||||
|
if (!routeData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const schemaUri = routeData.schemaUri;
|
||||||
|
const getSchema = this.http.get(routeData.schemaPath);
|
||||||
|
const getConfig = this.http.get(routeData.configPath, { responseType: 'text' });
|
||||||
|
|
||||||
|
forkJoin([getSchema, getConfig]).subscribe(
|
||||||
|
([schema, config]) => {
|
||||||
|
let code = config;
|
||||||
|
|
||||||
|
const override = sessionStorage.getItem('aca.extension.config');
|
||||||
|
if (override) {
|
||||||
|
code = override;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.model = {
|
||||||
|
language: 'json',
|
||||||
|
uri: 'app.extensions.json',
|
||||||
|
value: code,
|
||||||
|
schemas: [
|
||||||
|
{
|
||||||
|
uri: schemaUri,
|
||||||
|
schema
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
this.code = code;
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCodeChanged(value: string) {
|
||||||
|
this.code = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveChanges() {
|
||||||
|
sessionStorage.setItem('aca.extension.config', this.code);
|
||||||
|
// window.location.reload(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
revertChanges() {
|
||||||
|
sessionStorage.removeItem('aca.extension.config');
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
}
|
19
projects/aca-dev-tools/src/lib/aca-dev-tools.module.ts
Normal file
19
projects/aca-dev-tools/src/lib/aca-dev-tools.module.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CodeEditorModule } from '@ngstack/code-editor';
|
||||||
|
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||||
|
import { AcaDevToolsComponent } from './aca-dev-tools.component';
|
||||||
|
import { CoreModule } from '@alfresco/adf-core';
|
||||||
|
import { ContentModule } from '@alfresco/adf-content-services';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
FlexLayoutModule,
|
||||||
|
CodeEditorModule.forChild(),
|
||||||
|
CoreModule.forChild(),
|
||||||
|
ContentModule.forChild()
|
||||||
|
],
|
||||||
|
declarations: [AcaDevToolsComponent],
|
||||||
|
exports: [AcaDevToolsComponent],
|
||||||
|
entryComponents: [AcaDevToolsComponent]
|
||||||
|
})
|
||||||
|
export class AcaDevToolsModule {}
|
15
projects/aca-dev-tools/src/lib/aca-dev-tools.service.spec.ts
Normal file
15
projects/aca-dev-tools/src/lib/aca-dev-tools.service.spec.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AcaDevToolsService } from './aca-dev-tools.service';
|
||||||
|
|
||||||
|
describe('AcaDevToolsService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [AcaDevToolsService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([AcaDevToolsService], (service: AcaDevToolsService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
9
projects/aca-dev-tools/src/lib/aca-dev-tools.service.ts
Normal file
9
projects/aca-dev-tools/src/lib/aca-dev-tools.service.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AcaDevToolsService {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
}
|
7
projects/aca-dev-tools/src/public_api.ts
Normal file
7
projects/aca-dev-tools/src/public_api.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Public API Surface of aca-dev-tools
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/aca-dev-tools.service';
|
||||||
|
export * from './lib/aca-dev-tools.component';
|
||||||
|
export * from './lib/aca-dev-tools.module';
|
22
projects/aca-dev-tools/src/test.ts
Normal file
22
projects/aca-dev-tools/src/test.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'core-js/es7/reflect';
|
||||||
|
import 'zone.js/dist/zone';
|
||||||
|
import 'zone.js/dist/zone-testing';
|
||||||
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import {
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting
|
||||||
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
declare const require: any;
|
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment(
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting()
|
||||||
|
);
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
// And load the modules.
|
||||||
|
context.keys().map(context);
|
33
projects/aca-dev-tools/tsconfig.lib.json
Normal file
33
projects/aca-dev-tools/tsconfig.lib.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/lib",
|
||||||
|
"target": "es2015",
|
||||||
|
"module": "es2015",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"importHelpers": true,
|
||||||
|
"types": [],
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2015"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"annotateForClosureCompiler": true,
|
||||||
|
"skipTemplateCodegen": true,
|
||||||
|
"strictMetadataEmit": true,
|
||||||
|
"fullTemplateTypeCheck": true,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"flatModuleId": "AUTOGENERATED",
|
||||||
|
"flatModuleOutFile": "AUTOGENERATED"
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"src/test.ts",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
17
projects/aca-dev-tools/tsconfig.spec.json
Normal file
17
projects/aca-dev-tools/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/test.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
17
projects/aca-dev-tools/tslint.json
Normal file
17
projects/aca-dev-tools/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"directive-selector": [
|
||||||
|
true,
|
||||||
|
"attribute",
|
||||||
|
"lib",
|
||||||
|
"camelCase"
|
||||||
|
],
|
||||||
|
"component-selector": [
|
||||||
|
true,
|
||||||
|
"element",
|
||||||
|
"lib",
|
||||||
|
"kebab-case"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@@ -13,7 +13,8 @@
|
|||||||
"cardview": false,
|
"cardview": false,
|
||||||
"permissions": false,
|
"permissions": false,
|
||||||
"share": false,
|
"share": false,
|
||||||
"extensions": false
|
"extensions": false,
|
||||||
|
"external-plugins": false
|
||||||
},
|
},
|
||||||
"headerColor": "#2196F3",
|
"headerColor": "#2196F3",
|
||||||
"languagePicker": false,
|
"languagePicker": false,
|
||||||
|
@@ -88,7 +88,7 @@ import { ContextMenuModule } from './components/context-menu/context-menu.module
|
|||||||
}),
|
}),
|
||||||
MaterialModule,
|
MaterialModule,
|
||||||
CoreModule.forRoot(),
|
CoreModule.forRoot(),
|
||||||
ContentModule,
|
ContentModule.forRoot(),
|
||||||
AppStoreModule,
|
AppStoreModule,
|
||||||
CoreExtensionsModule.forRoot(),
|
CoreExtensionsModule.forRoot(),
|
||||||
ExtensionsModule,
|
ExtensionsModule,
|
||||||
|
@@ -90,7 +90,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'preview/:nodeId',
|
path: 'preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -120,7 +120,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':folderId/preview/:nodeId',
|
path: ':folderId/preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -152,7 +152,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'preview/:nodeId',
|
path: 'preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -161,7 +161,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':folderId/preview/:nodeId',
|
path: ':folderId/preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -185,7 +185,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'preview/:nodeId',
|
path: 'preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -209,7 +209,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'preview/:nodeId',
|
path: 'preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
@@ -228,7 +228,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'about',
|
path: 'about',
|
||||||
loadChildren: 'app/components/about/about.module#AboutModule',
|
loadChildren: 'src/app/components/about/about.module#AboutModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.BROWSE.ABOUT.TITLE'
|
title: 'APP.BROWSE.ABOUT.TITLE'
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ export const APP_ROUTES: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'preview/:nodeId',
|
path: 'preview/:nodeId',
|
||||||
loadChildren: 'app/components/preview/preview.module#PreviewModule',
|
loadChildren: 'src/app/components/preview/preview.module#PreviewModule',
|
||||||
data: {
|
data: {
|
||||||
title: 'APP.PREVIEW.TITLE',
|
title: 'APP.PREVIEW.TITLE',
|
||||||
navigateMultiple: true,
|
navigateMultiple: true,
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-comments-tab',
|
||||||
|
template: `
|
||||||
|
<adf-comments [nodeId]="node?.id"></adf-comments>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class CommentsTabComponent {
|
||||||
|
@Input()
|
||||||
|
node: MinimalNodeEntryEntity;
|
||||||
|
}
|
@@ -0,0 +1,94 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
Input,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
ViewChild,
|
||||||
|
ViewContainerRef,
|
||||||
|
ComponentRef,
|
||||||
|
ComponentFactoryResolver,
|
||||||
|
OnChanges,
|
||||||
|
SimpleChanges
|
||||||
|
} from '@angular/core';
|
||||||
|
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
|
import { ExtensionService } from '../../../extensions/extension.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dynamic-tab',
|
||||||
|
template: `<div #content></div>`
|
||||||
|
})
|
||||||
|
export class DynamicTabComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
@ViewChild('content', { read: ViewContainerRef })
|
||||||
|
content: ViewContainerRef;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
node: MinimalNodeEntryEntity;
|
||||||
|
|
||||||
|
private componentRef: ComponentRef<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private extensions: ExtensionService,
|
||||||
|
private componentFactoryResolver: ComponentFactoryResolver
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
const componentType = this.extensions.getComponentById(this.id);
|
||||||
|
if (componentType) {
|
||||||
|
const factory = this.componentFactoryResolver.resolveComponentFactory(
|
||||||
|
componentType
|
||||||
|
);
|
||||||
|
if (factory) {
|
||||||
|
this.content.clear();
|
||||||
|
this.componentRef = this.content.createComponent(factory, 0);
|
||||||
|
this.updateInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes.node) {
|
||||||
|
this.updateInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.componentRef) {
|
||||||
|
this.componentRef.destroy();
|
||||||
|
this.componentRef = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateInstance() {
|
||||||
|
if (this.componentRef && this.componentRef.instance) {
|
||||||
|
this.componentRef.instance.node = this.node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,38 +3,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="!isLoading && !!displayNode">
|
<ng-container *ngIf="!isLoading && !!displayNode">
|
||||||
<adf-info-drawer [title]="'APP.INFO_DRAWER.TITLE' | translate">
|
<adf-info-drawer [title]="'APP.INFO_DRAWER.TITLE' | translate">
|
||||||
<adf-info-drawer-tab [label]="'APP.INFO_DRAWER.TABS.PROPERTIES' | translate">
|
<adf-info-drawer-tab
|
||||||
<adf-content-metadata-card
|
*ngFor="let tab of tabs"
|
||||||
[readOnly]="!canUpdateNode"
|
[icon]="tab.icon"
|
||||||
[displayEmpty]="canUpdateNode"
|
[label]="tab.title | translate">
|
||||||
[preset]="'custom'"
|
<app-dynamic-tab [node]="displayNode" [id]="tab.component">
|
||||||
[node]="displayNode">
|
</app-dynamic-tab>
|
||||||
</adf-content-metadata-card>
|
|
||||||
</adf-info-drawer-tab>
|
</adf-info-drawer-tab>
|
||||||
|
|
||||||
<ng-container *ifExperimental="'comments'; else versions">
|
|
||||||
<adf-info-drawer-tab [label]="'APP.INFO_DRAWER.TABS.COMMENTS' | translate">
|
|
||||||
<adf-comments [nodeId]="displayNode.id"></adf-comments>
|
|
||||||
</adf-info-drawer-tab>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-template #versions>
|
|
||||||
<adf-info-drawer-tab [label]="'APP.INFO_DRAWER.TABS.VERSIONS' | translate">
|
|
||||||
<ng-container *ngIf="isFileSelected;else empty">
|
|
||||||
<adf-version-manager
|
|
||||||
[showComments]="'adf-version-manager.allowComments' | adfAppConfig:true"
|
|
||||||
[allowDownload]="'adf-version-manager.allowDownload' | adfAppConfig:true"
|
|
||||||
[node]="displayNode">
|
|
||||||
</adf-version-manager>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-template #empty>
|
|
||||||
<div class="adf-manage-versions-empty">
|
|
||||||
<mat-icon class="adf-manage-versions-empty-icon">face</mat-icon>
|
|
||||||
{{ 'VERSION.SELECTION.EMPTY' | translate }}
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</adf-info-drawer-tab>
|
|
||||||
</ng-template>
|
|
||||||
</adf-info-drawer>
|
</adf-info-drawer>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -23,41 +23,34 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||||
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
|
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
import { NodePermissionService } from '../../services/node-permission.service';
|
|
||||||
import { ContentApiService } from '../../services/content-api.service';
|
import { ContentApiService } from '../../services/content-api.service';
|
||||||
|
import { ExtensionService } from '../../extensions/extension.service';
|
||||||
|
import { SidebarTabRef } from '../../extensions/sidebar.extensions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aca-info-drawer',
|
selector: 'aca-info-drawer',
|
||||||
templateUrl: './info-drawer.component.html'
|
templateUrl: './info-drawer.component.html'
|
||||||
})
|
})
|
||||||
export class InfoDrawerComponent implements OnChanges {
|
export class InfoDrawerComponent implements OnChanges, OnInit {
|
||||||
@Input() nodeId: string;
|
@Input() nodeId: string;
|
||||||
@Input() node: MinimalNodeEntity;
|
@Input() node: MinimalNodeEntity;
|
||||||
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
displayNode: MinimalNodeEntryEntity;
|
displayNode: MinimalNodeEntryEntity;
|
||||||
canUpdateNode = false;
|
tabs: Array<SidebarTabRef> = [];
|
||||||
|
|
||||||
get isFileSelected(): boolean {
|
|
||||||
if (this.node && this.node.entry) {
|
|
||||||
// workaround for shared files type.
|
|
||||||
if (this.node.entry.nodeId) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return this.node.entry.isFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public permission: NodePermissionService,
|
private contentApi: ContentApiService,
|
||||||
private contentApi: ContentApiService
|
private extensions: ExtensionService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnInit() {
|
||||||
|
this.tabs = this.extensions.getSidebarTabs();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
const entry = this.node.entry;
|
const entry = this.node.entry;
|
||||||
if (entry.nodeId) {
|
if (entry.nodeId) {
|
||||||
@@ -103,6 +96,5 @@ export class InfoDrawerComponent implements OnChanges {
|
|||||||
|
|
||||||
private setDisplayNode(node: MinimalNodeEntryEntity) {
|
private setDisplayNode(node: MinimalNodeEntryEntity) {
|
||||||
this.displayNode = node;
|
this.displayNode = node;
|
||||||
this.canUpdateNode = node && this.permission.check(node, ['update']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,20 @@ import { ContentMetadataModule, VersionManagerModule } from '@alfresco/adf-conte
|
|||||||
import { InfoDrawerComponent } from './info-drawer.component';
|
import { InfoDrawerComponent } from './info-drawer.component';
|
||||||
import { DirectivesModule } from '../../directives/directives.module';
|
import { DirectivesModule } from '../../directives/directives.module';
|
||||||
import { MaterialModule } from '../../material.module';
|
import { MaterialModule } from '../../material.module';
|
||||||
|
import { MetadataTabComponent } from './metadata-tab/metadata-tab.component';
|
||||||
|
import { CommentsTabComponent } from './comments-tab/comments-tab.component';
|
||||||
|
import { VersionsTabComponent } from './versions-tab/versions-tab.component';
|
||||||
|
import { DynamicTabComponent } from './dynamic-tab/dynamic-tab.component';
|
||||||
|
|
||||||
|
export function components() {
|
||||||
|
return [
|
||||||
|
InfoDrawerComponent,
|
||||||
|
MetadataTabComponent,
|
||||||
|
CommentsTabComponent,
|
||||||
|
VersionsTabComponent,
|
||||||
|
DynamicTabComponent
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -41,10 +55,13 @@ import { MaterialModule } from '../../material.module';
|
|||||||
DirectivesModule
|
DirectivesModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
InfoDrawerComponent
|
...components()
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
InfoDrawerComponent
|
...components()
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
...components()
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppInfoDrawerModule {}
|
export class AppInfoDrawerModule {}
|
||||||
|
@@ -0,0 +1,55 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, Input, OnChanges, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
|
import { NodePermissionService } from '../../../services/node-permission.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-metadata-tab',
|
||||||
|
template: `
|
||||||
|
<adf-content-metadata-card
|
||||||
|
[readOnly]="!canUpdateNode"
|
||||||
|
[displayEmpty]="canUpdateNode"
|
||||||
|
[preset]="'custom'"
|
||||||
|
[node]="node">
|
||||||
|
</adf-content-metadata-card>
|
||||||
|
`,
|
||||||
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
host: { 'class': 'app-metadata-tab' }
|
||||||
|
})
|
||||||
|
export class MetadataTabComponent implements OnChanges {
|
||||||
|
@Input()
|
||||||
|
node: MinimalNodeEntryEntity;
|
||||||
|
|
||||||
|
canUpdateNode = false;
|
||||||
|
|
||||||
|
constructor(public permission: NodePermissionService) {}
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
|
this.canUpdateNode =
|
||||||
|
this.node && this.permission.check(this.node, ['update']);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,70 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||||
|
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-versions-tab',
|
||||||
|
template: `
|
||||||
|
<ng-container *ngIf="isFileSelected;else empty">
|
||||||
|
<adf-version-manager
|
||||||
|
[showComments]="'adf-version-manager.allowComments' | adfAppConfig:true"
|
||||||
|
[allowDownload]="'adf-version-manager.allowDownload' | adfAppConfig:true"
|
||||||
|
[node]="node">
|
||||||
|
</adf-version-manager>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-template #empty>
|
||||||
|
<div class="adf-manage-versions-empty">
|
||||||
|
<mat-icon class="adf-manage-versions-empty-icon">face</mat-icon>
|
||||||
|
{{ 'VERSION.SELECTION.EMPTY' | translate }}
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class VersionsTabComponent implements OnInit, OnChanges {
|
||||||
|
@Input()
|
||||||
|
node: MinimalNodeEntryEntity;
|
||||||
|
|
||||||
|
isFileSelected = false;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
|
this.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateState() {
|
||||||
|
if (this.node && this.node.nodeId) {
|
||||||
|
// workaround for shared files type.
|
||||||
|
this.isFileSelected = true;
|
||||||
|
} else {
|
||||||
|
this.isFileSelected = this.node.isFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +1,26 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { AcaDevToolsModule, AcaDevToolsComponent } from 'aca-dev-tools';
|
||||||
|
import { ExtensionService } from './extensions/extension.service';
|
||||||
|
import { CodeEditorModule } from '@ngstack/code-editor';
|
||||||
|
|
||||||
// Main entry point for external extensions only.
|
// Main entry point for external extensions only.
|
||||||
// For any application-specific code use CoreExtensionsModule instead.
|
// For any application-specific code use CoreExtensionsModule instead.
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: []
|
imports: [
|
||||||
|
CodeEditorModule.forRoot({
|
||||||
|
// use local Monaco installation
|
||||||
|
baseUrl: 'assets/monaco',
|
||||||
|
// use local Typings Worker
|
||||||
|
typingsWorkerUrl: 'assets/workers/typings-worker.js'
|
||||||
|
}),
|
||||||
|
AcaDevToolsModule
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class ExtensionsModule {}
|
export class ExtensionsModule {
|
||||||
|
constructor(extensions: ExtensionService) {
|
||||||
|
extensions.setComponents({
|
||||||
|
'app.dev.tools.component': AcaDevToolsComponent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -36,11 +36,17 @@ import { CustomExtensionComponent } from './components/custom-component/custom.c
|
|||||||
import { ToggleInfoDrawerComponent } from '../components/toolbar/toggle-info-drawer/toggle-info-drawer.component';
|
import { ToggleInfoDrawerComponent } from '../components/toolbar/toggle-info-drawer/toggle-info-drawer.component';
|
||||||
import { ToggleFavoriteComponent } from '../components/toolbar/toggle-favorite/toggle-favorite.component';
|
import { ToggleFavoriteComponent } from '../components/toolbar/toggle-favorite/toggle-favorite.component';
|
||||||
import { ToolbarButtonComponent } from './components/toolbar/toolbar-button.component';
|
import { ToolbarButtonComponent } from './components/toolbar/toolbar-button.component';
|
||||||
|
import { MetadataTabComponent } from '../components/info-drawer/metadata-tab/metadata-tab.component';
|
||||||
|
import { CommentsTabComponent } from '../components/info-drawer/comments-tab/comments-tab.component';
|
||||||
|
import { VersionsTabComponent } from '../components/info-drawer/versions-tab/versions-tab.component';
|
||||||
|
|
||||||
export function setupExtensions(extensions: ExtensionService): Function {
|
export function setupExtensions(extensions: ExtensionService): Function {
|
||||||
extensions.setComponents({
|
extensions.setComponents({
|
||||||
'app.layout.main': LayoutComponent,
|
'app.layout.main': LayoutComponent,
|
||||||
'app.components.trashcan': TrashcanComponent,
|
'app.components.trashcan': TrashcanComponent,
|
||||||
|
'app.components.tabs.metadata': MetadataTabComponent,
|
||||||
|
'app.components.tabs.comments': CommentsTabComponent,
|
||||||
|
'app.components.tabs.versions': VersionsTabComponent,
|
||||||
'app.toolbar.toggleInfoDrawer': ToggleInfoDrawerComponent,
|
'app.toolbar.toggleInfoDrawer': ToggleInfoDrawerComponent,
|
||||||
'app.toolbar.toggleFavorite': ToggleFavoriteComponent
|
'app.toolbar.toggleFavorite': ToggleFavoriteComponent
|
||||||
});
|
});
|
||||||
|
@@ -27,6 +27,7 @@ import { NavBarGroupRef } from './navbar.extensions';
|
|||||||
import { RouteRef } from './routing.extensions';
|
import { RouteRef } from './routing.extensions';
|
||||||
import { RuleRef } from './rule.extensions';
|
import { RuleRef } from './rule.extensions';
|
||||||
import { ActionRef, ContentActionRef } from './action.extensions';
|
import { ActionRef, ContentActionRef } from './action.extensions';
|
||||||
|
import { SidebarTabRef } from './sidebar.extensions';
|
||||||
|
|
||||||
export interface ExtensionConfig {
|
export interface ExtensionConfig {
|
||||||
$name: string;
|
$name: string;
|
||||||
@@ -44,6 +45,7 @@ export interface ExtensionConfig {
|
|||||||
actions?: Array<ContentActionRef>;
|
actions?: Array<ContentActionRef>;
|
||||||
};
|
};
|
||||||
navbar?: Array<NavBarGroupRef>;
|
navbar?: Array<NavBarGroupRef>;
|
||||||
|
sidebar?: Array<SidebarTabRef>;
|
||||||
content?: {
|
content?: {
|
||||||
actions?: Array<ContentActionRef>;
|
actions?: Array<ContentActionRef>;
|
||||||
contextActions?: Array<ContentActionRef>
|
contextActions?: Array<ContentActionRef>
|
||||||
|
@@ -37,6 +37,7 @@ import { RuleContext, RuleRef, RuleEvaluator, RuleParameter } from './rule.exten
|
|||||||
import { ActionRef, ContentActionRef, ContentActionType } from './action.extensions';
|
import { ActionRef, ContentActionRef, ContentActionType } from './action.extensions';
|
||||||
import * as core from './evaluators/core.evaluators';
|
import * as core from './evaluators/core.evaluators';
|
||||||
import { NodePermissionService } from '../services/node-permission.service';
|
import { NodePermissionService } from '../services/node-permission.service';
|
||||||
|
import { SidebarTabRef } from './sidebar.extensions';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExtensionService implements RuleContext {
|
export class ExtensionService implements RuleContext {
|
||||||
@@ -58,6 +59,7 @@ export class ExtensionService implements RuleContext {
|
|||||||
openWithActions: Array<ContentActionRef> = [];
|
openWithActions: Array<ContentActionRef> = [];
|
||||||
createActions: Array<ContentActionRef> = [];
|
createActions: Array<ContentActionRef> = [];
|
||||||
navbar: Array<NavBarGroupRef> = [];
|
navbar: Array<NavBarGroupRef> = [];
|
||||||
|
sidebar: Array<SidebarTabRef> = [];
|
||||||
|
|
||||||
authGuards: { [key: string]: Type<{}> } = {};
|
authGuards: { [key: string]: Type<{}> } = {};
|
||||||
components: { [key: string]: Type<{}> } = {};
|
components: { [key: string]: Type<{}> } = {};
|
||||||
@@ -88,7 +90,15 @@ export class ExtensionService implements RuleContext {
|
|||||||
this.loadConfig(this.configPath, 0).then(result => {
|
this.loadConfig(this.configPath, 0).then(result => {
|
||||||
let config = result.config;
|
let config = result.config;
|
||||||
|
|
||||||
if (config.$references && config.$references.length > 0) {
|
const override = sessionStorage.getItem('aca.extension.config');
|
||||||
|
if (override) {
|
||||||
|
console.log('overriding extension config');
|
||||||
|
config = JSON.parse(override);
|
||||||
|
}
|
||||||
|
|
||||||
|
const externalPlugins = localStorage.getItem('experimental.external-plugins') === 'true';
|
||||||
|
|
||||||
|
if (externalPlugins && config.$references && config.$references.length > 0) {
|
||||||
const plugins = config.$references.map(
|
const plugins = config.$references.map(
|
||||||
(name, idx) => this.loadConfig(`${this.pluginsPath}/${name}`, idx)
|
(name, idx) => this.loadConfig(`${this.pluginsPath}/${name}`, idx)
|
||||||
);
|
);
|
||||||
@@ -129,6 +139,7 @@ export class ExtensionService implements RuleContext {
|
|||||||
this.openWithActions = this.loadViewerOpenWith(config);
|
this.openWithActions = this.loadViewerOpenWith(config);
|
||||||
this.createActions = this.loadCreateActions(config);
|
this.createActions = this.loadCreateActions(config);
|
||||||
this.navbar = this.loadNavBar(config);
|
this.navbar = this.loadNavBar(config);
|
||||||
|
this.sidebar = this.loadSidebar(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadConfig(url: string, order: number): Promise<{ order: number, config: ExtensionConfig }> {
|
protected loadConfig(url: string, order: number): Promise<{ order: number, config: ExtensionConfig }> {
|
||||||
@@ -166,7 +177,7 @@ export class ExtensionService implements RuleContext {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadViewerActions(config: ExtensionConfig) {
|
protected loadViewerActions(config: ExtensionConfig): Array<ContentActionRef> {
|
||||||
if (config && config.features && config.features.viewer) {
|
if (config && config.features && config.features.viewer) {
|
||||||
return (config.features.viewer.actions || [])
|
return (config.features.viewer.actions || [])
|
||||||
.sort(this.sortByOrder)
|
.sort(this.sortByOrder)
|
||||||
@@ -184,7 +195,7 @@ export class ExtensionService implements RuleContext {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadNavBar(config: ExtensionConfig): any {
|
protected loadNavBar(config: ExtensionConfig): Array<NavBarGroupRef> {
|
||||||
if (config && config.features) {
|
if (config && config.features) {
|
||||||
return (config.features.navbar || [])
|
return (config.features.navbar || [])
|
||||||
.filter(entry => !entry.disabled)
|
.filter(entry => !entry.disabled)
|
||||||
@@ -206,7 +217,16 @@ export class ExtensionService implements RuleContext {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return {};
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected loadSidebar(config: ExtensionConfig): Array<SidebarTabRef> {
|
||||||
|
if (config && config.features) {
|
||||||
|
return (config.features.sidebar || [])
|
||||||
|
.filter(entry => !entry.disabled)
|
||||||
|
.sort(this.sortByOrder);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadViewerOpenWith(config: ExtensionConfig): Array<ContentActionRef> {
|
protected loadViewerOpenWith(config: ExtensionConfig): Array<ContentActionRef> {
|
||||||
@@ -271,6 +291,10 @@ export class ExtensionService implements RuleContext {
|
|||||||
return this.navbar;
|
return this.navbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSidebarTabs(): Array<SidebarTabRef> {
|
||||||
|
return this.sidebar;
|
||||||
|
}
|
||||||
|
|
||||||
getComponentById(id: string): Type<{}> {
|
getComponentById(id: string): Type<{}> {
|
||||||
return this.components[id];
|
return this.components[id];
|
||||||
}
|
}
|
||||||
|
38
src/app/extensions/sidebar.extensions.ts
Normal file
38
src/app/extensions/sidebar.extensions.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - 2018 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 class SidebarTabRef {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
component: string;
|
||||||
|
|
||||||
|
icon?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
order?: number;
|
||||||
|
rules?: {
|
||||||
|
visible?: string;
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
}
|
@@ -4,7 +4,8 @@
|
|||||||
"$version": "1.0.0",
|
"$version": "1.0.0",
|
||||||
"$references": [
|
"$references": [
|
||||||
"plugin1.json",
|
"plugin1.json",
|
||||||
"plugin2.json"
|
"plugin2.json",
|
||||||
|
"dev.tools.json"
|
||||||
],
|
],
|
||||||
|
|
||||||
"rules": [
|
"rules": [
|
||||||
@@ -727,6 +728,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"sidebar": [
|
||||||
|
{
|
||||||
|
"id": "app.sidebar.properties",
|
||||||
|
"order": 100,
|
||||||
|
"title": "APP.INFO_DRAWER.TABS.PROPERTIES",
|
||||||
|
"component": "app.components.tabs.metadata"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.sidebar.comments",
|
||||||
|
"order": 200,
|
||||||
|
"title": "APP.INFO_DRAWER.TABS.COMMENTS",
|
||||||
|
"component": "app.components.tabs.comments"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.sidebar.versions",
|
||||||
|
"order": 300,
|
||||||
|
"disabled": true,
|
||||||
|
"title": "APP.INFO_DRAWER.TABS.VERSIONS",
|
||||||
|
"component": "app.components.tabs.versions"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
376
src/assets/extension.schema.json
Normal file
376
src/assets/extension.schema.json
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://github.com/Alfresco/alfresco-content-app/blob/development/extension.schema.json",
|
||||||
|
"title": "ACA Extension Schema",
|
||||||
|
"description": "Provides a validation schema for ACA extensions",
|
||||||
|
|
||||||
|
"definitions": {
|
||||||
|
"ruleRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "type"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique rule definition id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"description": "Rule evaluator type",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"description": "Rule evaluator parameters",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/ruleParameter" },
|
||||||
|
"minItems": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ruleParameter": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["type", "value"],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"description": "Rule parameter type",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"description": "Rule parameter value",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"description": "Parameters",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/ruleParameter" },
|
||||||
|
"minItems": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"routeRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "path", "component"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique route reference identifier.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"description": "Route path to register.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"component": {
|
||||||
|
"description": "Unique identifier for the Component to use with the route.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"layout": {
|
||||||
|
"description": "Unique identifier for the custom layout component to use.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"description": "List of the authentication guards to use with the route.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"minLength": 1,
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"description": "Custom data to pass to the activated route so that your components can access it",
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actionRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "type"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique action identifier",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"description": "Action type",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"description": "Action payload value (string or expression)",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contentActionRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique action identifier.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"description": "Element type",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["default", "button", "separator", "menu", "custom"]
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "Element title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"description": "Element description, used for the tooltips.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description-disabled": {
|
||||||
|
"description": "Description to use when element is in the disabled state.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"description": "Element order",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"description": "Element icon",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"description": "Toggles disabled state",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"component": {
|
||||||
|
"description": "Custom component id (requires type to be 'custom')",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"description": "Child entries for the container types.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"description": "Element actions",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"click": {
|
||||||
|
"description": "Action reference for the click handler",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"description": "Element rules",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"description": "Rule to evaluate the enabled state",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"visible": {
|
||||||
|
"description": "Rule to evaluate the visibility state",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"navBarLinkRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "icon", "title", "route"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique identifier",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"description": "Element icon",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "Element title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"description": "Route reference identifier",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"description": "Element description or tooltip",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"description": "Element order",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"description": "Toggles the disabled state",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"navBarGroupRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "items"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique identifier for the navigation group",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"description": "Navigation group items",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/navBarLinkRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"description": "Group order",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"description": "Toggles the disabled state",
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sidebarTabRef": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "component"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique identifier for the navigation group",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "Element title",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"component": {
|
||||||
|
"description": "Component id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"description": "Material icon name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"description": "Toggles disabled state",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"description": "Element order",
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"description": "Element rules",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"visible": {
|
||||||
|
"description": "Rule to evaluate the visibility state",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"type": "object",
|
||||||
|
"required": ["$name", "$version"],
|
||||||
|
"properties": {
|
||||||
|
"$name": {
|
||||||
|
"description": "Extension name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"$version": {
|
||||||
|
"description": "Extension version",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"$description": {
|
||||||
|
"description": "Brief description on what the extension does"
|
||||||
|
},
|
||||||
|
"$references": {
|
||||||
|
"description": "References to external files",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"minItems": 1,
|
||||||
|
"uniqueItems": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"description": "List of rule definitions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/ruleRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"routes": {
|
||||||
|
"description": "List of custom application routes",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/routeRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"description": "List of action definitions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/actionRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"description": "Application-specific features and extensions",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"create": {
|
||||||
|
"description": "The [New] menu component extensions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"viewer": {
|
||||||
|
"description": "Viewer component extensions",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"openWith": {
|
||||||
|
"description": "The [Open With] menu extensions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"description": "Content actions (toolbar, context menus, etc.)",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/contentActionRef" },
|
||||||
|
"minItems": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"navbar": {
|
||||||
|
"description": "Navigation bar extensions",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/navBarGroupRef" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"description": "Sidebar extensions",
|
||||||
|
"type": "array",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/assets/plugins/dev.tools.json
Normal file
36
src/assets/plugins/dev.tools.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../extension.schema.json",
|
||||||
|
"$version": "1.0.0",
|
||||||
|
"$name": "dev.tools",
|
||||||
|
"$description": "ACA dev tools",
|
||||||
|
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"id": "app.dev.tools",
|
||||||
|
"component": "app.dev.tools.component",
|
||||||
|
"path": "dev-tools",
|
||||||
|
"data": {
|
||||||
|
"configPath": "assets/app.extensions.json",
|
||||||
|
"pluginsPath": "assets/plugins",
|
||||||
|
"schemaUri": "../../extension.schema.json",
|
||||||
|
"schemaPath": "assets/extension.schema.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"navbar": [
|
||||||
|
{
|
||||||
|
"id": "app.navbar.dev.tools",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": "app.navbar.dev.tools.main",
|
||||||
|
"icon": "build",
|
||||||
|
"title": "dev tools",
|
||||||
|
"route": "app.dev.tools"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@@ -95,3 +95,38 @@ import 'zone.js/dist/zone'; // Included with Angular CLI.
|
|||||||
* Need to import at least one locale-data with intl.
|
* Need to import at least one locale-data with intl.
|
||||||
*/
|
*/
|
||||||
// import 'intl/locale-data/jsonp/en';
|
// import 'intl/locale-data/jsonp/en';
|
||||||
|
|
||||||
|
// workaround for https://github.com/Microsoft/monaco-editor/issues/790
|
||||||
|
|
||||||
|
Promise.all = function(values: any): Promise<any> {
|
||||||
|
let resolve: (v: any) => void;
|
||||||
|
let reject: (v: any) => void;
|
||||||
|
const promise = new this((res, rej) => {
|
||||||
|
resolve = res;
|
||||||
|
reject = rej;
|
||||||
|
});
|
||||||
|
let count = 0;
|
||||||
|
let index = 0;
|
||||||
|
const resolvedValues: any[] = [];
|
||||||
|
for (let value of values) {
|
||||||
|
if (!(value && value.then)) {
|
||||||
|
value = this.resolve(value);
|
||||||
|
}
|
||||||
|
value.then(
|
||||||
|
(idx => (val: any) => {
|
||||||
|
resolvedValues[idx] = val;
|
||||||
|
count--;
|
||||||
|
if (!count) {
|
||||||
|
resolve(resolvedValues);
|
||||||
|
}
|
||||||
|
})(index),
|
||||||
|
reject
|
||||||
|
);
|
||||||
|
count++;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (!count) {
|
||||||
|
resolve(resolvedValues);
|
||||||
|
}
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
@@ -2,9 +2,7 @@
|
|||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../out-tsc/app",
|
"outDir": "../out-tsc/app",
|
||||||
"baseUrl": "./",
|
|
||||||
"module": "es2015",
|
|
||||||
"types": []
|
"types": []
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "test.ts", "**/*.spec.ts"]
|
"exclude": ["test.ts", "**/*.spec.ts"]
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,6 @@
|
|||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../out-tsc/spec",
|
"outDir": "../out-tsc/spec",
|
||||||
"baseUrl": "./",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": ["jasmine", "node"]
|
"types": ["jasmine", "node"]
|
||||||
},
|
},
|
||||||
"files": ["test.ts", "polyfills.ts"],
|
"files": ["test.ts", "polyfills.ts"],
|
||||||
|
@@ -17,7 +17,15 @@
|
|||||||
"dom"
|
"dom"
|
||||||
],
|
],
|
||||||
"module": "es2015",
|
"module": "es2015",
|
||||||
"baseUrl": "./"
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"aca-dev-tools": [
|
||||||
|
"dist/aca-dev-tools"
|
||||||
|
],
|
||||||
|
"aca-dev-tools/*": [
|
||||||
|
"dist/aca-dev-tools/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules"
|
"node_modules"
|
||||||
|
Reference in New Issue
Block a user