Skip to content

Commit

Permalink
Deploy to prod (#158)
Browse files Browse the repository at this point in the history
* Bug 78 bool (#100)

* updates readme

* defaults boolean vals to false (so checkbox works)

* Bug 78 bool (#101)

* updates readme

* defaults boolean vals to false (so checkbox works)

* recursive method to replace boolean widgets, need to fix

* -

* manual ui schema in progress

* ephys ui schema

* fix ephys ui schema

* endline

* small fix

* Bug 78 bool widget (#103)

* feat: adds rjsf material ui package

* feat: adds custom checkbox for booleans

---------

Co-authored-by: Mekhla Kapoor <54870020+mekhlakapoor@users.noreply.github.com>

* removes override

---------

Co-authored-by: jtyoung84 <104453205+jtyoung84@users.noreply.github.com>

* hot fix (#106)

* fix: filters version list by schema type (#116)

* Feat 110 remove schemas (#115)

* Deploy to prod (#107)

* Bug 78 bool (#100)

* updates readme

* defaults boolean vals to false (so checkbox works)

* Bug 78 bool (#101)

* updates readme

* defaults boolean vals to false (so checkbox works)

* recursive method to replace boolean widgets, need to fix

* -

* manual ui schema in progress

* ephys ui schema

* fix ephys ui schema

* endline

* small fix

* Bug 78 bool widget (#103)

* feat: adds rjsf material ui package

* feat: adds custom checkbox for booleans

---------

Co-authored-by: Mekhla Kapoor <54870020+mekhlakapoor@users.noreply.github.com>

* removes override

---------

Co-authored-by: jtyoung84 <104453205+jtyoung84@users.noreply.github.com>

* hot fix (#106)

---------

Co-authored-by: Mekhla Kapoor <54870020+mekhlakapoor@users.noreply.github.com>
Co-authored-by: jtyoung84 <104453205+jtyoung84@users.noreply.github.com>

* version bump [skip actions]

* removes ephys, ophys, behavior rigs & sessions

* off dev

* schemas filtered with env variable

* env template

---------

Co-authored-by: Yosef Bedaso <20714699+yosefmaru@users.noreply.github.com>
Co-authored-by: jtyoung84 <104453205+jtyoung84@users.noreply.github.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>

* Renders dictionaries (#118)

* recursion, unit test, additional properties

* fix import

* docstring

* Sort schema versions dropdown by lastest-first semantic version

* Add sample schema list and sorted version list for unit tests

* Add unit tests for Dropdowns and sorted schema version

* Feat 117: Sort schema versions list in dropdown by lastest-first semantic version (#123)

* Sort schema versions dropdown by lastest-first semantic version

* Add sample schema list and sorted version list for unit tests

* Add unit tests for Dropdowns and sorted schema version

* Fix 119: Fix pre-process and render issues and improve UI (#127)

* add error handling for preProcessSchema() andfetchAndSetSchema()
* handle prop.default is null
* improve App component UI and styling
* refactor Dropdowns to Toolbar, add styling, disable version dropdown and upload btn on default
* add default titles to dropdown of allowed types/ subschemas
* add react-toastify for notifications

* handle schema version changes from App component (#130)

* Feat 27: Add linter and unit test frameworks (#133)

* add ESLint with React plugin, JS Standard style guide

* add unit test commands

* add current coverage as test coverageThreshold

* linter auto-fix styling issues

* fix linting issues (imports, React in scope, camelCase)

* add propTypes to resolve prop validation linting issues

* Feat 27: Add linter and unit test frameworks

* finish merge

* Fix 131: Enforce re-render and handle errors in `RenderForm` component (#142)

* Add ErrorBoundary for RenderForm component

* use selectedSchemaPath as key to re-render RenderForm component

* create unit test suite for App component

* Fix 132: Update schema filtering and validation (#143)

* parse and validate schema type, version to fix filter logic

* create unit tests for parseAndFilterSchemas()

* replace selectedSchemaVersion with unique selectedSchemaPath

* Feat 68: Add border-left css for nested form fieldsets (#147)

* Fix 139: Enable discriminator support in validator and fix validation errors (#151)

* enable discriminator validation in ajv validator

* remove extra formData on changes to seleciton/ discriminator

* update empty object check

* update unit tests

* fix redundant lines

* Fix 108: Error handling, validation, and UI fixes for Autofill feature (#154)

* add error handling and file type validation for file upload

* validate uploaded schema type, version with possible schemas

* clear autofilled formData after change schema

* allow autofill with any schema type

* refactor RehydrateForm.js from component to util function

* success toast to indicate autofill complete, fix button focus

* code cleanup

* update unit tests for autofill feature changes

* update test coverage thresholds

* Fix 102: Fix nested constants render issues (#157)

* fix rendering of nested literals/ consts

* revert other widgets to material-ui to keep label

* Enforce const values set to formData, enforce null consts as null strings

* update @rjsf/core

* useLayoutEffect in custom widget to sync changes on screen

* explicityly set missing type for all consts, check default value is correct

* update unit tests to check consts preprocessed and rendered correctly

* update docstrings

* update docstrings

---------

Co-authored-by: Mekhla Kapoor <54870020+mekhlakapoor@users.noreply.github.com>
Co-authored-by: jtyoung84 <104453205+jtyoung84@users.noreply.github.com>
Co-authored-by: Yosef Bedaso <20714699+yosefmaru@users.noreply.github.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
5 people committed Apr 1, 2024
1 parent 1be36e7 commit 276aae9
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 45 deletions.
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

0 comments on commit 276aae9

Please sign in to comment.