import { Injectable } from "@angular/core" ; import { FilterSelection , FilterSelectionOption , } from "../../filter/filter-selection/filter-selection" ; import { BooleanFilterConfig , FilterConfig , PrebuiltFilterConfig , } from "./EntityListConfig" ; import { Entity , EntityConstructor } from "../../entity/model/entity" ; import { CONFIGURABLE_ENUM_CONFIG_PREFIX , ConfigurableEnumConfig , } from "../../configurable-enum/configurable-enum.interface" ; import { ConfigService } from "../../config/config.service" ; import { LoggingService } from "../../logging/logging.service" ; import { EntitySchemaField } from "../../entity/schema/entity-schema-field" ; import { FilterComponentSettings } from "./filter-component.settings" ; import { DynamicEntityService } from "../../entity/dynamic-entity.service" ; @ Injectable ( { providedIn : "root" , } ) export class FilterGeneratorService { constructor ( private configService , private loggingService , private dynamicEntityService ) { } param filtersConfig param entityConstructor param data param onlyShowUsedOptions async generate < T extends Entity > ( filtersConfig , entityConstructor , data , onlyShowUsedOptions = false ) { const filterSettings = [ ] ; for ( const filter of filtersConfig ) { const schema = entityConstructor . schema . get ( filter . id ) || { } ; const fs = { filterSettings : new FilterSelection ( filter . id , [ ] , filter . label || schema . label ) , display : filter . display , } ; try { fs . filterSettings . options = await this . getFilterOptions ( filter , schema , data ) ; } catch ( e ) { this . loggingService . warn ( `Could not init filter: ${ filter . id }: ${ e }` ) ; } if ( onlyShowUsedOptions ) { fs . filterSettings . options = fs . filterSettings . options . filter ( ( option ) => data . filter ( fs . filterSettings . getFilterFunction ( option . key ) ) . length > 0 ) ; } if ( fs . filterSettings . options ?. length > 1 ) { fs . selectedOption = filter . hasOwnProperty ( "default" ) ? filter . default : fs . filterSettings . options [ 0 ] . key ; filterSettings . push ( fs ) ; } } return filterSettings ; } private async getFilterOptions < T extends Entity > ( config , schema , data ) { if ( config . type === "prebuilt" ) { return ( config as PrebuiltFilterConfig < T > ) . options ; } else if ( schema . dataType === "boolean" || config . type === "boolean" ) { return this . createBooleanFilterOptions ( config as BooleanFilterConfig ) ; } else if ( schema . dataType === "configurable-enum" ) { return this . createConfigurableEnumFilterOptions ( config . id , schema . innerDataType ) ; } else if ( this . dynamicEntityService . hasAnyRegisteredEntity ( config . type , schema . additional ) ) { return await this . createEntityFilterOption ( config . id , config . type || schema . additional ) ; } else { const options = [ ... new Set ( data . map ( ( c ) => c [ config . id ] ) ) ] ; return FilterSelection . generateOptions ( options , config . id ) ; } } private createBooleanFilterOptions < T extends Entity > ( filter ) { return [ { key : "all" , label : filter . all , filterFun : ( ) => true } , { key : "true" , label : filter . true , filterFun : ( c ) => c [ filter . id ] , } , { key : "false" , label : filter . false , filterFun : ( c ) => ! c [ filter . id ] , } , ] ; } private createConfigurableEnumFilterOptions < T extends Entity > ( property , enumId ) { const options = [ { key : "all" , label : $localize `:Filter label:All` , filterFun : ( e ) => true , } , ] ; const enumValues = this . configService . getConfig < ConfigurableEnumConfig > ( CONFIGURABLE_ENUM_CONFIG_PREFIX + enumId ) ; for ( const enumValue of enumValues ) { options . push ( { key : enumValue . id , label : enumValue . label , filterFun : ( entity ) => entity [ property ] ?. id === enumValue . id , } ) ; } return options ; } private async createEntityFilterOption < T extends Entity > ( property , entityType ) { const filterEntities = await this . dynamicEntityService . loadType ( entityType ) ; const options = [ { key : "all" , label : $localize `:Filter option:All` , filterFun : ( e ) => true , } , ] ; options . push ( ... filterEntities . map ( ( filterEntity ) => { return { key : filterEntity . getId ( ) , label : filterEntity . toString ( ) , filterFun : ( entity ) => { if ( Array . isArray ( entity [ property ] ) ) { return entity [ property ] . includes ( filterEntity . getId ( ) ) ; } else { return entity [ property ] === filterEntity . getId ( ) ; } } , } ; } ) ) ; return options ; } }