Files
web2.0-frontend/src/views/SignUpPage/FormUtils.tsx
T
2020-10-10 01:56:51 +03:00

168 lines
4.2 KiB
TypeScript

import { Question } from "@components/Widgets/SignupQuestionsWidget";
import { SignupForm } from "@models/SignupForm";
import { EMAIL_REGEX } from "@utils/regexes";
import escapeRegExp from "lodash/escapeRegExp";
const questionToUISchemaProp = (question: Question): {} => {
let obj = {};
if (question.type == "checkbox") {
obj = {
"ui:widget": "checkboxes",
};
}
else if (question.type == "radiobutton") {
obj = {
"ui:widget": "radio",
}
}
// else {
// throw new Error(`No mapping to UI schema prop for question type ${question.type}`);
// }
return {
[question.id]: obj,
};
}
const questionToValidationSchema = (question: Question) => {
let obj = {};
if (question.type === "text" || question.type === "name") {
obj = {
type: "string",
title: question.name,
};
}
else if(question.type === "info") {
obj = {
type: "null",
title: question.name,
description: question.options
};
}
else if (question.type === "email") {
// Format is just a "FYI" field, so we also have pattern.
obj = {
type: question.required ? ["string"] : ["string", "null"],
title: question.name,
format: "email",
pattern: EMAIL_REGEX.source,
default: null
}
}
else if (question.type === "radiobutton") {
obj = {
type: "string",
title: question.name,
pattern: question.options.map(x => `^${escapeRegExp(x)}$`).join("|"),
enum: question.options,
}
}
else if (question.type === "checkbox") {
obj = {
type: "array",
title: question.name,
uniqueItems: true,
maxItems: question.options.length,
items: {
type: "string",
enum: question.options,
pattern: question.options.map(x => `^${escapeRegExp(x)}$`).join("|"),
},
}
}
// https://json-schema.org/understanding-json-schema/reference/numeric.html
else if (question.type === "integer") {
if (question.options.length === 1) {
obj = {
type: "number",
title: `${question.name} (Max: ${question.options[0]})`,
multipleOf: 1.0,
maximum: Number(question.options[0]),
}
}
else if (question.options.length === 2) {
obj = {
type: "number",
title: `${question.name} (${question.options[0]} -- ${question.options[1]})`,
multipleOf: 1.0,
minimum: Number(question.options[0]),
maximum: Number(question.options[1]),
}
}
else {
obj = {
type: "number",
title: question.name,
multipleOf: 1.0,
}
}
}
else {
throw new Error(`No mapping to schema prop for question type ${question.type}`);
}
return {
[question.id]: obj,
}
}
export const buildFormSchema = (signUpForm: SignupForm) => {
let schemaProps = {};
const {questions} = signUpForm;
const requiredIds = questions.filter(q => q.required).map(q => q.id);
const schemaPropsArray = questions.map(questionToValidationSchema);
schemaPropsArray.forEach((schemaProp) => {
schemaProps = {
...schemaProps,
...schemaProp,
};
});
const schema = {
title: signUpForm.id ? signUpForm.title_fi : "Loading...",
type: "object",
required: requiredIds,
properties: schemaProps,
};
return schema;
}
export const buildValidationSchema = (questions: Question[]) => {
let schemaProps = {};
const requiredIds = questions.filter(q => q.required).map(q => q.id);
const schemaPropsArray = questions.map(questionToValidationSchema);
schemaPropsArray.forEach((schemaProp) => {
schemaProps = {
...schemaProps,
...schemaProp,
};
});
const validationSchema = {
type: "object",
required: requiredIds,
// minProperties: requiredIds.length,
// maxProperties: requiredIds.length,
properties: schemaProps
}
return validationSchema;
}
export const buildUISchema = (signUpForm: SignupForm) => {
const {questions} = signUpForm;
const uiSchemaPropsArray = questions.map(questionToUISchemaProp);
let uiSchemaProps = {};
uiSchemaPropsArray.forEach((uiSchemaProp) => {
uiSchemaProps = {
...uiSchemaProps,
...uiSchemaProp,
};
});
const uiSchema = {
...uiSchemaProps,
};
return uiSchema;
}