mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACA-1597] allow extensions overwrite existing settings (#523)
* merge objects within the arrays * metadata properties * code cleanup
This commit is contained in:
parent
8c9ffc1160
commit
3ab9cee163
@ -214,20 +214,20 @@
|
||||
},
|
||||
|
||||
"type": "object",
|
||||
"required": ["name", "version"],
|
||||
"required": ["$name", "$version"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$name": {
|
||||
"description": "Extension name",
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"$version": {
|
||||
"description": "Extension version",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"$description": {
|
||||
"description": "Brief description on what the extension does"
|
||||
},
|
||||
"references": {
|
||||
"$references": {
|
||||
"description": "References to external files",
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -29,8 +29,10 @@ import { RuleRef } from './rule.extensions';
|
||||
import { ActionRef, ContentActionRef } from './action.extensions';
|
||||
|
||||
export interface ExtensionConfig {
|
||||
version: string;
|
||||
references?: Array<string>;
|
||||
$name: string;
|
||||
$version: string;
|
||||
$description?: string;
|
||||
$references?: Array<string>;
|
||||
rules?: Array<RuleRef>;
|
||||
routes?: Array<RouteRef>;
|
||||
actions?: Array<ActionRef>;
|
||||
|
@ -43,10 +43,59 @@ describe('ExtensionService', () => {
|
||||
extensions = TestBed.get(ExtensionService);
|
||||
});
|
||||
|
||||
describe('configs', () => {
|
||||
it('should merge two arrays based on [id] keys', () => {
|
||||
const left = [
|
||||
{
|
||||
name: 'item0'
|
||||
},
|
||||
{
|
||||
id: '#1',
|
||||
name: 'item1'
|
||||
},
|
||||
{
|
||||
id: '#2',
|
||||
name: 'item2'
|
||||
}
|
||||
];
|
||||
|
||||
const right = [
|
||||
{
|
||||
name: 'extra-1'
|
||||
},
|
||||
{
|
||||
id: '#2',
|
||||
name: 'custom2',
|
||||
tag: 'extra tag'
|
||||
}
|
||||
];
|
||||
|
||||
const result = extensions.mergeArrays(left, right);
|
||||
expect(result).toEqual([
|
||||
{
|
||||
id: '#1',
|
||||
name: 'item1'
|
||||
},
|
||||
{
|
||||
id: '#2',
|
||||
name: 'custom2',
|
||||
tag: 'extra tag'
|
||||
},
|
||||
{
|
||||
name: 'item0'
|
||||
},
|
||||
{
|
||||
name: 'extra-1'
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('actions', () => {
|
||||
beforeEach(() => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
actions: [
|
||||
{
|
||||
id: 'aca:actions/create-folder',
|
||||
@ -179,7 +228,8 @@ describe('ExtensionService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
routes: [
|
||||
{
|
||||
id: 'aca:routes/about',
|
||||
@ -237,7 +287,8 @@ describe('ExtensionService', () => {
|
||||
describe('content actions', () => {
|
||||
it('should load content actions from the config', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
content: {
|
||||
actions: [
|
||||
@ -263,7 +314,8 @@ describe('ExtensionService', () => {
|
||||
|
||||
it('should sort content actions by order', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
content: {
|
||||
actions: [
|
||||
@ -297,7 +349,8 @@ describe('ExtensionService', () => {
|
||||
describe('open with', () => {
|
||||
it('should load [open with] actions for the viewer', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
viewer: {
|
||||
openWith: [
|
||||
@ -322,7 +375,8 @@ describe('ExtensionService', () => {
|
||||
|
||||
it('should load only enabled [open with] actions for the viewer', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
viewer: {
|
||||
openWith: [
|
||||
@ -358,7 +412,8 @@ describe('ExtensionService', () => {
|
||||
|
||||
it('should sort [open with] actions by order', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
viewer: {
|
||||
openWith: [
|
||||
@ -396,7 +451,8 @@ describe('ExtensionService', () => {
|
||||
describe('create', () => {
|
||||
it('should load [create] actions from config', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
create: [
|
||||
{
|
||||
@ -415,7 +471,8 @@ describe('ExtensionService', () => {
|
||||
|
||||
it('should sort [create] actions by order', () => {
|
||||
extensions.setup({
|
||||
version: '1.0.0',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
features: {
|
||||
create: [
|
||||
{
|
||||
|
@ -74,8 +74,8 @@ export class ExtensionService implements RuleContext {
|
||||
this.loadConfig(this.configPath, 0).then(result => {
|
||||
let config = result.config;
|
||||
|
||||
if (config.references && config.references.length > 0) {
|
||||
const plugins = config.references.map(
|
||||
if (config.$references && config.$references.length > 0) {
|
||||
const plugins = config.$references.map(
|
||||
(name, idx) => this.loadConfig(`${this.pluginsPath}/${name}`, idx)
|
||||
);
|
||||
|
||||
@ -86,7 +86,7 @@ export class ExtensionService implements RuleContext {
|
||||
.map(entry => entry.config);
|
||||
|
||||
if (configs.length > 0) {
|
||||
config = this.mergeConfigs(config, ...configs);
|
||||
config = this.mergeObjects(config, ...configs);
|
||||
}
|
||||
|
||||
this.setup(config);
|
||||
@ -411,23 +411,50 @@ export class ExtensionService implements RuleContext {
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: requires overwrite support for array entries
|
||||
// todo: overwrite only particular areas, don't touch version or other top-level props
|
||||
protected mergeConfigs(...objects): any {
|
||||
mergeObjects(...objects): any {
|
||||
const result = {};
|
||||
|
||||
objects.forEach(source => {
|
||||
Object.keys(source).forEach(prop => {
|
||||
if (!prop.startsWith('$')) {
|
||||
if (prop in result && Array.isArray(result[prop])) {
|
||||
result[prop] = result[prop].concat(source[prop]);
|
||||
// result[prop] = result[prop].concat(source[prop]);
|
||||
result[prop] = this.mergeArrays(result[prop], source[prop]);
|
||||
} else if (prop in result && typeof result[prop] === 'object') {
|
||||
result[prop] = this.mergeConfigs(result[prop], source[prop]);
|
||||
result[prop] = this.mergeObjects(result[prop], source[prop]);
|
||||
} else {
|
||||
result[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
mergeArrays(left: any[], right: any[]): any[] {
|
||||
const result = [];
|
||||
const map = {};
|
||||
|
||||
(left || []).forEach(entry => {
|
||||
const element = entry;
|
||||
if (element && element.hasOwnProperty('id')) {
|
||||
map[element.id] = element;
|
||||
} else {
|
||||
result.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
(right || []).forEach(entry => {
|
||||
const element = entry;
|
||||
if (element && element.hasOwnProperty('id') && map[element.id]) {
|
||||
const merged = this.mergeObjects(map[element.id], element);
|
||||
map[element.id] = merged;
|
||||
} else {
|
||||
result.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
return Object.values(map).concat(result);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
{
|
||||
"$schema": "../../extension.schema.json",
|
||||
"name": "app",
|
||||
"version": "1.0.0",
|
||||
|
||||
"references": [
|
||||
"$name": "app",
|
||||
"$version": "1.0.0",
|
||||
"$references": [
|
||||
"plugin1.json",
|
||||
"plugin2.json"
|
||||
],
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"version": "1.0.0",
|
||||
"name": "plugin1",
|
||||
"description": "demo plugin",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin1",
|
||||
"$description": "demo plugin",
|
||||
|
||||
"actions": [
|
||||
{
|
||||
@ -36,6 +36,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"navbar": [
|
||||
{
|
||||
"id": "app.navbar.primary",
|
||||
"items": [
|
||||
{
|
||||
"id": "app.navbar.personalFiles",
|
||||
"icon": "extension",
|
||||
"title": "APP.BROWSE.PERSONAL.SIDENAV_LINK.LABEL",
|
||||
"route": "personal-files"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"content": {
|
||||
"actions": [
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"$schema": "../../../extension.schema.json",
|
||||
"version": "1.0.0",
|
||||
"name": "plugin2",
|
||||
"description": "demo plugin",
|
||||
"$version": "1.0.0",
|
||||
"$name": "plugin2",
|
||||
"$description": "demo plugin",
|
||||
|
||||
"routes": [
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user