forked from MapComplete/MapComplete
		
	Fix bug in bind, fix bug in tagrenderingquestion
This commit is contained in:
		
							parent
							
								
									2813c31a93
								
							
						
					
					
						commit
						b6b20ed3ca
					
				
					 2 changed files with 44 additions and 31 deletions
				
			
		|  | @ -69,7 +69,7 @@ export class UIEventSource<T> { | |||
|      * @param promise | ||||
|      * @constructor | ||||
|      */ | ||||
|     public static FromPromise<T>(promise : Promise<T>): UIEventSource<T>{ | ||||
|     public static FromPromise<T>(promise: Promise<T>): UIEventSource<T> { | ||||
|         const src = new UIEventSource<T>(undefined) | ||||
|         promise?.then(d => src.setData(d)) | ||||
|         promise?.catch(err => console.warn("Promise failed:", err)) | ||||
|  | @ -82,9 +82,9 @@ export class UIEventSource<T> { | |||
|      * @param promise | ||||
|      * @constructor | ||||
|      */ | ||||
|     public static FromPromiseWithErr<T>(promise : Promise<T>): UIEventSource<{success: T} | {error: any}>{ | ||||
|         const src = new UIEventSource<{success: T}|{error: any}>(undefined) | ||||
|         promise?.then(d => src.setData({success:d})) | ||||
|     public static FromPromiseWithErr<T>(promise: Promise<T>): UIEventSource<{ success: T } | { error: any }> { | ||||
|         const src = new UIEventSource<{ success: T } | { error: any }>(undefined) | ||||
|         promise?.then(d => src.setData({success: d})) | ||||
|         promise?.catch(err => src.setData({error: err})) | ||||
|         return src | ||||
|     } | ||||
|  | @ -97,42 +97,42 @@ export class UIEventSource<T> { | |||
|      * src.addCallback(_ => console.log("src pinged")) | ||||
|      * stable.addCallback(_ => console.log("stable pinged)) | ||||
|      * src.setDate([...src.data]) | ||||
|      *  | ||||
|      * | ||||
|      * This will only trigger 'src pinged' | ||||
|      *  | ||||
|      * | ||||
|      * @param src | ||||
|      * @constructor | ||||
|      */ | ||||
|     public static ListStabilized<T>(src: UIEventSource<T[]>) : UIEventSource<T[]>{ | ||||
|          | ||||
|     public static ListStabilized<T>(src: UIEventSource<T[]>): UIEventSource<T[]> { | ||||
| 
 | ||||
|         const stable = new UIEventSource<T[]>(src.data) | ||||
|         src.addCallback(list => { | ||||
|             if(list === undefined){ | ||||
|             if (list === undefined) { | ||||
|                 stable.setData(undefined) | ||||
|                 return; | ||||
|             } | ||||
|             const oldList = stable.data | ||||
|             if(oldList === list){ | ||||
|             if (oldList === list) { | ||||
|                 return; | ||||
|             } | ||||
|             if(oldList.length !== list.length){ | ||||
|             if (oldList.length !== list.length) { | ||||
|                 stable.setData(list); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             for (let i = 0; i < list.length; i++) { | ||||
|                 if(oldList[i] !== list[i]){ | ||||
|                 if (oldList[i] !== list[i]) { | ||||
|                     stable.setData(list); | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             // No actual changes, so we don't do anything
 | ||||
|             return; | ||||
|         }) | ||||
|         return stable | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * Adds a callback | ||||
|      * | ||||
|  | @ -190,21 +190,26 @@ export class UIEventSource<T> { | |||
|     /** | ||||
|      * Monadic bind function | ||||
|      */ | ||||
|     public bind<X>(f: ((t: T) => UIEventSource<X>)): UIEventSource<X>{ | ||||
|         const sink = new UIEventSource<X>( undefined ) | ||||
|     public bind<X>(f: ((t: T) => UIEventSource<X>)): UIEventSource<X> { | ||||
|         const mapped = this.map(f) | ||||
|         const sink = new UIEventSource<X>(undefined) | ||||
|         const seenEventSources = new Set<UIEventSource<X>>(); | ||||
|         this.addCallbackAndRun(data => { | ||||
|             const eventSource = f(data) | ||||
|             if(eventSource === undefined){ | ||||
|         mapped.addCallbackAndRun(newEventSource => { | ||||
|              | ||||
|             if (newEventSource === undefined) { | ||||
|                 sink.setData(undefined) | ||||
|             }else if(!seenEventSources.has(eventSource)){ | ||||
|                 eventSource.addCallbackAndRun(mappedData => sink.setData(mappedData)) | ||||
|                 seenEventSources.add(eventSource) | ||||
|             } else if (!seenEventSources.has(newEventSource)) { | ||||
|                 seenEventSources.add(newEventSource) | ||||
|                 newEventSource.addCallbackAndRun(resultData => { | ||||
|                     if (mapped.data === newEventSource) { | ||||
|                         sink.setData(resultData); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|         }) | ||||
|          | ||||
| 
 | ||||
|         return sink; | ||||
|     }  | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Monoidal map: | ||||
|  |  | |||
|  | @ -70,7 +70,10 @@ export default class TagRenderingQuestion extends Combine { | |||
|                 return TagRenderingQuestion.GenerateFullQuestion(tags, applicableMappings, configuration, options) | ||||
|             }) | ||||
|         )*/ | ||||
|         super([TagRenderingQuestion.GenerateFullQuestion(tags, (configuration.mappings??[]).filter(mapping => mapping.hideInAnswer !== undefined), configuration, options)]) | ||||
|          | ||||
|         const applicableMappings =  Utils.NoNull((configuration.mappings??[]).filter(mapping => mapping.hideInAnswer !== undefined)) | ||||
|          | ||||
|         super([TagRenderingQuestion.GenerateFullQuestion(tags, applicableMappings, configuration, options)]) | ||||
|     } | ||||
|      | ||||
|     private static GenerateFullQuestion(tags: UIEventSource<any>, | ||||
|  | @ -163,6 +166,13 @@ export default class TagRenderingQuestion extends Combine { | |||
|                                         applicableUnit: Unit, | ||||
|                                         tagsSource: UIEventSource<any>) | ||||
|             : InputElement<TagsFilter> { | ||||
| 
 | ||||
|         // FreeForm input will be undefined if not present; will already contain a special input element if applicable
 | ||||
|         const ff = TagRenderingQuestion.GenerateFreeform(configuration, applicableUnit, tagsSource); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         const hasImages = applicableMappings.filter(mapping => mapping.then.ExtractImages().length > 0).length > 0 | ||||
|         let inputEls: InputElement<TagsFilter>[]; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -173,11 +183,11 @@ export default class TagRenderingQuestion extends Combine { | |||
|                 return undefined | ||||
|             } | ||||
|             if (!ifNotsPresent) { | ||||
|                 return undefined | ||||
|                 return [] | ||||
|             } | ||||
|             if (configuration.multiAnswer) { | ||||
|                 // The multianswer will do the ifnot configuration themself
 | ||||
|                 return undefined | ||||
|                 return [] | ||||
|             } | ||||
|                  | ||||
|             const negativeMappings = [] | ||||
|  | @ -193,9 +203,7 @@ export default class TagRenderingQuestion extends Combine { | |||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         const ff = TagRenderingQuestion.GenerateFreeform(configuration, applicableUnit, tagsSource); | ||||
|         const hasImages = applicableMappings.filter(mapping => mapping.then.ExtractImages().length > 0).length > 0 | ||||
| 
 | ||||
|       | ||||
|         if (applicableMappings.length < 8 || configuration.multiAnswer || hasImages || ifNotsPresent) { | ||||
|             inputEls = (applicableMappings ?? []).map((mapping, i) => TagRenderingQuestion.GenerateMappingElement(tagsSource, mapping, allIfNotsExcept(i))); | ||||
|             inputEls = Utils.NoNull(inputEls); | ||||
|  | @ -226,7 +234,7 @@ export default class TagRenderingQuestion extends Combine { | |||
|         } | ||||
| 
 | ||||
|         if (configuration.multiAnswer) { | ||||
|             return TagRenderingQuestion.GenerateMultiAnswer(configuration, inputEls, ff, configuration.mappings.map(mp => mp.ifnot)) | ||||
|             return TagRenderingQuestion.GenerateMultiAnswer(configuration, inputEls, ff, applicableMappings.map(mp => mp.ifnot)) | ||||
|         } else { | ||||
|             return new RadioButton(inputEls, {selectFirstAsDefault: false}) | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue