diff --git a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx index 8db5e59b1fc27..cf9bead5a4e30 100644 --- a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx +++ b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx @@ -79,6 +79,22 @@ export const ContentEditorFlyoutContent: FC = ({ const i18nTexts = useMemo(() => getI18nTexts({ entityName }), [entityName]); const form = useMetadataForm({ item, customValidators }); + const hasNoChanges = () => { + const itemTags = item.tags.map((obj) => obj.id).sort(); + const formTags = form.tags.value.slice().sort(); + + const compareTags = (arr1: string[], arr2: string[]) => { + if (arr1.length !== arr2.length) return false; + return arr1.every((tag: string, index) => tag === arr2[index]); + }; + + return ( + item.title === form.title.value && + item.description === form.description.value && + compareTags(itemTags, formTags) + ); + }; + const onClickSave = useCallback(async () => { if (form.isValid && onSave && !form.getIsChangingValue()) { const id = item.id; @@ -177,7 +193,7 @@ export const ContentEditorFlyoutContent: FC = ({ onClick={onClickSave} data-test-subj="saveButton" fill - disabled={isSubmitted && !form.isValid} + disabled={(isSubmitted && !form.isValid) || hasNoChanges()} isLoading={isSubmitting} > {i18nTexts.saveButtonLabel} diff --git a/packages/content-management/content_editor/src/components/inspector_flyout_content.test.tsx b/packages/content-management/content_editor/src/components/inspector_flyout_content.test.tsx index b21c325ca9ed5..44ac09d8d666e 100644 --- a/packages/content-management/content_editor/src/components/inspector_flyout_content.test.tsx +++ b/packages/content-management/content_editor/src/components/inspector_flyout_content.test.tsx @@ -104,32 +104,37 @@ describe('', () => { expect(find('saveButton').text()).toBe('Update foo'); }); - test('should send back the updated item to the onSave() handler', async () => { + test('should save form only if something changes', async () => { const onSave = jest.fn(); await act(async () => { testBed = await setup({ onSave, isReadonly: false }); }); - const { - find, - component, - form: { setInputValue }, - } = testBed!; - - await waitForValidationResults(); + const { find, component } = testBed!; await act(async () => { find('saveButton').simulate('click'); }); - expect(onSave).toHaveBeenCalledWith({ - id: '123', - title: 'Foo', - description: 'Some description', - tags: ['id-1', 'id-2'], + component.update(); + + expect(onSave).not.toHaveBeenCalled(); + }); + + test('should send back the updated item to the onSave() handler', async () => { + const onSave = jest.fn(); + + await act(async () => { + testBed = await setup({ onSave, isReadonly: false }); }); + const { + find, + component, + form: { setInputValue }, + } = testBed!; + await act(async () => { setInputValue('metadataForm.nameInput', 'newTitle'); setInputValue('metadataForm.descriptionInput', 'newDescription'); @@ -196,7 +201,17 @@ describe('', () => { testBed = await setup({ onSave, isReadonly: false, services: { notifyError } }); }); - const { find, component } = testBed!; + const { + find, + component, + form: { setInputValue }, + } = testBed!; + + await act(async () => { + setInputValue('metadataForm.nameInput', 'changingTitleToUnblockDisabledButtonState'); + }); + + await waitForValidationResults(); component.update();