forked from MapComplete/MapComplete
First version of unit handling: canonicalizing on input
This commit is contained in:
parent
fca3f45908
commit
0012a2f683
11 changed files with 379 additions and 48 deletions
|
@ -8,6 +8,7 @@ import {TagUtils} from "../../Logic/Tags/TagUtils";
|
|||
import {And} from "../../Logic/Tags/And";
|
||||
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
|
||||
|
||||
|
||||
/***
|
||||
* The parsed version of TagRenderingConfigJSON
|
||||
* Identical data, but with some methods and validation
|
||||
|
@ -64,11 +65,16 @@ export default class TagRenderingConfig {
|
|||
this.condition = condition;
|
||||
}
|
||||
if (json.freeform) {
|
||||
|
||||
|
||||
|
||||
this.freeform = {
|
||||
key: json.freeform.key,
|
||||
type: json.freeform.type ?? "string",
|
||||
addExtraTags: json.freeform.addExtraTags?.map((tg, i) =>
|
||||
FromJSON.Tag(tg, `${context}.extratag[${i}]`)) ?? []
|
||||
FromJSON.Tag(tg, `${context}.extratag[${i}]`)) ?? [],
|
||||
|
||||
|
||||
}
|
||||
if (json.freeform["extraTags"] !== undefined) {
|
||||
throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})`
|
||||
|
@ -76,6 +82,9 @@ export default class TagRenderingConfig {
|
|||
if (this.freeform.key === undefined || this.freeform.key === "") {
|
||||
throw `Freeform.key is undefined or the empty string - this is not allowed; either fill out something or remove the freeform block alltogether. Error in ${context}`
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ValidatedTextField.AllTypes[this.freeform.type] === undefined) {
|
||||
const knownKeys = ValidatedTextField.tpList.map(tp => tp.name).join(", ");
|
||||
throw `Freeform.key ${this.freeform.key} is an invalid type. Known keys are ${knownKeys}`
|
||||
|
@ -91,8 +100,8 @@ export default class TagRenderingConfig {
|
|||
this.multiAnswer = json.multiAnswer ?? false
|
||||
if (json.mappings) {
|
||||
|
||||
if(!Array.isArray(json.mappings)){
|
||||
throw "Tagrendering has a 'mappings'-object, but expected a list ("+context+")"
|
||||
if (!Array.isArray(json.mappings)) {
|
||||
throw "Tagrendering has a 'mappings'-object, but expected a list (" + context + ")"
|
||||
}
|
||||
|
||||
this.mappings = json.mappings.map((mapping, i) => {
|
||||
|
@ -104,15 +113,15 @@ export default class TagRenderingConfig {
|
|||
if (mapping.ifnot !== undefined && !this.multiAnswer) {
|
||||
throw `${context}.mapping[${i}]: Invalid mapping: ifnot defined, but the tagrendering is not a multianswer`
|
||||
}
|
||||
|
||||
if(mapping.if === undefined){
|
||||
|
||||
if (mapping.if === undefined) {
|
||||
throw `${context}.mapping[${i}]: Invalid mapping: "if" is not defined, but the tagrendering is not a multianswer`
|
||||
}
|
||||
if(typeof mapping.if !== "string" && mapping.if["length"] !== undefined){
|
||||
if (typeof mapping.if !== "string" && mapping.if["length"] !== undefined) {
|
||||
throw `${context}.mapping[${i}]: Invalid mapping: "if" is defined as an array. Use {"and": <your conditions>} or {"or": <your conditions>} instead`
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let hideInAnswer: boolean | TagsFilter = false;
|
||||
if (typeof mapping.hideInAnswer === "boolean") {
|
||||
hideInAnswer = mapping.hideInAnswer;
|
||||
|
@ -246,22 +255,22 @@ export default class TagRenderingConfig {
|
|||
* @param tags
|
||||
* @constructor
|
||||
*/
|
||||
public GetRenderValues(tags: any): Translation[]{
|
||||
if(!this.multiAnswer){
|
||||
public GetRenderValues(tags: any): Translation[] {
|
||||
if (!this.multiAnswer) {
|
||||
return [this.GetRenderValue(tags)]
|
||||
}
|
||||
|
||||
// A flag to check that the freeform key isn't matched multiple times
|
||||
// If it is undefined, it is "used" already, or at least we don't have to check for it anymore
|
||||
let freeformKeyUsed = this.freeform?.key === undefined;
|
||||
let freeformKeyUsed = this.freeform?.key === undefined;
|
||||
// We run over all the mappings first, to check if the mapping matches
|
||||
const applicableMappings: Translation[] = Utils.NoNull((this.mappings ?? [])?.map(mapping => {
|
||||
if (mapping.if === undefined) {
|
||||
return mapping.then;
|
||||
}
|
||||
if (TagUtils.MatchesMultiAnswer(mapping.if, tags)) {
|
||||
if(!freeformKeyUsed){
|
||||
if(mapping.if.usedKeys().indexOf(this.freeform.key) >= 0){
|
||||
if (!freeformKeyUsed) {
|
||||
if (mapping.if.usedKeys().indexOf(this.freeform.key) >= 0) {
|
||||
// This mapping matches the freeform key - we mark the freeform key to be ignored!
|
||||
freeformKeyUsed = true;
|
||||
}
|
||||
|
@ -270,8 +279,7 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
return undefined;
|
||||
}))
|
||||
|
||||
|
||||
|
||||
|
||||
if (!freeformKeyUsed
|
||||
&& tags[this.freeform.key] !== undefined) {
|
||||
|
@ -279,9 +287,10 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
return applicableMappings
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the correct rendering value (or undefined if not known)
|
||||
* Not compatible with multiAnswer - use GetRenderValueS instead in that case
|
||||
* @constructor
|
||||
*/
|
||||
public GetRenderValue(tags: any): Translation {
|
||||
|
@ -308,14 +317,14 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
|
||||
public ExtractImages(isIcon: boolean): Set<string> {
|
||||
|
||||
|
||||
const usedIcons = new Set<string>()
|
||||
this.render?.ExtractImages(isIcon)?.forEach(usedIcons.add, usedIcons)
|
||||
|
||||
for (const mapping of this.mappings ?? []) {
|
||||
mapping.then.ExtractImages(isIcon).forEach(usedIcons.add, usedIcons)
|
||||
}
|
||||
|
||||
|
||||
return usedIcons;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue