| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | import {UIElement} from "../UI/UIElement"; | 
					
						
							|  |  |  | import {UIEventSource} from "../UI/UIEventSource"; | 
					
						
							|  |  |  | import {And, Tag, TagsFilter, TagUtils} from "../Logic/TagsFilter"; | 
					
						
							|  |  |  | import {FixedUiElement} from "../UI/Base/FixedUiElement"; | 
					
						
							|  |  |  | import {SaveButton} from "../UI/SaveButton"; | 
					
						
							|  |  |  | import {Changes} from "../Logic/Changes"; | 
					
						
							|  |  |  | import {VariableUiElement} from "../UI/Base/VariableUIElement"; | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  | import {TagDependantUIElement, TagDependantUIElementConstructor} from "./UIElementConstructor"; | 
					
						
							|  |  |  | import {OnlyShowIfConstructor} from "./OnlyShowIf"; | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  | import {UserDetails} from "../Logic/OsmConnection"; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | import {TextField} from "../UI/Input/TextField"; | 
					
						
							|  |  |  | import {InputElement} from "../UI/Input/InputElement"; | 
					
						
							|  |  |  | import {InputElementWrapper} from "../UI/Input/InputElementWrapper"; | 
					
						
							|  |  |  | import {FixedInputElement} from "../UI/Input/FixedInputElement"; | 
					
						
							|  |  |  | import {RadioButton} from "../UI/Input/RadioButton"; | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  | import Translations from "../UI/i18n/Translations"; | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  | import Locale from "../UI/i18n/Locale"; | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  | import * as EmailValidator from 'email-validator'; | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  | import {parsePhoneNumberFromString} from 'libphonenumber-js' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  | export class TagRenderingOptions implements TagDependantUIElementConstructor { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public static inputValidation = { | 
					
						
							|  |  |  |         "$": (str) => true, | 
					
						
							|  |  |  |         "string": (str) => true, | 
					
						
							|  |  |  |         "int": (str) => str.indexOf(".") < 0 && !isNaN(Number(str)), | 
					
						
							|  |  |  |         "nat": (str) => str.indexOf(".") < 0 && !isNaN(Number(str)) && Number(str) > 0, | 
					
						
							|  |  |  |         "float": (str) => !isNaN(Number(str)), | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         "pfloat": (str) => !isNaN(Number(str)) && Number(str) > 0, | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |         "email": (str) => EmailValidator.validate(str), | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  |         "phone": (str, country) => { | 
					
						
							|  |  |  |             return parsePhoneNumberFromString(str, country.toUpperCase())?.isValid() ?? false; | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     public static formatting = { | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  |         "phone": (str, country) => { | 
					
						
							|  |  |  |            console.log("country formatting", country) | 
					
						
							|  |  |  |             return parsePhoneNumberFromString(str, country.toUpperCase()).formatInternational() | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Notes: by not giving a 'question', one disables the question form alltogether | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public options: { | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         priority?: number; | 
					
						
							|  |  |  |         question?: string | UIElement; | 
					
						
							|  |  |  |         freeform?: { | 
					
						
							|  |  |  |             key: string; | 
					
						
							|  |  |  |             tagsPreprocessor?: (tags: any) => any; | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |             template: string | UIElement; | 
					
						
							|  |  |  |             renderTemplate: string | UIElement; | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             placeholder?: string | UIElement; | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             extraTags?: TagsFilter | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         mappings?: { k: TagsFilter; txt: string | UIElement; priority?: number, substitute?: boolean }[] | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(options: { | 
					
						
							| 
									
										
										
										
											2020-07-07 16:42:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  |         | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 16:42:25 +02:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * This is the string that is shown in the popup if this tag is missing. | 
					
						
							|  |  |  |          * | 
					
						
							|  |  |  |          * If 'question' is undefined, then the question is never asked at all | 
					
						
							|  |  |  |          * If the question is "" (empty string) then the question is  | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-07-20 12:39:43 +02:00
										 |  |  |         question?: UIElement | string, | 
					
						
							| 
									
										
										
										
											2020-07-07 16:42:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  |          * What is the priority of the question. | 
					
						
							|  |  |  |          * By default, in the popup of a feature, only one question is shown at the same time. If multiple questions are unanswered, the question with the highest priority is asked first | 
					
						
							| 
									
										
										
										
											2020-07-07 16:42:25 +02:00
										 |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  |         priority?: number, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-07 16:42:25 +02:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * Mappings convert a well-known tag combination into a user friendly text. | 
					
						
							|  |  |  |          * It converts e.g. 'access=yes' into 'this area can be accessed' | 
					
						
							|  |  |  |          *  | 
					
						
							|  |  |  |          * If there are multiple tags that should be matched, And can be used. All tags in AND will be added when the question is picked (and the corresponding text will only be shown if all tags are present). | 
					
						
							|  |  |  |          * If AND is used, it is best practice to make sure every used tag is in every option (with empty string) to erase extra tags. | 
					
						
							|  |  |  |          *  | 
					
						
							|  |  |  |          * If a 'k' is null, then this one is shown by default. It can be used to force a default value, e.g. to show that the name of a POI is not (yet) known . | 
					
						
							|  |  |  |          * A mapping where 'k' is null will not be shown as option in the radio buttons. | 
					
						
							|  |  |  |          *  | 
					
						
							|  |  |  |          *  | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-07-20 12:39:43 +02:00
										 |  |  |         mappings?: { k: TagsFilter, txt: UIElement | string, priority?: number, substitute?: boolean }[], | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * If one wants to render a freeform tag (thus no predefined key/values) or if there are a few well-known tags with a freeform object, | 
					
						
							|  |  |  |          * use this. | 
					
						
							|  |  |  |          * In the question, it'll offer a textfield | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         freeform?: { | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |             key: string, | 
					
						
							|  |  |  |             template: string | UIElement, | 
					
						
							|  |  |  |             renderTemplate: string | UIElement | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             placeholder?: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  |             extraTags?: TagsFilter, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * In some very rare cases, tags have to be rewritten before displaying | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  |          * This function can be used for that. | 
					
						
							|  |  |  |          * This function is ran on a _copy_ of the original properties | 
					
						
							| 
									
										
										
										
											2020-07-15 13:15:36 +02:00
										 |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  |         tagsPreprocessor?: ((tags: any) => void) | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     }) { | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         this.options = options; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-17 14:24:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  |     OnlyShowIf(tagsFilter: TagsFilter): TagDependantUIElementConstructor { | 
					
						
							|  |  |  |         return new OnlyShowIfConstructor(tagsFilter, this); | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IsQuestioning(tags: any): boolean { | 
					
						
							|  |  |  |         const tagsKV = TagUtils.proprtiesToKV(tags); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 12:10:43 +02:00
										 |  |  |         for (const oneOnOneElement of this.options.mappings ?? []) { | 
					
						
							| 
									
										
										
										
											2020-07-08 16:07:16 +02:00
										 |  |  |             if (oneOnOneElement.k === null || oneOnOneElement.k.matches(tagsKV)) { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this.options.freeform !== undefined && tags[this.options.freeform.key] !== undefined) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this.options.question === undefined) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 14:24:31 +02:00
										 |  |  |     construct(dependencies: { tags: UIEventSource<any>, changes: Changes }): TagDependantUIElement { | 
					
						
							|  |  |  |         return new TagRendering(dependencies.tags, dependencies.changes, this.options); | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 12:10:43 +02:00
										 |  |  |     IsKnown(properties: any): boolean { | 
					
						
							|  |  |  |         return !this.IsQuestioning(properties); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Priority(): number { | 
					
						
							|  |  |  |         return this.options.priority ?? 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  | class TagRendering extends UIElement implements TagDependantUIElement { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  |     private _userDetails: UIEventSource<UserDetails>; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     private _priority: number; | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |     private _question: UIElement; | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |     private _mapping: { k: TagsFilter, txt: string | UIElement, priority?: number }[]; | 
					
						
							| 
									
										
										
										
											2020-07-08 16:24:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     private _tagsPreprocessor?: ((tags: any) => any); | 
					
						
							|  |  |  |     private _freeform: { | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |         key: string,  | 
					
						
							|  |  |  |         template: string | UIElement, | 
					
						
							|  |  |  |         renderTemplate: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |         placeholder?: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         extraTags?: TagsFilter | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private readonly _questionElement: InputElement<TagsFilter>; | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private readonly _saveButton: UIElement; | 
					
						
							|  |  |  |     private readonly _skipButton: UIElement; | 
					
						
							|  |  |  |     private readonly _editButton: UIElement; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private readonly _questionSkipped: UIEventSource<boolean> = new UIEventSource<boolean>(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private readonly _editMode: UIEventSource<boolean> = new UIEventSource<boolean>(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(tags: UIEventSource<any>, changes: Changes, options: { | 
					
						
							|  |  |  |         priority?: number | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         question?: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         freeform?: { | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |             key: string,  | 
					
						
							|  |  |  |             template: string | UIElement, | 
					
						
							|  |  |  |             renderTemplate: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             placeholder?: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             extraTags?: TagsFilter, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         tagsPreprocessor?: ((tags: any) => any), | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     }) { | 
					
						
							|  |  |  |         super(tags); | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |         this.ListenTo(Locale.language); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         const self = this; | 
					
						
							|  |  |  |         this.ListenTo(this._questionSkipped); | 
					
						
							|  |  |  |         this.ListenTo(this._editMode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  |         this._userDetails = changes.login.userDetails; | 
					
						
							|  |  |  |         this.ListenTo(this._userDetails); | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         | 
					
						
							| 
									
										
										
										
											2020-07-12 23:19:05 +02:00
										 |  |  |         this._priority = options.priority ?? 0; | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  |         this._tagsPreprocessor = function (properties) { | 
					
						
							|  |  |  |             if (options.tagsPreprocessor === undefined) { | 
					
						
							|  |  |  |                 return properties; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const newTags = {}; | 
					
						
							|  |  |  |             for (const k in properties) { | 
					
						
							|  |  |  |                 newTags[k] = properties[k]; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             options.tagsPreprocessor(newTags); | 
					
						
							|  |  |  |             return newTags; | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (options.question !== undefined) { | 
					
						
							|  |  |  |             this._question = this.ApplyTemplate(options.question); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-17 17:21:07 +02:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         this._mapping = []; | 
					
						
							|  |  |  |         this._freeform = options.freeform; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-08 16:07:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         for (const choice of options.mappings ?? []) { | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             let choiceSubbed = { | 
					
						
							|  |  |  |                 k: choice.k, | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |                 txt: choice.txt, | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |                 priority: choice.priority | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             if (choice.substitute) { | 
					
						
							|  |  |  |                 choiceSubbed = { | 
					
						
							| 
									
										
										
										
											2020-07-08 11:23:36 +02:00
										 |  |  |                     k: choice.k.substituteValues( | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                         options.tagsPreprocessor(this._source.data)), | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |                     txt: choice.txt, | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                     priority: choice.priority | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-08 11:23:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             this._mapping.push({ | 
					
						
							|  |  |  |                 k: choiceSubbed.k, | 
					
						
							|  |  |  |                 txt: choiceSubbed.txt | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Prepare the actual input element -> pick an appropriate implementation
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         this._questionElement = this.InputElementFor(options); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         const save = () => { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |             const selection = self._questionElement.GetValue().data; | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             if (selection) { | 
					
						
							|  |  |  |                 changes.addTag(tags.data.id, selection); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             self._editMode.setData(false); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const cancel = () => { | 
					
						
							|  |  |  |             self._questionSkipped.setData(true); | 
					
						
							|  |  |  |             self._editMode.setData(false); | 
					
						
							| 
									
										
										
										
											2020-07-08 16:07:16 +02:00
										 |  |  |             self._source.ping(); // Send a ping upstream to render the next question
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Setup the save button and it's action
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         this._saveButton = new SaveButton(this._questionElement.GetValue()) | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             .onClick(save); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         this._editButton = new FixedUiElement(""); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         if (this._question !== undefined) { | 
					
						
							|  |  |  |             this._editButton = new FixedUiElement("<img class='editbutton' src='./assets/pencil.svg' alt='edit'>") | 
					
						
							|  |  |  |                 .onClick(() => { | 
					
						
							|  |  |  |                     self._editMode.setData(true); | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |                     self._questionElement.GetValue().setData(self.CurrentValue()); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const cancelContents = this._editMode.map((isEditing) => { | 
					
						
							|  |  |  |             if (isEditing) { | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |                 return "<span class='skip-button'>"+Translations.t.general.cancel.R()+"</span>"; | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |                 return "<span class='skip-button'>"+Translations.t.general.skip.R()+"</span>"; | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-22 00:18:07 +02:00
										 |  |  |         }, [Locale.language]); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         // And at last, set up the skip button
 | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |         this._skipButton = new VariableUiElement(cancelContents).onClick(cancel)    ; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     private InputElementFor(options: { | 
					
						
							|  |  |  |         freeform?: { | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |             key: string,  | 
					
						
							|  |  |  |             template: string | UIElement, | 
					
						
							|  |  |  |             renderTemplate: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             placeholder?: string | UIElement, | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |             extraTags?: TagsFilter, | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     }): | 
					
						
							|  |  |  |         InputElement<TagsFilter> { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const elements = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (options.mappings !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |              | 
					
						
							|  |  |  |             const previousTexts= []; | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |             for (const mapping of options.mappings) { | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |                 if(mapping.k === null){ | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if(previousTexts.indexOf(mapping.txt) >= 0){ | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 previousTexts.push(mapping.txt); | 
					
						
							|  |  |  |                  | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 elements.push(this.InputElementForMapping(mapping)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (options.freeform !== undefined) { | 
					
						
							|  |  |  |             elements.push(this.InputForFreeForm(options.freeform)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (elements.length == 0) { | 
					
						
							| 
									
										
										
										
											2020-07-26 23:28:31 +02:00
										 |  |  |             //console.warn("WARNING: no tagrendering with following options:", options);
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             return new FixedInputElement("This should not happen: no tag renderings defined", undefined); | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (elements.length == 1) { | 
					
						
							|  |  |  |             return elements[0]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new RadioButton(elements, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |     private InputElementForMapping(mapping: { k: TagsFilter, txt: string | UIElement }) { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |         return new FixedInputElement(mapping.txt, mapping.k); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private InputForFreeForm(freeform): InputElement<TagsFilter> { | 
					
						
							|  |  |  |         if (freeform === undefined) { | 
					
						
							|  |  |  |             return undefined; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |         const prepost = Translations.W(freeform.template).InnerRender().split("$"); | 
					
						
							|  |  |  |         const type = prepost[1]; | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |         let isValid = TagRenderingOptions.inputValidation[type]; | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  |         if (isValid === undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |             isValid = (str) => true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         let formatter = TagRenderingOptions.formatting[type] ?? ((str) => str); | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const pickString = | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |             (string: any) => { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 if (string === "" || string === undefined) { | 
					
						
							|  |  |  |                     return undefined; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  |                 if (!isValid(string, this._source.data._country)) { | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |                     return undefined; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-07-26 19:13:52 +02:00
										 |  |  |                 const tag = new Tag(freeform.key, formatter(string, this._source.data._country)); | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |                  | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 if (freeform.extraTags === undefined) { | 
					
						
							|  |  |  |                     return tag; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return new And([ | 
					
						
							| 
									
										
										
										
											2020-07-20 21:03:55 +02:00
										 |  |  |                         tag, | 
					
						
							|  |  |  |                         freeform.extraTags | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                     ] | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const toString = | 
					
						
							|  |  |  |             (tag) => { | 
					
						
							|  |  |  |                 if (tag instanceof And) { | 
					
						
							|  |  |  |                     return toString(tag.and[0]) | 
					
						
							|  |  |  |                 } else if (tag instanceof Tag) { | 
					
						
							|  |  |  |                     return tag.value | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return undefined; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let inputElement: InputElement<TagsFilter>; | 
					
						
							|  |  |  |         const textField = new TextField({ | 
					
						
							|  |  |  |             placeholder: this._freeform.placeholder, | 
					
						
							|  |  |  |             fromString: pickString, | 
					
						
							|  |  |  |             toString: toString | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 17:32:18 +02:00
										 |  |  |         return new InputElementWrapper(prepost[0], textField, prepost[2]); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     IsKnown(): boolean { | 
					
						
							|  |  |  |         const tags = TagUtils.proprtiesToKV(this._source.data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |         for (const oneOnOneElement of this._mapping) { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             if (oneOnOneElement.k === null || oneOnOneElement.k.matches(tags)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         return this._freeform !== undefined && this._source.data[this._freeform.key] !== undefined; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 01:07:02 +02:00
										 |  |  |     IsSkipped(): boolean { | 
					
						
							|  |  |  |         return this._questionSkipped.data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |     private CurrentValue(): TagsFilter { | 
					
						
							|  |  |  |         const tags = TagUtils.proprtiesToKV(this._source.data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |         for (const oneOnOneElement of this._mapping) { | 
					
						
							| 
									
										
										
										
											2020-07-20 21:03:55 +02:00
										 |  |  |             if (oneOnOneElement.k !== null && oneOnOneElement.k.matches(tags)) { | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |                 return oneOnOneElement.k; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this._freeform === undefined) { | 
					
						
							|  |  |  |             return undefined; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new Tag(this._freeform.key, this._source.data[this._freeform.key]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     IsQuestioning(): boolean { | 
					
						
							|  |  |  |         if (this.IsKnown()) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this._question === undefined) { | 
					
						
							|  |  |  |             // We don't ask this question in the first place
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this._questionSkipped.data) { | 
					
						
							|  |  |  |             // We don't ask for this question anymore, skipped by user
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |     private RenderAnwser(): UIElement { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         const tags = TagUtils.proprtiesToKV(this._source.data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         let freeform: UIElement = new FixedUiElement(""); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         let freeformScore = -10; | 
					
						
							|  |  |  |         if (this._freeform !== undefined && this._source.data[this._freeform.key] !== undefined) { | 
					
						
							|  |  |  |             freeform = this.ApplyTemplate(this._freeform.renderTemplate); | 
					
						
							|  |  |  |             freeformScore = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         let highestScore = -100; | 
					
						
							|  |  |  |         let highestTemplate = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |         for (const oneOnOneElement of this._mapping) { | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             if (oneOnOneElement.k == null || | 
					
						
							|  |  |  |                 oneOnOneElement.k.matches(tags)) { | 
					
						
							|  |  |  |                 // We have found a matching key -> we use the template, but only if it scores better
 | 
					
						
							|  |  |  |                 let score = oneOnOneElement.priority ?? | 
					
						
							|  |  |  |                     (oneOnOneElement.k === null ? -1 : 0); | 
					
						
							|  |  |  |                 if (score > highestScore) { | 
					
						
							|  |  |  |                     highestScore = score; | 
					
						
							|  |  |  |                     highestTemplate = oneOnOneElement.txt | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         if (freeformScore > highestScore) { | 
					
						
							|  |  |  |             return freeform; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (highestTemplate !== undefined) { | 
					
						
							|  |  |  |             // we render the found template
 | 
					
						
							|  |  |  |             return this.ApplyTemplate(highestTemplate); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |     InnerRender(): string { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |         if (this.IsQuestioning() || this._editMode.data) { | 
					
						
							|  |  |  |             // Not yet known or questioning, we have to ask a question
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |             const question = | 
					
						
							|  |  |  |                 this.ApplyTemplate(this._question).Render(); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return "<div class='question'>" + | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |                 "<span class='question-text'>" + question + "</span>" + | 
					
						
							| 
									
										
										
										
											2020-07-21 00:38:03 +02:00
										 |  |  |                 (this._question.IsEmpty() ? "" : "<br/>") + | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |                 "<div>" + this._questionElement.Render() + "</div>" + | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 this._skipButton.Render() + | 
					
						
							|  |  |  |                 this._saveButton.Render() + | 
					
						
							|  |  |  |                 "</div>" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (this.IsKnown()) { | 
					
						
							| 
									
										
										
										
											2020-07-21 00:38:03 +02:00
										 |  |  |             const answer = this.RenderAnwser() | 
					
						
							|  |  |  |             if (answer.IsEmpty()) { | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 return ""; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-21 00:38:03 +02:00
										 |  |  |             const html = answer.Render(); | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  |             let editButton = ""; | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |             if (this._userDetails.data.loggedIn && this._question !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  |                 editButton = this._editButton.Render(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |             return "<span class='answer'>" + | 
					
						
							| 
									
										
										
										
											2020-07-13 16:18:04 +02:00
										 |  |  |                 "<span class='answer-text'>" + html + "</span>" + | 
					
						
							|  |  |  |                 editButton + | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |                 "</span>"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Priority(): number { | 
					
						
							|  |  |  |         return this._priority; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |     private ApplyTemplate(template: string | UIElement): UIElement { | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         if (template === undefined || template === null) { | 
					
						
							| 
									
										
										
										
											2020-07-21 23:31:41 +02:00
										 |  |  |             throw "Trying to apply a template, but the template is null/undefined" | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         const contents = Translations.W(template).map(contents =>  | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 let templateStr = ""; | 
					
						
							|  |  |  |                 if (template instanceof UIElement) { | 
					
						
							|  |  |  |                     templateStr = template.Render(); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     templateStr = template; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const tags = this._tagsPreprocessor(this._source.data); | 
					
						
							|  |  |  |                 return TagUtils.ApplyTemplate(templateStr, tags); | 
					
						
							|  |  |  |             }, [this._source] | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         return new VariableUiElement(contents); | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2020-07-05 18:59:47 +02:00
										 |  |  | } |