2021-10-19 02:31:32 +02:00
import TagRenderingConfig from "./TagRenderingConfig" ;
import SharedTagRenderings from "../../Customizations/SharedTagRenderings" ;
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson" ;
import { Utils } from "../../Utils" ;
export default class WithContextLoader {
2021-10-22 18:53:07 +02:00
protected readonly _context : string ;
2021-11-07 16:34:51 +01:00
private readonly _json : any ;
2021-11-10 18:42:31 +01:00
2021-11-14 18:01:48 +01:00
public static getKnownTagRenderings : ( ( id : string ) = > TagRenderingConfigJson [ ] ) = function ( id ) {
const found = SharedTagRenderings . SharedTagRenderingJson . get ( id )
if ( found !== undefined ) {
return [ found ]
} else {
return [ ]
}
2021-11-10 18:42:31 +01:00
}
2021-10-22 18:53:07 +02:00
2021-10-19 02:31:32 +02:00
constructor ( json : any , context : string ) {
this . _json = json ;
this . _context = context ;
}
/ * * G i v e n a k e y , g e t s t h e c o r r e s p o n d i n g p r o p e r t y f r o m t h e j s o n ( o r t h e d e f a u l t i f n o t f o u n d
*
* The found value is interpreted as a tagrendering and fetched / parsed
* * /
public tr ( key : string , deflt ) {
const v = this . _json [ key ] ;
if ( v === undefined || v === null ) {
if ( deflt === undefined ) {
return undefined ;
}
return new TagRenderingConfig (
deflt ,
` ${ this . _context } . ${ key } .default value `
) ;
}
if ( typeof v === "string" ) {
const shared = SharedTagRenderings . SharedTagRendering . get ( v ) ;
if ( shared ) {
return shared ;
}
}
return new TagRenderingConfig (
v ,
` ${ this . _context } . ${ key } `
) ;
}
/ * *
* Converts a list of tagRenderingCOnfigJSON in to TagRenderingConfig
* A string is interpreted as a name to call
* /
2021-10-22 18:53:07 +02:00
public ParseTagRenderings (
2021-11-11 17:14:03 +01:00
tagRenderings : ( string | { builtin : string , override : any } | TagRenderingConfigJson ) [ ] ,
options ? : {
/ * *
* Throw an error if 'question' is defined
* /
readOnlyMode? : boolean ,
requiresId? : boolean
prepConfig ? : ( ( config : TagRenderingConfigJson ) = > TagRenderingConfigJson )
}
2021-11-07 16:34:51 +01:00
) : TagRenderingConfig [ ] {
2021-10-19 02:31:32 +02:00
if ( tagRenderings === undefined ) {
return [ ] ;
}
2021-10-22 18:53:07 +02:00
2021-10-19 02:31:32 +02:00
const context = this . _context
2021-11-11 17:14:03 +01:00
options = options ? ? { }
if ( options . prepConfig === undefined ) {
options . prepConfig = c = > c
2021-10-22 18:53:07 +02:00
}
2021-11-14 18:01:48 +01:00
const preparedConfigs : TagRenderingConfigJson [ ] = [ ]
2021-10-19 02:31:32 +02:00
for ( let i = 0 ; i < tagRenderings . length ; i ++ ) {
2021-10-22 18:53:07 +02:00
let renderingJson = tagRenderings [ i ]
2021-11-15 14:31:21 +01:00
if ( renderingJson === "questions" ) {
renderingJson = {
id : "questions"
}
}
2021-10-19 02:31:32 +02:00
if ( typeof renderingJson === "string" ) {
renderingJson = { builtin : renderingJson , override : undefined }
}
2021-11-14 18:01:48 +01:00
if ( renderingJson [ "builtin" ] === undefined ) {
const patchedConfig = options . prepConfig ( < TagRenderingConfigJson > renderingJson )
preparedConfigs . push ( patchedConfig )
continue
}
const renderingId = renderingJson [ "builtin" ]
let sharedJsons = [ ]
if ( typeof renderingId === "string" ) {
sharedJsons = WithContextLoader . getKnownTagRenderings ( renderingId )
} else {
sharedJsons = [ ] . concat ( . . . ( < string [ ] > renderingId ) . map ( id = > WithContextLoader . getKnownTagRenderings ( id ) ) )
}
if ( sharedJsons . length === 0 ) {
const keys = Array . from ( SharedTagRenderings . SharedTagRenderingJson . keys ( ) ) ;
throw ` Predefined tagRendering ${ renderingId } not found in ${ context } . \ n Try one of ${ keys . join (
", "
) } \ n If you intent to output this text literally , use { \ "render\": <your text>} instead" } ` ;
}
for ( let sharedJson of sharedJsons ) {
2021-10-19 02:31:32 +02:00
if ( renderingJson [ "override" ] !== undefined ) {
2021-11-07 15:31:51 +01:00
sharedJson = Utils . Merge ( renderingJson [ "override" ] , JSON . parse ( JSON . stringify ( sharedJson ) ) )
2021-10-19 02:31:32 +02:00
}
2021-11-14 18:01:48 +01:00
const patchedConfig = options . prepConfig ( < TagRenderingConfigJson > sharedJson )
preparedConfigs . push ( patchedConfig )
2021-10-19 02:31:32 +02:00
}
2021-11-14 18:01:48 +01:00
}
2021-10-22 18:53:07 +02:00
2021-11-14 18:01:48 +01:00
const renderings : TagRenderingConfig [ ] = [ ]
for ( let i = 0 ; i < preparedConfigs . length ; i ++ ) {
const preparedConfig = preparedConfigs [ i ] ;
const tr = new TagRenderingConfig ( preparedConfig , ` ${ context } .tagrendering[ ${ i } ] ` ) ;
2021-11-11 17:14:03 +01:00
if ( options . readOnlyMode && tr . question !== undefined ) {
throw "A question is defined for " + ` ${ context } .tagrendering[ ${ i } ], but this is not allowed at this position - probably because this rendering is an icon, badge or label `
}
if ( options . requiresId && tr . id === "" ) {
throw ` ${ context } .tagrendering[ ${ i } ] has an invalid ID - make sure it is defined and not empty `
}
2021-10-19 02:31:32 +02:00
renderings . push ( tr )
}
return renderings ;
}
}