From b8dbf835088295246f457d27daa44d2546e17565 Mon Sep 17 00:00:00 2001 From: Paulina Shakirova Date: Wed, 6 Nov 2024 13:50:19 +0100 Subject: [PATCH] feat: SavedObjectSaveModal - add postfix if the title is duplicated (#198777) ## Summary This PR fixes the issue with the [[Dashboard][Event annotations][Lens] appending a postfix when there is a duplicate title instead of interrupting the save flow](https://github.com/elastic/kibana/issues/161119). Currently, if a user wants to save an object as a new group without modifying the title, they will see a warning about it. This PR introduces an additional step. If the user attempts to save an object as a new group, we automatically append a postfix to the title. If the user manually changes the title back to the original and tries to save it, they will see the currently configured warning. https://github.com/user-attachments/assets/4f764b75-5b83-4277-8e5e-42fe1174fae7 --- .../saved_object_save_modal.test.tsx | 50 +++++++++++++++++++ .../save_modal/saved_object_save_modal.tsx | 21 ++++++++ 2 files changed, 71 insertions(+) diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.test.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.test.tsx index 82e8051b897c7..273a79c307001 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.test.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.test.tsx @@ -121,4 +121,54 @@ describe('SavedObjectSaveModal', () => { expect(onSave.mock.calls[0][0].newCopyOnSave).toBe(true); }); }); + + describe('handle title duplication logic', () => { + it('should append "[1]" to title if no number is present', async () => { + const onSave = jest.fn(); + + render( + + {}} + title="Saved Object" + objectType="visualization" + showDescription={true} + showCopyOnSave={true} + /> + + ); + + const switchElement = screen.getByTestId('saveAsNewCheckbox'); + await userEvent.click(switchElement); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectTitle')).toHaveValue('Saved Object [1]'); + }); + }); + + it('should increment the number by one when a number is already present', async () => { + const onSave = jest.fn(); + + render( + + {}} + title="Saved Object [1]" + objectType="visualization" + showDescription={true} + showCopyOnSave={true} + /> + + ); + + const switchElement = screen.getByTestId('saveAsNewCheckbox'); + await userEvent.click(switchElement); + + await waitFor(() => { + expect(screen.getByTestId('savedObjectTitle')).toHaveValue('Saved Object [2]'); + }); + }); + }); }); diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx index aa82feafb60aa..a3e6d1cc22b2a 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx @@ -276,7 +276,28 @@ export class SavedObjectSaveModal extends React.Component }); }; + private handleTitleDuplication = () => { + const regex = /\s*\[(\d+)\]$/; + const match = this.state.title.match(regex); + + if (match) { + const newNumber = Number(match[1]) + 1; + + this.setState({ + title: this.state.title.replace(regex, ` [${newNumber}]`), + }); + } else { + this.setState({ + title: this.state.title + ' [1]', + }); + } + }; + private onCopyOnSaveChange = (event: EuiSwitchEvent) => { + if (this.props.title === this.state.title && event.target.checked) { + this.handleTitleDuplication(); + } + this.setState({ copyOnSave: event.target.checked, });