From 465cd7a605e83797af998f19c72c17d473ae5301 Mon Sep 17 00:00:00 2001 From: suvarnakale Date: Wed, 10 Jul 2024 19:20:41 +0530 Subject: [PATCH] Issue #PS-1252 feat: script added to get rjsf readable schema and uischema --- src/components/DynamicForm.tsx | 10 +- src/components/GeneratedSchemas.tsx | 144 ++++++++++++++ src/pages/addLearner.tsx | 3 +- src/utils/schema.js | 292 ++++++++++++++++++++++++++++ 4 files changed, 440 insertions(+), 9 deletions(-) create mode 100644 src/components/GeneratedSchemas.tsx diff --git a/src/components/DynamicForm.tsx b/src/components/DynamicForm.tsx index c6cf2382..a3491314 100644 --- a/src/components/DynamicForm.tsx +++ b/src/components/DynamicForm.tsx @@ -1,13 +1,10 @@ -import React, { useRef } from 'react'; +import React from 'react'; import { IChangeEvent } from '@rjsf/core'; -import ISubmitEvent from '@rjsf/core'; import validator from '@rjsf/validator-ajv8'; import { Theme as MaterialUITheme } from '@rjsf/mui'; import { withTheme } from '@rjsf/core'; import MultiSelectCheckboxes from './MultiSelectCheckboxes'; -import CustomCheckboxWidget from './CustomCheckboxWidget'; import CustomRadioWidget from './CustomRadioWidget'; -import CustomErrorList from './CustomErrorList'; import { RJSFSchema, WidgetProps } from '@rjsf/utils'; const FormWithMaterialUI = withTheme(MaterialUITheme); @@ -37,15 +34,14 @@ const DynamicForm: React.FC = ({ }) => { const widgets = { MultiSelectCheckboxes: MultiSelectCheckboxes, - CustomCheckboxWidget: CustomCheckboxWidget, CustomRadioWidget: CustomRadioWidget, }; - console.log('CustomErrorList', CustomErrorList); + // console.log('CustomErrorList', CustomErrorList); const handleError = (errors: any) => { if (errors.length > 0) { // Adjust the selector based on the actual structure of the form element names - const property = errors[0].property.replace(/^root\./, ''); + const property = errors[0].property?.replace(/^root\./, ''); const errorField = document.querySelector( `[name$="${property}"]` ) as HTMLElement; diff --git a/src/components/GeneratedSchemas.tsx b/src/components/GeneratedSchemas.tsx new file mode 100644 index 00000000..48e0ffd8 --- /dev/null +++ b/src/components/GeneratedSchemas.tsx @@ -0,0 +1,144 @@ +import { UiSchema } from '@rjsf/utils'; +import { JSONSchema7 } from 'json-schema'; +import { apiResponse } from '@/utils/schema'; + +interface FieldOption { + label: string; + value: string; +} + +interface Field { + label: string; + name: string; + type: 'text' | 'numeric' | 'drop_down' | 'checkbox' | 'radio'; + isEditable: boolean; + isPIIField?: boolean | null; + placeholder?: string; + validation?: any[]; + options: FieldOption[]; + isMultiSelect: boolean; + maxSelections?: number | null; + hint?: string | null; + pattern?: string | null; + maxLength?: number | null; + minLength?: number | null; + fieldId: string; + dependsOn: boolean; +} + +const GenerateSchemaAndUiSchema = (apiResponse: any) => { + const schema: JSONSchema7 = { + title: 'A registration form', + description: 'A simple form example', + type: 'object', + required: [], + properties: {}, + dependencies: {}, + }; + + const uiSchema: UiSchema = {}; + + apiResponse.result.forEach((field: Field) => { + const { + label, + name, + type, + isEditable, + validation, + options, + isMultiSelect, + maxSelections, + dependsOn, + } = field; + + let fieldSchema: any = { + title: label, + }; + + let fieldUiSchema: any = {}; + + switch (type) { + case 'text': + fieldSchema.type = 'string'; + break; + case 'numeric': + fieldSchema.type = 'number'; + break; + case 'drop_down': + fieldSchema.type = 'string'; + fieldSchema.oneOf = options.map((opt: FieldOption) => ({ + const: opt.value, + title: opt.label, + })); + fieldUiSchema['ui:widget'] = 'select'; + break; + case 'checkbox': + fieldSchema.type = 'array'; + fieldSchema.items = { + type: 'string', + oneOf: options.map((opt: FieldOption) => ({ + const: opt.value, + title: opt.label, + })), + }; + fieldSchema.uniqueItems = true; + fieldUiSchema['ui:widget'] = 'checkboxes'; + break; + case 'radio': + fieldSchema.type = 'string'; + fieldSchema.oneOf = options.map((opt: FieldOption) => ({ + const: opt.value, + title: opt.label, + })); + fieldUiSchema['ui:widget'] = 'CustomRadioWidget'; + break; + default: + break; + } + + if (isEditable === false) { + fieldUiSchema['ui:disabled'] = true; + } + + if (dependsOn) { + // Handle dependencies logic if needed + } + + if (isMultiSelect && type === 'drop_down') { + fieldSchema.type = 'array'; + fieldSchema.items = { + type: 'string', + oneOf: options.map((opt: FieldOption) => ({ + const: opt.value, + title: opt.label, + })), + }; + fieldSchema.uniqueItems = true; + fieldUiSchema['ui:widget'] = 'select'; + } + + if (isMultiSelect && type === 'checkbox') { + fieldSchema.type = 'array'; + fieldSchema.items = { + type: 'string', + oneOf: options.map((opt: FieldOption) => ({ + const: opt.value, + title: opt.label, + })), + }; + fieldSchema.uniqueItems = true; + fieldUiSchema['ui:widget'] = 'MultiSelectCheckboxes'; + } + + if (schema !== undefined && schema.properties) { + schema.properties[name] = fieldSchema; + uiSchema[name] = fieldUiSchema; + } + }); + + return { schema, uiSchema }; +}; + +const { schema, uiSchema } = GenerateSchemaAndUiSchema(apiResponse); + +export { schema, uiSchema }; diff --git a/src/pages/addLearner.tsx b/src/pages/addLearner.tsx index 3355a6e6..4c498e58 100644 --- a/src/pages/addLearner.tsx +++ b/src/pages/addLearner.tsx @@ -1,7 +1,6 @@ import DynamicForm from '@/components/DynamicForm'; import React from 'react'; -import { schema, uiSchema } from '@/utils/schema'; -// import { schema, uiSchema } from '@/components/GeneratedSchemas'; +import { schema, uiSchema } from '@/components/GeneratedSchemas'; import { IChangeEvent } from '@rjsf/core'; import ISubmitEvent from '@rjsf/core'; import { Box } from '@mui/material'; diff --git a/src/utils/schema.js b/src/utils/schema.js index ef9b7706..db67659c 100644 --- a/src/utils/schema.js +++ b/src/utils/schema.js @@ -214,3 +214,295 @@ const formReadResponse = { }, ], }; + +export const apiResponse = { + result: [ + { + label: 'Age', + name: 'age', + type: 'numeric', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: '57b50148-2b58-45e5-9b27-6a07c5317c18', + dependsOn: false, + }, + { + label: 'Unit Name', + name: 'unit_name', + type: 'text', + isEditable: false, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: '2f7c44e8-5890-4f09-a759-da08b1fda38c', + dependsOn: false, + }, + { + label: 'Number of Clusters I Teach', + name: 'no_of_clusters', + type: 'numeric', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'f5249ac0-931a-4136-8c82-8767263a5460', + dependsOn: false, + }, + { + label: 'Year of joining SCP', + name: 'year_of_joining_scp', + type: 'numeric', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'f9fb37a4-d5d0-4f71-9ff6-cfd7d54a1611', + dependsOn: false, + }, + { + label: 'State', + name: 'state', + type: 'drop_down', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: true, + maxSelections: 1, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'b61edfc6-3787-4079-86d3-37262bf23a9e', + dependsOn: false, + }, + { + label: 'My Main Subjects', + name: 'main_subject', + type: 'checkbox', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [ + { + label: 'English', + value: 'english', + }, + { + label: 'Home Science', + value: 'home_science', + }, + { + label: 'Math', + value: 'math', + }, + { + label: 'Language', + value: 'language', + }, + { + label: 'Science', + value: 'science', + }, + { + label: 'Social Science', + value: 'social_science', + }, + { + label: 'Life Skills', + value: 'life_skills', + }, + ], + isMultiSelect: true, + maxSelections: 7, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: '935bfb34-9be7-4676-b9cc-cec1ec4c0a2c', + dependsOn: false, + }, + { + label: 'Designation', + name: 'designation', + type: 'radio', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [ + { + label: 'Facilitator', + value: 'facilitator', + }, + { + label: 'Team Leader', + value: 'team_leader', + }, + ], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'cb407d11-f1c5-424c-a422-4755a1c4ab29', + dependsOn: false, + }, + { + label: 'Gender', + name: 'gender', + type: 'radio', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [ + { + label: 'Male', + value: 'male', + }, + { + label: 'Female', + value: 'female', + }, + ], + isMultiSelect: false, + maxSelections: null, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'a71fd390-fd67-45c3-ab1e-6994b8d967a2', + dependsOn: false, + }, + { + label: 'District', + name: 'district', + type: 'drop_down', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [ + { + label: 'English', + value: 'english', + }, + { + label: 'Home Science', + value: 'home_science', + }, + { + label: 'Math', + value: 'math', + }, + ], + isMultiSelect: true, + maxSelections: 1, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'f2d731dd-2298-40d3-80bb-9ae6c5b38fb8', + dependsOn: true, + }, + { + label: 'Block', + name: 'block', + type: 'drop_down', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [], + isMultiSelect: true, + maxSelections: 1, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: '549d3575-bf01-48a9-9fff-59220fede174', + dependsOn: true, + }, + { + label: 'Subjects I Teach', + name: 'subject_taught', + type: 'checkbox', + isEditable: true, + isPIIField: null, + placeholder: '', + validation: [], + options: [ + { + label: 'English', + value: 'english', + }, + { + label: 'Home Science', + value: 'home_science', + }, + { + label: 'Math', + value: 'math', + }, + { + label: 'Language', + value: 'language', + }, + { + label: 'Science', + value: 'science', + }, + { + label: 'Social Science', + value: 'social_science', + }, + { + label: 'Life Skills', + value: '_lifeskills', + }, + ], + isMultiSelect: true, + maxSelections: 7, + hint: null, + pattern: null, + maxLength: null, + minLength: null, + fieldId: 'abb7f3fe-f7fa-47be-9d28-5747dd3159f2', + dependsOn: false, + }, + ], +};