/** * OpenFin Notification Templates API Version 1 * * @module Templates */ /** * imports */ import { IndicatorColor } from '../indicator'; import { FormField, FormFieldWithRequiredLabel, NotificationFormData, NotificationFormDataWithRequiredLabel } from '../forms'; import { BaseNotificationOptions } from './BaseNotificationOptions'; import { ActionDeclaration } from '../main'; export type SectionAlignment = 'left' | 'center' | 'right'; export type ListPairs = [string, string][]; export type CustomTemplateData = Record; /** * The options you pass to the [[create]] function to generate a notification. */ export type NotificationOptions = TemplateMarkdown | TemplateList | TemplateCustom; /** * The options to build your custom template composition layout. */ export type TemplateFragment = ContainerTemplateFragment | TextTemplateFragment | ListTemplateFragment | ImageTemplateFragment | ActionableTextTemplateFragment; export declare const TemplateNames: { readonly markdown: "markdown"; readonly list: "list"; readonly custom: "custom"; }; export declare const ContainerTemplateFragmentNames: { readonly container: "container"; }; export declare const PresentationTemplateFragmentNames: { readonly text: "text"; readonly image: "image"; readonly list: "list"; readonly actionableText: "actionableText"; }; export declare const TemplateFragmentNames: { readonly text: "text"; readonly image: "image"; readonly list: "list"; readonly actionableText: "actionableText"; readonly container: "container"; }; export interface TemplateComposition { /** * Minimum Template API version required for the service to render this composition. * * For example, a composition that consists only of container, text, image, or list * fragments must declare a minimum template API version of "1". * * See {@link BodyTemplateOptions} for more details. */ minTemplateAPIVersion: string; /** * Root of the template composition tree. See {@link ContainerTemplateFragment} for nesting. */ layout: TemplateFragment; } export interface IndicatorTemplateOptions { /** * Alignment of the notification's indicator section. * * Can be `left`, `center` or `right`. * * The default value is `center`. */ align?: SectionAlignment; /** * Color of the indicator bar. * * Note: {@link BaseNotificationOptions|Notification's indicator color} definition has precedence over Template definition. * Template's indicator color value will be taken into account only if the notification itself doesn't have the indicator color * specified. */ color?: IndicatorColor; } export interface ButtonTemplateOptions { /** * Alignment of the notification's button section. * * Can be `left`, `center` or `right`. * * The default value is `right`. */ align?: SectionAlignment; } export interface BodyTemplateOptions { /** * A list of template compositions. * * You can include multiple compositions with different minimum Template API version to create fallback compositions and support the * earlier versions of Notification Center (Starting from the Template API version 1). * * The service will search for the composition with the version number matching the Template API version it is supporting. * If this doesn't exist, the service will then select the composition with the nearest version number smaller than the Template API version * it is supporting and render the notification card with that composition. */ compositions: TemplateComposition[]; /** * Composition fallback text. * * The service will render this text instead of the notification body section if there are no compatible compositions found in the template. * * (E.g. All of the compositions in the template declare a greater minimum Template API version than the version supported by the running * service instance.) * */ fallbackText?: string; } export interface BaseTemplateFragment { /** * Type of the template fragment. */ type: T; /** * CSS style properties of the fragment. * * All the available custom template fragments support all of the React's inline style properties (with camelCase keys) * * Note: "position: fixed" is disallowed in the fragments. */ style?: Record; } export interface ContainerTemplateFragment extends BaseTemplateFragment<'container'>, ActionableFragment { /** * Sub-fragments of the container. * * You can use container template fragment to create nested composition structures. */ children?: TemplateFragment[]; } export interface PresentationTemplateFragment extends BaseTemplateFragment { /** * Optional flag. * * If a presentation template fragment is flagged as optional, The service will not require * the fragment's `dataKey` to exist in `templateData`. If a fragment is optional and its data * is missing, the fragment will be omitted quietly by the server. */ optional?: boolean; /** * Data key of the template fragment. * * The data associated with this fragment will be looked up in `templateData` map with this key. * * Example: * ```ts * const myTemplate = { * body: { * compositions: [{ * minTemplateAPIVersion: '1', * layout: { * type: CustomTemplateFragmentNames.text, * dataKey: 'message', * }, * }], * }, * } * * const notificationOption: TemplateCustom = { * //... * templateOptions: myTemplate, * templateData: { * message: 'My Custom Notification Message', * } * }; * ``` * */ dataKey: string; } export interface ActionableFragment { /** * onClick object that is user defined. * * If provided, notification-action event will be raised when clicking on the fragment. * * * Example: * ```ts * { * "type": "actionableText", * "dataKey": "titlexyz", * "tooltipKey": "some_key", * "onClick": { // contents are user-defined * "task": "schedule-reminder", * "eventId": 142341, * "intervalMs": 5000 * } * } * * import { addEventListener, clear } from 'openfin-notifications'; * * addEventListener('notification-action', (event: NotificationActionEvent)) => { * if (event.result.task === 'schedule-reminder') { * scheduleReminder(event.result.eventId, Date.now() + event.result.intervalMs); * } * clear(event.notification.id); * }); * ``` * */ onClick?: ActionDeclaration | null; /** * Tooltip key of the template fragment. * * The string tooltip associated with this fragment will be looked up in templateData map with this key. * * * Example: * ```ts * const myTemplate = { * body: { * compositions: [{ * minTemplateAPIVersion: '1', * layout: { * type: "actionableText", * dataKey: 'message', * tooltipKey: 'tooltipxyz', * }, * }], * }, * } * * const notificationOption: TemplateCustom = { * //... * templateOptions: myTemplate, * templateData: { * message: 'view stock tracker', * tooltipxyz: 'My Custom Tooltip', * } * }; * ``` * */ tooltipKey?: string; } export type TextTemplateFragment = PresentationTemplateFragment<'text'>; export type ImageTemplateFragment = PresentationTemplateFragment<'image'> & ActionableFragment; export type ListTemplateFragment = PresentationTemplateFragment<'list'>; export type ActionableTextTemplateFragment = PresentationTemplateFragment<'actionableText'> & ActionableFragment; /** * Configuration options for the custom notification template. */ export interface CustomTemplateOptions { /** * Configuration options for the custom notification template body. */ body: BodyTemplateOptions; /** * Configuration options for the custom notification template's modifications on the notification's indicator section. */ indicator?: IndicatorTemplateOptions; /** * Configuration options for the custom notification template's modifications on the notification's button section. */ buttons?: ButtonTemplateOptions; } /** * Default markdown template. Contains a markdown body and forms data. */ export interface TemplateMarkdown extends Omit, 'template'> { template?: 'markdown'; /** * Notification body text. * * This is the main notification content, displayed below the notification title. The notification will expand to fit the length of this text. * Markdown may be used in the body text to control how it is styled when rendered. * With the exception of links and code blocks, all basic syntax as documented [here](https://www.markdownguide.org/basic-syntax) is supported. */ body: string; /** * A collection of form fields or a form definition (Form) * @example * ```ts * [ * { * key: 'phone', * type: 'string', * label: 'Phone', * helperText: * 'Must be in the following formats 123-456-7890, 123 456 7890, (123) 456 7890 or 1234567890', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * }, * { * key: 'email', * type: 'string', * label: 'Email', * helperText: 'We will use this email to send you the report after we crawl your website', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * } * ] * ``` */ form?: NotificationFormData | Form | null; } /** * Simple template that can render a list of name-value pairs. */ export interface TemplateList extends BaseNotificationOptions<'list'> { /** * Notification list template data. */ list: Record; } /** * Notification that renders custom templates. */ export interface TemplateCustom extends BaseNotificationOptions<'custom'> { templateOptions: CustomTemplateOptions; /** * Data associated with the custom notification template's presentation fragments. */ templateData: CustomTemplateData; /** * A collection of form fields or a form definition (Form) * @example * ```ts * [ * { * key: 'phone', * type: 'string', * label: 'Phone', * helperText: * 'Must be in the following formats 123-456-7890, 123 456 7890, (123) 456 7890 or 1234567890', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * }, * { * key: 'email', * type: 'string', * label: 'Email', * helperText: 'We will use this email to send you the report after we crawl your website', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * } * ] * ``` */ form?: NotificationFormDataWithRequiredLabel | Form | null; } export interface FormSettings { /** * Controls that display of (Required) or (Optional) labels next to form fields. */ displayFieldRequirementStatus?: boolean; } export interface Form extends FormSettings { /** * A collection of form fields. * @example * ```ts * [ * { * key: 'phone', * type: 'string', * label: 'Phone', * helperText: * 'Must be in the following formats 123-456-7890, 123 456 7890, (123) 456 7890 or 1234567890', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * }, * { * key: 'email', * type: 'string', * label: 'Email', * helperText: 'We will use this email to send you the report after we crawl your website', * widget: { * type: 'Text' * }, * validation: { * required: { * arg: true * } * } * } * ] * ``` */ fields: ReadonlyArray; }