/************************************************************************* * Copyright 2020 Adobe * All Rights Reserved. * * NOTICE: Adobe permits you to use, modify, and distribute this file in * accordance with the terms of the Adobe license agreement accompanying * it. If you have received this file from a source other than Adobe, * then your use, modification, or distribution of it requires the prior * written permission of Adobe. **************************************************************************/ export interface ObjectWithHref { /** * The URL of the solution page. * * ***Example:*** * * ```typescript * { href: 'https://example.com/abc' } * ``` */ href: string; } export interface BlockNavigationOptions { /** * Set to true if org changes are the only hash location changes that should be blocked. * * ***Example:*** * * ```typescript * {onOrgChangeOnly: true} * ``` */ onOrgChangeOnly: boolean; } export interface ObjectWithPath { /** * Optional collaborator id to be added to URL path. * * ***Example:*** * * ```typescript * {path: '/abc', collaborator: 'id1234'} * ``` */ collaborator?: string; /** * Optional instance id to be added to URL path. * * ***Example:*** * * ```typescript * {path: '/abc', instance: 'id1234'} * ``` */ instance?: string; /** * Optional organization name to be added to URL path. This can be in the form of a tenant or an organization string. * * ***Example:*** * * ```typescript * {path: '/abc', org: 'tenant'} * {path: '/abc', org: '4E9432245BC7C44B0A494037@AdobeOrg'} * ``` */ org?: string; /** * The relative path within the solution. * * ***Example:*** * * ```typescript * {path: '/abc'} * ``` */ path: string; /** * Optional sandbox name to be added to URL path. * * ***Example:*** * * ```typescript * {path: '/abc', sandbox: 'prod'} * ``` */ sandbox?: string; /** * Optional subOrg name to be added to URL path. * * ***Example:*** * * ```typescript * {path: '/abc', subOrg: 'sub-org-value'} * ``` */ subOrg?: string; } export interface ShellRedirectOptions { /** * Optional boolean which specifies if the redirect requires discovery. * * ***Example:*** * * ```typescript * {discovery: true} * ``` */ discovery?: boolean; /** * Optional boolean which specifies if the history action should be a replace * instead of a push. * * ***Example:*** * * ```typescript * {replace: true} * ``` */ replace?: boolean; } /** * Defines the location-like object for which to get the shell URL. You can either specify a path or * an absolute URL. * * ***Example:*** * * `{path: '/abc'}` or `{href: 'https://example.com/abc'}` */ export type LocationLike = ObjectWithHref | ObjectWithPath; /** * Subset of page-level APIs available to solutions that are settable attributes. */ export interface PageApiProperties { /** * Configuration for specifying which element should have the left margin and top margin added to it when * fullscreen overlay or modal needs to be displayed. Left margin will only be added if there is a side nav. * This should be a string with an element selector. * * ***Example:*** * * ```typescript * page.appContainer = '#example' * ``` */ appContainer: string; /** * @deprecated * Gets or set the favicon for the page. If this isn't set, then the default experience cloud * favicon will be used. * * ***Example:*** * * ```typescript * page.favicon = "https://img.icons8.com/color/48/000000/thumb-up.png"; * ``` */ favicon: string; /** * Configuration to show/hide an AI modal with fullscreen overlay for agent-notebook app. * This is automatically set by modalAutoDetect when the app is agent-notebook. Defaults to false. * * ***Example:*** * * ```typescript * page.isAiModalOpen = true; * ``` */ isAiModalOpen: boolean; /** * Configuration to show/hide a modal with fullscreen overlay. Defaults to false. * * ***Example:*** * * ```typescript * page.modal = true; * ``` */ modal: boolean; /** * Toggle for whether or not runtime should observe DOM changes and check the changes against * modal query selectors to automatically set modal = true. If you use this option consider adding * selectors with setObservableQuerySelectors. * * ***Example:*** * * ```typescript * page.modalAutoDetect = true; * ``` */ modalAutoDetect: boolean; /** * An array of key combinations for the shell to prevent default browser behavior on in cases * where an application performs some other action. * * ***Example:*** * * ```typescript * page.preventDefaultCombos = [ * { * ctrlKey: true, * key: 's' * } * ]; * ``` */ preventDefaultCombos: { altKey?: boolean; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean; key: string; }[]; /** * Gets or sets a value indicating whether or not to show a spinner on the page. This * configuration value is NOT used for the initial loading spinner (see Route Configuration * hideInitialSpinner for that), but can be used to dismiss it if the spinner needs to be * dismissed before a solution invokes runtime.done(). * * ***Example:*** * * ```typescript * page.spinner = true; * ``` */ spinner: boolean; /** * Gets or sets the title of the page. * * ***Example:*** * * ```typescript * page.title = 'Adobe Experience Cloud'; * ``` */ title: string; /** * Sets a message to be displayed if the user is prompted before navigating away from the page. * This will only be effective if page.blockNavigation is being used. Prompt messages should be * localized based on the current locale of the user before being set. The default value is 'Are you sure?'. * * ***Example:*** * * ```typescript * page.unloadPromptMessage = 'Are you sure you want to leave?'; * ``` */ unloadPromptMessage: string; } export interface Callback { (value?: any): void; } export declare enum ObservableType { MODAL = "MODAL", POPOVER = "POPOVER" } /** * Scope for the solution's release type in the product lifecycle */ export declare enum RELEASE_SCOPE { PARENT = "parent", SELF = "self" } /** * Solution's release type in the product lifecycle */ export declare enum RELEASE_TYPE { POC = "poc", DEV = "dev", ALPHA = "alpha", BETA = "beta", GA = "ga" } /** * @deprecated Solution's list of multiple subdomains */ export declare enum SRC_DOC { DISABLED = 0, HTML = 1, MANIFEST = 2 } export declare enum THUNDERBIRD { OFF = 0, SRC_DOC = 1, SERVICE_WORKER = 2 } /** * Defines the types of url contexts that can be used in the shell URL. */ export declare enum UrlContextKey { COLLABORATOR = "collaborator", INSTANCE = "instance", SANDBOX = "sandbox", SUBORG = "subOrg" } export interface UrlContextUpdate { /** * Payload for updating a context in the url * * ***Example:*** * import {CollaboratorType} from '@adobe/exc-app/user'; * import {UrlContextKey} from '@adobe/exc-app/page'; * * ```typescript * page.updateUrlContext({contextKey: UrlContextKey.COLLABORATOR}); * ``` */ /** * Identifies which context value is being updated * Currently support only exists for collaborator and instance */ contextKey: Omit; } export interface LoadTimesMetrics { 'first-contentful-paint'?: number; 'first-paint'?: number; domInteractive?: number; fetchStart?: number; 'iframe-first-paint'?: number; iframeDomInteractive?: number; iframeFetchStart?: number; iframeResponseEnd?: number; loadEventStart?: number; responseEnd?: number; rt_page_done?: number; rt_route_change?: number; rt_runtime_constructed?: number; rt_runtime_ready?: number; rt_script_end?: number; rt_script_start?: number; us_appassembly_done?: number; us_appassembly_start?: number; us_check_token_start?: number; us_check_token_end?: number; us_errormessage?: number; us_iframetimer_start?: number; us_page_done?: number; us_postauth_loaded?: number; us_reload_reason?: number; us_sandbox_connected?: number; us_sandbox_onmessage_ping?: number; us_serviceworker_active?: number; us_serviceworker_nohtmlupdates?: number; us_shell_done?: number; us_shell_isloginflow_done?: number; us_shell_start?: number; us_shellinitdataquery_data_initialized?: number; us_shellinitdataquery_start?: number; us_start?: number; us_switchaccount_authProcessDone?: number; us_switchaccount_start?: number; us_switchaccount_switchdone?: number; } export interface LoadTimes extends LoadTimesMetrics { legacyTiming?: boolean; } export interface PageDoneOptions { /** * Optional name for the page loaded. This can be used to identify different parts (routes) of the application * being loaded. It can also be used to track internal navigations within the same app. */ name?: string; } export interface PageStartOptions { /** * Optional name for the page loaded. This needs to match the name used in the done call. * Keep empty if the name is not known yet. */ name?: string; /** * Optional nested App ID. Set this right before nesting SPA inside another SPA. */ nestedAppId?: string; /** * Optional nested SPA name. Set this right before nesting SPA inside another SPA. */ nestedSpaName?: string; /** * Optional true to show the loading spinner. * page.start({spinner: true}) is equivalent to: * ```typescript * page.start(); * page.spinner = true; * ``` */ spinner?: boolean; } export interface PerformanceRecord { appId: string; capability?: string; error?: string; lastAppId?: string; loadTimes?: LoadTimes; loadType?: string; name?: string; nestingParent?: { appId: string; spaAppId?: string; topAppId?: string; topSpaAppId?: string; }; previousSection?: string; region?: string; retries?: number; section?: string; serviceWorker: boolean; spaAppId?: string; thunderbird?: THUNDERBIRD; valid?: boolean; version: string; } /** * Defines page-level APIs available to solutions. */ export interface PageApi extends PageApiProperties { /** * A function that listens and handles the afterPrint event. * * ```typescript * ***Example:*** * page.afterPrintHandler = function () { * // Revert temporary CSS changes * }; * ```` * @param callback The function that results in printing. */ afterPrintHandler(callback: Callback): void; /** * A function that listens and handles the beforePrint event. * * ```typescript * ***Example:*** * page.beforePrintHandler = function () { * // Temporary CSS changes, like unsetting height * }; * ```` * @param callback The function that results in printing. */ beforePrintHandler(callback: Callback): void; /** * Sometimes applications will need to block navigation away from the current page. The most common use case * for this is when a user has unsaved changes that would be lost on navigation. * * There are 3 types of navigation in unified shell that must be accounted for: * 1. User attempts to navigate in a way that will cause the browser to reload. This includes page refreshes, manual URL changes, and solution switcher clicks to a non-unified shell application. * 2. User attempts to navigate to another page hosted on unified shell via the shell. This includes workspace clicks, org changes, and solution switches to a unified shell application. Because this is only a hash history change, it does not cause a full browser reload. * 3. User attempts to navigate to another page in the current application via a link in the iframe. * * In order to prevent the first and second types of navigation, unified shell offers a `blockNavigation` function. To turn on navigation blocking, the application should set: * * ***Example:*** * * ```typescript * page.blockNavigation(true); * ``` * When this function is called with `true`, Unified Shell will set a `beforeUnload` handler on the page. This will block the first type of navigation. Unified Shell will also use `history.block` to block hash navigations such as org switches and workspace changes. * To handle the third type of navigation, applications must block the location change from within the iframe before it propogates to the shell. This is because unified shell won't know about the iframe navigation until after it happens. * To solve for this, solutions should `history.block` from within the iframe as well. It is important to note that only `push` location changes should be blocked. If the solution blocks all location changes, the navigation blocking prompt will be shown to the user multiple times. * When navigation blocking is no longer needed the application should set `runtime.blockNavigation(false)`. * * In special cases, a solution may want to allow workspace changes but block any other type of navigation. To enable this, the option `onOrgChangeOnly` should be passed in. * * ***Example:*** * * ``` * runtime.blockNavigation(true, {onOrgChangeOnly: true}); * ``` * * Please note that navigation blocking is currently only supported for tenanted solutions. If you would like to block navigation from a tenantless solution please contact a unified shell team member to discuss your use case. */ blockNavigation(enabled: boolean, options?: BlockNavigationOptions): void; /** * Browsers do not currently allow pages within the iframe to write data to the user's clipboard. * Utilizing this method, we are able to check that the user has granted permission to write to * their clipboard and then do so. * * **Example:** * * ```typescript * page.clipboardWrite('Message to write to the clipboard'); * ``` * @param msg The string to write to the clipboard. */ clipboardWrite(msg: string): void; /** * Tells the Shell that the Solution has loaded and is ready to be used by a user and dismisses * the initial loading spinner. * * At the earliest, done should be called after Ready event was fired to ensure accurate reporting. * * One of the main objectives of using done is to measure UX performance, it should be called after * all network activity is completed and the app is interactive - Ready for users to do their work. * * ***Example:*** * * ```typescript * page.done(); * ``` * @returns A promise that resolves with the performance metrics of this page load. * done should only be called once. Ignored when called twice. */ done(options?: PageDoneOptions): Promise; /** * Method to take a relative path or full iframe URL and generate a unified shell url. * * ***Example:*** * * ```typescript * // returns `https://experience.adobe.com/#/@tenant/solution/abc` * page.generateShellUrl({path: '/abc'}); * * // returns `https://experience.adobe.com/#/@tenant/sname:prod/solution/abc` * page.generateShellUrl({path: '/abc', sandbox: 'prod'}); * * // returns `https://experience.adobe.com/#/@tenant/solution/abc` * page.generateShellUrl({href: 'https://example.com/abc'}); * ``` * @param location Object with either a path and optional sandbox or href key and corresponding * value from which to generate the shell URL. * @param newApp When true generates a new url with the given location without hash values * or pathname resolutions specific to the current app. * @returns The shell URL for the specified view of the solution. */ generateShellUrl(location: LocationLike, newApp?: boolean): string; /** * Get the list of selectors presently being used by modalAutoDetect. * * ***Example:*** * * ```typescript * page.getModalQuerySelectors(); * ``` * @returns The list of selectors presently being used by modalAutoDetect. */ getModalQuerySelectors(): Array; /** * Get the list of selectors for a specific observed type. This will return default values unless * those have been overridden using setObservableQuerySelectors. * * ***Example:*** * * ```typescript * page.getObservableQuerySelectors(ObservableType.MODAL); * // returns ['selector1', 'selector2] * ``` * @returns The list of selectors or object containing observed type to selector array map. */ getObservableQuerySelectors(type: ObservableType): string[]; /** * Triggers the reload of the solution iframe. Calling this function will regenerate the iframe * source, triggering the discovery URL flow if configured. * * ***Example:*** * * ```typescript * page.iframeReload(); * ``` * @param cacheBust Whether the reload should include a unique query param on the iframe URL to * cache bust the page. This defaults to false for SPA pipeline apps, true to other apps for * backwards compatibility purposes. */ iframeReload(cacheBust?: boolean): void; /** * Replaces the application iframe with the not found page. * * ***Example:*** * * ```typescript * page.notFound(); * ``` */ notFound(): void; /** * Opens the specified URL in the shell in a new tab. This is useful in scenarios where an element * won't be an anchor or link and solution needs to open the URL. * * ***Example:*** * * ```typescript * page.openInNewTab('/path'); * ``` * @param path The relative path within the solution. * @param newApp When true generates a new url with the given location without hash values * or pathname resolutions specific to the current app. */ openInNewTab(path: string, newApp?: boolean): void; /** * A function to control printing. The callback function should call `window.print()` * at some point. It's important that the callback not be an arrow function if you * want the `window` object to be the iframe contents. Feel free to adjust your * CSS or UI before `window.print()` and reverse those changes afterwards. * * ***Example:*** * * ```typescript * page.print = function () { * window.print(); * }; * ```` * @param callback The function that results in printing. */ print(callback: Callback): void; /** * Reloads the current Sandbox. Currently only works on AppSelectorSandboxes * which use the alternateRoute Solution config property. * * ***Example:*** * * ```typescript * page.reloadSandbox(); * ``` * @deprecated */ reloadSandbox(): void; /** * Tells the Shell that the Solution is starting load a new page. * @param options */ start(options?: PageStartOptions): void; /** * Set the list of selectors presently being used by modalAutoDetect. If set to an empty * array, the default selectors used by runtime will be used instead. To stop observing changes * unset modalAutoDetect. Setting additonal selectors replaces the currently set selectors, use * page.getModalQuerySelectors and append new selectors to the returned list before resetting * to modify the existing list of selectors. * * ***Example:*** * * ```typescript * page.setModalQuerySelectors(['.someSpecialCaseModal', '.yourNormalModal']); * ``` * @param selectors The list of selectors for modalAutoDetect to use. */ setModalQuerySelectors(selectors?: Array): void; /** * Set the list of selectors presently being used by the observable `type`. If set to an empty * array, the default selectors used by runtime will be used instead. Setting additonal selectors * replaces the currently set selectors, use page.getObservableQuerySelectors and append new * selectors to the returned list before resetting to modify the existing list of selectors. * Adding the `forceCustomOnly` parameter removes the `[data-testid="popover"]` selector that's * otherwise automatically added to modals. * * ***Example:*** * * ```typescript * page.setObservableQuerySelectors(ObservableType.POPOVER, ['.someSpecialCaseModal', '.yourNormalModal']); * ``` * @param type The observable type to set custom selectors for. * @param selectors The list of selectors to set. * @param forceCustomOnly Only use the custom selectors given. */ setObservableQuerySelectors(type: ObservableType, selectors?: string[], forceCustomOnly?: boolean): void; /** * Redirects to another unified shell solution. `pathOrUrl` can be either: * 1. Complete relative path of a valid unified shell solution url, * 2. Full URL of a valid unified shell solution url. * * Relative: * If shellRedirect is called from /target to /analytics, the path paremeter would need to start * with /analytics). Query and hash are optional. * * URL: * The full URL such as https://experience.adobe.com/#/@tenant/analytics/path. The tenant is optional. * If the origin provided is already the current origin, it will stay on this origin and update the * path. However, if the origin is different, the unified shell will be redirected. * * ***Example:*** * * ```typescript * page.shellRedirect('/path?a=b#workspace'); * ``` * @param pathOrUrl Path or full URL including search and hash to a unified shell solution. * @param options Options for redirect. Options include discovery which determines if the new * location requires a discovery call and replace which determines if the history action should be * a replace or push. */ shellRedirect(pathOrUrl: string, options?: ShellRedirectOptions): void; /** * Toggle whether or not runtime should observe DOM changes and check the changes against * `type` query selectors. If you use this option consider adding selectors with * setObservableQuerySelectors to ensure the functionality works as expected. * * Outcomes: * MODAL: `page.modal` is toggled. If enabled, the modal underlay shows on top of Unified Shell. * POPOVER: The height of the popovers are adjusted such that they will not be hidden by the Unified Shell header. * * ***Example:*** * * ```typescript * page.toggleAutoDetect(ObservableType.MODAL, true); * ``` * @param type The observable type to enable auto detection for. * @param enable Whether to enable or disable the auto detection for this `type`. */ toggleAutoDetect(type: ObservableType, enable: boolean): Promise; /** * Allows an app to update context data options in the url. */ updateUrlContext: (payload: UrlContextUpdate) => void; } declare const page: PageApi; export default page;