diff --git a/changelogs/fragments/6478.yml b/changelogs/fragments/6478.yml new file mode 100644 index 000000000000..d8009500a060 --- /dev/null +++ b/changelogs/fragments/6478.yml @@ -0,0 +1,2 @@ +feat: +- [Workspace] Duplicate selected/all saved objects ([#6478](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6478)) \ No newline at end of file diff --git a/src/plugins/saved_objects_management/public/index.ts b/src/plugins/saved_objects_management/public/index.ts index 317b3079efa0..ba04384a28a2 100644 --- a/src/plugins/saved_objects_management/public/index.ts +++ b/src/plugins/saved_objects_management/public/index.ts @@ -46,11 +46,17 @@ export { ISavedObjectsManagementServiceRegistry, SavedObjectsManagementServiceRegistryEntry, } from './services'; -export { ProcessedImportResponse, processImportResponse, FailedImport } from './lib'; +export { + ProcessedImportResponse, + processImportResponse, + FailedImport, + duplicateSavedObjects, + getSavedObjectLabel, +} from './lib'; export { SavedObjectRelation, SavedObjectWithMetadata, SavedObjectMetadata } from './types'; export { SAVED_OBJECT_DELETE_TRIGGER, savedObjectDeleteTrigger } from './triggers'; export { SavedObjectDeleteContext } from './ui_actions_bootstrap'; - +export { SavedObjectsDuplicateModal } from './management_section'; export function plugin(initializerContext: PluginInitializerContext) { return new SavedObjectsManagementPlugin(); } diff --git a/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.test.ts b/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.test.ts new file mode 100644 index 000000000000..def28a431551 --- /dev/null +++ b/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.test.ts @@ -0,0 +1,71 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { httpServiceMock } from '../../../../core/public/mocks'; +import { duplicateSavedObjects } from './duplicate_saved_objects'; + +describe('copy saved objects', () => { + const httpClient = httpServiceMock.createStartContract(); + const objects = [ + { type: 'dashboard', id: '1' }, + { type: 'visualization', id: '2' }, + ]; + const targetWorkspace = '1'; + + it('make http call with all parameter provided', async () => { + const includeReferencesDeep = true; + await duplicateSavedObjects(httpClient, objects, targetWorkspace, includeReferencesDeep); + expect(httpClient.post).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + "/api/workspaces/_duplicate_saved_objects", + Object { + "body": "{\\"objects\\":[{\\"type\\":\\"dashboard\\",\\"id\\":\\"1\\"},{\\"type\\":\\"visualization\\",\\"id\\":\\"2\\"}],\\"includeReferencesDeep\\":true,\\"targetWorkspace\\":\\"1\\"}", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + } + `); + }); + + it('make http call without includeReferencesDeep parameter provided', async () => { + await duplicateSavedObjects(httpClient, objects, targetWorkspace); + expect(httpClient.post).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + "/api/workspaces/_duplicate_saved_objects", + Object { + "body": "{\\"objects\\":[{\\"type\\":\\"dashboard\\",\\"id\\":\\"1\\"},{\\"type\\":\\"visualization\\",\\"id\\":\\"2\\"}],\\"includeReferencesDeep\\":true,\\"targetWorkspace\\":\\"1\\"}", + }, + ], + Array [ + "/api/workspaces/_duplicate_saved_objects", + Object { + "body": "{\\"objects\\":[{\\"type\\":\\"dashboard\\",\\"id\\":\\"1\\"},{\\"type\\":\\"visualization\\",\\"id\\":\\"2\\"}],\\"includeReferencesDeep\\":true,\\"targetWorkspace\\":\\"1\\"}", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + Object { + "type": "return", + "value": undefined, + }, + ], + } + `); + }); +}); diff --git a/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.ts b/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.ts new file mode 100644 index 000000000000..560e0c1fddb3 --- /dev/null +++ b/src/plugins/saved_objects_management/public/lib/duplicate_saved_objects.ts @@ -0,0 +1,21 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { HttpStart } from 'src/core/public'; + +export async function duplicateSavedObjects( + http: HttpStart, + objects: any[], + targetWorkspace: string, + includeReferencesDeep: boolean = true +) { + return await http.post('/api/workspaces/_duplicate_saved_objects', { + body: JSON.stringify({ + objects, + includeReferencesDeep, + targetWorkspace, + }), + }); +} diff --git a/src/plugins/saved_objects_management/public/lib/index.ts b/src/plugins/saved_objects_management/public/lib/index.ts index fae58cad3eb2..80630b8780e7 100644 --- a/src/plugins/saved_objects_management/public/lib/index.ts +++ b/src/plugins/saved_objects_management/public/lib/index.ts @@ -57,3 +57,4 @@ export { extractExportDetails, SavedObjectsExportResultDetails } from './extract export { createFieldList } from './create_field_list'; export { getAllowedTypes } from './get_allowed_types'; export { filterQuery } from './filter_query'; +export { duplicateSavedObjects } from './duplicate_saved_objects'; diff --git a/src/plugins/saved_objects_management/public/management_section/index.ts b/src/plugins/saved_objects_management/public/management_section/index.ts index 333bee71b0c0..25488f636741 100644 --- a/src/plugins/saved_objects_management/public/management_section/index.ts +++ b/src/plugins/saved_objects_management/public/management_section/index.ts @@ -29,3 +29,4 @@ */ export { mountManagementSection } from './mount_section'; +export { SavedObjectsDuplicateModal } from './objects_table'; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap index d01a503c2620..45deb7c2f2f4 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap @@ -226,6 +226,611 @@ exports[`SavedObjectsTable delete should show error toast when failing to delete `; +exports[`SavedObjectsTable duplicate should allow the user to choose on header when duplicating all 1`] = ` + +`; + +exports[`SavedObjectsTable duplicate should allow the user to choose on table when duplicating all 1`] = ` + +`; + +exports[`SavedObjectsTable duplicate should allow the user to choose on table when duplicating single 1`] = ` + +`; + exports[`SavedObjectsTable export should allow the user to choose when exporting all 1`] = `
`; + +exports[`SavedObjectsTable should unmount normally 1`] = `""`; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_modal.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_modal.test.tsx.snap new file mode 100644 index 000000000000..1e8c8acc083b --- /dev/null +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_modal.test.tsx.snap @@ -0,0 +1,252 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DuplicateModal should Unmount normally 1`] = `""`; + +exports[`DuplicateModal should render normally 1`] = ` +HTMLCollection [ + + + + + + + +
+
+
+
+ +
+
+
+ + Copy 3 objects to another workspace? + +
+
+
+
+
+
+ +
+
+
+
+ Move copied saved objects to the selected workspace. +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+
+ + +
+
+
+
+
+ + , +] +`; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_result_flyout.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_result_flyout.test.tsx.snap new file mode 100644 index 000000000000..b82303876131 --- /dev/null +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/duplicate_result_flyout.test.tsx.snap @@ -0,0 +1,375 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DuplicateResultFlyout copy count is null 1`] = ` +HTMLCollection [ + + + + + + + + +