| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | import {UIEventSource} from "../../Logic/UIEventSource"; | 
					
						
							|  |  |  | import Combine from "../Base/Combine"; | 
					
						
							|  |  |  | import BaseUIElement from "../BaseUIElement"; | 
					
						
							|  |  |  | import {SubtleButton} from "../Base/SubtleButton"; | 
					
						
							|  |  |  | import Svg from "../../Svg"; | 
					
						
							|  |  |  | import Translations from "../i18n/Translations"; | 
					
						
							|  |  |  | import {VariableUiElement} from "../Base/VariableUIElement"; | 
					
						
							|  |  |  | import Toggle from "../Input/Toggle"; | 
					
						
							|  |  |  | import {UIElement} from "../UIElement"; | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  | import {FixedUiElement} from "../Base/FixedUiElement"; | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | export interface FlowStep<T> extends BaseUIElement { | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     readonly IsValid: UIEventSource<boolean> | 
					
						
							|  |  |  |     readonly Value: UIEventSource<T> | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FlowPanelFactory<T> { | 
					
						
							|  |  |  |     private _initial: FlowStep<any>; | 
					
						
							|  |  |  |     private _steps: ((x: any) => FlowStep<any>)[]; | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |     private _stepNames: (string | BaseUIElement)[]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private constructor(initial: FlowStep<any>, steps: ((x: any) => FlowStep<any>)[], stepNames: (string | BaseUIElement)[]) { | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         this._initial = initial; | 
					
						
							|  |  |  |         this._steps = steps; | 
					
						
							|  |  |  |         this._stepNames = stepNames; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 01:32:04 +02:00
										 |  |  |     public static start<TOut>(name:{title: BaseUIElement}, step: FlowStep<TOut>): FlowPanelFactory<TOut> { | 
					
						
							|  |  |  |         return new FlowPanelFactory(step, [], [name.title]) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 01:32:04 +02:00
										 |  |  |     public then<TOut>(name: string | {title: BaseUIElement}, construct: ((t: T) => FlowStep<TOut>)): FlowPanelFactory<TOut> { | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         return new FlowPanelFactory<TOut>( | 
					
						
							|  |  |  |             this._initial, | 
					
						
							|  |  |  |             this._steps.concat([construct]), | 
					
						
							| 
									
										
										
										
											2022-04-14 01:32:04 +02:00
										 |  |  |             this._stepNames.concat([name["title"] ?? name]) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public finish(name: string | BaseUIElement, construct: ((t: T, backButton?: BaseUIElement) => BaseUIElement)): { | 
					
						
							|  |  |  |         flow: BaseUIElement, | 
					
						
							|  |  |  |         furthestStep: UIEventSource<number>, | 
					
						
							|  |  |  |         titles: (string | BaseUIElement)[] | 
					
						
							|  |  |  |     } { | 
					
						
							|  |  |  |         const furthestStep = new UIEventSource(0) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         // Construct all the flowpanels step by step (in reverse order)
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         const nextConstr: ((t: any, back?: UIElement) => BaseUIElement)[] = this._steps.map(_ => undefined) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         nextConstr.push(construct) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         for (let i = this._steps.length - 1; i >= 0; i--) { | 
					
						
							|  |  |  |             const createFlowStep: (value) => FlowStep<any> = this._steps[i]; | 
					
						
							|  |  |  |             const isConfirm = i == this._steps.length - 1; | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             nextConstr[i] = (value, backButton) => { | 
					
						
							|  |  |  |                 const flowStep = createFlowStep(value) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                 furthestStep.setData(i + 1); | 
					
						
							|  |  |  |                 const panel = new FlowPanel(flowStep, nextConstr[i + 1], backButton, isConfirm); | 
					
						
							|  |  |  |                 panel.isActive.addCallbackAndRun(active => { | 
					
						
							|  |  |  |                     if (active) { | 
					
						
							|  |  |  |                         furthestStep.setData(i + 1); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |                 return panel | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const flow = new FlowPanel(this._initial, nextConstr[0]) | 
					
						
							|  |  |  |         flow.isActive.addCallbackAndRun(active => { | 
					
						
							|  |  |  |             if (active) { | 
					
						
							|  |  |  |                 furthestStep.setData(0); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             flow, | 
					
						
							|  |  |  |             furthestStep, | 
					
						
							|  |  |  |             titles: this._stepNames | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FlowPanel<T> extends Toggle { | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |     public isActive: UIEventSource<boolean> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         initial: (FlowStep<T>), | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         constructNextstep: ((input: T, backButton: BaseUIElement) => BaseUIElement), | 
					
						
							|  |  |  |         backbutton?: BaseUIElement, | 
					
						
							|  |  |  |         isConfirm = false | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     ) { | 
					
						
							|  |  |  |         const t = Translations.t.general; | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         const currentStepActive = new UIEventSource(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         let nextStep: UIEventSource<BaseUIElement> = new UIEventSource<BaseUIElement>(undefined) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         const backButtonForNextStep = new SubtleButton(Svg.back_svg(), t.back).onClick(() => { | 
					
						
							|  |  |  |             currentStepActive.setData(true) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let elements: (BaseUIElement | string)[] = [] | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |         const isError = new UIEventSource(false) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         if (initial !== undefined) { | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             // Startup the flow
 | 
					
						
							|  |  |  |             elements = [ | 
					
						
							|  |  |  |                 initial, | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                 new Combine([ | 
					
						
							|  |  |  |                     backbutton, | 
					
						
							|  |  |  |                     new Toggle( | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                         new SubtleButton( | 
					
						
							|  |  |  |                             isConfirm ? Svg.checkmark_svg() : | 
					
						
							|  |  |  |                                 Svg.back_svg().SetStyle("transform: rotate(180deg);"), | 
					
						
							|  |  |  |                             isConfirm ? t.confirm : t.next | 
					
						
							|  |  |  |                         ).onClick(() => { | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                             try { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                 const v = initial.Value.data; | 
					
						
							|  |  |  |                                 nextStep.setData(constructNextstep(v, backButtonForNextStep)) | 
					
						
							|  |  |  |                                 currentStepActive.setData(false) | 
					
						
							|  |  |  |                             } catch (e) { | 
					
						
							|  |  |  |                                 console.error(e) | 
					
						
							|  |  |  |                                 isError.setData(true) | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                         }), | 
					
						
							| 
									
										
										
										
											2022-04-14 03:01:54 +02:00
										 |  |  |                         new SubtleButton(Svg.invalid_svg(), t.notValid), | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |                         initial.IsValid | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                     ), | 
					
						
							|  |  |  |                     new Toggle( | 
					
						
							| 
									
										
										
										
											2022-04-14 03:01:54 +02:00
										 |  |  |                         t.error.SetClass("alert"), | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                         undefined, | 
					
						
							|  |  |  |                         isError), | 
					
						
							|  |  |  |                 ]).SetClass("flex w-full justify-end space-x-2"), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             ] | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         super( | 
					
						
							|  |  |  |             new Combine(elements).SetClass("h-full flex flex-col justify-between"), | 
					
						
							|  |  |  |             new VariableUiElement(nextStep), | 
					
						
							|  |  |  |             currentStepActive | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         this.isActive = currentStepActive | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | } |