Combine Schema creation functions
This commit is contained in:
@@ -11,7 +11,13 @@ export interface SignupForm {
|
||||
questions: Question[];
|
||||
signups: string[];
|
||||
quota: number;
|
||||
schema: object;
|
||||
schema: {
|
||||
title?: string;
|
||||
type: string;
|
||||
required: string[];
|
||||
properties: any;
|
||||
minProperties?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export async function getForms(): Promise<SignupForm[]> {
|
||||
|
||||
@@ -6,7 +6,7 @@ import Form from "react-jsonschema-form";
|
||||
import { createForm, getForm, updateForm, SignupForm } from "@models/SignupForm";
|
||||
import DatetimeWidget from "@components/DatetimeWidget";
|
||||
import SignupQuestionsWidget from "@components/SignupQuestionsWidget";
|
||||
import { buildQuestionsSchema } from "@views/SignUpPage/FormUtils";
|
||||
import { buildValidationSchema } from "@views/SignUpPage/FormUtils";
|
||||
|
||||
const widgets = {
|
||||
datetime: DatetimeWidget,
|
||||
@@ -64,7 +64,7 @@ class SignupCreatePage extends React.Component<SignupCreatePageProps, SignupCrea
|
||||
const payload: SignupForm = {
|
||||
...data.formData,
|
||||
questions,
|
||||
schema: buildQuestionsSchema(questions)
|
||||
schema: buildValidationSchema(questions)
|
||||
}
|
||||
|
||||
if (payload.id === undefined) {
|
||||
|
||||
@@ -3,86 +3,6 @@ import { Question } from "@components/SignupQuestionsWidget";
|
||||
import { SignupForm } from "@models/SignupForm";
|
||||
import { EMAIL_REGEX } from "@utils/regexes";
|
||||
|
||||
const questionToSchemaProp = (question: Question): {} => {
|
||||
let obj: any;
|
||||
if (question.type === "text" || question.type === "name") {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
default: "",
|
||||
};
|
||||
}
|
||||
else if (question.type === "radiobutton") {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
enum: question.options,
|
||||
};
|
||||
}
|
||||
else if (question.type === "checkbox") {
|
||||
obj = {
|
||||
type: "array",
|
||||
title: question.name,
|
||||
items: {
|
||||
type: "string",
|
||||
enum: question.options,
|
||||
},
|
||||
uniqueItems: true,
|
||||
};
|
||||
}
|
||||
else if (question.type === "email") {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
format: "email",
|
||||
default: ""
|
||||
}
|
||||
}
|
||||
else if (question.type === "info") {
|
||||
obj = {
|
||||
type: "null",
|
||||
title: question.name,
|
||||
description: question.options
|
||||
}
|
||||
}
|
||||
// https://json-schema.org/understanding-json-schema/reference/numeric.html
|
||||
else if (question.type === "integer") {
|
||||
if (question.options.length === 1) {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: `${question.name} (Max: ${question.options[0]})`,
|
||||
maximum: Number(question.options[0]),
|
||||
}
|
||||
}
|
||||
|
||||
else if (question.options.length === 2) {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: `${question.name} (${question.options[0]} -- ${question.options[1]})`,
|
||||
minimum: Number(question.options[0]),
|
||||
maximum: Number(question.options[1]),
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: question.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error(`No mapping to schema prop for question type ${question.type}`);
|
||||
}
|
||||
|
||||
return {
|
||||
[question.id]: obj,
|
||||
}
|
||||
}
|
||||
|
||||
const questionToUISchemaProp = (question: Question): {} => {
|
||||
let obj = {};
|
||||
if (question.type == "checkbox") {
|
||||
@@ -104,33 +24,48 @@ const questionToUISchemaProp = (question: Question): {} => {
|
||||
}
|
||||
|
||||
const questionToValidationSchema = (question: Question) => {
|
||||
let obj = {};
|
||||
if (question.type === "text" || question.type === "name") {
|
||||
return {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
default: "",
|
||||
};
|
||||
}
|
||||
|
||||
if (question.type == "email") {
|
||||
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.
|
||||
return {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
format: "email",
|
||||
pattern: EMAIL_REGEX.source
|
||||
pattern: EMAIL_REGEX.source,
|
||||
default: ""
|
||||
}
|
||||
}
|
||||
if (question.type == "radiobutton") {
|
||||
return {
|
||||
"type": "string",
|
||||
"pattern": question.options.map(x => `^${x}$`).join("|"),
|
||||
else if (question.type === "radiobutton") {
|
||||
obj = {
|
||||
type: "string",
|
||||
title: question.name,
|
||||
pattern: question.options.map(x => `^${x}$`).join("|"),
|
||||
enum: question.options,
|
||||
}
|
||||
}
|
||||
if (question.type == "checkbox") {
|
||||
return {
|
||||
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 => `^${x}$`).join("|"),
|
||||
}
|
||||
}
|
||||
@@ -138,37 +73,45 @@ const questionToValidationSchema = (question: Question) => {
|
||||
// https://json-schema.org/understanding-json-schema/reference/numeric.html
|
||||
else if (question.type === "integer") {
|
||||
if (question.options.length === 1) {
|
||||
return {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: `${question.name} (Max: ${question.options[0]})`,
|
||||
multipleOf: 1.0,
|
||||
maximum: Number(question.options[0]),
|
||||
}
|
||||
}
|
||||
else if (question.options.length === 2) {
|
||||
return {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: `${question.name} (${question.options[0]} -- ${question.options[1]})`,
|
||||
multipleOf: 1.0,
|
||||
minimum: Number(question.options[0]),
|
||||
maximum: Number(question.options[1]),
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {
|
||||
obj = {
|
||||
type: "number",
|
||||
multipleOf: 1.0,
|
||||
title: question.name,
|
||||
multipleOf: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(`No mapping to schema prop for question type ${question.type}`);
|
||||
else {
|
||||
throw new Error(`No mapping to schema prop for question type ${question.type}`);
|
||||
|
||||
}
|
||||
return {
|
||||
[question.id]: obj,
|
||||
}
|
||||
}
|
||||
|
||||
export const buildSchema = (signUpForm: SignupForm) => {
|
||||
const {questions} = signUpForm;
|
||||
const schemaPropsArray = questions.map(questionToSchemaProp);
|
||||
export const buildFormSchema = (signUpForm: SignupForm) => {
|
||||
let schemaProps = {};
|
||||
const {questions} = signUpForm;
|
||||
const filtered = questions.filter(x => x.type !== "info");
|
||||
const ids = filtered.map(q => q.id);
|
||||
const schemaPropsArray = questions.map(questionToValidationSchema);
|
||||
schemaPropsArray.forEach((schemaProp) => {
|
||||
schemaProps = {
|
||||
...schemaProps,
|
||||
@@ -179,20 +122,23 @@ export const buildSchema = (signUpForm: SignupForm) => {
|
||||
const schema = {
|
||||
title: signUpForm.id ? signUpForm.title : "Loading...",
|
||||
type: "object",
|
||||
required: [],
|
||||
required: ids,
|
||||
properties: schemaProps,
|
||||
};
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
export const buildQuestionsSchema = (questions: Question[]) => {
|
||||
const schemaProps = {};
|
||||
export const buildValidationSchema = (questions: Question[]) => {
|
||||
let schemaProps = {};
|
||||
const filtered = questions.filter(x => x.type !== "info");
|
||||
const ids = filtered.map(q => q.id);
|
||||
const schemaPropsArray = filtered.map(questionToValidationSchema);
|
||||
schemaPropsArray.forEach((schemaProp, idx) => {
|
||||
schemaProps[ids[idx]] = schemaProp;
|
||||
schemaPropsArray.forEach((schemaProp) => {
|
||||
schemaProps = {
|
||||
...schemaProps,
|
||||
...schemaProp,
|
||||
};
|
||||
});
|
||||
|
||||
const validationSchema = {
|
||||
|
||||
@@ -3,7 +3,7 @@ import Form, { IChangeEvent, ISubmitEvent, ErrorSchema } from "react-jsonschema-
|
||||
import "./SignUpPage.scss";
|
||||
import PageSection from "@components/PageSection";
|
||||
import { SignupForm } from "@models/SignupForm";
|
||||
import { buildSchema, buildUISchema } from "./FormUtils";
|
||||
import { buildFormSchema, buildUISchema } from "./FormUtils";
|
||||
import AsideSection from "@components/AsideSection";
|
||||
import MainSection from "@components/MainSection";
|
||||
import Checkboxes from "@components/Checkbox/Checkboxes";
|
||||
@@ -46,7 +46,7 @@ const SignUpPageView: React.FC<SignUpPageViewProps> = ({
|
||||
}) => {
|
||||
|
||||
const renderForm = () => {
|
||||
const schema = buildSchema(signUpForm);
|
||||
const schema = buildFormSchema(signUpForm);
|
||||
const uiSchema = buildUISchema(signUpForm);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user