Skip to content

Commit

Permalink
Update react-jsonschema-form package
Browse files Browse the repository at this point in the history
  • Loading branch information
cyril-ui-developer committed Jun 17, 2021
1 parent 2f804f6 commit 8b34a85
Show file tree
Hide file tree
Showing 23 changed files with 212 additions and 143 deletions.
8 changes: 4 additions & 4 deletions frontend/package.json
Expand Up @@ -129,6 +129,7 @@
"@patternfly/react-tokens": "4.11.12",
"@patternfly/react-topology": "4.8.72",
"@patternfly/react-virtualized-extension": "4.8.23",
"@rjsf/core": "^2.5.1",
"abort-controller": "3.0.0",
"ajv": "^6.12.3",
"apollo-cache-inmemory": "^1.6.5",
Expand All @@ -155,7 +156,7 @@
"immutable": "3.x",
"js-base64": "^2.5.1",
"js-yaml": "^3.13.1",
"json-schema": "0.2.3",
"json-schema": "^0.3.0",
"lodash-es": "^4.17.21",
"monaco-languageclient": "^0.13.0",
"murmurhash-js": "1.0.x",
Expand All @@ -175,7 +176,6 @@
"react-draggable": "4.x",
"react-helmet": "^6.1.0",
"react-i18next": "^11.7.3",
"react-jsonschema-form": "1.7.0",
"react-linkify": "^0.2.2",
"react-measure": "^2.2.6",
"react-modal": "^3.12.1",
Expand Down Expand Up @@ -226,14 +226,14 @@
"@types/jasmine": "2.8.x",
"@types/jasminewd2": "2.0.x",
"@types/jest": "21.x",
"@types/json-schema": "7.0.4",
"@types/json-schema": "^7.0.7",
"@types/lodash-es": "4.17.x",
"@types/node": "10.x",
"@types/prop-types": "15.5.6",
"@types/react": "16.8.13",
"@types/react-dom": "16.8.4",
"@types/react-helmet": "5.x",
"@types/react-jsonschema-form": "^1.0.8",
"@types/react-jsonschema-form": "^1.3.8",
"@types/react-redux": "6.0.2",
"@types/react-router-dom": "5.1.2",
"@types/react-transition-group": "2.x",
Expand Down
@@ -1,14 +1,12 @@
import * as React from 'react';
import { AccordionContent, AccordionItem, AccordionToggle } from '@patternfly/react-core';
import { FieldProps, UiSchema } from '@rjsf/core';
import SchemaField, { SchemaFieldProps } from '@rjsf/core/dist/cjs/components/fields/SchemaField';
import { getUiOptions } from '@rjsf/core/dist/cjs/utils';
import * as classnames from 'classnames';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import * as _ from 'lodash';
import { useTranslation } from 'react-i18next';
import { FieldProps, UiSchema } from 'react-jsonschema-form';
import SchemaField, {
SchemaFieldProps,
} from 'react-jsonschema-form/lib/components/fields/SchemaField';
import { getUiOptions, getSchemaType } from 'react-jsonschema-form/lib/utils';
import { ConfigureUpdateStrategy } from '@console/internal/components/modals/configure-update-strategy-modal';
import { LinkifyExternal, SelectorInput, Dropdown } from '@console/internal/components/utils';
import {
Expand All @@ -17,8 +15,7 @@ import {
} from '@console/operator-lifecycle-manager/src/components/descriptors/spec/affinity';
import { MatchExpressions } from '@console/operator-lifecycle-manager/src/components/descriptors/spec/match-expressions';
import { ResourceRequirements } from '@console/operator-lifecycle-manager/src/components/descriptors/spec/resource-requirements';
import { JSONSchemaType } from './types';
import { hasNoFields, useSchemaDescription, useSchemaLabel } from './utils';
import { useSchemaDescription, useSchemaLabel } from './utils';

const Description = ({ id, description }) =>
description ? (
Expand Down Expand Up @@ -324,31 +321,7 @@ export const DropdownField: React.FC<FieldProps> = ({
};

export const CustomSchemaField: React.FC<SchemaFieldProps> = (props) => {
// TODO Remove this workaround when the issue has been fixed upstream in react-jsonschema-form and
// we bump our version to include that fix.
// Provide a fallback formData value for objects and arrays to prevent undefined
// references. This can occur if formData is malformed (for example, almExamples annotation
// explicitly sets an array value to null). This is an edge case that should be handled in the
// react-jsonschema-form package. An issue and fix have been opened upstream:
// Issue filed in @rjsf/core repo: https://github.com/rjsf-team/react-jsonschema-form/issues/2153
// PR opened for fix: https://github.com/rjsf-team/react-jsonschema-form/pull/2154
const type = getSchemaType(props.schema);
const fallbackFormData = React.useMemo(() => {
switch (type) {
case JSONSchemaType.array:
return [];
case JSONSchemaType.object:
return {};
default:
return undefined;
}
}, [type]);

// If a the provided schema will not generate any form field elements, return null.
if (hasNoFields(props.schema, props.uiSchema)) {
return null;
}
return <SchemaField {...props} formData={props.formData ?? fallbackFormData} />;
return <SchemaField {...props} />;
};

export const NullField = () => null;
Expand All @@ -370,7 +343,7 @@ type FormFieldProps = {
id: string;
defaultLabel?: string;
required: boolean;
schema: JSONSchema6;
schema: JSONSchema7;
uiSchema: UiSchema;
};

Expand Down
@@ -1,8 +1,8 @@
import * as React from 'react';
import { Accordion, ActionGroup, Button, Alert } from '@patternfly/react-core';
import Form, { FormProps } from '@rjsf/core';
import * as _ from 'lodash';
import { useTranslation } from 'react-i18next';
import Form, { FormProps } from 'react-jsonschema-form';
import { history } from '@console/internal/components/utils';
import { K8S_UI_SCHEMA } from './const';
import defaultFields from './fields';
Expand Down
@@ -1,14 +1,10 @@
import * as React from 'react';
import { Button, Alert, FormHelperText } from '@patternfly/react-core';
import { MinusCircleIcon, PlusCircleIcon } from '@patternfly/react-icons';
import { ArrayFieldTemplateProps, FieldTemplateProps, ObjectFieldTemplateProps } from '@rjsf/core';
import { getUiOptions, getSchemaType } from '@rjsf/core/dist/cjs/utils';
import * as _ from 'lodash';
import { useTranslation } from 'react-i18next';
import {
ArrayFieldTemplateProps,
FieldTemplateProps,
ObjectFieldTemplateProps,
} from 'react-jsonschema-form';
import { getUiOptions, getSchemaType } from 'react-jsonschema-form/lib/utils';
import { ExpandCollapse } from '@console/internal/components/utils';
import { JSON_SCHEMA_GROUP_TYPES } from './const';
import { FieldSet, FormField } from './fields';
Expand Down
@@ -1,27 +1,27 @@
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import { JSONSchemaType } from './types';
import { hasNoFields, prune } from './utils';

const OBJECT: JSONSchema6 = {
const OBJECT: JSONSchema7 = {
type: JSONSchemaType.object,
properties: {
test: { type: JSONSchemaType.string },
},
};

const ARRAY: JSONSchema6 = {
const ARRAY: JSONSchema7 = {
type: JSONSchemaType.array,
items: {
type: JSONSchemaType.string,
},
};

const ADDITIONAL_PROPERTIES_OBJECT: JSONSchema6 = {
const ADDITIONAL_PROPERTIES_OBJECT: JSONSchema7 = {
type: JSONSchemaType.object,
additionalProperties: { type: JSONSchemaType.string },
};

const NESTED: JSONSchema6 = {
const NESTED: JSONSchema7 = {
type: JSONSchemaType.object,
properties: {
emptyArray: {
Expand Down
@@ -1,8 +1,8 @@
import { UiSchema } from '@rjsf/core';
import { getSchemaType, getUiOptions } from '@rjsf/core/dist/cjs/utils';
import * as Immutable from 'immutable';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import * as _ from 'lodash';
import { UiSchema } from 'react-jsonschema-form';
import { getSchemaType, getUiOptions } from 'react-jsonschema-form/lib/utils';
import { THOUSAND, MILLION, BILLION } from './const';
import { DynamicFormSchemaError, JSONSchemaType } from './types';

Expand All @@ -14,23 +14,23 @@ export const stringPathToUISchemaPath = (path: string): string[] =>
return /^\d+$/.test(subPath) ? 'items' : subPath;
});

export const useSchemaLabel = (schema: JSONSchema6, uiSchema: UiSchema, defaultLabel?: string) => {
export const useSchemaLabel = (schema: JSONSchema7, uiSchema: UiSchema, defaultLabel?: string) => {
const options = getUiOptions(uiSchema ?? {});
const showLabel = options?.label ?? true;
const label = (options?.title || schema?.title) as string;
return [showLabel, label || _.startCase(defaultLabel)] as [boolean, string];
};

export const useSchemaDescription = (
schema: JSONSchema6,
schema: JSONSchema7,
uiSchema: UiSchema,
defaultDescription?: string,
) =>
(getUiOptions(uiSchema ?? {})?.description ||
schema?.description ||
defaultDescription) as string;

export const getSchemaErrors = (schema: JSONSchema6): DynamicFormSchemaError[] => {
export const getSchemaErrors = (schema: JSONSchema7): DynamicFormSchemaError[] => {
return [
...(_.isEmpty(schema)
? [
Expand All @@ -51,7 +51,7 @@ export const getSchemaErrors = (schema: JSONSchema6): DynamicFormSchemaError[] =
};

// Determine if a schema will produce no form fields.
export const hasNoFields = (jsonSchema: JSONSchema6 = {}, uiSchema: UiSchema = {}): boolean => {
export const hasNoFields = (jsonSchema: JSONSchema7 = {}, uiSchema: UiSchema = {}): boolean => {
// If schema is empty or has unsupported properties, it will not render any fields on the form
if (getSchemaErrors(jsonSchema).length > 0) {
return true;
Expand All @@ -61,12 +61,12 @@ export const hasNoFields = (jsonSchema: JSONSchema6 = {}, uiSchema: UiSchema = {
const noUIFieldOrWidget = !uiSchema?.['ui:field'] && !uiSchema?.['ui:widget'];
switch (type) {
case JSONSchemaType.array:
return noUIFieldOrWidget && hasNoFields(jsonSchema.items as JSONSchema6, uiSchema?.items);
return noUIFieldOrWidget && hasNoFields(jsonSchema.items as JSONSchema7, uiSchema?.items);
case JSONSchemaType.object:
return (
noUIFieldOrWidget &&
_.every(jsonSchema?.properties, (property, propertyName) =>
hasNoFields(property as JSONSchema6, uiSchema?.[propertyName]),
hasNoFields(property as JSONSchema7, uiSchema?.[propertyName]),
)
);
case JSONSchemaType.boolean:
Expand Down Expand Up @@ -129,7 +129,7 @@ const getControlFieldsAtPath = (uiSchema: UiSchema, path: string[]): string[] =>
*/
const getJSONSchemaPropertySortWeight = (
property: string,
jsonSchema: JSONSchema6,
jsonSchema: JSONSchema7,
uiSchema: UiSchema,
currentPath?: string[],
): number => {
Expand Down Expand Up @@ -190,13 +190,13 @@ const getJSONSchemaPropertySortWeight = (
// - field dependency properties (control then dependent)
// - all other properties
export const getJSONSchemaOrder = (
jsonSchema: JSONSchema6,
jsonSchema: JSONSchema7,
uiSchema: UiSchema,
currentPath?: string[],
) => {
const type = getSchemaType(jsonSchema ?? {});
const handleArray = () => {
const descendantOrder = getJSONSchemaOrder(jsonSchema?.items as JSONSchema6, uiSchema?.items, [
const descendantOrder = getJSONSchemaOrder(jsonSchema?.items as JSONSchema7, uiSchema?.items, [
...(currentPath ?? []),
'items',
]);
Expand All @@ -221,7 +221,7 @@ export const getJSONSchemaOrder = (
jsonSchema?.properties ?? {},
(orderAccumulator, propertySchema, propertyName) => {
const descendantOrder = getJSONSchemaOrder(
propertySchema as JSONSchema6,
propertySchema as JSONSchema7,
uiSchema?.[propertyName],
[...(currentPath ?? []), propertyName],
);
Expand Down
@@ -1,9 +1,9 @@
import * as React from 'react';
import { Checkbox, Switch } from '@patternfly/react-core';
import { WidgetProps } from '@rjsf/core';
import { getSchemaType } from '@rjsf/core/dist/cjs/utils';
import * as _ from 'lodash';
import { useTranslation } from 'react-i18next';
import { WidgetProps } from 'react-jsonschema-form';
import { getSchemaType } from 'react-jsonschema-form/lib/utils';
import { RadioGroup } from '@console/internal/components/radio';
import { NumberSpinner, ListDropdown, Dropdown } from '@console/internal/components/utils';
import { K8sKind, GroupVersionKind, ImagePullPolicy } from '@console/internal/module/k8s';
Expand Down
@@ -1,5 +1,5 @@
import * as React from 'react';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import MonacoEditor from 'react-monaco-editor';
import { ResourceSidebar } from '@console/internal/components/sidebars/resource-sidebar';
import { K8sKind } from '@console/internal/module/k8s';
Expand All @@ -10,7 +10,7 @@ type YAMLEditorSidebarProps = {
editorRef: React.MutableRefObject<MonacoEditor>;
model?: K8sKind;
samples?: Sample[];
schema?: JSONSchema6;
schema?: JSONSchema7;
snippets?: Sample[];
sidebarLabel?: string;
sanitizeYamlContent?: (id: string, yaml: string, kind: string) => string;
Expand Down
@@ -1,7 +1,7 @@
import * as React from 'react';
import { FormProps } from '@rjsf/core';
import cx from 'classnames';
import { useField, useFormikContext, FormikValues } from 'formik';
import { FormProps } from 'react-jsonschema-form';
import { AsyncComponent } from '@console/internal/components/utils';

type DynamicFormFieldProps = FormProps<any> & {
Expand Down
@@ -1,5 +1,5 @@
import { ValidatedOptions, TextInputTypes, gridItemSpanValueShape } from '@patternfly/react-core';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { RowRendererProps } from './multi-column-field/MultiColumnFieldRow';

Expand Down Expand Up @@ -106,7 +106,7 @@ export interface MultiColumnFieldProps extends FieldProps {

export interface YAMLEditorFieldProps extends FieldProps {
model?: K8sKind;
schema?: JSONSchema6;
schema?: JSONSchema7;
onChange?: (value: string) => void;
onSave?: () => void;
}
Expand Down
12 changes: 6 additions & 6 deletions frontend/packages/console-shared/src/utils/utils.ts
@@ -1,4 +1,4 @@
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import { toPath } from 'lodash';
import { FirehoseResult } from '@console/internal/components/utils/types';
import { K8sResourceKind } from '@console/internal/module/k8s';
Expand Down Expand Up @@ -48,19 +48,19 @@ export const isValidUrl = (url: string): boolean => {

// Recursive helper for getSchemaAtPath
const recursiveGetSchemaAtPath = (
schema: JSONSchema6,
schema: JSONSchema7,
[segment, ...path]: string[] = [],
): JSONSchema6 => {
): JSONSchema7 => {
if (segment) {
return /^\d+$/.test(segment)
? recursiveGetSchemaAtPath(schema?.items as JSONSchema6, path)
: recursiveGetSchemaAtPath(schema?.properties?.[segment] as JSONSchema6, path);
? recursiveGetSchemaAtPath(schema?.items as JSONSchema7, path)
: recursiveGetSchemaAtPath(schema?.properties?.[segment] as JSONSchema7, path);
}
return schema;
};

// Get a schema at the provided path string.
export const getSchemaAtPath = (schema: JSONSchema6, path: string): JSONSchema6 => {
export const getSchemaAtPath = (schema: JSONSchema7, path: string): JSONSchema7 => {
return recursiveGetSchemaAtPath(schema, toPath(path));
};

Expand Down
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import * as Ajv from 'ajv';
import { Formik } from 'formik';
import { safeDump, safeLoad } from 'js-yaml';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import * as _ from 'lodash';
import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -42,7 +42,7 @@ export type HelmInstallUpgradeFormData = {
appVersion: string;
yamlData: string;
formData: any;
formSchema: JSONSchema6;
formSchema: JSONSchema7;
editorType: EditorType;
};

Expand Down Expand Up @@ -70,7 +70,7 @@ const HelmInstallUpgradePage: React.FunctionComponent<HelmInstallUpgradePageProp

const [initialYamlData, setInitialYamlData] = React.useState<string>('');
const [initialFormData, setInitialFormData] = React.useState<object>();
const [initialFormSchema, setInitialFormSchema] = React.useState<JSONSchema6>();
const [initialFormSchema, setInitialFormSchema] = React.useState<JSONSchema7>();

const helmAction: HelmActionType =
initialChartURL !== 'null' ? HelmActionType.Install : HelmActionType.Upgrade;
Expand Down
@@ -1,7 +1,7 @@
import * as React from 'react';
import { TextVariants, Text } from '@patternfly/react-core';
import { useFormikContext, FormikValues } from 'formik';
import { JSONSchema6 } from 'json-schema';
import { JSONSchema7 } from 'json-schema';
import * as _ from 'lodash';
import AppSection from '@console/dev-console/src/components/import/app/AppSection';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
Expand Down Expand Up @@ -49,7 +49,7 @@ const EventSourceSection: React.FC<EventSourceSectionProps> = ({
const projectResource = { kind: ProjectModel.kind, prop: ProjectModel.id, isList: true };
const [data, loaded] = useK8sWatchResource<K8sResourceKind[]>(projectResource);
useFormikValidationFix(values);
const formSchema: JSONSchema6 = React.useMemo(
const formSchema: JSONSchema7 = React.useMemo(
() => ({
type: 'object',
required: kameletSource?.spec?.definition?.required,
Expand Down

0 comments on commit 8b34a85

Please sign in to comment.