Conditions¶
Deprecated
The condition registry described on this page is deprecated in favour of a newer rule primitive API. Conditions still work, through a compatibility layer, but new code should not be written against them.
In the newer model a rule declares which pieces of context it needs — a record, a value — and then builds a check over them, rather than receiving a subject and parameters. Such a rule is a RulePrimitive, created with definePrimitive and registered with the platform's RuleRegistry service, all from @limetech/lime-web-components. Full documentation for it is not yet available.
Conditions are reusable objects registrable to the condition registry, which act as wrappers for evaluation functions callable from within any web component in the CRM. Every condition is specified by
- A string-based type, describing what object we are evaluating (e.g., "limeobject"), useful for type hinting
- An evaluation function, a function as explained below
- A string-based id, a unique identifier for this condition
In turn, evaluation functions are callback functions returning a boolean value. That is, they return either true or false. This may seem trivial, but evaluation functions are the perfect tool for when we want to achieve reusable "if this holds, then perform this action"-kind-of behaviour.
Every evaluation function requires as input
- A subject, which encodes an object—such as a limeobject or a string—related to the type of the condition
- Parameters, describing additional data besides the subject that the evaluation function expects to construct an output
Examples¶
Because of their generality, conditions can be quite difficult to grasp when presented in this abstract form. It helps to look at a concrete examples to better understand conditions.
There exist hard-coded conditions needed for the CRM to work that are registered in the loader on every page refresh.
Limeobject-matches-filter¶
In a typical solution, you can expect a number of conditions to be evaluated when a card is opened, to determine the visibility of sections, fields and actions. The boolean output of the corresponding evaluation functions simply specifies whether the item should be visible or not. How a condition is exposed to configurators, and how it is combined with others, is covered in Rules.
A condition performing this function is the condition with ID limeobject-matches-filter, whose evaluation function returns true if and only if a limeobject matches a given filter expression. It is surfaced in the rule builder as Record matches filter, and the expressions it accepts are documented in Built-in Rules.
The code for this condition is as follows:
const limeObjectMatchesFilter: Condition<Action> = {
id: "limeobject-matches-filter",
type: "action",
evaluate: (subject: Action, params: Expression): boolean => {
const limeobject = (subject.command as any).limeobject;
const filter = params as Expression;
return matchFilter(filter, limeobject); // (1)!
},
};
-
- This is a call to a function internal to the crm-components repository
Is-past-8¶
A more contrived example illustrating parameterless evaluation functions is one that checks if it is past 8 o'clock according to the system's local time zone.
const isPastEight: Condition = {
id: 'is-past-8',
type: 'action',
evaluate: (): boolean => {
return date.getHours() >= 8; // (1)!
},
};
-
- Note that if equal to
8, then the additional seconds still imply it is past8
- Note that if equal to
Note
At present (October 2023), evaluation functions do not support asynchronous function calls. This implies that we offer no means of communicating with an external API, internal endpoint or database from within an evaluation function.
Registering Your Own Condition in a Plugin¶
If you were to register a condition yourself—let's call it myCondition—you would want to add it to your package in the loader using code similar to the below snippet
import {
ConditionRegistry,
LimePluginLoader,
LimeWebComponentContext,
LimeWebComponentPlatform,
PlatformServiceName,
} from '@limetech/lime-web-components';
import { Component, Prop } from '@stencil/core';
import { myCondition } from '../my-condition';
@Component({
tag: 'lwc-limepkg-my-plugin-loader',
shadow: true,
})
export class Loader implements LimePluginLoader {
/**
* @inheritdoc
*/
@Prop()
public platform: LimeWebComponentPlatform;
/**
* @inheritdoc
*/
@Prop()
public context: LimeWebComponentContext;
...
public componentWillLoad() {
...
this.registerConditions();
...
}
...
private registerConditions() {
this.conditions.addCondition(myCondition);
}
...
private get conditions(): ConditionRegistry {
return this.platform.get(PlatformServiceName.ConditionRegistry);
}
}
Type Guarding¶
At present, we have two preexisting types defined according to
type LimeObjectCondition = Condition<LimeObject> & {
type: "limeobject";
};
type ActionCondition = Condition<Action> & {
type: "action";
};
As well as associated helper functions
function isLimeObjectCondition(
condition: Condition
): condition is Condition<LimeObject> {
return condition.type === "limeobject";
}
function isActionCondition(
condition: Condition
): condition is Condition<Action> {
return condition.type === "action";
}
These helpers give you the benefit of static type checking. They can be imported from @limetech/lime-web-components. You can follow the same approach to implement type guarding for your own custom types.