mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
extensibility improvements (#4484)
* add missing interfaces to extensions library * separate rule service * api enhancements * fix test * improve APIs
This commit is contained in:
committed by
Eugenio Romano
parent
80aaaef65d
commit
26c5982a1a
@@ -1,9 +1,15 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../../lib/extensions/config/schema/app-extension.schema.json",
|
"$schema": "../../../lib/extensions/src/lib/config/schema/app-extension.schema.json",
|
||||||
"$references": [
|
"$references": [
|
||||||
"plugin1.json",
|
"plugin1.json",
|
||||||
"plugin2.json",
|
"plugin2.json",
|
||||||
"monaco-extension.json"
|
"monaco-extension.json"
|
||||||
],
|
],
|
||||||
"$dependencies": []
|
"$dependencies": [],
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"viewer": {
|
||||||
|
"content": []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -196,7 +196,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'custom'">
|
<ng-container *ngSwitchCase="'custom'">
|
||||||
<ng-container *ngFor="let ext of viewerExtensions">
|
<ng-container *ngFor="let ext of viewerExtensions">
|
||||||
<adf-preview-extension
|
<adf-preview-extension
|
||||||
*ngIf="checkExtensions(ext.fileExtension)"
|
*ngIf="checkExtensions(ext.fileExtension)"
|
||||||
[id]="ext.component"
|
[id]="ext.component"
|
||||||
@@ -208,9 +208,10 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<span class="adf-viewer-custom-content" *ngFor="let extensionTemplate of extensionTemplates">
|
<span class="adf-viewer-custom-content" *ngFor="let extensionTemplate of extensionTemplates">
|
||||||
<ng-template *ngIf="extensionTemplate.isVisible"
|
<ng-template
|
||||||
[ngTemplateOutlet]="extensionTemplate.template"
|
*ngIf="extensionTemplate.isVisible"
|
||||||
[ngTemplateOutletContext]="{ urlFileContent: urlFileContent, extension:extension }">
|
[ngTemplateOutlet]="extensionTemplate.template"
|
||||||
|
[ngTemplateOutletContext]="{ urlFileContent: urlFileContent, extension:extension }">
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</span>
|
</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -31,7 +31,7 @@ import { ViewerSidebarComponent } from './viewer-sidebar.component';
|
|||||||
import { ViewerToolbarComponent } from './viewer-toolbar.component';
|
import { ViewerToolbarComponent } from './viewer-toolbar.component';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { ViewUtilService } from '../services/view-util.service';
|
import { ViewUtilService } from '../services/view-util.service';
|
||||||
import { ExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
import { AppExtensionService, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-viewer',
|
selector: 'adf-viewer',
|
||||||
@@ -238,7 +238,7 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
private viewUtils: ViewUtilService,
|
private viewUtils: ViewUtilService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private location: Location,
|
private location: Location,
|
||||||
private extensionService: ExtensionService,
|
private extensionService: AppExtensionService,
|
||||||
private el: ElementRef) {
|
private el: ElementRef) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,14 +251,15 @@ export class ViewerComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
this.apiService.nodeUpdated.subscribe((node) => this.onNodeUpdated(node))
|
this.apiService.nodeUpdated.subscribe((node) => this.onNodeUpdated(node))
|
||||||
);
|
);
|
||||||
|
|
||||||
this.extensionLoad();
|
this.loadExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private extensionLoad() {
|
private loadExtensions() {
|
||||||
this.viewerExtensions = this.extensionService.getFeature('viewer.content');
|
this.viewerExtensions = this.extensionService.getViewerExtensions();
|
||||||
this.viewerExtensions.forEach((currentViewerExtension: ViewerExtensionRef) => {
|
this.viewerExtensions
|
||||||
this.externalExtensions.push(currentViewerExtension.fileExtension);
|
.forEach((extension: ViewerExtensionRef) => {
|
||||||
});
|
this.externalExtensions.push(extension.fileExtension);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
29
lib/extensions/src/lib/config/document-list.extensions.ts
Normal file
29
lib/extensions/src/lib/config/document-list.extensions.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ExtensionElement } from './extension-element';
|
||||||
|
|
||||||
|
export interface DocumentListPresetRef extends ExtensionElement {
|
||||||
|
key: string;
|
||||||
|
type: string; // text|image|date
|
||||||
|
title?: string;
|
||||||
|
format?: string;
|
||||||
|
class?: string;
|
||||||
|
sortable: boolean;
|
||||||
|
template: string;
|
||||||
|
desktopOnly: boolean;
|
||||||
|
}
|
22
lib/extensions/src/lib/config/icon.extensions.ts
Normal file
22
lib/extensions/src/lib/config/icon.extensions.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ExtensionElement } from './extension-element';
|
||||||
|
|
||||||
|
export interface IconRef extends ExtensionElement {
|
||||||
|
value: string;
|
||||||
|
}
|
@@ -19,10 +19,13 @@ import { SelectionState } from '../store/states/selection.state';
|
|||||||
import { NavigationState } from '../store/states/navigation.state';
|
import { NavigationState } from '../store/states/navigation.state';
|
||||||
import { NodePermissions } from './permission.extensions';
|
import { NodePermissions } from './permission.extensions';
|
||||||
import { ProfileState } from '../store/states/profile.state';
|
import { ProfileState } from '../store/states/profile.state';
|
||||||
|
import { RepositoryInfo } from '@alfresco/js-api';
|
||||||
|
|
||||||
export type RuleEvaluator = (context: RuleContext, ...args: any[]) => boolean;
|
export type RuleEvaluator = (context: RuleContext, ...args: any[]) => boolean;
|
||||||
|
|
||||||
export interface RuleContext {
|
export interface RuleContext {
|
||||||
|
repository: RepositoryInfo;
|
||||||
|
auth: any;
|
||||||
selection: SelectionState;
|
selection: SelectionState;
|
||||||
navigation: NavigationState;
|
navigation: NavigationState;
|
||||||
profile: ProfileState;
|
profile: ProfileState;
|
||||||
|
@@ -20,4 +20,9 @@ import { ExtensionElement } from './extension-element';
|
|||||||
export interface ViewerExtensionRef extends ExtensionElement {
|
export interface ViewerExtensionRef extends ExtensionElement {
|
||||||
fileExtension: string;
|
fileExtension: string;
|
||||||
component: string;
|
component: string;
|
||||||
|
|
||||||
|
rules?: {
|
||||||
|
visible?: string;
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { ExtensionConfig, ExtensionRef } from '../config/extension.config';
|
import { ExtensionConfig, ExtensionRef } from '../config/extension.config';
|
||||||
import { ExtensionService } from '../services/extension.service';
|
import { ExtensionService } from '../services/extension.service';
|
||||||
import { Observable, BehaviorSubject } from 'rxjs';
|
import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
|
import { ViewerExtensionRef } from '../config/viewer.extensions';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -47,4 +48,28 @@ export class AppExtensionService {
|
|||||||
.map((entry) => <ExtensionRef> entry);
|
.map((entry) => <ExtensionRef> entry);
|
||||||
this._references.next(references);
|
this._references.next(references);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of the Viewer content extensions,
|
||||||
|
* filtered by disabled state and rules.
|
||||||
|
*/
|
||||||
|
getViewerExtensions(): ViewerExtensionRef[] {
|
||||||
|
return this.extensionService
|
||||||
|
.getElements<ViewerExtensionRef>('features.viewer.content')
|
||||||
|
.filter((extension) => !this.isViewerExtensionDisabled(extension));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isViewerExtensionDisabled(extension: ViewerExtensionRef): boolean {
|
||||||
|
if (extension) {
|
||||||
|
if (extension.disabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extension.rules && extension.rules.disabled) {
|
||||||
|
return this.extensionService.evaluateRule(extension.rules.disabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -105,6 +105,12 @@ export class ExtensionLoaderService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves configuration elements.
|
||||||
|
* Filters element by **enabled** and **order** attributes.
|
||||||
|
* Example:
|
||||||
|
* `getElements<ViewerExtensionRef>(config, 'features.viewer.content')`
|
||||||
|
*/
|
||||||
getElements<T extends ExtensionElement>(
|
getElements<T extends ExtensionElement>(
|
||||||
config: ExtensionConfig,
|
config: ExtensionConfig,
|
||||||
key: string,
|
key: string,
|
||||||
|
@@ -22,6 +22,7 @@ import { RuleRef } from '../config/rule.extensions';
|
|||||||
import { RouteRef } from '../config/routing.extensions';
|
import { RouteRef } from '../config/routing.extensions';
|
||||||
import { ActionRef } from '../config/action.extensions';
|
import { ActionRef } from '../config/action.extensions';
|
||||||
import { ComponentRegisterService } from './component-register.service';
|
import { ComponentRegisterService } from './component-register.service';
|
||||||
|
import { RuleService } from './rule.service';
|
||||||
|
|
||||||
describe('ExtensionService', () => {
|
describe('ExtensionService', () => {
|
||||||
const blankConfig: ExtensionConfig = {
|
const blankConfig: ExtensionConfig = {
|
||||||
@@ -36,11 +37,13 @@ describe('ExtensionService', () => {
|
|||||||
let loader: ExtensionLoaderService;
|
let loader: ExtensionLoaderService;
|
||||||
let componentRegister: ComponentRegisterService;
|
let componentRegister: ComponentRegisterService;
|
||||||
let service: ExtensionService;
|
let service: ExtensionService;
|
||||||
|
let ruleService: RuleService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
loader = new ExtensionLoaderService(null);
|
loader = new ExtensionLoaderService(null);
|
||||||
componentRegister = new ComponentRegisterService();
|
componentRegister = new ComponentRegisterService();
|
||||||
service = new ExtensionService(loader, componentRegister);
|
ruleService = new RuleService(loader);
|
||||||
|
service = new ExtensionService(loader, componentRegister, ruleService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should load and setup a config', async () => {
|
it('should load and setup a config', async () => {
|
||||||
|
@@ -16,32 +16,35 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable, Type } from '@angular/core';
|
import { Injectable, Type } from '@angular/core';
|
||||||
import { RuleEvaluator, RuleRef, RuleContext, RuleParameter } from '../config/rule.extensions';
|
import { RuleEvaluator, RuleRef, RuleContext } from '../config/rule.extensions';
|
||||||
import { ExtensionConfig } from '../config/extension.config';
|
import { ExtensionConfig } from '../config/extension.config';
|
||||||
import { ExtensionLoaderService } from './extension-loader.service';
|
import { ExtensionLoaderService } from './extension-loader.service';
|
||||||
import { RouteRef } from '../config/routing.extensions';
|
import { RouteRef } from '../config/routing.extensions';
|
||||||
import { ActionRef } from '../config/action.extensions';
|
import { ActionRef } from '../config/action.extensions';
|
||||||
import * as core from '../evaluators/core.evaluators';
|
import * as core from '../evaluators/core.evaluators';
|
||||||
import { ComponentRegisterService } from './component-register.service';
|
import { ComponentRegisterService } from './component-register.service';
|
||||||
|
import { RuleService } from './rule.service';
|
||||||
|
import { ExtensionElement } from '../config/extension-element';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ExtensionService {
|
export class ExtensionService {
|
||||||
|
|
||||||
|
protected config: ExtensionConfig = null;
|
||||||
|
|
||||||
configPath = 'assets/app.extensions.json';
|
configPath = 'assets/app.extensions.json';
|
||||||
pluginsPath = 'assets/plugins';
|
pluginsPath = 'assets/plugins';
|
||||||
|
|
||||||
rules: Array<RuleRef> = [];
|
|
||||||
routes: Array<RouteRef> = [];
|
routes: Array<RouteRef> = [];
|
||||||
actions: Array<ActionRef> = [];
|
actions: Array<ActionRef> = [];
|
||||||
features: Array<any> = [];
|
features: Array<any> = [];
|
||||||
|
|
||||||
authGuards: { [key: string]: Type<{}> } = {};
|
authGuards: { [key: string]: Type<{}> } = {};
|
||||||
evaluators: { [key: string]: RuleEvaluator } = {};
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private loader: ExtensionLoaderService,
|
protected loader: ExtensionLoaderService,
|
||||||
private componentRegister: ComponentRegisterService
|
protected componentRegister: ComponentRegisterService,
|
||||||
|
protected ruleService: RuleService
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,16 +71,19 @@ export class ExtensionService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
this.setEvaluators({
|
this.setEvaluators({
|
||||||
'core.every': core.every,
|
'core.every': core.every,
|
||||||
'core.some': core.some,
|
'core.some': core.some,
|
||||||
'core.not': core.not
|
'core.not': core.not
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rules = this.loader.getRules(config);
|
|
||||||
this.actions = this.loader.getActions(config);
|
this.actions = this.loader.getActions(config);
|
||||||
this.routes = this.loader.getRoutes(config);
|
this.routes = this.loader.getRoutes(config);
|
||||||
this.features = this.loader.getFeatures(config);
|
this.features = this.loader.getFeatures(config);
|
||||||
|
|
||||||
|
this.ruleService.setup(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,14 +96,16 @@ export class ExtensionService {
|
|||||||
return properties.reduce((prev, curr) => prev && prev[curr], this.features) || [];
|
return properties.reduce((prev, curr) => prev && prev[curr], this.features) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getElements<T extends ExtensionElement>(key: string, fallback: Array<T> = []): Array<T> {
|
||||||
|
return this.loader.getElements(this.config, key, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds one or more new rule evaluators to the existing set.
|
* Adds one or more new rule evaluators to the existing set.
|
||||||
* @param values The new evaluators to add
|
* @param values The new evaluators to add
|
||||||
*/
|
*/
|
||||||
setEvaluators(values: { [key: string]: RuleEvaluator }) {
|
setEvaluators(values: { [key: string]: RuleEvaluator }) {
|
||||||
if (values) {
|
this.ruleService.setEvaluators(values);
|
||||||
this.evaluators = Object.assign({}, this.evaluators, values);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,36 +161,17 @@ export class ExtensionService {
|
|||||||
* @returns RuleEvaluator or null if not found
|
* @returns RuleEvaluator or null if not found
|
||||||
*/
|
*/
|
||||||
getEvaluator(key: string): RuleEvaluator {
|
getEvaluator(key: string): RuleEvaluator {
|
||||||
if (key && key.startsWith('!')) {
|
return this.ruleService.getEvaluator(key);
|
||||||
const fn = this.evaluators[key.substring(1)];
|
|
||||||
return (context: RuleContext, ...args: RuleParameter[]): boolean => {
|
|
||||||
return !fn(context, ...args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return this.evaluators[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates a rule.
|
* Evaluates a rule.
|
||||||
* @param ruleId ID of the rule to evaluate
|
* @param ruleId ID of the rule to evaluate
|
||||||
* @param context Parameter object for the evaluator with details of app state
|
* @param context (optional) Custom rule execution context.
|
||||||
* @returns True if the rule passed, false otherwise
|
* @returns True if the rule passed, false otherwise
|
||||||
*/
|
*/
|
||||||
evaluateRule(ruleId: string, context: RuleContext): boolean {
|
evaluateRule(ruleId: string, context?: RuleContext): boolean {
|
||||||
const ruleRef = this.getRuleById(ruleId);
|
return this.ruleService.evaluateRule(ruleId, context);
|
||||||
|
|
||||||
if (ruleRef) {
|
|
||||||
const evaluator = this.getEvaluator(ruleRef.type);
|
|
||||||
if (evaluator) {
|
|
||||||
return evaluator(context, ...ruleRef.parameters);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const evaluator = this.getEvaluator(ruleId);
|
|
||||||
if (evaluator) {
|
|
||||||
return evaluator(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,7 +189,7 @@ export class ExtensionService {
|
|||||||
* @returns The rule or null if not found
|
* @returns The rule or null if not found
|
||||||
*/
|
*/
|
||||||
getRuleById(id: string): RuleRef {
|
getRuleById(id: string): RuleRef {
|
||||||
return this.rules.find((ref) => ref.id === id);
|
return this.ruleService.getRuleById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
94
lib/extensions/src/lib/services/rule.service.ts
Normal file
94
lib/extensions/src/lib/services/rule.service.ts
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { RuleRef, RuleContext, RuleEvaluator, RuleParameter } from '../config/rule.extensions';
|
||||||
|
import { ExtensionConfig } from '../config/extension.config';
|
||||||
|
import { ExtensionLoaderService } from './extension-loader.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class RuleService {
|
||||||
|
context: RuleContext = null;
|
||||||
|
rules: Array<RuleRef> = [];
|
||||||
|
evaluators: { [key: string]: RuleEvaluator } = {};
|
||||||
|
|
||||||
|
constructor(protected loader: ExtensionLoaderService) {}
|
||||||
|
|
||||||
|
setup(config: ExtensionConfig) {
|
||||||
|
this.rules = this.loader.getRules(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds one or more new rule evaluators to the existing set.
|
||||||
|
* @param values The new evaluators to add
|
||||||
|
*/
|
||||||
|
setEvaluators(values: { [key: string]: RuleEvaluator }) {
|
||||||
|
if (values) {
|
||||||
|
this.evaluators = Object.assign({}, this.evaluators, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a rule using its ID value.
|
||||||
|
* @param id The ID value to look for
|
||||||
|
* @returns The rule or null if not found
|
||||||
|
*/
|
||||||
|
getRuleById(id: string): RuleRef {
|
||||||
|
return this.rules.find((ref) => ref.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a RuleEvaluator function using its key name.
|
||||||
|
* @param key Key name to look for
|
||||||
|
* @returns RuleEvaluator or null if not found
|
||||||
|
*/
|
||||||
|
getEvaluator(key: string): RuleEvaluator {
|
||||||
|
if (key && key.startsWith('!')) {
|
||||||
|
const fn = this.evaluators[key.substring(1)];
|
||||||
|
return (context: RuleContext, ...args: RuleParameter[]): boolean => {
|
||||||
|
return !fn(context, ...args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return this.evaluators[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates a rule.
|
||||||
|
* @param ruleId ID of the rule to evaluate
|
||||||
|
* @param context (optional) Custom rule execution context.
|
||||||
|
* @returns True if the rule passed, false otherwise
|
||||||
|
*/
|
||||||
|
evaluateRule(ruleId: string, context?: RuleContext): boolean {
|
||||||
|
const ruleRef = this.getRuleById(ruleId);
|
||||||
|
context = context || this.context;
|
||||||
|
|
||||||
|
if (ruleRef) {
|
||||||
|
const evaluator = this.getEvaluator(ruleRef.type);
|
||||||
|
if (evaluator) {
|
||||||
|
return evaluator(context, ...ruleRef.parameters);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const evaluator = this.getEvaluator(ruleId);
|
||||||
|
if (evaluator) {
|
||||||
|
return evaluator(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -18,9 +18,11 @@
|
|||||||
export * from './lib/extensions.module';
|
export * from './lib/extensions.module';
|
||||||
|
|
||||||
export * from './lib/config/action.extensions';
|
export * from './lib/config/action.extensions';
|
||||||
|
export * from './lib/config/document-list.extensions';
|
||||||
export * from './lib/config/extension-element';
|
export * from './lib/config/extension-element';
|
||||||
export * from './lib/config/extension-utils';
|
export * from './lib/config/extension-utils';
|
||||||
export * from './lib/config/extension.config';
|
export * from './lib/config/extension.config';
|
||||||
|
export * from './lib/config/icon.extensions';
|
||||||
export * from './lib/config/navbar.extensions';
|
export * from './lib/config/navbar.extensions';
|
||||||
export * from './lib/config/permission.extensions';
|
export * from './lib/config/permission.extensions';
|
||||||
export * from './lib/config/routing.extensions';
|
export * from './lib/config/routing.extensions';
|
||||||
|
Reference in New Issue
Block a user