| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { Store, 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" | 
					
						
							|  |  |  | 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-06-05 02:24:14 +02:00
										 |  |  |     readonly IsValid: Store<boolean> | 
					
						
							|  |  |  |     readonly Value: Store<T> | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FlowPanelFactory<T> { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private _initial: FlowStep<any> | 
					
						
							|  |  |  |     private _steps: ((x: any) => FlowStep<any>)[] | 
					
						
							|  |  |  |     private _stepNames: (string | BaseUIElement)[] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private constructor( | 
					
						
							|  |  |  |         initial: FlowStep<any>, | 
					
						
							|  |  |  |         steps: ((x: any) => FlowStep<any>)[], | 
					
						
							|  |  |  |         stepNames: (string | BaseUIElement)[] | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |         this._initial = initial | 
					
						
							|  |  |  |         this._steps = steps | 
					
						
							|  |  |  |         this._stepNames = stepNames | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static start<TOut>( | 
					
						
							|  |  |  |         name: { title: BaseUIElement }, | 
					
						
							|  |  |  |         step: FlowStep<TOut> | 
					
						
							|  |  |  |     ): FlowPanelFactory<TOut> { | 
					
						
							| 
									
										
										
										
											2022-04-14 01:32:04 +02:00
										 |  |  |         return new FlowPanelFactory(step, [], [name.title]) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public finish( | 
					
						
							|  |  |  |         name: string | BaseUIElement, | 
					
						
							|  |  |  |         construct: (t: T, backButton?: BaseUIElement) => BaseUIElement | 
					
						
							|  |  |  |     ): { | 
					
						
							|  |  |  |         flow: BaseUIElement | 
					
						
							|  |  |  |         furthestStep: UIEventSource<number> | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         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-09-08 21:40:48 +02: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--) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             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-09-08 21:40:48 +02:00
										 |  |  |                 furthestStep.setData(i + 1) | 
					
						
							|  |  |  |                 const panel = new FlowPanel(flowStep, nextConstr[i + 1], backButton, isConfirm) | 
					
						
							|  |  |  |                 panel.isActive.addCallbackAndRun((active) => { | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                     if (active) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         furthestStep.setData(i + 1) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |                 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]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         flow.isActive.addCallbackAndRun((active) => { | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |             if (active) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 furthestStep.setData(0) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             flow, | 
					
						
							|  |  |  |             furthestStep, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             titles: this._stepNames, | 
					
						
							| 
									
										
										
										
											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( | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         initial: FlowStep<T>, | 
					
						
							|  |  |  |         constructNextstep: (input: T, backButton: BaseUIElement) => BaseUIElement, | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         backbutton?: BaseUIElement, | 
					
						
							|  |  |  |         isConfirm = false | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const t = Translations.t.general | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const currentStepActive = new UIEventSource(true) | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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( | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             isConfirm | 
					
						
							|  |  |  |                                 ? Svg.checkmark_svg() | 
					
						
							|  |  |  |                                 : Svg.back_svg().SetStyle("transform: rotate(180deg);"), | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |                             isConfirm ? t.confirm : t.next | 
					
						
							|  |  |  |                         ).onClick(() => { | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                             try { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                                 const v = initial.Value.data | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                                 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
										 |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     new Toggle(t.error.SetClass("alert"), undefined, isError), | 
					
						
							| 
									
										
										
										
											2022-01-22 02:56:35 +01:00
										 |  |  |                 ]).SetClass("flex w-full justify-end space-x-2"), | 
					
						
							| 
									
										
										
										
											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-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-01-21 01:57:16 +01:00
										 |  |  |         this.isActive = currentStepActive | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |