support rule negation (#541)

This commit is contained in:
Denys Vuika
2018-08-01 12:06:20 +01:00
committed by GitHub
parent ae8675dfd7
commit a419726cf2
3 changed files with 18 additions and 7 deletions

View File

@@ -32,7 +32,7 @@ export function not(context: RuleContext, ...args: RuleParameter[]): boolean {
return args return args
.every(arg => { .every(arg => {
const evaluator = context.evaluators[arg.value]; const evaluator = context.getEvaluator(arg.value);
if (!evaluator) { if (!evaluator) {
console.warn('evaluator not found: ' + arg.value); console.warn('evaluator not found: ' + arg.value);
} }
@@ -47,7 +47,7 @@ export function every(context: RuleContext, ...args: RuleParameter[]): boolean {
return args return args
.every(arg => { .every(arg => {
const evaluator = context.evaluators[arg.value]; const evaluator = context.getEvaluator(arg.value);
if (!evaluator) { if (!evaluator) {
console.warn('evaluator not found: ' + arg.value); console.warn('evaluator not found: ' + arg.value);
} }
@@ -62,7 +62,7 @@ export function some(context: RuleContext, ...args: RuleParameter[]): boolean {
return args return args
.some(arg => { .some(arg => {
const evaluator = context.evaluators[arg.value]; const evaluator = context.getEvaluator(arg.value);
if (!evaluator) { if (!evaluator) {
console.warn('evaluator not found: ' + arg.value); console.warn('evaluator not found: ' + arg.value);
} }

View File

@@ -33,7 +33,7 @@ import { NavigationState } from '../store/states/navigation.state';
import { selectionWithFolder } from '../store/selectors/app.selectors'; import { selectionWithFolder } from '../store/selectors/app.selectors';
import { NavBarGroupRef } from './navbar.extensions'; import { NavBarGroupRef } from './navbar.extensions';
import { RouteRef } from './routing.extensions'; import { RouteRef } from './routing.extensions';
import { RuleContext, RuleRef, RuleEvaluator } from './rule.extensions'; import { RuleContext, RuleRef, RuleEvaluator, RuleParameter } from './rule.extensions';
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';
@@ -440,16 +440,26 @@ export class ExtensionService implements RuleContext {
return value; return value;
} }
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];
}
evaluateRule(ruleId: string): boolean { evaluateRule(ruleId: string): boolean {
const ruleRef = this.rules.find(ref => ref.id === ruleId); const ruleRef = this.rules.find(ref => ref.id === ruleId);
if (ruleRef) { if (ruleRef) {
const evaluator = this.evaluators[ruleRef.type]; const evaluator = this.getEvaluator(ruleRef.type);
if (evaluator) { if (evaluator) {
return evaluator(this, ...ruleRef.parameters); return evaluator(this, ...ruleRef.parameters);
} }
} else { } else {
const evaluator = this.evaluators[ruleId]; const evaluator = this.getEvaluator(ruleId);
if (evaluator) { if (evaluator) {
return evaluator(this); return evaluator(this);
} }

View File

@@ -32,8 +32,9 @@ export type RuleEvaluator = (context: RuleContext, ...args: any[]) => boolean;
export interface RuleContext { export interface RuleContext {
selection: SelectionState; selection: SelectionState;
navigation: NavigationState; navigation: NavigationState;
evaluators: { [key: string]: RuleEvaluator };
permissions: NodePermissions; permissions: NodePermissions;
getEvaluator(key: string): RuleEvaluator;
} }
export class RuleRef { export class RuleRef {