File

libs/ngx-pfe/models/navigation-config.model.ts

Description

This interface define the content of a state update

Index

Properties

Properties

conditions
conditions: Conditions
Type : Conditions
Optional

List of conditions that identify in which case we want to do this update. In case of not define this list we will apply the update directly

key
key: JsonPathExpression
Type : JsonPathExpression

Key or id of the element to be modified in the state

operation
operation: StateOperations
Type : StateOperations
Optional

Possible operations to be apply

value
value: any | JsonPathExpression
Type : any | JsonPathExpression
Optional

Value to be added, replace, update or copy an existing inputState item

import { Conditions } from '../pfe-conditions/public-api';
import { NavServiceActivatorConfig, NavServiceActivatorConfigsArray } from '../pfe-service-activator/service/service-activator.model';
import { PfeActionConfig } from './../pfe-actions/pfe-actions.model';
import { JsonPathExpression } from './jsonpath-expression-type.model';
import { NavOptionErrorPageConfig } from './navigation-config-error-page.model';

/**
 * Unique ID of a page.
 */
export type PageId = string;
/**
 * Enum of meta keys that can be used to do specific navigations to other sections of navigation config
 */
export enum META_KEYS {
  FIRST_PAGE = 'FIRST_PAGE',
}

export interface MetaNav {
  metaNavId: META_KEYS;
}

export enum NavigationType {
  FORWARD = 'FORWARD',
  BACKWARD = 'BACKWARD',
}
/**
 * Configuration for a service activator to be called.
 */
export interface GlobalServiceActivators<ACTIONS = PfeActionConfig> {
  [id: string]: NavServiceActivatorConfig<ACTIONS>;
}

/**
 * The PfeNavigationConfiguration contains all configuration values that are required for
 * the navigation between different pages in a flow.
 * The execution flow is as follows:
 *
 * 1. Execute service activators
 * 2. Retrieve result and store to state
 * 3. Execute navigation conditions
 *
 */
export interface PfeNavigationConfiguration<ACTIONS = PfeActionConfig> {
  /**
   * The id to be displayed when a non recoverable error occurs.
   *
   * An example for such an error is a failed service activator call.
   * It is possible to exclude certain http status codes from the automatic error handling with the
   * serviceActivatorErrorHandlingExcludeStatusCodes configuration in the application config.
   *
   * @deprecated true
   * @deprecationMessage Use the errorPageNavigation instead.
   */
  errorPageID?: string;

  /**
   * Determines the error page to be displayed.
   * Allows it to evaluate navigation options. Additionally to the state, the full response object is available under the key "$.response"
   * For example the status response code can be accessed like this: "$.response.status"
   *
   * The state is available under the key "$.state"
   */
  errorPageNavigation?: NavOptionErrorPageConfig[];

  /**
   * First page configuration.
   * It can be either a pageId (as string) or a first page configuration with their next options.
   */
  firstPage?: string | FirstPageConfiguration<ACTIONS>;
  /**
   * The collection of the navigation configuration for all pages of a flow.
   */
  pages: PageNavigationConfiguration<ACTIONS>[];

  /**
   * Global service activators configuration registry. The service activators here can be triggered by their
   * ID in the navigation page configuration.
   * This makes it possible to trigger the same service activator on multiple navigations.
   * It is also possible to overwrite some of the attributes in the page navigations.
   *
   * Example:
   *
   *  "serviceActivators": {
   *     "IDofThisServiceActivator": {
   *       "path": "customerInformation",
   *       "responseDataMapping": [
   *         {
   *           "responseDataExpression": "$",
   *           "stateKeyExpression": "$.saveResponseHere"
   *         }
   *       ]
   *     }
   *   }
   */
  serviceActivators?: GlobalServiceActivators<ACTIONS>;
}

export type PageNavigationConfiguration<ACTIONS = PfeActionConfig> =
  | RegularPageNavigationConfiguration<ACTIONS>
  | NavigationNodeConfiguration<ACTIONS>;

/**
 * # Navigation configuration
 *
 * The navigation configuration determines the next page to be shown, dependent on values in the state.
 *
 * Each next page can have a number of conditions. These conditions are connected with AND,
 * which means, all of them have to evaluate to true for the page to be shown.
 *
 * The navigation options are checked in the order, as they are defined in the configuration.
 * This means, if the conditions of the first option evaluates to true, the navigation is started
 * immediately, the other options are not checked anymore.
 *
 */
interface RegularPageNavigationConfiguration<ACTIONS = PfeActionConfig> {
  /**
   * The pageID is a unique ID of a page throughout the whole configuration.
   * In the navigation it references pages from the page configuration.
   */
  pageId: PageId;

  /**
   * The pageConfigIdReference allows it to map a navigation config to a different pageConfig than the pageID.
   * This makes it possible, to reuse the same pageConfig multiple times in the navigation. (1 pageConfig -> n navigationConfigs)
   *
   * If there is also a pageConfig with the pageId of this navigation config, a deep merge is done on top of the pageConfigIdReference.
   * This makes it possible, to overwrite certain parts of the referenced page config.
   * By default, arrays are replaced. If a concat should be done instead, the pageConfigIdReferenceDeepMergeArrays flag can be used.
   */
  pageConfigIdReference?: PageId;

  /**
   * Used in combination with pageConfigIdReference. Do not overwrite arrays, but concat them.
   */
  pageConfigIdReferenceDeepMergeArrays?: boolean;

  /**
   * Flag that sequentially executes all the service activators configured in the page.
   *
   * Should not be used anymore. Instead use the TRIGGER_SERVICE_ACTIVATORS action with the executeServiceActivatorsSequential flag.
   *
   * @deprecated true
   * @deprecationMessage Use "executeServiceActivatorsSequential" inside "onPageEnterActions"
   */
  executeServiceActivatorsSync?: boolean;

  /**
   * Service activators to be called, when a page is opened.
   */
  onPageEnterServiceActivators?: NavServiceActivatorConfigsArray<ACTIONS>;

  /**
   * Service activators to be called, when a user leaves the current page. (=click on the next button)
   */
  onPageLeaveServiceActivators?: NavServiceActivatorConfigsArray<ACTIONS>;

  /**
   * Service activators to be called, when a user click in some button on the current page.
   *
   * Example of how add a new serviceActivator call called "getCustomerInformation":
   *
   *  "serviceActivators": {
   *     "getCustomerInformation": {
   *       "path": "customerInformation",
   *       "serviceActivatorMethod": "GET",
   *       "requestDataMapping": [
   *         {
   *           "stateKeyExpression": "$.documentId",
   *           "requestDataExpression": "$.documentId"
   *         }
   *       ],
   *       "responseDataMapping": [
   *         {
   *           "responseDataExpression": "$",
   *           "stateKeyExpression": "$.saveResponseHere"
   *         }
   *       ]
   *     }
   *   }
   */
  serviceActivators?: {
    [key: string]: NavServiceActivatorConfig<ACTIONS>;
  };

  /**
   * The list of possible next pages in the navigation flow.
   */
  nextOptionList?: NavOptionConfig[];

  /**
   * The list of possible previous pages in the navigation flow.
   *
   * If the backOptionList is not set, the automatically remembered history of the visited pages
   * will be used for the back navigation.
   * An empty backOptionList ([]) will prevent a back navigation.
   */
  backOptionList?: NavOptionConfig[];

  /**
   * Do not add this page to the history of navigated pages.
   */
  omitFromHistory?: boolean;

  /**
   * If this attribute is set to true, the remote state storage will
   * be shutdown when this page is entered.
   * This means the latest state will not be updated anymore.
   */
  shutdownStateStorage?: boolean;

  /**
   * Allows the user to directly navigate this page within the flow
   * without a restored state.
   * Default is false, which means the user gets redirected to the first page, if no state
   * was restored.
   */
  allowDirectNavigationWithoutState?: boolean;
  /**
   * By default when restoring the state it will navigate to the last visited page. If false
   * then it will navigate to the page passed in the fragment of url.
   * ex: allianz.com/blabla#navigateToThisPage
   */
  navigateToLastVisitedPage?: boolean;

  /**
   * set to true to remove pages that have been visited
   * multiple nextOptionList pages that stores value to the state
   */
  removePageFromState?: boolean;

  /**
   * A list of actions of the page,
   * the actions are executed sequentially before the user enters the page
   *
   * They can use conditions to determine if they should be executed or not.
   * The following information is available for this in the state:
   * $._pfe.navigationState.navigatingTo
   * $._pfe.navigationState.navigatingFrom
   */
  onPageEnterActions?: ACTIONS[];

  /**
   * A list of actions of the page,
   * the actions are executed sequentially before the user leaves the page in forward direction in the flow.
   */
  onPageLeaveActions?: ACTIONS[];

  /**
   * Actions that are executed when the navigation of one page to another one is started.
   * They can use conditions to determine if they should be executed or not.
   *
   * The following information is available for this in the state:
   * $._pfe.navigationState.navigatingTo
   * $._pfe.navigationState.navigatingFrom
   */
  onNavigationStartActions?: ACTIONS[];

  /**
   * A list of actions of the page,
   * the actions are executed sequentially before the user leaves the page in a backward direction in the flow.
   */
  onPageLeaveBackwardsActions?: ACTIONS[];
}

interface NavigationNodeConfiguration<ACTIONS = PfeActionConfig> extends RegularPageNavigationConfiguration<ACTIONS> {
  /**
   * Setting the navigationNode flag, turns this page into a pure navigation node.
   *
   * This means the page is not attached to a pageType (=invisible). Instead navigating to it, immediately triggers another navigation.
   * This makes it possible to use a navigationNode as a decision gateway that navigates to another page, based on certain conditions.
   *
   * Navigation nodes are not added to the history of visited pages, that means navigating backwards after a navigation node
   * leads to the page that triggered the original navigation to the navigation node.
   * A backwards navigation from within a navigationNode is therefore also not possible.
   *
   * When a page is turned into a navigation node, it cannot be used together with the pageConfigIdReference, pageConfigIdReferenceDeepMergeArrays,
   * backOptionList, onPageLeaveActions and onPageLeaveBackwardsActions attributes.
   *
   * omitFromHistory will be activated automatically.
   */
  navigationNode: boolean;
  pageConfigIdReference?: never;
  pageConfigIdReferenceDeepMergeArrays?: never;
  backOptionList?: never;
  onPageLeaveActions: never;
  onPageLeaveBackwardsActions: never;
}

export function isNavigationNode(
  pageConfig?: RegularPageNavigationConfiguration<unknown> | NavigationNodeConfiguration<unknown>
): pageConfig is NavigationNodeConfiguration {
  return (pageConfig as NavigationNodeConfiguration)?.navigationNode !== undefined;
}

/**
 * First page configurations which includes a list of possible first pages.
 *
 */
export interface FirstPageConfiguration<ACTIONS = PfeActionConfig> {
  /**
   * ServiceActivators that are executed before the first page evaluation is done.
   * The navigation to the first page can use the response data.
   * @deprecated true
   * @deprecationMessage Use "onEnterActions"
   */
  onEnterServiceActivators?: NavServiceActivatorConfigsArray<ACTIONS>;

  /**
   * A list of actions to be executed before navigate to the
   * first page.
   */
  onEnterActions?: ACTIONS[];

  /**
   * The list of possible first pages.
   */
  nextOptionList: NavOptionConfig[];
}

export interface NavOptionConfig {
  /**
   * The ID of the next page to be displayed, if the conditions evaluate to true.
   * The ID is a reference to the page configuration.
   *
   * The nextPageId can also be a jsonPath expression, that will be resolved during navigation.
   */
  nextPageId?: string;

  /**
   * # ExpressionCondition Syntax
   *
   * The navigation conditions use jsonPath (https://github.com/dchester/jsonpath) expressions to select data from the state.
   * There is tooling support available to create and test jsonpath expression.
   * The PFE dev tools also contain a possibility to test and debug expressions against a JSON.
   *
   * The conditions to be evaluated can either be an array of {@link Condition} or an {@link ConditionAdvanced} object.
   *
   * They are an optional attribute. If they are omitted, the result of true is assumed.
   *
   * The selected data can then be compared with certain operators to a second value or a literal.
   *
   * Possible operators are
   *
   * ```
   * ==
   * ```
   * Checks if the two values are equal.
   *
   * ```
   * !=
   * ```
   * Checks that the two values are not equal.
   *
   * ```
   * < and >
   * ```
   * Compares the numerical value, to check if one of them is larger or
   * smaller than the other one.
   *
   * The jsonpath syntax has the following basic format:
   *
   * ```
   *  $.<attribute or expression>
   * ```
   *
   * For example:
   *
   * ```
   *  $.myCustomTextAreaID
   * ```
   *
   * Keys, that contain special characters can be accessed in the following way:
   *
   * ```
   *  $['some-attribute-name']
   * ```
   *
   * Example configuration.
   *
   * This example also shows, how jsonpath expressions can be used, to extract data from arrays.
   *
   * ```json
   *  {
   *    "pageId": "damage-type-selection",
   *    "nextOptionList": [
   *      {
   *        "nextPageId": "page-type-overview",
   *        "conditions": [
   *          {
   *            "value1Expression":
   *              "$.damageTypeButtons..[?(@ == 'pageTypeOverview')]"
   *          }
   *        ]
   *      },
   *      {
   *        "nextPageId": "settlement-option",
   *        "conditions": [
   *          {
   *            "value1Expression": "$.damageTypeButtons..[?(@ == 'WATER_DAMAGE')]"
   *          }
   *        ]
   *      },
   *      {
   *        "nextPageId": "other-page",
   *        "conditions": {
   *          "operator": "AND",
   *          "conditions": [
   *            {
   *              "value1Expression": "$.damageTypeButtons..[?(@ == 'PARK_DAMAGE')]"
   *            }
   *          ]
   *        }
   *      }
   *    ]
   *  }
   * ```
   */
  conditions?: Conditions;

  /**
   * Navigation to an external url:
   *
   * Also it is possible to specify an external url as the next page based on a specific condition.
   *
   * In this case the configuration will be:
   *
   *     - nextPageId : <External url> It is possible, to use JSON Path expressions within the URL using {} and inside the expression
   *     - external: true
   *
   * ```json
   * [
   *   {
   *     "pageId": "lastpage",
   *     "nextOptionList": [
   *       {
   *         "nextPageId": "https://www.google.es?someValue={$.aaa.bbb}",
   *         "external": true
   *       }
   *     ]
   *   }
   * ]
   * ```
   *
   * Its also possible to use a more complex parse of the params on the URL @see ExternalNavigationPathParams but both
   * options are not compatible.
   */
  external?: boolean;

  /**
   * Allow to handle all the navigation path params that are provided when
   * its an external navigation.
   * You can use this in 2 different ways, that can be mixed together, in the following examples
   * the final URL its the same.
   * ```json
   * [
   *   {
   *     "pageId": "lastpage",
   *     "nextOptionList": [
   *       {
   *         "nextPageId": "/account/?contractId={contractId}",
   *         "external": true,
   *         "externalNavigationPathParams": [
   *            {
   *              "id": "contractId",
   *              "value": "$.policy.contractId"
   *            }
   *          ]
   *       }
   *     ]
   *   }
   * ]
   * ```
   * ```json
   * [
   *   {
   *     "pageId": "lastpage",
   *     "nextOptionList": [
   *       {
   *         "nextPageId": "/account/?",
   *         "external": true,
   *         "externalNavigationPathParams": [
   *            {
   *              "name": "contractId",
   *              "value": "$.policy.contractId"
   *            }
   *          ]
   *       }
   *     ]
   *   }
   * ]
   * ```
   */
  externalNavigationPathParams?: ExternalNavigationPathParams[];

  /**
   * Propagate forward specified path params from the current route to external navigation.
   * If a path param is not found, it will be ignored.
   *
   * ```json
   * [
   *   {
   *     "pageId": "lastpage",
   *     "nextOptionList": [
   *       {
   *         "nextPageId": "/account/",
   *         "external": true,
   *         "externalPathParamPropagations": ["startImpersonation"]
   *       }
   *     ]
   *   }
   * ]
   * ```
   *
   * It is not possible to use JSON Path expressions within the URL if this option is in use.
   * Define them with externalNavigationPathParams instead.
   */
  externalPathParamPropagations?: string[];

  /**
   * List of possibles userInputState updates
   */
  updateStateValues?: StateUpdates[];

  /**
   * The meta navigation for the next page to be displayed, if the conditions evaluate to true.
   * This meta navigation is a group of navigations that appear in the navigation.json. (f.e first page nav)
   *
   */
  metaNavigation?: MetaNav;
}

export interface ExternalNavigationPathParams {
  /** The name of the param, for example "contractNumber" */
  name?: string;
  /** The value in the URL for example {contractNumber} */
  id?: string;
  /** The value of the param, it can be a JsonPathExpression or just a value */
  value: string;
  /** A list of conditions to add that param */
  conditions?: Conditions;
}

/**
 * This interface define the content of a state update
 */
export interface StateUpdates {
  /**
   * Key or id of the element to be modified in the state
   */
  key: JsonPathExpression;
  /**
   * Value to be added, replace, update or copy an existing inputState item
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  value?: any | JsonPathExpression;
  /**
   * Possible operations to be apply
   */
  operation?: StateOperations;
  /**
   * List of conditions that identify in which case we want to do this update.
   * In case of not define this list we will apply the update directly
   */
  conditions?: Conditions;
}

/**
 * State operation through different variables
 */
export enum StateOperations {
  REMOVE = 'remove',
  PUSH = 'push',
  DECREASE = 'decrease',
  INCREASE = 'increase',
  /** Joins the "key" using the "value" as a join operator */
  JOIN = 'join',
}

/**
 * Defines the serviceActivators to be triggered while doing so manually.
 */
export enum ServiceActivatorHook {
  'ENTER' = 0,
  'LEAVE' = 1,
}

/**
 * Defines the UrlParametersInState to save url parameter value to state.
 */
export interface UrlParametersInState {
  key: string;
  stateKeyExpression: JsonPathExpression;
}

results matching ""

    No results matching ""