Skip to content

Commit

Permalink
Preserve set values in request
Browse files Browse the repository at this point in the history
  • Loading branch information
ElenaStoeva committed Oct 1, 2024
1 parent 332b803 commit 8e58d70
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { createArrayItem, getInternalArrayFieldPath } from '../components/use_ar
const DEFAULT_OPTIONS = {
valueChangeDebounceTime: 500,
stripEmptyFields: true,
stripUnmodifiedFields: false,
stripUnsetFields: false,
};

export interface UseFormReturn<T extends FormData, I extends FormData> {
Expand Down Expand Up @@ -70,15 +70,15 @@ export function useForm<T extends FormData = FormData, I extends FormData = T>(
const {
valueChangeDebounceTime,
stripEmptyFields: doStripEmptyFields,
stripUnmodifiedFields,
stripUnsetFields,
} = options ?? {};
const formOptions = useMemo(
() => ({
stripEmptyFields: doStripEmptyFields ?? DEFAULT_OPTIONS.stripEmptyFields,
valueChangeDebounceTime: valueChangeDebounceTime ?? DEFAULT_OPTIONS.valueChangeDebounceTime,
stripUnmodifiedFields: stripUnmodifiedFields ?? DEFAULT_OPTIONS.stripUnmodifiedFields
stripUnsetFields: stripUnsetFields ?? DEFAULT_OPTIONS.stripUnsetFields,
}),
[valueChangeDebounceTime, doStripEmptyFields, stripUnmodifiedFields]
[valueChangeDebounceTime, doStripEmptyFields, stripUnsetFields]
);

const [isSubmitted, setIsSubmitted] = useState(false);
Expand Down Expand Up @@ -186,7 +186,7 @@ export function useForm<T extends FormData = FormData, I extends FormData = T>(
const getFieldsForOutput = useCallback(
(
fields: FieldsMap,
opts: { stripEmptyFields: boolean; stripUnmodifiedFields: boolean }
opts: { stripEmptyFields: boolean; stripUnsetFields: boolean }
): FieldsMap => {
return Object.entries(fields).reduce((acc, [key, field]) => {
if (!field.__isIncludedInOutput) {
Expand All @@ -200,8 +200,8 @@ export function useForm<T extends FormData = FormData, I extends FormData = T>(
}
}

if (opts.stripUnmodifiedFields) {
if (!field.isModified) {
if (opts.stripUnsetFields) {
if (!field.isDirty && getFieldDefaultValue(field.path) === undefined) {
return acc;
}
}
Expand Down Expand Up @@ -411,18 +411,13 @@ export function useForm<T extends FormData = FormData, I extends FormData = T>(
const getFormData: FormHook<T, I>['getFormData'] = useCallback(() => {
const fieldsToOutput = getFieldsForOutput(fieldsRefs.current, {
stripEmptyFields: formOptions.stripEmptyFields,
stripUnmodifiedFields: formOptions.stripUnmodifiedFields,
stripUnsetFields: formOptions.stripUnsetFields,
});
const fieldsValue = mapFormFields(fieldsToOutput, (field) => field.__serializeValue());
return serializer
? serializer(unflattenObject<I>(fieldsValue))
: unflattenObject<T>(fieldsValue);
}, [
getFieldsForOutput,
formOptions.stripEmptyFields,
formOptions.stripUnmodifiedFields,
serializer,
]);
}, [getFieldsForOutput, formOptions.stripEmptyFields, formOptions.stripUnsetFields, serializer]);

const getErrors: FormHook<T, I>['getErrors'] = useCallback(() => {
if (isValid === true) {
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ export interface FormOptions {
* Remove empty string field ("") from form data
*/
stripEmptyFields?: boolean;
/**
* Remove fields from form data that don't have initial value and are not modified by the user.
*/
stripUnsetFields?: boolean;
}

export interface FieldHook<T = unknown, I = T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const formDeserializer = (formData: GenericObject) => {
return {
dynamicMapping: {
enabled: dynamic === 'strict' ? false : dynamic,
throwErrorsForUnmappedFields: dynamic === 'strict',
throwErrorsForUnmappedFields: dynamic === 'strict' ? true : undefined,
numeric_detection,
date_detection,
dynamic_date_formats,
Expand Down Expand Up @@ -108,11 +108,12 @@ export const ConfigurationForm = React.memo(({ value, esNodesPlugins }: Props) =
schema: configurationFormSchema,
serializer: serializerCallback,
deserializer: formDeserializer,
defaultValue: value,
id: 'configurationForm',
options: { stripUnmodifiedFields: true },
options: { stripUnsetFields: true },
});
const dispatch = useDispatch();
const { subscribe, submit, getFormData, updateFieldValues } = form;
const { subscribe, submit, reset, getFormData } = form;

const isMapperSizeSectionVisible =
value?._size !== undefined || esNodesPlugins.includes(MapperSizePluginId);
Expand All @@ -134,8 +135,12 @@ export const ConfigurationForm = React.memo(({ value, esNodesPlugins }: Props) =
}, [dispatch, subscribe, submit]);

useEffect(() => {
updateFieldValues(value);
}, [value, updateFieldValues]);
if (isMounted.current) {
// If the value has changed (it probably means that we have loaded a new JSON)
// we need to reset the form to update the fields values.
reset({ resetValues: true, defaultValue: value });
}
}, [value, reset]);

useEffect(() => {
isMounted.current = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const comboBox = getService('comboBox');
const find = getService('find');
const browser = getService('browser');
const log = getService('log');

describe('Index template wizard', function () {
before(async () => {
Expand Down Expand Up @@ -162,6 +163,40 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
expect(await testSubjects.exists('fieldSubType')).to.be(true);
expect(await testSubjects.exists('nextButton')).to.be(true);
});

it("advanced options tab doesn't add default values to request by default", async () => {
await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');
await testSubjects.click('previewIndexTemplate');
const templatePreview = await testSubjects.getVisibleText('simulateTemplatePreview');

await log.debug(`Template preview text: ${templatePreview}`);

// All advanced options should not be part of the request
expect(templatePreview).to.not.contain('"dynamic"');
expect(templatePreview).to.not.contain('"subobjects"');
expect(templatePreview).to.not.contain('"dynamic_date_formats"');
expect(templatePreview).to.not.contain('"date_detection"');
expect(templatePreview).to.not.contain('"numeric_detection"');
});

it('advanced options tab adds the set values to the request', async () => {
await pageObjects.indexManagement.changeMappingsEditorTab('advancedOptions');

// Toggle the subobjects field to false
await testSubjects.click('subobjectsToggle');

await testSubjects.click('previewIndexTemplate');
const templatePreview = await testSubjects.getVisibleText('simulateTemplatePreview');

await log.debug(`Template preview text: ${templatePreview}`);

// Only the subobjects option should be part of the request
expect(templatePreview).to.contain('"subobjects": false');
expect(templatePreview).to.not.contain('"dynamic"');
expect(templatePreview).to.not.contain('"dynamic_date_formats"');
expect(templatePreview).to.not.contain('"date_detection"');
expect(templatePreview).to.not.contain('"numeric_detection"');
});
});
});
};
15 changes: 15 additions & 0 deletions x-pack/test/functional/page_objects/index_management_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../ftr_provider_context';
import { act } from "react-dom/test-utils";

export function IndexManagementPageProvider({ getService }: FtrProviderContext) {
const retry = getService('retry');
Expand Down Expand Up @@ -118,6 +119,20 @@ export function IndexManagementPageProvider({ getService }: FtrProviderContext)
await testSubjects.click(tab);
},

async changeMappingsEditorTab(
tab: 'mappedFields' | 'runtimeFields' | 'dynamicTemplates' | 'advancedOptions'
) {
const index = [
'mappedFields',
'runtimeFields',
'dynamicTemplates',
'advancedOptions',
].indexOf(tab);

const tabs = await testSubjects.findAll('formTab');
await tabs[index].click();
},

async clickNextButton() {
await testSubjects.click('nextButton');
},
Expand Down

0 comments on commit 8e58d70

Please sign in to comment.