| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | import {InputElement} from "./InputElement"; | 
					
						
							|  |  |  | import {UIEventSource} from "../../Logic/UIEventSource"; | 
					
						
							|  |  |  | import {UIElement} from "../UIElement"; | 
					
						
							|  |  |  | import Combine from "../Base/Combine"; | 
					
						
							|  |  |  | import {SubtleButton} from "../Base/SubtleButton"; | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  | import {CheckBox} from "./CheckBox"; | 
					
						
							|  |  |  | import {AndOrTagConfigJson} from "../../Customizations/JSON/TagConfigJson"; | 
					
						
							|  |  |  | import {MultiTagInput} from "./MultiTagInput"; | 
					
						
							|  |  |  | import {FormatNumberOptions} from "libphonenumber-js"; | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  | class AndOrConfig implements AndOrTagConfigJson { | 
					
						
							|  |  |  |     public and: (string | AndOrTagConfigJson)[] = undefined; | 
					
						
							|  |  |  |     public or: (string | AndOrTagConfigJson)[] = undefined; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  | export class AndOrTagInput extends InputElement<AndOrTagConfigJson> { | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     private readonly _rawTags = new MultiTagInput(); | 
					
						
							|  |  |  |     private readonly _subAndOrs: AndOrTagInput[] = []; | 
					
						
							|  |  |  |     private readonly _isAnd: UIEventSource<boolean> = new UIEventSource<boolean>(true); | 
					
						
							|  |  |  |     private readonly _isAndButton; | 
					
						
							|  |  |  |     private readonly _addBlock: UIElement; | 
					
						
							|  |  |  |     private readonly _value: UIEventSource<AndOrConfig> = new UIEventSource<AndOrConfig>(undefined); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     public bottomLeftButton: UIElement; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IsSelected: UIEventSource<boolean>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor() { | 
					
						
							|  |  |  |         super(); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |         const self = this; | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |         this._isAndButton = new CheckBox( | 
					
						
							|  |  |  |             new SubtleButton("./assets/ampersand.svg", null).SetClass("small-button"), | 
					
						
							|  |  |  |             new SubtleButton("./assets/or.svg", null).SetClass("small-button"), | 
					
						
							|  |  |  |             this._isAnd); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |         this._addBlock = | 
					
						
							|  |  |  |             new SubtleButton("./assets/addSmall.svg", "Add an and/or-expression") | 
					
						
							|  |  |  |                 .SetClass("small-button") | 
					
						
							|  |  |  |                 .onClick(() => {self.createNewBlock()}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this._isAnd.addCallback(() => self.UpdateValue()); | 
					
						
							|  |  |  |         this._rawTags.GetValue().addCallback(() => { | 
					
						
							|  |  |  |             self.UpdateValue() | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.IsSelected = this._rawTags.IsSelected; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this._value.addCallback(tags => self.loadFromValue(tags)); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     private createNewBlock(){ | 
					
						
							|  |  |  |         const inputEl = new AndOrTagInput(); | 
					
						
							|  |  |  |         inputEl.GetValue().addCallback(() => this.UpdateValue()); | 
					
						
							|  |  |  |         const deleteButton = this.createDeleteButton(inputEl.id); | 
					
						
							|  |  |  |         inputEl.bottomLeftButton = deleteButton; | 
					
						
							|  |  |  |         this._subAndOrs.push(inputEl); | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     private createDeleteButton(elementId: string): UIElement { | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         return new SubtleButton("./assets/delete.svg", null).SetClass("small-button") | 
					
						
							|  |  |  |             .onClick(() => { | 
					
						
							|  |  |  |                 for (let i = 0; i < self._subAndOrs.length; i++) { | 
					
						
							|  |  |  |                     if (self._subAndOrs[i].id === elementId) { | 
					
						
							|  |  |  |                         self._subAndOrs.splice(i, 1); | 
					
						
							|  |  |  |                         self.Update(); | 
					
						
							|  |  |  |                         self.UpdateValue(); | 
					
						
							|  |  |  |                         return; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private loadFromValue(value: AndOrTagConfigJson) { | 
					
						
							|  |  |  |         this._isAnd.setData(value.and !== undefined); | 
					
						
							|  |  |  |         const tags = value.and ?? value.or; | 
					
						
							|  |  |  |         const rawTags: string[] = []; | 
					
						
							|  |  |  |         const subTags: AndOrTagConfigJson[] = []; | 
					
						
							|  |  |  |         for (const tag of tags) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (typeof (tag) === "string") { | 
					
						
							|  |  |  |                 rawTags.push(tag); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 subTags.push(tag); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (let i = 0; i < rawTags.length; i++) { | 
					
						
							|  |  |  |             if (this._rawTags.GetValue().data[i] !== rawTags[i]) { | 
					
						
							|  |  |  |                 // For some reason, 'setData' isn't stable as the comparison between the lists fails
 | 
					
						
							|  |  |  |                 // Probably because we generate a new list object every timee
 | 
					
						
							|  |  |  |                 // So we compare again here and update only if we find a difference
 | 
					
						
							|  |  |  |                 this._rawTags.GetValue().setData(rawTags); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |         while(this._subAndOrs.length < subTags.length){ | 
					
						
							|  |  |  |             this.createNewBlock(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (let i = 0; i < subTags.length; i++){ | 
					
						
							|  |  |  |             let subTag = subTags[i]; | 
					
						
							|  |  |  |             this._subAndOrs[i].GetValue().setData(subTag); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     private UpdateValue() { | 
					
						
							|  |  |  |         const tags: (string | AndOrTagConfigJson)[] = []; | 
					
						
							|  |  |  |         tags.push(...this._rawTags.GetValue().data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const subAndOr of this._subAndOrs) { | 
					
						
							|  |  |  |             const subAndOrData = subAndOr._value.data; | 
					
						
							|  |  |  |             if (subAndOrData === undefined) { | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             console.log(subAndOrData); | 
					
						
							|  |  |  |             tags.push(subAndOrData); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const tagConfig = new AndOrConfig(); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |         if (this._isAnd.data) { | 
					
						
							|  |  |  |             tagConfig.and = tags; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             tagConfig.or = tags; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this._value.setData(tagConfig); | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     GetValue(): UIEventSource<AndOrTagConfigJson> { | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  |         return this._value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:37:34 +02:00
										 |  |  |     InnerRender(): string { | 
					
						
							|  |  |  |         const leftColumn = new Combine([ | 
					
						
							|  |  |  |             this._isAndButton, | 
					
						
							|  |  |  |             "<br/>", | 
					
						
							|  |  |  |             this.bottomLeftButton ?? "" | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |         const tags = new Combine([ | 
					
						
							|  |  |  |             this._rawTags, | 
					
						
							|  |  |  |             ...this._subAndOrs, | 
					
						
							|  |  |  |             this._addBlock | 
					
						
							|  |  |  |         ]).Render(); | 
					
						
							|  |  |  |         return `<span class="bordered"><table><tr><td>${leftColumn.Render()}</td><td>${tags}</td></tr></table></span>`; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IsValid(t: AndOrTagConfigJson): boolean { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-31 13:25:13 +02:00
										 |  |  | } |