feat: support scopes for dynamic field entries

This commit is contained in:
Ali BARIN
2025-01-15 11:26:03 +00:00
parent 7130d8e934
commit 61624baa68
11 changed files with 167 additions and 52 deletions

View File

@@ -0,0 +1,50 @@
import PropTypes from 'prop-types';
import * as React from 'react';
import Stack from '@mui/material/Stack';
import InputCreator from 'components/InputCreator';
import { EditorContext } from 'contexts/Editor';
import { FieldsPropType } from 'propTypes/propTypes';
import { FieldEntryProvider } from 'contexts/FieldEntry';
import useFieldEntryContext from 'hooks/useFieldEntryContext';
function DynamicFieldEntry(props) {
const { fields, stepId, namePrefix } = props;
const editorContext = React.useContext(EditorContext);
const fieldEntryContext = useFieldEntryContext();
const newFieldEntryPaths = [
...(fieldEntryContext?.fieldEntryPaths || []),
namePrefix,
];
return (
<FieldEntryProvider value={{ fieldEntryPaths: newFieldEntryPaths }}>
{fields.map((fieldSchema, fieldSchemaIndex) => (
<Stack
minWidth={0}
flex="1 0 0px"
spacing={2}
key={`field-${namePrefix}-${fieldSchemaIndex}`}
>
<InputCreator
schema={fieldSchema}
namePrefix={namePrefix}
disabled={editorContext.readOnly}
shouldUnregister={false}
stepId={stepId}
/>
</Stack>
))}
</FieldEntryProvider>
);
}
DynamicFieldEntry.propTypes = {
stepId: PropTypes.string,
namePrefix: PropTypes.string,
index: PropTypes.number,
fields: FieldsPropType.isRequired,
};
export default DynamicFieldEntry;

View File

@@ -7,15 +7,17 @@ import Stack from '@mui/material/Stack';
import IconButton from '@mui/material/IconButton';
import RemoveIcon from '@mui/icons-material/Remove';
import AddIcon from '@mui/icons-material/Add';
import InputCreator from 'components/InputCreator';
import { EditorContext } from 'contexts/Editor';
import { FieldsPropType } from 'propTypes/propTypes';
import DynamicFieldEntry from './DynamicFieldEntry';
import { FieldEntryProvider } from 'contexts/FieldEntry';
import useFieldEntryContext from 'hooks/useFieldEntryContext';
function DynamicField(props) {
const { label, description, fields, name, defaultValue, stepId } = props;
const { control, setValue, getValues } = useFormContext();
const fieldsValue = useWatch({ control, name });
const editorContext = React.useContext(EditorContext);
const fieldEntryContext = useFieldEntryContext();
const createEmptyItem = React.useCallback(() => {
return fields.reduce((previousValue, field) => {
@@ -60,7 +62,7 @@ function DynamicField(props) {
);
return (
<React.Fragment>
<FieldEntryProvider value={fieldEntryContext}>
<Typography variant="subtitle2">{label}</Typography>
{fieldsValue?.map?.((field, index) => (
<Stack direction="row" spacing={2} key={`fieldGroup-${field.__id}`}>
@@ -76,22 +78,11 @@ function DynamicField(props) {
minWidth: 0,
}}
>
{fields.map((fieldSchema, fieldSchemaIndex) => (
<Stack
minWidth={0}
flex="1 0 0px"
spacing={2}
key={`field-${field.__id}-${fieldSchemaIndex}`}
>
<InputCreator
schema={fieldSchema}
namePrefix={`${name}.${index}`}
disabled={editorContext.readOnly}
shouldUnregister={false}
stepId={stepId}
/>
</Stack>
))}
<DynamicFieldEntry
fields={fields}
namePrefix={`${name}.${index}`}
stepId={stepId}
/>
</Stack>
<IconButton
size="small"
@@ -115,7 +106,7 @@ function DynamicField(props) {
</IconButton>
</Stack>
<Typography variant="caption">{description}</Typography>
</React.Fragment>
</FieldEntryProvider>
);
}

View File

@@ -26,6 +26,7 @@ function InputCreator(props) {
showOptionValue,
shouldUnregister,
} = props;
const {
key: name,
label,
@@ -35,9 +36,11 @@ function InputCreator(props) {
description,
type,
} = schema;
const { data, loading } = useDynamicData(stepId, schema);
const { data: additionalFieldsData, isLoading: isDynamicFieldsLoading } =
useDynamicFields(stepId, schema);
const additionalFields = additionalFieldsData?.data;
const computedName = namePrefix ? `${namePrefix}.${name}` : name;