2021-01-08 03:57:18 +01:00
|
|
|
import {And, TagsFilter} from "../../Logic/Tags";
|
2020-10-27 01:01:34 +01:00
|
|
|
import {TagRenderingConfigJson} from "./TagRenderingConfigJson";
|
|
|
|
import Translations from "../../UI/i18n/Translations";
|
|
|
|
import {FromJSON} from "./FromJSON";
|
|
|
|
import ValidatedTextField from "../../UI/Input/ValidatedTextField";
|
2020-11-06 01:58:26 +01:00
|
|
|
import {Translation} from "../../UI/i18n/Translation";
|
2020-10-27 01:01:34 +01:00
|
|
|
|
|
|
|
/***
|
|
|
|
* The parsed version of TagRenderingConfigJSON
|
|
|
|
* Identical data, but with some methods and validation
|
|
|
|
*/
|
|
|
|
export default class TagRenderingConfig {
|
|
|
|
|
2021-01-08 03:57:18 +01:00
|
|
|
readonly render?: Translation;
|
|
|
|
readonly question?: Translation;
|
|
|
|
readonly condition?: TagsFilter;
|
2020-10-27 01:01:34 +01:00
|
|
|
|
2021-01-08 03:57:18 +01:00
|
|
|
readonly freeform?: {
|
|
|
|
readonly key: string,
|
|
|
|
readonly type: string,
|
|
|
|
readonly addExtraTags: TagsFilter[];
|
2020-10-27 01:01:34 +01:00
|
|
|
};
|
|
|
|
|
2021-01-06 01:11:07 +01:00
|
|
|
readonly multiAnswer: boolean;
|
2020-10-27 01:01:34 +01:00
|
|
|
|
2021-01-08 03:57:18 +01:00
|
|
|
readonly mappings?: {
|
|
|
|
readonly if: TagsFilter,
|
|
|
|
readonly then: Translation
|
|
|
|
readonly hideInAnswer: boolean | TagsFilter
|
2020-10-27 01:01:34 +01:00
|
|
|
}[]
|
2021-01-08 03:57:18 +01:00
|
|
|
readonly roaming: boolean;
|
2020-10-27 01:01:34 +01:00
|
|
|
|
2021-01-08 03:57:18 +01:00
|
|
|
constructor(json: string | TagRenderingConfigJson, conditionIfRoaming: TagsFilter, context?: string) {
|
2020-10-27 01:01:34 +01:00
|
|
|
|
2020-12-08 23:44:34 +01:00
|
|
|
if (json === "questions") {
|
|
|
|
// Very special value
|
|
|
|
this.render = null;
|
|
|
|
this.question = null;
|
|
|
|
this.condition = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (json === undefined) {
|
|
|
|
throw "Initing a TagRenderingConfig with undefined in " + context;
|
2020-10-27 01:01:34 +01:00
|
|
|
}
|
|
|
|
if (typeof json === "string") {
|
|
|
|
this.render = Translations.T(json);
|
|
|
|
this.multiAnswer = false;
|
|
|
|
return;
|
|
|
|
}
|
2021-01-08 03:57:18 +01:00
|
|
|
|
2020-10-27 01:01:34 +01:00
|
|
|
this.render = Translations.T(json.render);
|
|
|
|
this.question = Translations.T(json.question);
|
2021-01-08 03:57:18 +01:00
|
|
|
this.roaming = json.roaming ?? false;
|
|
|
|
const condition = FromJSON.Tag(json.condition ?? {"and": []}, `${context}.condition`);
|
|
|
|
if (this.roaming && conditionIfRoaming !== undefined) {
|
|
|
|
this.condition = new And([condition, conditionIfRoaming]);
|
|
|
|
} else {
|
|
|
|
this.condition = condition;
|
|
|
|
}
|
2020-10-27 01:01:34 +01:00
|
|
|
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}]`)) ?? []
|
|
|
|
}
|
|
|
|
if (ValidatedTextField.AllTypes[this.freeform.type] === undefined) {
|
|
|
|
throw `Freeform.key ${this.freeform.key} is an invalid type`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.multiAnswer = json.multiAnswer ?? false
|
|
|
|
if (json.mappings) {
|
|
|
|
this.mappings = json.mappings.map((mapping, i) => {
|
|
|
|
|
|
|
|
if (mapping.then === undefined) {
|
|
|
|
throw "Invalid mapping: if without body"
|
|
|
|
}
|
2021-01-06 01:11:07 +01:00
|
|
|
let hideInAnswer: boolean | TagsFilter = false;
|
2020-12-08 23:44:34 +01:00
|
|
|
if (typeof mapping.hideInAnswer === "boolean") {
|
2020-12-07 03:02:50 +01:00
|
|
|
hideInAnswer = mapping.hideInAnswer;
|
2020-12-08 23:44:34 +01:00
|
|
|
} else if (mapping.hideInAnswer !== undefined) {
|
|
|
|
hideInAnswer = FromJSON.Tag(mapping.hideInAnswer, `${context}.mapping[${i}].hideInAnswer`);
|
2020-12-07 03:02:50 +01:00
|
|
|
}
|
2020-10-27 01:01:34 +01:00
|
|
|
return {
|
2020-12-08 23:44:34 +01:00
|
|
|
if: FromJSON.Tag(mapping.if, `${context}.mapping[${i}].if`),
|
2020-10-27 01:01:34 +01:00
|
|
|
then: Translations.T(mapping.then),
|
2020-12-07 03:02:50 +01:00
|
|
|
hideInAnswer: hideInAnswer
|
2020-10-27 01:01:34 +01:00
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.question && this.freeform?.key === undefined && this.mappings === undefined) {
|
|
|
|
throw `A question is defined, but no mappings nor freeform (key) are. The question is ${this.question.txt} at ${context}`
|
|
|
|
}
|
2021-01-12 20:46:01 +01:00
|
|
|
|
|
|
|
if(this.freeform && this.render === undefined){
|
|
|
|
throw `Detected a freeform key without rendering... Key: ${this.freeform.key} in ${context}`
|
|
|
|
}
|
2020-10-27 01:01:34 +01:00
|
|
|
|
|
|
|
if (json.multiAnswer) {
|
|
|
|
if ((this.mappings?.length ?? 0) === 0) {
|
|
|
|
throw "MultiAnswer is set, but no mappings are defined"
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the correct rendering value (or undefined if not known)
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
public GetRenderValue(tags: any): Translation {
|
|
|
|
if (this.mappings !== undefined && !this.multiAnswer) {
|
|
|
|
for (const mapping of this.mappings) {
|
|
|
|
if (mapping.if === undefined) {
|
|
|
|
return mapping.then;
|
|
|
|
}
|
|
|
|
if (mapping.if.matchesProperties(tags)) {
|
|
|
|
return mapping.then;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-06 01:11:07 +01:00
|
|
|
|
|
|
|
if (this.freeform?.key === undefined) {
|
2020-10-27 01:01:34 +01:00
|
|
|
return this.render;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tags[this.freeform.key] !== undefined) {
|
|
|
|
return this.render;
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|