@leanix/reporting
Version:
Library for writing LeanIX EAM reports
1,362 lines (1,360 loc) • 109 kB
TypeScript
declare const lx: lxr.LxCustomReportLib;
declare module lxr
{
interface HostReportSetup extends ReportSetup {
settings: HostReportSetupSettings;
}
interface HostReportSetupSettings extends ReportSetupSettings {
features: Feature[];
}
type FeatureType = 'FUNCTIONAL' | 'QUOTA';
type FeatureStatus = 'DISABLED' | 'ENABLED';
interface Feature {
id?: string;
name?: string;
type?: FeatureType;
description?: string;
status?: FeatureStatus;
quota?: number;
roles?: string[];
customized?: boolean;
}
/**
* Entry class of the LeanIX Reporting Library.
* An instance of this class is globally available as `lx` variable.
*
* @example
* ```js
* // The sequence to initialise the library for a report looks like this:
* lx.init()
* .then(function (setupInfo) {
* // Process setupInfo and create config object
* var config = {};
* lx.ready(config);
* });
* ```
*/
export class LxCustomReportLib {
table: ReportLibTable;
get latestPublishedState(): any;
readonly dataModelHelpers: DataModelHelpers;
private messenger;
private _currentSetup;
private latestFacetsResults;
private _latestPublishedState;
private customDropdownCallbacks;
private latestMouseEvent;
private latestFocusedElement;
constructor();
/**
* Starts initialisation of the reporting framework. Returns a promise
* which is resolved once initialisation with the framework is finished. The
* resolved promise contains a {@link ReportSetup} instance with information
* provided to you through the framework.
* With that information you should be able to set up your report properly. Once
* that is done the {@link LxCustomReportLib.ready} function needs be called to signal
* that the report is ready to receive and process data and user events.
*
* @return A promise that resolves to the ReportSetup object
*/
init(): Promise<ReportSetup>;
/**
* Signals that the custom report is ready. A configuration must be provided
* to tell the framework about the requirements of the report (most importantly which data it needs).
* The provided configuration acts as an interface between the report code
* and the report framework.
*
* @param {ReportConfiguration} [configuration={}] Configuration object
*/
ready(configuration?: ReportConfiguration): void;
/**
* Getter to receive the current state of the report setup.
* The object is only available if the report already called a successful init() {@link LxCustomReportLib.init}.
*/
get currentSetup(): HostReportSetup;
/**
* In case the report has new requirements towards the report framework it can
* update the configuration that was initially passed to {@link LxCustomReportLib.ready}.
*
* @param configuration
*/
updateConfiguration(configuration: ReportConfiguration): void;
/**
* A static tableConfig should be returned via {@link ReportConfiguration.tableConfigCallback},
* but if the tableConfig is dynamic, this function can be used to update it at any time.
*
* Hint: if the provided attribute is a string field name, which is not present in the data model, this
* field would be ignored, and not shown as a table column.
*
* @param tableConfig
*/
updateTableConfig(tableConfig: ReportTableConfig): void;
/**
* Execute a custom GraphQL query to the LeanIX GraphQL API.
*
* @param query GraphQL query
* @param variables GraphQL variables
* @return A promise that resolves to the resulting data
* @example
* ```js
* lx.executeGraphQL(`{
* allFactSheets(factSheetType: ITComponent) {
* edges {
* node {
* id
* name
* type
* description
* }
* }
* }
* }`)
* ```
*/
executeGraphQL(query: string, variables?: string, trackingKey?: string): Promise<any>;
/**
* Get projections from the impact service.
*
* @param attributes Fact Sheet attributes that the projection items should include.
* @param filters Filter definition for the projection items
* @param pointsOfView Amount of different point of views that the projection should include.
*
* @beta
*/
getProjections(attributes: ProjectionAttribute[], filters: ProjectionFilter[], pointsOfView: PointOfViewInput[]): Promise<ProjectionsResponse>;
/**
* Get all Fact Sheets from the GraphQL endpoint.
*
* @param factSheetType Fact Sheet type that needs to match.
* @param attributes Fact Sheet attributes that the response should include.
* @param facetSelection Filter definition for the Fact Sheets, if Composite Filters are defined, they are used instead of the normal Facet Filters.
* @param pointsOfView A record of different point of views and their associated keys that the response should include and will return the Fact Sheets per each point of view key.
* @param options Optional options to further specify the Fact Sheets
*
* @beta
*/
getAllFactSheets(factSheetType: string, attributes: AttributeDescription[], facetSelection: ReportFacetsSelection, pointsOfView: Record<string, GraphQLPointOfViewInput>, options?: GraphQLOptions): Promise<ReportAllFactSheetsResponse>;
/**
* Get a list of measurements from the metrics service.
*
* @param nameOnly Set this to true to receive only the measurement names
* @return A promise that resolves to an array of measurements
*
* @beta
*/
getMetricsMeasurements(nameOnly?: boolean): Promise<MetricsMeasurement[]>;
/**
* Get raw data for a metrics time series.
*
* @param query A metrics service query
* @return A promise that resolves to the raw series data
*
* @beta
*/
getMetricsRawSeries(query: string): Promise<number[][]>;
/**
* Allows making XHR requests through the parent's origin.
*
* @param method The HTTP method for the request. GET, PUT, and POST requests are permitted.
* For POST and PUT requests, not every endpoint is allowed.
* @param path Relative URL for the request.
* @param body Optional body for POST and PUT requests. Defaults to an empty object.
* @param responseType The expected type of the response. Can be 'text' or 'blob'. Defaults to 'text'.
* @param extendedHandling Optional boolean to add a custom header for extended request handling.
* If true, adds 'x-gateway-handle-request: EXTENDED' header. Defaults to false.
* @return A promise that resolves to the returned data.
*/
executeParentOriginXHR(method: 'GET' | 'POST' | 'PUT', path: string, body?: any, responseType?: 'text' | 'blob', extendedHandling?: boolean): Promise<any>;
/**
* Get the current filter result.
*
* @return Current filter result
*/
getFilterResult(): any[];
/**
* Show a dialog to the user to select one or more Fact Sheets.
*
* @param config Configures the Fact Sheet selection.
* @return A promise that resolves to the selected Fact Sheet(s)
* or to `false` if the user canceled the selection
*/
requestFactSheetSelection(config: FactSheetSelectionConfig): Promise<false | any | any[]>;
/**
* Show a customisable configuration dialog to the user, in which the user can adjust report settings.
*
* @param fields An object containing the form fields to be displayed in this dialog.
* @param values An object with the same keys as __fields__ containing the initial values of those fields.
* @return A promise that resolves to the configuration confirmed by the user or to `false` if the user canceled the configuration
* @example
* ```js
* const fields = {
* level: {
* type: 'SingleSelect',
* label: 'Level to be displayed',
* options: [
* { value: '1', label: 'First level' },
* { value: '2', label: 'Both levels' }
* ]
* },
* hideEmpty: {
* type: 'Checkbox',
* label: 'Hide empty elements'
* }
* };
* const initialValues = {
* level: '2',
* hideEmpty: false
* };
*
* lx.openFormModal(fields, initialValues).then((values) => {
* if (values) {
* console.log('Selection:', values.level, values.hideEmpty);
* } else {
* console.log('Selection cancelled');
* }
* });
* ```
*/
openFormModal(fields: FormModalFields, values: FormModalValues, update?: (form: FormModal) => FormModal): Promise<FormModalValues | false>;
/**
* Show a customisable configuration dialog to the user, in which the user can adjust report settings.
*
* @param formModal An object {@link FormModal} containing the form fields, values, optional messages and optional valid flag.
* @param update Callback function called on form update.
* @return A promise that resolves to the configuration confirmed by the user or to `false` if the user canceled the configuration
* @example
* ```js
* const fields = {
* level: {
* type: 'SingleSelect',
* label: 'Level to be displayed',
* options: [
* { value: '1', label: 'First level' },
* { value: '2', label: 'Both levels' }
* ]
* },
* hideEmpty: {
* type: 'Checkbox',
* label: 'Hide empty elements'
* }
* };
* const values = {
* level: '2',
* hideEmpty: false
* };
*
* const messages = {
* level: {type: 'error', message:'example message'}
* }
*
* const update = (formModal: lxr.FormModal): lxr.FormModal => {return createFormModal()}
*
* lx.openFormModal({fields, values, messages, valid: true}, updated).then((values) => {
* if (values) {
* console.log('Selection:', values.level, values.hideEmpty);
* } else {
* console.log('Selection cancelled');
* }
* });
* ```
*/
openFormModal(formModal: FormModal, update?: (form: FormModal) => FormModal): Promise<FormModalValues | false>;
private doOpenFormModal;
/**
* Shows an overlaying sidepane with the provided elements.
*
* @beta
*/
openSidePane(sidePaneElements: SidePaneElements, update?: (factSheetUpdate: FactSheetUpdate) => void, onClick?: (sidepaneClick: SidePaneClick) => void): void;
/**
* This method allows you to open any link in a new browser tab. Only Chrome and Safari
* allows you to open a new tab out of an iframe. Since reports run inside an iframe,
* they are not allowed to open links in other browsers.
* Therefore, the framework allows you to request to open a link.
* This will show a popup box outside the iframe containing the link.
* The user can click on it in order to open the link in a new tab.
*
* It is not possible to directly open the link outside the iframe,
* since some browsers (e.g. Firefox) show a popup warning
* whenever a link is opened via a message coming from an iframe.
*
* @param url Link-URL
* @param @deprecated _target (target is ignored due to new popup behavior)
* @example
* ```js
* lx.openLink(this.baseUrl + '/factsheet/Application/28fe4aa2-6e46-41a1-a131-72afb3acf256');
* // The baseUrl can be found in the setup returned by lx.init() like this:
* // lx.init().then(setup => { this.baseUrl = setup.settings.baseUrl });
* ```
*/
openLink(url: string, _target?: string): void;
/**
* Navigate to a route within the LeanIX single-page app.
*
* @param url Relative URL within LeanIX to navigate to
*/
openRouterLink(url: string): void;
/**
* Navigate to inventory using provided filters
*
* @param filters Specified filters will be applied to inventory
*/
navigateToInventory(filters: NavigateToInventoryFilters): void;
/**
* In case the report has some sort of internal state it should be published
* to the framework. The state will be persisted when the user saves a certain
* report configuration. Once that report configuration is restored the framework
* will pass the saved state to the report on initialisation
* ({@link LxCustomReportLib.init} and {@link ReportSetup.savedState})
*
* @param state Custom report state
*/
publishState(state: any): void;
/**
* This function opens a "new" instance of the report in a separate tab.
* The state and facet filter parameters can be used as initial values for the new opened instance of the report.
*
* @param state Custom report state
* @param facetSelection Facet filter selection ({@link UISelection.facets})
* @param name Preset name of the new report opened in new tab. If not set, falls back to default name.
*
* @beta
*/
openReportInNewTab(state: any, facetSelection: ContextFacetsSelectionState[], name?: string): void;
/**
* Show a spinner on top of the report. Call {@link LxCustomReportLib.hideSpinner} to hide it again.
*/
showSpinner(): void;
/**
* This method allows reports to check on users' workspace permissions.
* Therefore, reports can enable features according to given workspace permissions.
* See: [Authorization Model]{@link https://docs-eam.leanix.net/docs/authorization-model}
* @param permissions Shiro permissions string array to check (example: `['BOOKMARKS:CREATE:VISUALIZER', 'BOOKMARKS:CREATE:REPORTS']` creation of diagram bookmarks)
* @returns Promise of all requested permissions as key-value pair of the requested user permissions.
*/
hasPermission(permissions: string[]): Promise<{
[permissionKey: string]: boolean;
}>;
/**
* Hide the spinner that was previously shown via {@link LxCustomReportLib.showSpinner}.
*/
hideSpinner(): void;
/**
* @deprecated. UI Elements are created on {@link ReportConfiguration.ui}.
*
* Display a button to toggle edit mode. Call {@link LxCustomReportLib.hideEditToggle} to hide it again.
* {@link ReportConfiguration.allowEditing} and {@link ReportConfiguration.toggleEditingCallback} need to be set
* to enable edit mode.
*/
showEditToggle(): void;
/**
* @deprecated. UI Elements are created or removed on {@link ReportConfiguration.ui}.
*
* Hide the button shown via {@link LxCustomReportLib.showEditToggle}.
*/
hideEditToggle(): void;
/**
* Send list of Fact Sheets that could not be displayed in the report due to missing data.
* A warning will be shown the user to inform them of this.
*
* @param excludedFactSheets List of excluded Fact Sheets
*/
sendExcludedFactSheets(excludedFactSheets: any[]): void;
/**
* Display a custom legend for a given number of items. If a legend from a view is currently
* displayed, the calls to this function are ignored.
*
* @param items Legend items to be displayed
* @exampleHide the spinner that was previously shown via
* ```js
* lx.showLegend([
* { label: 'foo', bgColor: '#ff0000' },
* { label: 'bar', bgColor: '#0000ff' }
* ])
* ```
*/
showLegend(items: LegendItem[]): void;
/**
* Show toastr of different types, with a custom message and a optional title.
*
* @param {ToastrType} type toastr type
* @param {string} message message content
* @param {string} [title] optional title
* @example
* ```js
* lx.showToastr('error', 'Something went wrong');
* lx.showToastr('warning', 'This is a warning', 'Attention');
* ```
*/
showToastr(type: ToastrType, message: string, title?: string): void;
/**
* Track report framework events with amplitude tracking.
*
* @param {ReportEvent} event event type and content
* @example
* ```js
* lx.trackReportEvent(
* {
* type: 'DataChange'
* reportType: 'net.leanix.matrix'
* baseFactSheetType: 'Application'
* view: 'lifecycle'
* cluster: ['relApplicationToBusinessCapability']
* drilldown: ['relToChild']
* }
* );
* ```
*/
trackReportEvent(event: ReportEvent): void;
/**
* Returns the translation of a custom translation key according to the user's current language.
* If the translation key can be resolved to a translated string interpolation will be applied.
* If the translation key resolves to an object the object will be returned.
*
* @param key Translation key
* @param interpolationData Interpolation data
* @return Translation string or object
* @example
* ```js
* // For the custom translation json
* {
* "header": {
* "title": "The title",
* "subtitle": "Subtitle",
* "description": "Hello {{name}}"
* }
* }
*
* lx.translateCustomKey('header.title') // => 'The title'
* lx.translateCustomKey('header') // => { "title": "The title", "subtitle": "Subtitle", "description": "Hello {{name}}" }
* lx.translateCustomKey('header.description', { name: 'John' }) // => 'Hello John'
* ```
*/
translateCustomKey(key: string, interpolationData?: Record<string, string | number>): string | any;
/**
* Returns the translation of a Fact Sheet type in singular or plural form.
* If multiplicity is not provided the singular version will be returned.
*
* @param fsType Fact Sheet type
* @param grammaticalNumber Grammatical number, i.e., 'singular' or 'plural'. Defaults to 'singular'.
* @return Translation
* @example
* ```js
* lx.translateFactSheetType('BusinessCapability') // => 'Business Capability'
* lx.translateFactSheetType('BusinessCapability', 'plural') // => 'Business Capabilities'
* ```
*/
translateFactSheetType(fsType: string, grammaticalNumber?: 'singular' | 'plural'): string;
/**
* Returns the translation of a field on a Fact Sheet.
* In case the field is not present in the translation model, the fieldName would be returned.
*
* @param fsType Fact Sheet type
* @param fieldName Name of the Fact Sheet field
* @return Translation
* @example
* ```js
* lx.translateField('Application', 'release') // => 'Release'
* ```
*/
translateField(fsType: string, fieldName: string): string;
/**
* Returns the translation of a field value for fields with predefined set of values (e.g. Single Select).
* In case the field value is not present in the translation model, the value would be returned.
*
* @param fsType Fact Sheet type
* @param fieldName Name of the Fact Sheet field
* @param value Value of this field
* @return Translation
* @example
* ```js
* lx.translateFieldValue('Application', 'functionalSuitability', 'appropriate') // => 'Appropriate'
* ```
*/
translateFieldValue(fsType: string, fieldName: string, value: string): string;
/**
* Returns the translation of the items a Fact Sheet relation links to.
* In case the relation is not present in the translation model, the relationName would be returned.
*
* @param relationName Name of the relation
* @return Translation
* @example
* ```js
* lx.translateRelation('relDataObjectToApplication') // => 'Applications'
* lx.translateRelation('relToChild') // => 'Children'
* ```
*/
translateRelation(relationName: string): string;
/**
* Returns the translation of a field present in a relation.
* In case the relation is not present in the translation model, the fieldName would be returned.
*
* @param relationName Name of the relation
* @param fieldName Field of the relation
* @return Translation
* @example
* ```js
* lx.translateRelationField('relDataObjectToApplication', 'usage') // => 'Usage'
* lx.translateRelationField('relApplicationToBusinessCapability', 'functionalSuitability') // => 'Functional Fit'
* ```
*/
translateRelationField(relationName: string, fieldName: string): string;
/**
* Returns the translation of a field value for fields with predefined set of values (e.g. Single Select)
* present in a relation. In case the relation, fieldName or fieldValue is not present in the translation model, the fieldValue would be returned.
*
* @param relationName Name of the relation
* @param fieldName Field of the relation
* @param fieldValue Value of this field
* @return Translation
* @example
* ```js
* lx.translateRelationFieldValue('relApplicationToBusinessCapability', 'functionalSuitability', 'appropriate') // => 'Appropriate'
* ```
*/
translateRelationFieldValue(relationName: string, fieldName: string, fieldValue: string): string;
/**
* Check if a given Feature is enabled for the current Workspace.
*
* @param featureId Feature identifier
* @return Boolean expressing if the feature is enabled.
*/
isFeatureEnabled(featureId: string): Promise<boolean>;
/**
* Returns a formatted currency number according to the users currency settings.
*
* @param value Value to be formatted
* @param minimumFractionDigits Minimum number of digits to use for the fraction
* @param compact Defines whether to show compact display
* @param locale Defines locale info 'de-DE', 'en-EN'
* @param maximumFractionDigits Maximum number of digits to use for the fraction. When specified,
* restricts the number of decimal places shown (useful for rounding).
* @return Currency string
* @example
* ```js
* lx.formatCurrency(123.50, 2) => '€123.50'
* lx.formatCurrency(12333.50, 0, true) => '€12K'
* lx.formatCurrencyWithoutCode(10255, 0, true, undefined, 1) => '€10.3K'
* lx.formatCurrency(1288893.50, 2, true, 'de-DE') => '1,29 Mio. €'
* ```
*/
formatCurrency(value: number, minimumFractionDigits?: number, compact?: boolean, locale?: string, maximumFractionDigits?: number): string;
/**
* Returns the configured or default meta data for a field at a Fact Sheet.
*
* @param fsType Fact Sheet type
* @param fieldName Name of a Fact Sheet field or relation
* @return Meta data
* @example
* ```js
* lx.getFactSheetFieldMetaData('Application', 'functionalSuitability')
* // Returns:
* // {
* // values: {
* // perfect: {
* // bgColor: '#fff',
* // color: '#000'
* // }
* // ...
* // }
* // }
* // Getting the actual background color for a field value:
* lx.getFactSheetFieldMetaData('Application', 'functionalSuitability').values['perfect'].bgColor
* ```
*/
getFactSheetFieldMetaData(fsType: string, fieldName: string): FieldViewMetaData | undefined;
/**
* Returns the configured or default meta data for a field of a Fact Sheet relation.
*
* @param fsType Fact Sheet type
* @param relationName Name of the directed relation
* @param fieldName Name of a field on the relation
* @return Meta data
* @example
* ```js
* lx.getFactSheetRelationFieldMetaData('Application', 'relApplicationToITComponent', 'technicalSuitability')
* // Returns:
* // {
* // values: {
* // fullyAppropriate: {
* // bgColor: '#fff',
* // color: '#000'
* // }
* // ...
* // }
* // }
*
* // Getting the actual background color for a field value:
* lx.getFactSheetRelationFieldMetaData(
* 'Application',
* 'relApplicationToITComponent',
* 'technicalSuitability'
* ).values['perfect'].bgColor
* ```
*/
getFactSheetRelationFieldMetaData(fsType: string, relationName: string, fieldName: string): FieldViewMetaData;
private setupPerformanceObserver;
private createReportRequirements;
private mountCallbacks;
private mountUISelectionCallback;
private mountUISelectionUpdateCallback;
private mountUIElementsButtonClickCallback;
private mountUIButtonCallback;
private mountFacetsCallbacks;
private mountFacetsResultCallback;
private validateConfig;
private mountSetupCallback;
private mountCustomDropdownSelectionCallbacks;
private mountExportDataCallback;
private mountTableConfigCallback;
private mountFormModalUpdate;
private mountSidepaneFactSheetUpdate;
private mountSidepaneClick;
private mountSidepaneClose;
private mountCallback;
private getLocationQuery;
private createReportExportData;
private getCurrentStyles;
private encodeAllImages;
private encodeImage;
private encodeSvgImage;
private translateHtmlTags;
private replaceInterpolations;
private mountDomEventPublishing;
private mountErrorEventPublishing;
private waitForElement;
}
export const lxCustomReportLib: LxCustomReportLib;
export {};
export class DataModelHelpers {
getRelationDefinition(enrichedDataModel: EnrichedDataModel, directionalRelation: string): RelationDataModel | null;
isConstrainingRelation(enrichedDataModel: EnrichedDataModel, relationName: string): boolean;
}
export type PaperOrientation = 'portrait' | 'landscape';
export interface BaseExportData {
name: string;
content: string;
styles?: string;
}
export interface SvgExportData extends BaseExportData {
inputType: 'SVG';
outputType: 'SVG';
}
export interface RasterImageExportData extends BaseExportData {
inputType: 'SVG' | 'HTML';
outputType: 'JPEG' | 'PNG';
}
export interface PdfExportData extends BaseExportData {
inputType: 'SVG' | 'HTML';
outputType: 'PDF';
fitHorizontally?: boolean;
fitVertically?: boolean;
/** @default 'A4' */
format?: PaperFormat;
/** @default 'portrait' */
orientation?: PaperOrientation;
/** @default { top: 0, right: 0, bottom: 0, left: 0 } */
margin?: PageMargin;
footer?: string;
header?: string;
}
export type PaperFormat = 'A0' | 'A1' | 'A2' | 'A3' | 'A4' | 'Letter';
export interface PageMargin {
/** @default '0' */
top?: number;
/** @default '0' */
right?: number;
/** @default '0' */
bottom?: number;
/** @default '0' */
left?: number;
}
export type ImageExportData = RasterImageExportData | SvgExportData;
export type ExportData = PdfExportData | ImageExportData;
export interface ExportInitialData {
title?: string;
data: string;
styles: string;
fileNameSuffix?: string;
inputType: ExportData['inputType'];
paperSize: {
format: 'a0' | 'a1' | 'a2' | 'a3' | 'a4' | 'letter' | 'autofit';
};
orientation: PaperOrientation | null;
fitHorizontally: boolean;
fitVertically: boolean;
viewLegendData?: {
html: string;
styles: string;
};
usage?: 'thumbnail' | 'export';
}
export interface ReportUser {
id: string;
firstName: string;
lastName: string;
email: string;
userName: string;
}
export type ReportFactSheetPermissibleAction = 'READ' | 'CREATE' | 'UPDATE' | 'DELETE' | 'ARCHIVE' | 'INLINE_EDIT';
export interface ReportFactSheetFieldPermissions {
[fieldName: string]: ReportFactSheetPermissibleAction[];
}
export interface ReportFactSheetRelationPermission {
self: ReportFactSheetPermissibleAction[];
}
export interface ReportFactSheetRelationPermissions {
[relationName: string]: ReportFactSheetRelationPermission;
}
export interface ReportFactSheetPermission {
self: ReportFactSheetPermissibleAction[];
fields: ReportFactSheetFieldPermissions;
relations: ReportFactSheetRelationPermissions;
}
export interface ReportFactSheetPermissions {
[factSheetName: string]: ReportFactSheetPermission;
}
export type Language = 'en' | 'de' | 'es' | 'fr' | 'pt';
export interface ReportSetupSettings {
baseUrl: string;
environment: Environment;
viewModel: ViewModel;
dataModel: EnrichedDataModel;
tagModel: TagModel;
factSheetPermissions: ReportFactSheetPermissions;
translations: ReportSetupTranslations;
impactConfiguration?: ImpactConfiguration;
currency: ReportSetupCurrency;
currentUser: ReportUser;
language: Language;
workspace: Workspace;
page: PageContext;
mtmWorkspaceSettings: MtmWorkspaceSettings;
}
export interface ReportSetupConfig {
factSheetType?: string;
[others: string]: any;
}
export interface ReportSetupTranslations {
factSheetTypes: {
[key: string]: string;
};
relations: {
[relationName: string]: RelationTranslation;
};
fields: {
[factSheetType: string]: FactSheetFieldsTranslation;
};
/**
* The reports custom translation for the current language.
*/
custom: {
label: string;
[customKeys: string]: any;
};
}
export interface FactSheetFieldsTranslation {
[fieldName: string]: FieldTranslation;
}
export interface FieldTranslation {
label: string | null;
values: Record<string, FieldValueTranslation>;
}
export interface FieldValueTranslation {
label: string | null;
}
export interface RelationTranslation {
label: string | null;
fields: Record<string, FieldTranslation>;
}
export interface ReportSetupCurrency {
code: string;
symbol: string;
}
export interface Workspace {
id: string;
name: string;
/** @internal */
type: MtmWorkspaceType;
/** @internal */
status: MtmWorkspaceStatus;
/** @internal */
contract: {
/** @internal */
type: MtmContractType;
};
}
/** @internal */
export type MtmWorkspaceStatus = 'ACTIVE' | 'BLOCKED';
/** @internal */
export type MtmWorkspaceType = 'LIVE' | 'DEMO' | 'SANDBOX';
/** @internal */
export type MtmContractType = 'REGULAR' | 'TRIAL';
export interface FiscalYears {
default?: {
/**
* Month starting from 0 = Jan, 1 = Feb, ...
*/
month: number;
/**
* the day-of-the-month, starting from 1
*/
date: number;
};
}
/** Workspace settings that are stored in MTM */
export interface MtmWorkspaceSettings {
fiscalYears?: FiscalYears;
}
export interface BookmarkFilter {
/**
* The FactSheet type can be get and set with:
* - FacetsService.getSelectedFactSheetTypeFromFilters(facetFilter)
* - FacetsService.updateFactSheetTypeInFilters(facetFilter, newFactSheetType)
*/
fsType?: string;
facetFilter: FacetFilter[];
fullTextSearchTerm?: string;
factSheetIds?: string[];
sorting?: Sorting[];
}
export interface ReportingBookmarkState<T = any> {
filters: {
[key: string]: BookmarkFilter;
};
views: {
[context: string]: {
activeViewKey?: string;
factSheetType?: string;
viewOption?: ViewOption;
};
};
customState?: T | null;
customDropdownSelections?: ReportDropdownSelections;
tableConfig?: TableConfig;
tableSortings?: Sorting[];
/**
* @deprecated
*/
timeline?: TimelineBookmarkSelection;
}
export interface ReportSetup {
reportId: string;
bookmarkName: string;
config: ReportSetupConfig;
settings: ReportSetupSettings;
savedState?: ReportingBookmarkState;
}
export interface FacetFilter {
facetKey: string;
keys: string[];
operator?: FacetKeyOperator;
dateFilter?: DateFilter;
subscriptionFilter?: SubscriptionFilterInput;
excludeTransitiveRelations?: boolean;
subFilter?: {
facetFilters: FacetFilter[];
fullTextSearch?: string;
ids?: string[];
};
}
export type DateFilterType = 'POINT' | 'TODAY' | 'END_OF_MONTH' | 'END_OF_YEAR' | 'RANGE' | 'RANGE_STARTS' | 'RANGE_ENDS' | 'TIMELINE';
export interface DateFilter {
type: DateFilterType;
minDate?: string;
maxDate?: string;
from?: string;
to?: string;
useTimelineDates?: boolean;
}
/** Valid GraphQL FacetType; constants defined in facets.const.ts */
export type BackendFacetType = 'SIMPLE' | 'TAG' | 'FACTSHEETTYPE' | 'FACTSHEETSUBTYPE' | 'RELATION' | 'LIFECYCLE' | 'SUBSCRIPTIONS' | 'EXTERNAL_ID' | 'HIERARCHY';
/** Pseudo-FacetTypes implemented only in front-end; constants defined in facets.const.ts */
export type FrontendFacetType = 'FACT_SHEET_ID' | 'FULLTEXTSEARCH' | 'SINGLE_SELECT' | 'UNKNOWN' | 'AGGREGATION';
export type FacetType = BackendFacetType | FrontendFacetType;
export enum FacetKeyOperator {
OR = "OR",
AND = "AND",
NOR = "NOR"
}
interface FacetListEntry {
/**
* Key that identifies this FacetListEntry.
*/
key: string;
/**
* Name of the FacetListEntry
*/
name: string;
/**
* Translated label of the FacetListEntry
*/
label?: string;
/**
* How many search results can be expected if this
* facet list entry is selected.
*/
count: number;
/**
* Is this FacetListEntry selected. Default: false.
*/
selected?: boolean;
}
export interface FacetGroup {
/**
* Key of the facet.
* For facets of type TAG the facetKey contains the tag's UUID.
*/
facetKey: string;
/**
* The logical operation that is set for this facet.
*/
operator: FacetKeyOperator;
/**
* List of operators the backend supports for this facet.
*/
possibleOperators?: string[];
/**
* The type of the facet results.
* Depending on the type of the results the facet is rendered differently.
* 'UNKNOWN' is set when the information from the BE is missing, for example
* when the Facet is generated on the fly (in the Bookmarks)
*/
facetType: FacetType;
/**
* Might contain additional information depending on the 'facetType'.
* For facetType FACTSHEETSUBTYPE: contains the selected Fact Sheet type.
* For facetType TAG: contains the facet key.
*/
facetSubType?: string;
/**
* List of available entries.
*/
results: FacetListEntry[];
/**
* Subfilter applied to this facet.
*/
subFilter?: FacetSubfilter;
/**
* Optional date filter
*/
dateFilter?: DateFilter;
/**
* Optional subscription filter
*/
subscriptionFilter?: SubscriptionFilter;
/**
* Total number of available results (including the ones from results)
*/
total?: number;
/**
* Facet is open; default = true
*/
open?: boolean;
isSelected?: boolean;
/**
* Facet is visible
*/
visible?: boolean;
/**
* Facet is read-only
*/
readOnly?: boolean;
/**
* Facet is read-only
*/
initialValue?: FacetGroupSettingValue;
}
export interface FacetGroupSettingValue extends FacetFilter {
facetKey: string;
keys: string[];
operator?: FacetKeyOperator;
dateFilter?: DateFilter;
subscriptionFilter?: SubscriptionFilter;
facetType?: FacetType;
}
export interface SubscriptionFilter {
type: SubscriptionType;
role?: SubscriptionRole;
}
export interface SubscriptionRole {
id: string;
name: string;
description?: string;
comment?: string;
subscriptionType: SubscriptionType;
restrictToFactSheetTypes?: string[];
}
export type SubscriptionType = 'RESPONSIBLE' | 'OBSERVER' | 'ACCOUNTABLE';
export interface FacetSubfilter {
facetGroups?: FacetGroup[];
facetFilters?: FacetFilter[];
fullTextSearch?: string;
ids?: string[];
}
export interface SubscriptionFilterInput {
type: SubscriptionType;
roleId?: string;
}
export enum CompositeOperator {
OR = "OR",
AND = "AND"
}
export interface CompositeFactSheetFilter {
group: CompositeGroupFilter;
}
export interface CompositeGroupFilter {
operator: CompositeOperator;
elements: SimpleCompositeFilter[];
}
export interface SimpleCompositeFilter {
filter: CompositeFilter;
}
export interface CompositeFilter {
operator: CompositeOperator;
elements: FacetFilter[];
}
export type SortingMode = 'BY_FIELD' | 'BY_LIFECYCLE_LAST_PHASE';
export type SortingOrder = 'asc' | 'desc';
export interface Sorting {
mode?: SortingMode;
key: string;
order: SortingOrder;
}
export interface TableConfig {
columns: TableColumn[];
}
export interface TableColumn {
factSheetType: string;
key: string;
/**
* Field type
*/
type: DataModelFieldType;
virtualKey?: string;
/**
* Frontend attributes
* @type {string}
*/
sort?: string;
required?: boolean;
editable?: boolean;
sortable?: boolean;
align?: TableColumnAlign;
resizable?: boolean;
movable?: boolean;
width?: number;
label?: string;
expanded?: boolean;
isRelationColumn?: boolean;
isCustomColumn?: boolean;
}
export type DataModelFieldType = 'DOUBLE' | 'INTEGER' | 'LIFECYCLE' | 'LOCATION' | 'MULTIPLE_SELECT' | 'SINGLE_SELECT' | 'STRING' | 'EXTERNAL_ID' | 'PROJECT_STATUS' | 'AGGREGATED' | 'READ_ACCESS_CONTROL_LIST' | 'WRITE_ACCESS_CONTROL_LIST' | 'RELATION' | 'TAGS' | 'SUBSCRIPTIONS' | 'DATE_TIME' | 'COMPLETION' | 'QUALITYSEALSTATUS';
export type TableColumnAlign = 'LEFT' | 'RIGHT' | 'CENTER' | 'JUSTIFY';
export interface ReportDropdownSelections {
[dropdownId: string]: string;
}
/**
* Configures the reporting table for the report.
* It allows to specify the initial attributes
* that should be displayed in the table.
*
* Example:
* factSheetType: 'Application',
* attributes: ['release', 'alias'],
* relatedFactSheetTypes: \{
* BusinessCapability: 'relApplicationToBusinessCapability',
* UserGroup: 'relApplicationToUserGroup'
* \}
*/
export interface ReportTableConfig {
factSheetType: string;
attributes: ReportTableConfigAttribute[];
columns?: TableColumn[];
/**
* Maps Fact Sheet type to relation type in order to
* add them as subfilter in table view.
*/
relatedFactSheetTypes?: {
[facetsConfigKey: string]: string;
};
}
/**
* Represents a Fact Sheet attribute to be displayed in a table. The attribute can be either the field name, as string, or a table column for more advanced fields.
*/
export type ReportTableConfigAttribute = string | ReportTableColumn;
export interface ReportTableColumn {
key: string;
label?: string;
type: DataModelFieldType;
sortable?: boolean;
align?: TableColumnAlign;
/** A custom column is one that is provided by the report and does not correspond to an existing Fact Sheet attribute */
isCustomColumn?: boolean;
virtualKey?: string;
}
/**
* Represents one selectable entry.
*
* @deprecated Use `DropdownEntry` in the UI configuration instead.
*/
export interface CustomDropdownEntry {
id: string;
name: string;
/**
* This callback is invoked once the user selects the corresponding entry.
*/
callback?: (currentEntry: CustomDropdownEntry) => void;
}
/**
* Represents a custom dropdown menu with several entries.
*
* @deprecated Use {@link UIDropdown} in the UI configuration instead.
*/
export interface CustomDropdown {
id: string;
name: string;
entries: CustomDropdownEntry[];
position?: 'left' | 'right';
initialSelectionEntryId?: string;
}
/**
* Describes the available configuration options for a report.
*/
export interface ReportConfiguration {
/**
* Multiple facets configurations ({@link ReportFacetsConfig}) can be provided
* in order to allow the user to filter different aspects of your report.
*/
facets?: ReportFacetsConfig[];
menuActions?: {
/**
* Does the report provide configuration possibilities.
* If true: There will be a configuration action shown to the user,
* that triggers __configureCallback__.
*
* @default false.
*/
showConfigure?: boolean;
/**
* This callback is invoked whenever the user wants to see / change
* the reports configuration.
*/
configureCallback?: () => void;
/**
* Define custom dropdowns that are shown to the user and allow him or her
* to select different options that influcene how the report behaves or
* presents data.
*
* @deprecated Use `elements` in the UI configuration instead.
*/
customDropdowns?: CustomDropdown[];
};
/**
*
* This callback is invoked whenever the user changes the view of the report.
* It is also invoked, once the report view results are loaded during
* initialization.
*
* In order to define which views should be available to the user, you can
* specify a Fact Sheet type via {@link ReportConfiguration.reportViewFactSheetType}.
*/
reportViewCallback?: (view: ViewResult) => void;
/**
* If defined the views that are applicable for this Fact Sheet type will be
* available for the user to be selected from a dropdown.
* Whenever the view is fetched from the backend the view data will be
* provided via {@link ReportConfiguration.reportViewCallback}.
*/
reportViewFactSheetType?: string;
/**
* Additional options that can be provided for the view calculation.
*/
reportViewOption?: ViewOption;
/**
* Defines whether the reporting framework should allow the user to switch
* into a table view that shows the data of the report.
* If not specified the default value is `true`, so the table view will be
* allowed if not explicitly disabled.
*
* Hint: In order to configure the table (e.g. initially visible columns)
* for the report use {@link ReportConfiguration.tableConfigCallback}
*/
allowTableView?: boolean;
/**
* This callback is invoked one time after the report has been initialised to
* get an initial, static configuration for the table. If the configuration is dynamic or
* computed asynchronously, {@link LxCustomReportLib.ready} needs to be used instead.
*/
tableConfigCallback?: () => ReportTableConfig;
/**
* @deprecated. Use UIButton to show the edit toggle.
*
* Specifiy whether the user shall be able to edit the report.
* If the user toggles the editing mode the reporting framework
* calls {@link ReportConfiguration.toggleEditingCallback} to inform
* you about enabled or disabled edit mode.
*/
allowEditing?: boolean;
/**
* @deprecated. Use UIButton click callback to invoke an action for enable/disable.
*
* This callback is invoked whenever the user enables or disables editing.
* The action to enable or disable editing is only visible when {@link ReportConfiguration.allowEditing}
* is set to true.
*/
toggleEditingCallback?: (editingEnabled: boolean) => void;
/**
* The export options allow to influence the PDF or image export of a report.
*/
export?: ReportExportConfiguration;
/**
* `ui` defines the configuration of the UI elements to be displayed around the report.
*
* @beta
*/
ui?: UIConfiguration;
}
export interface ReportExportConfiguration {
/**
* Flag to disable export for the given report.
* This option hides the export capabilities within the report container.
* @default false
*/
disabled?: boolean;
/**
* CSS selector which specifies the DOM element whose contents should be
* extracted for export to PDF or image.
*/
exportElementSelector?: string;
/**
* The type of content that is extracted from the DOM
* to be exported. Default is HTML.
*
* Specify SVG if your report uses SVG elements for visualization.
*/
inputType?: 'HTML' | 'SVG';
/**
* autoScale has been renamed to {@link fitHorizontally} and will be
* removed in the near future.
*
* @default false
* @deprecated
*/
autoScale?: boolean;
/**
* fitHorizontally scales the content for PDF exports to fit it to the
* page width so that no content is cut off.
* It should not be enabled if the content is already responsive HTML.
*
* @default true
*/
fitHorizontally?: boolean;
/**
* fitVertically scales the content for PDF exports to fit it to the
* page height so that the content fits on a single page.
*
* @default true
*/
fitVertically?: boolean;
/**
* Paper format for PDF exports.
* @default 'a4'
*/
format?: 'a0' | 'a1' | 'a2' | 'a3' | 'a4' | 'letter' | 'autofit';
/**
* Paper orientation for PDF exports.
* @default 'portrait'
*/
orientation?: 'portrait' | 'landscape';
/**
* Usage of the export.
* Determines if the export is triggered for thumbnail creation or from the user.
* @default thumbnail
*/
usage?: 'thumbnail' | 'export';
/**
* This callback is invoked just before the report framework extracts the HTML
* from the report to export it as PDF or image. It allows to make adjustments
* to the HTML for exporting.
*/
beforeExport?: (exportElement: HTMLElement, reportExportConfig: ReportExportConfiguration) => HTMLElement | Promise<HTMLElement>;
}
export interface UIMinimalConfiguration {
/**
* `timeline` defines the timeline UI element.
*/
timeline?: UITimeline | null;
/**
* `elements` defines the configuration of each UI element.
*
*/
elements?: UIElements;
/**
* `showCompositeFilters` flag to show composite filters in the report ui
*
* @beta
*/
showCompositeFilters?: boolean;
}
export interface UIConfiguration extends UIMinimalConfiguration {
/**
* `update` provides a callback to react to changes from the UI elements.
*
* It's called when initializing the report's UI elements and whenever the user
* interacts with them.
*
* `selection` is an object that reflects the state of the current selection
* of the UI elements.
*
* `update` also allows modifying the ui configuration by returning the target configuration. Use `null` to
* destroy any visible elements. When using an `undefined` value for a specific element, the element remains
* untouched.
*
*/
update: (selection: UISelection) => undefined | UIMinimalConfiguration | Promise<UIMinimalConfiguration | undefined>;
}
/**
* `UIElements` defines the configuration needed to allow a report to show certain {@link UIElement} items in the Reports page.
*/
export interface UIElements {
/**
* `values` is the collection of values associated to the {@link UIElement} items.
*/
values: UIElementValues;
/**
* `root` defines the root structure of the {@link UIElements}.
*/
root: UIRoot;
}
/**
* `UIRoot` allows to define the root items structure with an optional `style` for basic templating.
*/
export interface UIRoot {
/**
* `items` define the collection of {@link UIElement} items to be used.
*/
items: UIElement[];
/**
* `style` allows a certain limited template styling for the `items`.
*/
style?: UIStyle;
}
/**
* `UIElementValues` defines a key-value collection of values that each {@link UIElement} has assigned.
* `UIElementValues` expects as a key the `id` property defined for a given {@link UIElement}. The type of value is
* dependent on the type of {@link UIElement} being used.
*/
export type UIElementValues = Record<string, unknown>;
/**
* `UIElementType` is a identificator for each type of UI element that is used.
*/
export type UIElementType = 'container' | 'dropdown' | 'groupDropdown' | 'factSheetDropdown' | 'buttonGroup' | 'button' | 'impactSourcePicker' | 'layoutMode' | 'zoom' | 'hierarchyDepth';
export interface UIBaseElement {
id: string;
type: UIElementType;
}
/**
* `UIElement` defines the different types of UI elements that are available to be defined in the Reports page.
*/
export type UIElement = UIContainer | UIDropdown | UIGroupDropdown | UIFactSheetDropdown | UIButtonGroup |