import { Capabilities } from 'src/core/public' ; import { IconType } from '@elastic/eui' ; public export enum FeatureCatalogueCategory { ADMIN = 'admin' , DATA = 'data' , OTHER = 'other' } public export interface FeatureCatalogueEntry { /** Unique string identifier for this feature. */ readonly id : string ; /** Title of feature displayed to the user. */ readonly title : string ; /**  FeatureCatalogueCategory to display this feature in.  readonly category : FeatureCatalogueCategory ; /** A tagline of feature displayed to the user. */ readonly subtitle ? : string ; /** One-line description of feature displayed to the user. */ readonly description : string ; /** EUI `IconType` for icon to be displayed to the user. EUI supports any known EUI icon, SVG URL, or ReactElement. */ readonly icon : IconType ; /** URL path to link to this future. Should not include the basePath. */ readonly path : string ; /** Whether or not this link should be shown on the front page of OpenSearch Dashboards. */ readonly showOnHomePage : boolean ; /** An ordinal used to sort features relative to one another for display on the home page */ readonly order ? : number ; /** Optional function to control visibility of this feature. */ readonly visible ? : ( ) => boolean ; /** Unique string identifier of the solution this feature belongs to */ readonly solutionId ? : string ; } public export interface FeatureCatalogueSolution { /** Unique string identifier for this solution. */ readonly id : string ; /** Title of solution displayed to the user. */ readonly title : string ; /** The tagline of the solution displayed to the user. */ readonly subtitle : string ; /** One-line description of the solution displayed to the user. */ readonly description ? : string ; /** A list of use cases for this solution displayed to the user. */ readonly appDescriptions : string [ ] ; /** EUI `IconType` for icon to be displayed to the user. EUI supports any known EUI icon, SVG URL, or ReactElement. */ readonly icon : IconType ; /** URL path to link to this future. Should not include the basePath. */ readonly path : string ; /** An ordinal used to sort solutions relative to one another for display on the home page */ readonly order ? : number ; } export class FeatureCatalogueRegistry { private capabilities : Capabilities | null = null ; private readonly features = new Map < string , FeatureCatalogueEntry > ( ) ; private readonly solutions = new Map < string , FeatureCatalogueSolution > ( ) ; public setup ( ) { return { register : ( feature ) => { if ( this . features . has ( feature . id ) ) { throw new Error ( `Feature with id [${ feature . id }] has already been registered. Use a unique id.` ) ; } this . features . set ( feature . id , feature ) ; } , registerSolution : ( solution ) => { if ( this . solutions . has ( solution . id ) ) { throw new Error ( `Solution with id [${ solution . id }] has already been registered. Use a unique id.` ) ; } this . solutions . set ( solution . id , solution ) ; } , } ; } public start ( { capabilities } ) { this . capabilities = capabilities ; } public get ( ) { if ( this . capabilities === null ) { throw new Error ( 'Catalogue entries are only available after start phase' ) ; } const capabilities = this . capabilities ; return [ ... this . features . values ( ) ] . filter ( ( entry ) => capabilities . catalogue [ entry . id ] !== false && ( entry . visible ? entry . visible ( ) : true ) ) . sort ( compareByKey ( 'title' ) ) ; } public getSolutions ( ) { if ( this . capabilities === null ) { throw new Error ( 'Catalogue entries are only available after start phase' ) ; } const capabilities = this . capabilities ; return [ ... this . solutions . values ( ) ] . filter ( ( solution ) => capabilities . catalogue [ solution . id ] !== false ) . sort ( compareByKey ( 'title' ) ) ; } public removeFeature ( appId ) { this . features . delete ( appId ) ; } } export type FeatureCatalogueRegistrySetup = ReturnType < FeatureCatalogueRegistry [ 'setup' ] > ; const compareByKey = < T > ( key ) => ( left , right ) => { if ( left [ key ] < right [ key ] ) { return - 1 ; } else if ( left [ key ] > right [ key ] ) { return 1 ; } else { return 0 ; } } ;