Root node rule
TypeScript type: RootNodeRule.
Root node rules are used to define nodes that are displayed at the root hierarchy level.
The rules have two types of attributes: for defining placement and for defining branch content. Placement attributes can make the whole rule return no nodes (e.g. when condition evaluates to false
). In that case branch content attributes have no effect.
Attributes
Name | Required? | Type | Default |
---|---|---|---|
Placement attributes | |||
condition |
No | ECExpression | "" |
requiredSchemas |
No | RequiredSchemaSpecification[] |
[] |
priority |
No | number |
1000 |
onlyIfNotHandled |
No | boolean |
false |
stopFurtherProcessing |
No | boolean |
false |
Branch content attributes | |||
autoExpand |
No | boolean |
false |
specifications |
No | ChildNodeSpecification[] |
[] |
customizationRules |
No | CustomizationRule[] |
[] |
subConditions |
No | SubCondition[] |
[] |
Attribute: condition
Defines a condition which needs to be met in order for the rule to be used. The condition is an ECExpression which has to evaluate to a boolean value.
For root node rule the most commonly used symbols are ruleset variables — values that can be set and changed at runtime to affect rule outcomes.
Type | ECExpression |
Is Required | No |
Default Value | "" |
// This ruleset defines two rules that can be enabled or disabled by setting variable DISPLAY_A_NODES and
// DISPLAY_B_NODES values.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
condition: `GetVariableBoolValue("DISPLAY_A_NODES")`,
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
ruleType: "RootNodes",
condition: `GetVariableBoolValue("DISPLAY_B_NODES")`,
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
},
],
};
Ruleset variable values | Result |
---|---|
DISPLAY_A_NODES = false DISPLAY_B_NODES = false |
|
DISPLAY_A_NODES = false DISPLAY_B_NODES = true |
|
DISPLAY_A_NODES = true DISPLAY_B_NODES = true |
Attribute: requiredSchemas
A list of ECSchema requirements that need to be met for the rule to be used.
Type | RequiredSchemaSpecification[] |
Is Required | No |
Default Value | [] |
// The ruleset has one root node rule that returns `bis.ExternalSourceAspect` instances. The
// ECClass was introduced in BisCore version 1.0.2, so the rule needs a `requiredSchemas` attribute
// to only use the rule if the version meets the requirement.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
requiredSchemas: [{ name: "BisCore", minVersion: "1.0.2" }],
specifications: [
{
specType: "InstanceNodesOfSpecificClasses",
classes: [
{
schemaName: "BisCore",
classNames: ["ExternalSourceAspect"],
},
],
},
],
},
],
};
Attribute: priority
Defines the order in which rules are handled, higher number means the rule is handled first. If priorities are equal, the rules are handled in the order they're defined. The attribute may be especially useful when combined with onlyIfNotHandled
attribute.
Type | number |
Is Required | No |
Default Value | 1000 |
// The ruleset has two root node rules that return nodes "A" and "B" respectively. The rules
// have different priorities and higher priority rule is handled first - it's node appears first.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
priority: 1,
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
ruleType: "RootNodes",
priority: 2,
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
},
],
};
Attribute: onlyIfNotHandled
When true
, the rule takes effect only when all other root node rules with higher priority are ruled out. This attribute is most useful for defining fallback rules.
Type | boolean |
Is Required | No |
Default Value | false |
// The ruleset has two root node rules that return nodes "A" and "B" respectively. The "A" rule has
// lower priority and `onlyIfNotHandled` attribute, which allows it to be overriden by higher priority rules.
// The "B" rule does exactly that.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
priority: 1,
onlyIfNotHandled: true,
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
ruleType: "RootNodes",
priority: 2,
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
},
],
};
Attribute: stopFurtherProcessing
Stop processing rules that have lower priority. Used in cases when recursion suppression is needed.
Note: If this flag is set,
specifications
andsubConditions
are not processed.
Type | boolean |
Is Required | No |
Default Value | false |
Attribute: autoExpand
Tells the library to assign produced nodes a flag, indicating that they should be automatically expanded.
Type | boolean |
Is Required | No |
Default Value | false |
// The ruleset defines a root node "A" which should be automatically expanded. The flag is only
// set if the node actually has children.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
autoExpand: true,
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
ruleType: "ChildNodes",
condition: `ParentNode.Type = "A"`,
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
},
],
};
Attribute: specifications
A list of hierarchy specifications that define what nodes are going to be returned. There are 4 types of specifications:
- Instance nodes of specific classes specification returns nodes for instances of given ECClass(-es) without attempting to join them to the parent node using some relationship or attribute. This is mostly useful when specifying root nodes.
- Related instance nodes specification returns nodes for instances that are related to the parent instance node through given ECRelationship. This is the most commonly used specification to create child nodes.
- Custom query instance nodes specification returns nodes for instances based on a given ECSQL query. Generally, this specification is rarely needed as majority of cases can be handled by Instance nodes of specific classes specification which is more performant and easier to set up.
- Custom node specification returns a single node that's not based on data in the iModel. Instead, the specification itself specifies all the attributes (type, label, description, image, etc.) of the node.
Multiple specifications can contribute to the same branch by specifying multiple specifications in a single rule or specifying multiple rules that match the same parent node.
Note: grouping and sorting is done at specification level which means nodes generated from different specifications do not get grouped and sorted together.
Type | ChildNodeSpecification[] |
Is Required | No |
Default Value | [] |
Attribute: customizationRules
A list of customization rules that apply only to nodes produced by this rule. Specifying customization rules at this level (as opposed to specifying them at ruleset root level) helps them isolate from other rules, which is useful when same type of nodes need to be customized differently based on what rule creates them.
Type | CustomizationRule[] |
Is Required | No |
Default Value | [] |
// The ruleset has a global label override rule and two root node rules that return nodes "A" and "B"
// respectively. The "B" rule has a label override of its own.
const ruleset: Ruleset = {
id: "example",
rules: [
{
// This label override applies to all nodes in the hierarchy
ruleType: "LabelOverride",
label: `"Global: " & ThisNode.Label`,
},
{
ruleType: "RootNodes",
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
ruleType: "RootNodes",
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
customizationRules: [
{
// This label override applies only to nodes created at its scope and takes
// precedence over the global rule
ruleType: "LabelOverride",
label: `"Nested: " & ThisNode.Label`,
},
],
},
],
};
Attribute: subConditions
A list of sub-rules which share placement attributes and nested customization rules of the hierarchy rule. This means the attributes of hierarchy rule are still in effect and the sub-rules can add additional condition of their own.
Type | SubCondition[] |
Is Required | No |
Default Value | [] |
// The ruleset has a root node rule with a schemas requirement and 2 sub-conditions. The latter are only used if schemas
// requirement is met. Each sub-condition can have additional conditions.
const ruleset: Ruleset = {
id: "example",
rules: [
{
ruleType: "RootNodes",
// the schemas requirement gets applied to both sub-conditions
requiredSchemas: [{ name: "BisCore", minVersion: "1.0.1" }],
subConditions: [
{
condition: `TRUE`,
specifications: [
{
specType: "CustomNode",
type: "A",
label: "A",
},
],
},
{
condition: `FALSE`,
specifications: [
{
specType: "CustomNode",
type: "B",
label: "B",
},
],
},
],
},
],
};
Last Updated: 15 May, 2024