Skip to content

Commit a54107b

Browse files
authored
ENG-40660 - Support Transitional Navigation (#231)
Adds support for conditionally enabled routes within a route hierarchy. Routes that are disabled cannot be activated or made visible, and their children are ignored.
1 parent 604cc29 commit a54107b

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@al/core",
3-
"version": "1.0.188",
3+
"version": "1.0.189",
44
"description": "Node Enterprise Packages for Alert Logic (NEPAL) Core Library",
55
"main": "./dist/index.cjs.js",
66
"types": "./dist/index.d.ts",

src/common/errors/al-error.types.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ export class AlBaseError extends Error
2424
* this error.
2525
*/
2626
public origin?:any;
27+
public details?:any;
2728

28-
constructor( message?:string, derivedFrom?:any ) {
29+
constructor( message?:string, derivedFrom?:any, details?:any ) {
2930
const trueProto = new.target.prototype;
3031
super(message);
3132
this.origin = derivedFrom;
33+
this.details = details;
3234

3335
this.__proto__ = trueProto;
3436
}
@@ -243,9 +245,9 @@ export class AlNotFoundError extends AlBaseError
243245
* @param inner - the underly error
244246
*/
245247
export class AlWrappedError extends AlBaseError {
246-
constructor( message:string, inner:any ) {
248+
constructor( message:string, inner:any, details?:any ) {
247249
/* istanbul ignore next */
248-
super( message, inner );
250+
super( message, inner, details );
249251
}
250252

251253
public getInnerError():any {

src/common/navigation/al-navigation.types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ export interface AlExperienceMapping
4949
*/
5050
trigger:AlRouteCondition|AlRouteCondition[]|boolean;
5151

52+
/**
53+
* If present and true, indicates the user can opt in or out of this experience, and their opt-in status should be "sticky."
54+
*/
55+
optional?:boolean;
56+
5257
/**
5358
* If provided, defines the zero state to provide when an experience isn't available.
5459
*/

src/common/navigation/al-route.types.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,13 @@ export interface AlRouteDefinition {
171171
/* The caption of the menu item */
172172
caption:string;
173173

174-
/* An arbitrary id associated with this menu item. This is most useful (practically) for retrieving specific menu items by code. */
174+
/* An arbitrary identifier associated with this menu item. This is most useful (practically) for retrieving specific menu items by code. */
175175
id?:string;
176176

177+
/* An arbitrary name associated with this menu item. These augment named routes for conditional schema branches. And if that sounds vaguely
178+
* gibberishy -- (wasntme) */
179+
name?:string;
180+
177181
/* An arbitrary bookmark code for this menu item. This allows a specific submenu to be retrieved and worked with programmatically. */
178182
bookmarkId?:string;
179183

@@ -184,6 +188,10 @@ export interface AlRouteDefinition {
184188
* If the provided value is a string, it will be treated as a reference to a named route in the current schema. */
185189
action?:AlRouteAction|string;
186190

191+
/* A condition that can be evaluated to calculated the `enabled` property at any given moment.
192+
* This can be a fixed boolean value, a shared condition ID (see AlNavigationSchema.conditions), or a condition literal. */
193+
enabled?:AlRouteCondition|string|boolean;
194+
187195
/* A condition that can be evaluated to calculate the `visible` property at any given moment.
188196
* This can be a fixed boolean value, a shared condition ID (see AlNavigationSchema.conditions), or a condition literal. */
189197
visible?:AlRouteCondition|string|boolean;
@@ -248,7 +256,7 @@ export class AlRoute {
248256
/* Is the menu item visible? */
249257
visible:boolean = true;
250258

251-
/* Is the menu item enabled? This is provided for use by custom menu implementations, and no managed by this module. */
259+
/* Is the menu item enabled? Disabled menu items and their children will not be considered for activation. */
252260
enabled:boolean = true;
253261

254262
/* Is the menu item locked? This prevents refresh cycles from changing its state. */
@@ -374,6 +382,15 @@ export class AlRoute {
374382
return;
375383
}
376384

385+
if ( this.definition.enabled ) {
386+
this.enabled = this.evaluateCondition( this.definition.enabled );
387+
if ( ! this.enabled ) {
388+
this.visible = false;
389+
// This item and its family tree are disabled, and thus not considered for visibility or activation.
390+
return;
391+
}
392+
}
393+
377394
state.depth++;
378395

379396
/* Evaluate visibility */
@@ -728,7 +745,29 @@ export class AlRoute {
728745
return child || null;
729746
}
730747

731-
748+
/**
749+
* Generic method for recursing a menu hierarchy, using a callback to match the route.
750+
*
751+
* @param callback is a method that accepts a route (and optionally its definition) and returns
752+
* `true` if the route is the correct one, in which case it is the result of the search method.
753+
* `false` if the route is incorrect but its children should be iterated.
754+
* `null` if the route is incorrect and its children should be ignored
755+
*/
756+
search( matcher:{(route:AlRoute, definition?:AlRouteDefinition):boolean}, enabledOnly:boolean = true ):AlRoute|undefined {
757+
if ( this.enabled !== enabledOnly ) {
758+
return;
759+
}
760+
if ( matcher( this, this.definition ) ) {
761+
return this;
762+
} else {
763+
for ( let i = 0; i < this.children.length; i++ ) {
764+
let target = this.children[i].search( matcher, enabledOnly );
765+
if ( target ) {
766+
return target;
767+
}
768+
}
769+
}
770+
}
732771

733772
/**
734773
* This method will return the deepest activated, childless route within its first activated child. If this sounds obtuse,

src/common/utility/al-trigger.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class AlTriggeredEvent<ResponseType=any>
7676
*
7777
* Callback type for triggered events.
7878
*/
79-
export declare type AlTriggeredEventCallback<EventType> = {(event:EventType):void|boolean};
79+
export declare type AlTriggeredEventCallback<EventType> = {(event:EventType):void|boolean|Promise<void>};
8080

8181
/**
8282
* @public

0 commit comments

Comments
 (0)