2020-09-02 11:37:34 +02:00
import { UIElement } from "../UIElement" ;
import { UIEventSource } from "../../Logic/UIEventSource" ;
import { InputElement } from "../Input/InputElement" ;
import SingleSetting from "./SingleSetting" ;
import SettingsTable from "./SettingsTable" ;
2020-09-25 17:57:01 +02:00
import { TextField } from "../Input/TextField" ;
2020-09-02 11:37:34 +02:00
import Combine from "../Base/Combine" ;
import MultiLingualTextFields from "../Input/MultiLingualTextFields" ;
2020-10-02 19:00:24 +02:00
import AndOrTagInput from "../Input/AndOrTagInput" ;
2020-09-02 11:37:34 +02:00
import { MultiTagInput } from "../Input/MultiTagInput" ;
import { MultiInput } from "../Input/MultiInput" ;
import MappingInput from "./MappingInput" ;
import { AndOrTagConfigJson } from "../../Customizations/JSON/TagConfigJson" ;
import { TagRenderingConfigJson } from "../../Customizations/JSON/TagRenderingConfigJson" ;
2021-01-04 04:36:21 +01:00
import UserDetails from "../../Logic/Osm/OsmConnection" ;
2020-09-08 00:33:05 +02:00
import { VariableUiElement } from "../Base/VariableUIElement" ;
2020-09-25 17:57:01 +02:00
import ValidatedTextField from "../Input/ValidatedTextField" ;
2020-10-17 02:37:53 +02:00
import SpecialVisualizations from "../SpecialVisualizations" ;
2020-10-30 00:56:46 +01:00
import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig" ;
2021-01-02 19:09:49 +01:00
import Constants from "../../Models/Constants" ;
2020-09-02 11:37:34 +02:00
export default class TagRenderingPanel extends InputElement < TagRenderingConfigJson > {
private intro : UIElement ;
private settingsTable : UIElement ;
public IsImage = false ;
private readonly _value : UIEventSource < TagRenderingConfigJson > ;
public options : { title? : string ; description? : string ; disableQuestions? : boolean ; isImage? : boolean ; } ;
2020-09-08 00:33:05 +02:00
public readonly validText : UIElement ;
2020-09-02 11:37:34 +02:00
constructor ( languages : UIEventSource < string [ ] > ,
currentlySelected : UIEventSource < SingleSetting < any > > ,
2020-09-03 16:44:48 +02:00
userDetails : UserDetails ,
2020-09-02 11:37:34 +02:00
options ? : {
title? : string ,
description? : string ,
disableQuestions? : boolean ,
2020-09-05 17:43:30 +02:00
isImage? : boolean ,
noLanguage? : boolean
2020-09-02 11:37:34 +02:00
} ) {
super ( ) ;
this . SetClass ( "bordered" ) ;
this . SetClass ( "min-height" ) ;
this . options = options ? ? { } ;
2021-01-02 19:09:49 +01:00
const questionsNotUnlocked = userDetails . csCount < Constants . userJourney . themeGeneratorFullUnlock ;
2020-09-03 16:44:48 +02:00
this . options . disableQuestions =
2020-09-03 19:05:18 +02:00
( this . options . disableQuestions ? ? false ) ||
2020-09-03 16:44:48 +02:00
questionsNotUnlocked ;
2020-09-02 11:37:34 +02:00
2020-10-02 19:00:24 +02:00
this . intro = new Combine ( [ "<h3>" , options ? . title ? ? "TagRendering" , "</h3>" ,
options ? . description ? ? "A tagrendering converts OSM-tags into a value on screen. Fill out the field 'render' with the text that should appear. Note that `{key}` will be replaced with the corresponding `value`, if present.<br/>For specific known tags (e.g. if `foo=bar`, make a mapping). " ] )
2020-09-02 11:37:34 +02:00
this . IsImage = options ? . isImage ? ? false ;
const value = new UIEventSource < TagRenderingConfigJson > ( { } ) ;
this . _value = value ;
function setting ( input : InputElement < any > , id : string | string [ ] , name : string , description : string | UIElement ) : SingleSetting < any > {
return new SingleSetting < any > ( value , input , id , name , description ) ;
}
const questionSettings = [
2020-09-05 17:43:30 +02:00
2020-09-25 17:57:01 +02:00
setting ( options ? . noLanguage ? new TextField ( { placeholder : "question" } ) : new MultiLingualTextFields ( languages )
2020-09-05 17:43:30 +02:00
, "question" , "Question" , "If the key or mapping doesn't match, this question is asked" ) ,
2020-09-02 11:37:34 +02:00
"<h3>Freeform key</h3>" ,
2020-09-25 17:57:01 +02:00
setting ( ValidatedTextField . KeyInput ( true ) , [ "freeform" , "key" ] , "Freeform key<br/>" ,
2020-09-02 11:37:34 +02:00
"If specified, the rendering will search if this key is present." +
"If it is, the rendering above will be used to display the element.<br/>" +
"The rendering will go into question mode if <ul><li>this key is not present</li><li>No single mapping matches</li><li>A question is given</li>" ) ,
setting ( ValidatedTextField . TypeDropdown ( ) , [ "freeform" , "type" ] , "Freeform type" ,
"The type of this freeform text field, in order to validate" ) ,
setting ( new MultiTagInput ( ) , [ "freeform" , "addExtraTags" ] , "Extra tags on freeform" ,
"When the freeform text field is used, the user might mean a predefined key. This field allows to add extra tags, e.g. <span class='literal-code'>fixme=User used a freeform field - to check</span>" ) ,
] ;
const settings : ( string | SingleSetting < any > ) [ ] = [
2020-09-05 17:43:30 +02:00
setting (
2020-09-25 17:57:01 +02:00
options ? . noLanguage ? new TextField ( { placeholder : "Rendering" } ) :
2020-10-17 02:37:53 +02:00
new MultiLingualTextFields ( languages ) , "render" , "Value to show" ,
"Renders this value. Note that <span class='literal-code'>{key}</span>-parts are substituted by the corresponding values of the element. If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value." +
"<br/><br/>" +
"Furhtermore, some special functions are supported:" + SpecialVisualizations . HelpMessage . Render ( ) ) ,
2020-09-14 20:16:03 +02:00
2021-01-02 19:09:49 +01:00
questionsNotUnlocked ? ` You need at least ${ Constants . userJourney . themeGeneratorFullUnlock } changesets to unlock the 'question'-field and to use your theme to edit OSM data ` : "" ,
2020-09-02 11:37:34 +02:00
. . . ( options ? . disableQuestions ? [ ] : questionSettings ) ,
"<h3>Mappings</h3>" ,
setting ( new MultiInput < { if : AndOrTagConfigJson , then : ( string | any ) , hideInAnswer? : boolean } > ( "Add a mapping" ,
2020-09-09 18:42:13 +02:00
( ) = > ( { if : { and : [ ] } , then : { } } ) ,
2020-09-07 02:25:45 +02:00
( ) = > new MappingInput ( languages , options ? . disableQuestions ? ? false ) ,
undefined , { allowMovement : true } ) , "mappings" ,
2020-09-14 20:16:03 +02:00
"If a tag matches, then show the first respective text" , "" ) ,
"<h3>Condition</h3>" ,
setting ( new AndOrTagInput ( ) , "condition" , "Only show this tagrendering if the following condition applies" ,
"Only show this tag rendering if these tags matches. Optional field.<br/>Note that the Overpass-tags are already always included in this object" ) ,
2020-09-02 11:37:34 +02:00
] ;
this . settingsTable = new SettingsTable ( settings , currentlySelected ) ;
2020-09-08 00:33:05 +02:00
this . validText = new VariableUiElement ( value . map ( ( json : TagRenderingConfigJson ) = > {
try {
2021-01-08 03:57:18 +01:00
new TagRenderingConfig ( json , undefined , options ? . title ? ? "" ) ;
2020-09-08 00:33:05 +02:00
return "" ;
} catch ( e ) {
return "<span class='alert'>" + e + "</span>"
}
} ) ) ;
2020-09-02 11:37:34 +02:00
}
InnerRender ( ) : string {
return new Combine ( [
this . intro ,
2020-09-08 00:33:05 +02:00
this . settingsTable ,
this . validText ] ) . Render ( ) ;
2020-09-02 11:37:34 +02:00
}
GetValue ( ) : UIEventSource < TagRenderingConfigJson > {
return this . _value ;
}
IsSelected : UIEventSource < boolean > = new UIEventSource < boolean > ( false ) ;
IsValid ( t : TagRenderingConfigJson ) : boolean {
return false ;
}
}