Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy to prod #158

Merged
merged 29 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
32a3db7
Bug 78 bool (#100)
mekhlakapoor Aug 10, 2023
88c68fc
Bug 78 bool (#101)
mekhlakapoor Sep 26, 2023
fdb838b
hot fix (#106)
mekhlakapoor Sep 27, 2023
60825fa
fix: filters version list by schema type (#116)
mekhlakapoor Nov 8, 2023
9ac3a98
Feat 110 remove schemas (#115)
mekhlakapoor Nov 10, 2023
60fff32
Renders dictionaries (#118)
mekhlakapoor Nov 10, 2023
d9cc1b1
Sort schema versions dropdown by lastest-first semantic version
helen-m-lin Jan 20, 2024
8257d63
Add sample schema list and sorted version list for unit tests
helen-m-lin Jan 22, 2024
f22d1e7
Add unit tests for Dropdowns and sorted schema version
helen-m-lin Jan 22, 2024
d1ce154
Feat 117: Sort schema versions list in dropdown by lastest-first sema…
helen-m-lin Jan 23, 2024
462ec55
Merge branch 'dev' of https://github.com/AllenNeuralDynamics/aind-met…
mekhlakapoor Jan 26, 2024
e8a274a
resolves conflicts
mekhlakapoor Jan 26, 2024
cb6fe7b
Fix 119: Fix pre-process and render issues and improve UI (#127)
helen-m-lin Feb 1, 2024
deef3c5
Merge branch 'main' into dev
mekhlakapoor Feb 3, 2024
e498479
Merge branch 'dev' of https://github.com/AllenNeuralDynamics/aind-met…
mekhlakapoor Feb 3, 2024
0b282bf
handle schema version changes from App component (#130)
helen-m-lin Feb 9, 2024
6922d77
Feat 27: Add linter and unit test frameworks (#133)
helen-m-lin Feb 14, 2024
85b95ad
fixing merge conflicts
mekhlakapoor Feb 17, 2024
fcafe31
finish merge
mekhlakapoor Feb 17, 2024
72ac7f1
Fix 131: Enforce re-render and handle errors in `RenderForm` componen…
helen-m-lin Feb 20, 2024
ab64a7c
Fix 132: Update schema filtering and validation (#143)
helen-m-lin Feb 22, 2024
77589b4
Feat 68: Add border-left css for nested form fieldsets (#147)
helen-m-lin Feb 26, 2024
3c55bad
Fix 139: Enable discriminator support in validator and fix validation…
helen-m-lin Mar 2, 2024
8c34722
Merge branch 'main' into dev
mekhlakapoor Mar 2, 2024
c7e1fa0
fix redundant lines
mekhlakapoor Mar 2, 2024
b25c5d6
Fix 108: Error handling, validation, and UI fixes for Autofill featur…
helen-m-lin Mar 7, 2024
56572ad
Merge branch 'main' into dev
mekhlakapoor Mar 13, 2024
6c1e8c3
Fix 102: Fix nested constants render issues (#157)
helen-m-lin Mar 27, 2024
2948489
Merge branch 'main' into dev
helen-m-lin Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.1.2",
"@rjsf/core": "^5.13.0",
"@rjsf/core": "^5.17.1",
"@rjsf/material-ui": "^5.13.0",
"@rjsf/utils": "^5.13.0",
"@rjsf/validator-ajv8": "^5.13.0",
Expand Down Expand Up @@ -51,11 +51,17 @@
"jest": {
"coverageThreshold": {
"global": {
"statements": 58,
"branches": 55,
"functions": 68,
"lines": 58
"statements": 62,
"branches": 61,
"functions": 70,
"lines": 62
}
},
"transformIgnorePatterns": [
"/node_modules/(?!@rjsf)"
],
"moduleNameMapper": {
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
}
},
"eslintConfig": {
Expand Down
1 change: 0 additions & 1 deletion src/components/Toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ function Toolbar (props) {
* Based on selected schema, renders a dropdown menu for version-selection.
* Gives user the option to autofill the form with previously input data
*/

const { ParentTypeCallback, ParentVersionCallback, selectedSchemaType, selectedSchemaPath, schemaList, handleRehydrate } = props

const schemaTypes = Array.from(
Expand Down
32 changes: 30 additions & 2 deletions src/custom-ui/CustomWidgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import 'react-datetime/css/react-datetime.css'
import moment from 'moment'
import RadioWidget from '@rjsf/material-ui/lib/RadioWidget/RadioWidget'
import CheckboxWidget from '@rjsf/material-ui/lib/CheckboxWidget/CheckboxWidget'
import React from 'react'
import TextWidget from '@rjsf/core/lib/components/widgets/TextWidget'
import React, { useLayoutEffect } from 'react'
import PropTypes from 'prop-types'
import { toConstant } from '@rjsf/utils'

const CustomTimeWidget = (props) => {
const onChange = (selectedDate) => {
Expand Down Expand Up @@ -41,4 +43,30 @@ const CustomCheckboxWidget = (props) => {
}
}

export const widgets = { checkbox: CustomCheckboxWidget, time: CustomTimeWidget }
/**
* Custom text widget to enable custom behavior for constants.
* If const, update formData value to const value using onChange callback, render as readonly (grayed out)
* Otherwise, return default text widget
* @param {*} props RJSF widget props
* @returns A custom text widget
*/
const CustomTextWidget = (props) => {
// useLayoutEffect to run effect runs before browser repaints screen (reduce flickering)
useLayoutEffect(() => {
if (props.schema.const !== undefined) {
props.onChange(toConstant(props.schema))
}
}, [props])
return <TextWidget {...props}
readonly={props.schema.const !== undefined ?? props.readonly}
value={props.schema.const !== undefined ? toConstant(props.schema) : props.value}
/>
}
CustomTextWidget.propTypes = {
value: PropTypes.any,
onChange: PropTypes.func,
schema: PropTypes.object,
readonly: PropTypes.bool
}

export const widgets = { checkbox: CustomCheckboxWidget, time: CustomTimeWidget, text: CustomTextWidget }
38 changes: 38 additions & 0 deletions src/custom-ui/CustomWidgets.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import { fireEvent, render, screen } from '@testing-library/react'
import Form from '@rjsf/core'
import { widgets } from './CustomWidgets'
import validator from '@rjsf/validator-ajv8'

describe('CustomTextWidget', () => {
it('renders a TextWidget', () => {
const testSchema = {
title: 'Test String Const',
type: 'string'
}
render(<Form schema={testSchema}
validator={validator}
widgets={ { text: widgets.text } }
/>)
expect(screen.getByLabelText('Test String Const')).toBeInTheDocument()
})

it('adds const value into formData and renders const input as readonly', () => {
const testSchema = {
title: 'Test String Const',
const: 'const example string value',
type: 'string'
}
render(<Form schema={testSchema}
validator={validator}
widgets={ { text: widgets.text } }
onSubmit={({ formData }) => {
expect(formData).toEqual('const example string value')
}
}
/>)
expect(screen.getByDisplayValue('const example string value')).toBeInTheDocument()
expect(screen.getByDisplayValue('const example string value')).toHaveAttribute('readonly')
fireEvent.click(screen.getByRole('button', { name: /submit/i }))
})
})
47 changes: 44 additions & 3 deletions src/utilities/schemaHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,37 @@ const testSchema1 = ({
const: 'https://github.com/AllenNeuralDynamics/data_schema/blob/main/schemas/subject.json',
description: 'The URL reference to the schema.',
title: 'Described by'
},
schema_version: {
const: '1.0.0',
default: '1.0.0',
description: 'The version of the schema.',
title: 'Schema Version'
},
number_const: {
title: 'Number with missing type',
const: 1,
default: 1
},
boolean_const: {
title: 'Boolean with missing type',
const: true,
default: true
},
object_const: {
title: 'Object with missing type',
const: { key: 'value' },
default: { key: 'value' }
},
array_const: {
title: 'Array with missing type',
const: [1, 2, 3],
default: [1, 2, 3]
},
null_const: {
title: 'Null with missing type',
const: null,
default: null
}
}
})
Expand Down Expand Up @@ -118,10 +149,21 @@ const testSchema4 = ({
]
})

test('Checks preProcessSchema modifies const schema', () => {
test('Checks preProcessSchema modifies const schema to add missing default or type', () => {
const expectedTypes = [
{ key: 'describedBy', type: 'string' },
{ key: 'schema_version', type: 'string' },
{ key: 'number_const', type: 'number' },
{ key: 'boolean_const', type: 'boolean' },
{ key: 'object_const', type: 'object' },
{ key: 'array_const', type: 'array' },
{ key: 'null_const', type: 'null' }
]
const processedSchema1 = preProcessSchema(testSchema1)
expect(processedSchema1.properties.describedBy.default).toBe(testSchema1.properties.describedBy.const)
expect(processedSchema1.properties.describedBy.readOnly).toBe(true)
for (const expectedType of expectedTypes) {
expect(processedSchema1.properties[expectedType.key].type).toBe(expectedType.type)
}
})

test('Checks preProcessSchema modifies dictionary additional properties', () => {
Expand All @@ -146,7 +188,6 @@ test('Checks preProcessSchema modifies discriminator property', () => {

test('Checks preProcessSchema recurses through nested schema as expected', () => {
const processedSchema3 = preProcessSchema(testSchema3)
expect(processedSchema3.properties.resume.properties.education.readOnly).toBe(true)
expect(processedSchema3.properties.resume.properties.education.default).toBe(testSchema3.properties.resume.properties.education.const)
expect(processedSchema3.definitions.PastExperience.key_points.additionalProperties).toStrictEqual({ type: 'string' })
})
Expand Down
11 changes: 7 additions & 4 deletions src/utilities/schemaHandlers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { toast } from 'react-toastify'
import { guessType, deepEquals } from '@rjsf/utils'

export const AJV_OPTIONS = {
ajvOptionsOverrides: {
Expand All @@ -9,7 +10,7 @@ export const AJV_OPTIONS = {
const preProcessHelper = (obj) => {
/*
Recursively iterates through schema for rendering purposes
Makes const fields non-fillable
Specifies type for consts if missing
Renders dictionaries
Displays type selection dropdown with better default text
Enables validation for discriminator keyword
Expand All @@ -18,10 +19,12 @@ const preProcessHelper = (obj) => {
if (obj[key] !== null) {
const prop = obj[key]

// grays out const fields (readOnly) and autofills the field with the const value (default)
// Need to explicitly specify missing type for consts (bug in pydantic, may be fixed in next release)
// If default is undefined or not matching const value, set to const
// Note: We use a custom text widget to autofill the const value and set the field as readonly.
if (prop.const !== undefined) {
prop.readOnly = true
prop.default = prop.const
if (prop.type === undefined) { prop.type = guessType(prop.const) }
if (!deepEquals(prop.default, prop.const)) { prop.default = prop.const }
}

// if default is {}, expected value is a dictionary of strings
Expand Down