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
|
* @param promise
|
||||||
* @constructor
|
* @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)
|
const src = new UIEventSource<T>(undefined)
|
||||||
promise?.then(d => src.setData(d))
|
promise?.then(d => src.setData(d))
|
||||||
promise?.catch(err => console.warn("Promise failed:", err))
|
promise?.catch(err => console.warn("Promise failed:", err))
|
||||||
|
@ -82,9 +82,9 @@ export class UIEventSource<T> {
|
||||||
* @param promise
|
* @param promise
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
public static FromPromiseWithErr<T>(promise : Promise<T>): UIEventSource<{success: T} | {error: any}>{
|
public static FromPromiseWithErr<T>(promise: Promise<T>): UIEventSource<{ success: T } | { error: any }> {
|
||||||
const src = new UIEventSource<{success: T}|{error: any}>(undefined)
|
const src = new UIEventSource<{ success: T } | { error: any }>(undefined)
|
||||||
promise?.then(d => src.setData({success:d}))
|
promise?.then(d => src.setData({success: d}))
|
||||||
promise?.catch(err => src.setData({error: err}))
|
promise?.catch(err => src.setData({error: err}))
|
||||||
return src
|
return src
|
||||||
}
|
}
|
||||||
|
@ -97,42 +97,42 @@ export class UIEventSource<T> {
|
||||||
* src.addCallback(_ => console.log("src pinged"))
|
* src.addCallback(_ => console.log("src pinged"))
|
||||||
* stable.addCallback(_ => console.log("stable pinged))
|
* stable.addCallback(_ => console.log("stable pinged))
|
||||||
* src.setDate([...src.data])
|
* src.setDate([...src.data])
|
||||||
*
|
*
|
||||||
* This will only trigger 'src pinged'
|
* This will only trigger 'src pinged'
|
||||||
*
|
*
|
||||||
* @param src
|
* @param src
|
||||||
* @constructor
|
* @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)
|
const stable = new UIEventSource<T[]>(src.data)
|
||||||
src.addCallback(list => {
|
src.addCallback(list => {
|
||||||
if(list === undefined){
|
if (list === undefined) {
|
||||||
stable.setData(undefined)
|
stable.setData(undefined)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const oldList = stable.data
|
const oldList = stable.data
|
||||||
if(oldList === list){
|
if (oldList === list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(oldList.length !== list.length){
|
if (oldList.length !== list.length) {
|
||||||
stable.setData(list);
|
stable.setData(list);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
for (let i = 0; i < list.length; i++) {
|
||||||
if(oldList[i] !== list[i]){
|
if (oldList[i] !== list[i]) {
|
||||||
stable.setData(list);
|
stable.setData(list);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No actual changes, so we don't do anything
|
// No actual changes, so we don't do anything
|
||||||
return;
|
return;
|
||||||
})
|
})
|
||||||
return stable
|
return stable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a callback
|
* Adds a callback
|
||||||
*
|
*
|
||||||
|
@ -190,21 +190,26 @@ export class UIEventSource<T> {
|
||||||
/**
|
/**
|
||||||
* Monadic bind function
|
* Monadic bind function
|
||||||
*/
|
*/
|
||||||
public bind<X>(f: ((t: T) => UIEventSource<X>)): UIEventSource<X>{
|
public bind<X>(f: ((t: T) => UIEventSource<X>)): UIEventSource<X> {
|
||||||
const sink = new UIEventSource<X>( undefined )
|
const mapped = this.map(f)
|
||||||
|
const sink = new UIEventSource<X>(undefined)
|
||||||
const seenEventSources = new Set<UIEventSource<X>>();
|
const seenEventSources = new Set<UIEventSource<X>>();
|
||||||
this.addCallbackAndRun(data => {
|
mapped.addCallbackAndRun(newEventSource => {
|
||||||
const eventSource = f(data)
|
|
||||||
if(eventSource === undefined){
|
if (newEventSource === undefined) {
|
||||||
sink.setData(undefined)
|
sink.setData(undefined)
|
||||||
}else if(!seenEventSources.has(eventSource)){
|
} else if (!seenEventSources.has(newEventSource)) {
|
||||||
eventSource.addCallbackAndRun(mappedData => sink.setData(mappedData))
|
seenEventSources.add(newEventSource)
|
||||||
seenEventSources.add(eventSource)
|
newEventSource.addCallbackAndRun(resultData => {
|
||||||
|
if (mapped.data === newEventSource) {
|
||||||
|
sink.setData(resultData);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monoidal map:
|
* Monoidal map:
|
||||||
|
|
|
@ -70,7 +70,10 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
return TagRenderingQuestion.GenerateFullQuestion(tags, applicableMappings, configuration, options)
|
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>,
|
private static GenerateFullQuestion(tags: UIEventSource<any>,
|
||||||
|
@ -163,6 +166,13 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
applicableUnit: Unit,
|
applicableUnit: Unit,
|
||||||
tagsSource: UIEventSource<any>)
|
tagsSource: UIEventSource<any>)
|
||||||
: InputElement<TagsFilter> {
|
: 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>[];
|
let inputEls: InputElement<TagsFilter>[];
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,11 +183,11 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
if (!ifNotsPresent) {
|
if (!ifNotsPresent) {
|
||||||
return undefined
|
return []
|
||||||
}
|
}
|
||||||
if (configuration.multiAnswer) {
|
if (configuration.multiAnswer) {
|
||||||
// The multianswer will do the ifnot configuration themself
|
// The multianswer will do the ifnot configuration themself
|
||||||
return undefined
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const negativeMappings = []
|
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) {
|
if (applicableMappings.length < 8 || configuration.multiAnswer || hasImages || ifNotsPresent) {
|
||||||
inputEls = (applicableMappings ?? []).map((mapping, i) => TagRenderingQuestion.GenerateMappingElement(tagsSource, mapping, allIfNotsExcept(i)));
|
inputEls = (applicableMappings ?? []).map((mapping, i) => TagRenderingQuestion.GenerateMappingElement(tagsSource, mapping, allIfNotsExcept(i)));
|
||||||
inputEls = Utils.NoNull(inputEls);
|
inputEls = Utils.NoNull(inputEls);
|
||||||
|
@ -226,7 +234,7 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.multiAnswer) {
|
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 {
|
} else {
|
||||||
return new RadioButton(inputEls, {selectFirstAsDefault: false})
|
return new RadioButton(inputEls, {selectFirstAsDefault: false})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue