diff --git a/changelogs/fragments/8648.yml b/changelogs/fragments/8648.yml
new file mode 100644
index 000000000000..84cc02108e2d
--- /dev/null
+++ b/changelogs/fragments/8648.yml
@@ -0,0 +1,2 @@
+fix:
+- [Workspace] Workspace assets page crashed after library_write permission revoked ([#8648](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8648))
\ No newline at end of file
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
index 39270a4557ed..9501523a3755 100644
--- 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
@@ -142,9 +142,13 @@ HTMLCollection [
-
- Copy saved objects to targetWorkspace
-
+
+
+ Copy saved objects to targetWorkspace
+
+
-
+
+
+
{this.copyResult({ failedCopies, successfulCopies })}
diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx
index df7bec839a90..b3e440460428 100644
--- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx
@@ -1021,7 +1021,38 @@ describe('SavedObjectsTable', () => {
});
});
- it('should catch error when duplicating selected object is fail', async () => {
+ it('should catch error when duplicating selected object is failed', async () => {
+ const component = shallowRender({ applications, workspaces });
+ component.setState({ isShowingDuplicateModal: true });
+
+ const mockCopy = jest.fn().mockResolvedValue({ error: 'error' });
+ workspaces.client$.next({ copy: mockCopy });
+ const client = workspaces.client$.getValue();
+
+ // Ensure all promises resolve
+ await new Promise((resolve) => process.nextTick(resolve));
+ // Ensure the state changes are reflected
+ component.update();
+
+ await component.instance().onDuplicate(mockSelectedSavedObjects, false, 'workspace2', 'bar');
+
+ expect(client?.copy).toHaveBeenCalledWith(
+ [
+ { id: '1', type: 'dashboard' },
+ { id: '2', type: 'dashboard' },
+ ],
+ 'workspace2',
+ false
+ );
+ component.update();
+
+ expect(notifications.toasts.addDanger).toHaveBeenCalledWith({
+ title: 'Unable to copy 2 saved objects.',
+ text: 'error',
+ });
+ });
+
+ it('should show error toast when copy is fail', async () => {
const component = shallowRender({ applications, workspaces });
component.setState({ isShowingDuplicateModal: true });
diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx
index 3ecfd103488b..8c77f9dd3eff 100644
--- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx
+++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx
@@ -761,13 +761,14 @@ export class SavedObjectsTable extends Component {
+ const showErrorNotification = (text?: string) => {
notifications.toasts.addDanger({
title: i18n.translate('savedObjectsManagement.objectsTable.duplicate.dangerNotification', {
defaultMessage:
'Unable to copy {useUpdatedUX, select, true {{errorCount, plural, one {# asset} other {# assets}}} other {{errorCount, plural, one {# saved object} other {# saved objects}}}}.',
values: { errorCount: savedObjects.length, useUpdatedUX },
}),
+ ...(text && { text }),
});
};
if (!workspaceClient) {
@@ -781,18 +782,22 @@ export class SavedObjectsTable extends Component 0 ? result.successResults : [],
- targetWorkspaceName,
- });
+ if (result?.error) {
+ showErrorNotification(result.error);
+ } else {
+ this.setState({
+ isShowingDuplicateResultFlyout: true,
+ failedCopies: result?.errors || [],
+ successfulCopies: result?.successCount > 0 ? result.successResults : [],
+ targetWorkspaceName,
+ });
+ }
} catch (e) {
showErrorNotification();
+ } finally {
+ this.hideDuplicateModal();
+ await this.refreshObjects();
}
- this.hideDuplicateModal();
- await this.refreshObjects();
};
renderDuplicateModal() {