163 lines
4.3 KiB
TypeScript
163 lines
4.3 KiB
TypeScript
import { Question } from "@components/Widgets/SignupQuestionsWidget/common";
|
|
import { SignupForm } from "@models/Signup";
|
|
import { EMAIL_REGEX } from "@utils/regexes";
|
|
import escapeRegExp from "lodash/escapeRegExp";
|
|
|
|
const questionToUISchemaProp = (question: Question) => {
|
|
let obj: Record<"ui:widget", string>;
|
|
if (question.type === "checkbox") {
|
|
obj = {
|
|
"ui:widget": "checkboxes",
|
|
};
|
|
} else if (question.type === "radiobutton") {
|
|
obj = {
|
|
"ui:widget": "radio",
|
|
};
|
|
}
|
|
return {
|
|
[question.id]: obj,
|
|
};
|
|
};
|
|
|
|
const questionToValidationSchema = (question: Question) => {
|
|
let obj: Record<string, unknown>;
|
|
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("|"),
|
|
},
|
|
};
|
|
} else if (question.type === "integer") {
|
|
// https://json-schema.org/understanding-json-schema/reference/numeric.html
|
|
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 = {};
|
|
|
|
// Force every radiobutton to be required field
|
|
questions.forEach((q) => {
|
|
if (q.type === "radiobutton") {
|
|
// eslint-disable-next-line no-param-reassign
|
|
q.required = true;
|
|
}
|
|
});
|
|
|
|
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;
|
|
};
|