Skip to content

Commit

Permalink
Make fields with const pre-fiiled and readonl
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdallah Al-Soqatri committed Oct 4, 2024
1 parent d3af307 commit 36011f6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
6 changes: 5 additions & 1 deletion packages/core/src/components/fields/ObjectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,18 @@ class ObjectField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
const newFormData = { ...formData } as T;

let type: RJSFSchema['type'] = undefined;
let constValue: RJSFSchema['const'] = undefined;
let defaultValue: RJSFSchema['default'] = undefined;
if (isObject(schema.additionalProperties)) {
type = schema.additionalProperties.type;
constValue = schema.additionalProperties.const;
defaultValue = schema.additionalProperties.default;
let apSchema = schema.additionalProperties;
if (REF_KEY in apSchema) {
const { schemaUtils } = registry;
apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[REF_KEY] } as S, formData);
type = apSchema.type;
constValue = apSchema.const;
defaultValue = apSchema.default;
}
if (!type && (ANY_OF_KEY in apSchema || ONE_OF_KEY in apSchema)) {
Expand All @@ -219,8 +222,9 @@ class ObjectField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
}

const newKey = this.getAvailableKey('newKey', newFormData);
const newValue = constValue ?? defaultValue ?? this.getDefaultValue(type);
// Cast this to make the `set` work properly
set(newFormData as GenericObjectType, newKey, defaultValue ?? this.getDefaultValue(type));
set(newFormData as GenericObjectType, newKey, newValue);

onChange(newFormData);
};
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/fields/SchemaField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ function SchemaFieldRender<T = any, S extends StrictRJSFSchema = RJSFSchema, F e

const FieldComponent = getFieldComponent<T, S, F>(schema, uiOptions, idSchema, registry);
const disabled = Boolean(uiOptions.disabled ?? props.disabled);
const readonly = Boolean(uiOptions.readonly ?? (props.readonly || props.schema.readOnly || schema.readOnly));
const readonly = Boolean(
uiOptions.readonly ?? (props.readonly || props.schema.const || props.schema.readOnly || schema.readOnly)
);
const uiSchemaHideError = uiOptions.hideError;
// Set hideError to the value provided in the uiSchema, otherwise stick with the prop to propagate to children
const hideError = uiSchemaHideError === undefined ? props.hideError : Boolean(uiSchemaHideError);
Expand Down
29 changes: 23 additions & 6 deletions packages/utils/src/schema/getDefaultFormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import isEmpty from 'lodash/isEmpty';

import {
ANY_OF_KEY,
CONST_KEY,
DEFAULT_KEY,
DEPENDENCIES_KEY,
PROPERTIES_KEY,
Expand All @@ -29,6 +30,7 @@ import {
} from '../types';
import isMultiSelect from './isMultiSelect';
import retrieveSchema, { resolveDependencies } from './retrieveSchema';
import isConstant from '../isConstant';

/** Enum that indicates how `schema.additionalItems` should be handled by the `getInnerSchemaForArrayItem()` function.
*/
Expand Down Expand Up @@ -92,6 +94,7 @@ export function getInnerSchemaForArrayItem<S extends StrictRJSFSchema = RJSFSche
* @param requiredFields - The list of fields that are required
* @param experimental_defaultFormStateBehavior - Optional configuration object, if provided, allows users to override
* default form state behavior
* @param isConst - Optional flag, if true, indicates that the schema has a const property defined, thus we should always return the computedDefault since it's coming from the const.
*/
function maybeAddDefaultToObject<T = any>(
obj: GenericObjectType,
Expand All @@ -100,10 +103,13 @@ function maybeAddDefaultToObject<T = any>(
includeUndefinedValues: boolean | 'excludeObjectChildren',
isParentRequired?: boolean,
requiredFields: string[] = [],
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior = {}
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior = {},
isConst = false
) {
const { emptyObjectFields = 'populateAllDefaults' } = experimental_defaultFormStateBehavior;
if (includeUndefinedValues) {
if (includeUndefinedValues || isConst) {
// If includeUndefinedValues
// Or if the schema has a const property defined, then we should always return the computedDefault since it's coming from the const.
obj[key] = computedDefault;
} else if (emptyObjectFields !== 'skipDefaults') {
if (isObject(computedDefault)) {
Expand Down Expand Up @@ -190,7 +196,9 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
let schemaToCompute: S | null = null;
let updatedRecurseList = _recurseList;

if (isObject(defaults) && isObject(schema.default)) {
if (isConstant(schema)) {
defaults = schema.const as unknown as T;
} else if (isObject(defaults) && isObject(schema.default)) {
// For object defaults, only override parent defaults that are defined in
// schema.default.
defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
Expand Down Expand Up @@ -313,9 +321,11 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
: schema;
const objectDefaults = Object.keys(retrievedSchema.properties || {}).reduce(
(acc: GenericObjectType, key: string) => {
const propertySchema = get(retrievedSchema, [PROPERTIES_KEY, key]);
const hasConst = isObject(propertySchema) && CONST_KEY in propertySchema;
// Compute the defaults for this node, with the parent defaults we might
// have from a previous run: defaults[key].
const computedDefault = computeDefaults<T, S, F>(validator, get(retrievedSchema, [PROPERTIES_KEY, key]), {
const computedDefault = computeDefaults<T, S, F>(validator, propertySchema, {
rootSchema,
_recurseList,
experimental_defaultFormStateBehavior,
Expand All @@ -331,7 +341,8 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
includeUndefinedValues,
required,
retrievedSchema.required,
experimental_defaultFormStateBehavior
experimental_defaultFormStateBehavior,
hasConst
);
return acc;
},
Expand Down Expand Up @@ -545,7 +556,13 @@ export default function getDefaultFormState<
experimental_defaultFormStateBehavior,
rawFormData: formData,
});
if (formData === undefined || formData === null || (typeof formData === 'number' && isNaN(formData))) {

if (
formData === undefined ||
formData === null ||
typeof formData === 'string' ||
(typeof formData === 'number' && isNaN(formData))
) {
// No form data? Use schema defaults.
return defaults;
}
Expand Down

0 comments on commit 36011f6

Please sign in to comment.