2021-08-07 23:11:34 +02:00
import { Translation } from "../../UI/i18n/Translation" ;
import { TagsFilter } from "../../Logic/Tags/TagsFilter" ;
import FilterConfigJson from "./Json/FilterConfigJson" ;
import Translations from "../../UI/i18n/Translations" ;
import { TagUtils } from "../../Logic/Tags/TagUtils" ;
2022-01-07 17:31:39 +01:00
import ValidatedTextField from "../../UI/Input/ValidatedTextField" ;
import { Utils } from "../../Utils" ;
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson" ;
import { AndOrTagConfigJson } from "./Json/TagConfigJson" ;
2021-08-07 23:11:34 +02:00
export default class FilterConfig {
2021-09-27 18:35:32 +02:00
public readonly id : string
public readonly options : {
2021-08-07 23:11:34 +02:00
question : Translation ;
osmTags : TagsFilter ;
2022-01-07 17:31:39 +01:00
originalTagsSpec : string | AndOrTagConfigJson
fields : { name : string , type : string } [ ]
2021-08-07 23:11:34 +02:00
} [ ] ;
2022-01-07 17:31:39 +01:00
2021-08-07 23:11:34 +02:00
constructor ( json : FilterConfigJson , context : string ) {
2021-09-09 00:05:51 +02:00
if ( json . options === undefined ) {
2021-09-06 22:19:57 +02:00
throw ` A filter without options was given at ${ context } `
}
2021-09-27 18:35:32 +02:00
if ( json . id === undefined ) {
throw ` A filter without id was found at ${ context } `
}
2021-11-07 16:34:51 +01:00
if ( json . id . match ( /^[a-zA-Z0-9_-]*$/ ) === null ) {
2021-09-27 18:35:32 +02:00
throw ` A filter with invalid id was found at ${ context } . Ids should only contain letters, numbers or - _ `
}
2021-09-06 22:19:57 +02:00
2021-09-09 00:05:51 +02:00
if ( json . options . map === undefined ) {
2021-09-06 22:19:57 +02:00
throw ` A filter was given where the options aren't a list at ${ context } `
}
2021-09-27 18:35:32 +02:00
this . id = json . id ;
2021-08-07 23:11:34 +02:00
this . options = json . options . map ( ( option , i ) = > {
2022-01-07 17:31:39 +01:00
const ctx = ` ${ context } .options[ ${ i } ] ` ;
2021-08-07 23:11:34 +02:00
const question = Translations . T (
option . question ,
2022-01-07 17:31:39 +01:00
` ${ ctx } .question `
2021-08-07 23:11:34 +02:00
) ;
2022-01-07 17:31:39 +01:00
let osmTags = TagUtils . Tag (
option . osmTags ? ? { and : [ ] } ,
` ${ ctx } .osmTags `
) ;
2021-09-09 00:05:51 +02:00
if ( question === undefined ) {
2022-01-07 17:31:39 +01:00
throw ` Invalid filter: no question given at ${ ctx } `
2021-09-07 00:23:00 +02:00
}
2021-08-07 23:11:34 +02:00
2022-01-07 17:31:39 +01:00
const fields : { name : string , type : string } [ ] = ( ( option . fields ) ? ? [ ] ) . map ( ( f , i ) = > {
const type = f . type ? ? "string"
if ( ! ValidatedTextField . AllTypes . has ( type ) ) {
throw ` Invalid filter: ${ type } is not a valid validated textfield type (at ${ ctx } .fields[ ${ i } ]) \ n \ tTry one of ${ Array . from ( ValidatedTextField . AllTypes . keys ( ) ) . join ( "," ) } `
}
if ( f . name === undefined || f . name === "" || f . name . match ( /[a-z0-9_-]+/ ) == null ) {
throw ` Invalid filter: a variable name should match [a-z0-9_-]+ at ${ ctx } .fields[ ${ i } ] `
}
return {
name : f.name ,
type
}
} )
if ( fields . length > 0 ) {
// erase the tags, they aren't needed
osmTags = TagUtils . Tag ( { and : [ ] } )
}
return { question : question , osmTags : osmTags , fields , originalTagsSpec : option.osmTags } ;
2021-08-07 23:11:34 +02:00
} ) ;
2021-11-07 16:34:51 +01:00
2022-01-07 17:31:39 +01:00
if ( this . options . some ( o = > o . fields . length > 0 ) && this . options . length > 1 ) {
throw ` Invalid filter at ${ context } : a filter with textfields should only offer a single option. `
}
2021-11-07 16:34:51 +01:00
if ( this . options . length > 1 && this . options [ 0 ] . osmTags [ "and" ] ? . length !== 0 ) {
throw "Error in " + context + "." + this . id + ": the first option of a multi-filter should always be the 'reset' option and not have any filters"
2021-09-30 00:26:21 +02:00
}
2021-08-07 23:11:34 +02:00
}
2022-01-07 17:31:39 +01:00
2021-08-07 23:11:34 +02:00
}