diff --git a/public/components/custom_panels/helpers/add_visualization_helper.ts b/public/components/custom_panels/helpers/add_visualization_helper.ts index 9b7b5c236..5c57ab53a 100644 --- a/public/components/custom_panels/helpers/add_visualization_helper.ts +++ b/public/components/custom_panels/helpers/add_visualization_helper.ts @@ -58,7 +58,7 @@ export const addVisualizationPanel = ( // client: ILegacyScopedClusterClient, // panelId: string, savedVisualizationId: string, - oldVisualizationId?: string, + oldVisualizationId: string | undefined, allPanelVisualizations: VisualizationType[] ) => { try { diff --git a/public/components/custom_panels/home.tsx b/public/components/custom_panels/home.tsx index 4ac8cf4fc..090c37adf 100644 --- a/public/components/custom_panels/home.tsx +++ b/public/components/custom_panels/home.tsx @@ -32,13 +32,12 @@ import { ObservabilityPanelAttrs, PanelType, } from '../../../common/types/custom_panels'; -import { ObservabilitySideBar } from '../common/side_nav'; import { CustomPanelTable } from './custom_panel_table'; import { CustomPanelView } from './custom_panel_view'; import { isNameValid } from './helpers/utils'; import { CustomPanelViewSO } from './custom_panel_view_so'; import { coreRefs } from '../../framework/core_refs'; -import { fetchPanels } from './redux/panel_slice'; +import { deletePanel, fetchPanels, uuidRx } from './redux/panel_slice'; // import { ObjectFetcher } from '../common/objectFetcher'; @@ -143,8 +142,6 @@ export const Home = ({ }); }; - const uuidRx = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/; - const isUuid = (id) => !!id.match(uuidRx); const fetchSavedObjectPanel = async (id: string) => { @@ -178,44 +175,46 @@ export const Home = ({ // Deletes multiple existing Operational Panels const deleteCustomPanelList = (customPanelIdList: string[], toastMessage: string) => { - // Promise.all([ - // deletePanelSO(customPanelIdList), - // deletePanels(customPanelIdList) - // ]).then((res) => { - // setcustomPanelData((prevCustomPanelData) => { - // return prevCustomPanelData.filter( - // (customPanel) => !customPanelIdList.includes(customPanel.id) - // ); - // }); - // setToast(toastMessage); - // }) - // .catch((err) => { - // setToast( - // 'Error deleting Operational Panels, please make sure you have the correct permission.', - // 'danger' - // ); - // console.error(err.body.message); - // }); + Promise.all([deletePanelSO(customPanelIdList), deletePanels(customPanelIdList)]) + .then((res) => { + // setcustomPanelData((prevCustomPanelData) => { + // return prevCustomPanelData.filter( + // (customPanel) => !customPanelIdList.includes(customPanel.id) + // ); + // }); + // setToast(toastMessage); + }) + .catch((err) => { + setToast( + 'Error deleting Operational Panels, please make sure you have the correct permission.', + 'danger' + ); + console.error(err.body.message); + }); }; // Deletes an existing Operational Panel const deleteCustomPanel = async (customPanelId: string, customPanelName: string) => { - // return http - // .delete(`${CUSTOM_PANELS_API_PREFIX}/panels/` + customPanelId) - // .then((res) => { - // setcustomPanelData((prevCustomPanelData) => { - // return prevCustomPanelData.filter((customPanel) => customPanel.id !== customPanelId); - // }); - // setToast(`Operational Panel "${customPanelName}" successfully deleted!`); - // return res; - // }) - // .catch((err) => { - // setToast( - // 'Error deleting Operational Panel, please make sure you have the correct permission.', - // 'danger' - // ); - // console.error(err.body.message); - // }); + return http + .delete(`${CUSTOM_PANELS_API_PREFIX}/panels/` + customPanelId) + .then((res) => { + dispatch(fetchPanels()); + setToast(`Operational Panel "${customPanelName}" successfully deleted!`); + return res; + }) + .catch((err) => { + setToast( + 'Error deleting Operational Panel, please make sure you have the correct permission.', + 'danger' + ); + console.error(err.body.message); + }); + }; + + // Deletes an existing SO Operational Panel + const deleteCustomPanelSO = async (customPanelId: string, customPanelName: string) => { + dispatch(deletePanel(customPanelId)); + // TODO: toast here }; const addSamplePanels = async () => { @@ -258,7 +257,6 @@ export const Home = ({ }) .then((res) => { dispatch(fetchPanels()); - // setcustomPanelData([...customPanelData, ...res.demoPanelsData]); }); setToast(`Sample panels successfully added.`); } catch (err: any) { diff --git a/public/components/custom_panels/redux/panel_slice.ts b/public/components/custom_panels/redux/panel_slice.ts index 0ac857965..32bba7f3f 100644 --- a/public/components/custom_panels/redux/panel_slice.ts +++ b/public/components/custom_panels/redux/panel_slice.ts @@ -1,6 +1,7 @@ import { createSelector, createSlice } from '@reduxjs/toolkit'; -import { concat, from, Observable, of } from 'rxjs'; +import { async, concat, from, Observable, of } from 'rxjs'; import { map, mergeMap, tap, toArray } from 'rxjs/operators'; +import { forEach } from 'lodash'; import { CUSTOM_PANELS_API_PREFIX, CUSTOM_PANELS_SAVED_OBJECT_TYPE, @@ -16,6 +17,7 @@ import { import { coreRefs } from '../../../framework/core_refs'; import { SavedObject, SimpleSavedObject } from '../../../../../../src/core/public'; import { isNameValid } from '../helpers/utils'; +import { addVisualizationPanel } from '../helpers/add_visualization_helper'; interface InitialState { id: string; @@ -59,10 +61,7 @@ export const panelReducer = panelSlice.reducer; export const selectPanel = (rootState): CustomPanelType => rootState.customPanel.panel; -export const selectPanelList = (rootState): CustomPanelType[] => { - // console.log('selectPanelList', { rootState, panelList: rootState.customPanel.panelList }); - return rootState.customPanel.panelList; -}; +export const selectPanelList = (rootState): CustomPanelType[] => rootState.customPanel.panelList; // export const selectPanelList = createSelector( // rootState => { console.log("selectPanelList", { rootState }); return rootState.customPanel.panelList }, @@ -125,8 +124,6 @@ const updateLegacyPanel = (panel: CustomPanelType) => const updateSavedObjectPanel = (panel: CustomPanelType) => savedObjectPanelsClient.update(panel); -const uuidRx = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/; - const isUuid = (id) => !!id.match(uuidRx); export const updatePanel = (panel: CustomPanelType) => async (dispatch, getState) => { @@ -142,6 +139,23 @@ export const updatePanel = (panel: CustomPanelType) => async (dispatch, getState } }; +export const addVizToPanels = (panels, vizId) => async (dispatch, getState) => { + forEach(panels, (oldPanel) => { + const panel = getState().customPanel.panelList.find((p) => p.id === oldPanel.panel.id); + + const allVisualizations = panel!.visualizations; + + const visualizationsWithNewPanel = addVisualizationPanel(vizId, undefined, allVisualizations); + + const updatedPanel = { ...panel, visualizations: visualizationsWithNewPanel }; + try { + dispatch(updatePanel(updatedPanel)); + } catch (err) { + console.error(err?.body?.message || err); + } + }); +}; + export const deletePanel = (id) => async (dispatch, getState) => { await savedObjectPanelsClient.delete(id); const panelList: CustomPanelType[] = getState().panelList.filter((p) => p.id !== id); diff --git a/public/components/event_analytics/explorer/save_panel/save_panel.tsx b/public/components/event_analytics/explorer/save_panel/save_panel.tsx index a2dc5b44b..d6ee5940c 100644 --- a/public/components/event_analytics/explorer/save_panel/save_panel.tsx +++ b/public/components/event_analytics/explorer/save_panel/save_panel.tsx @@ -50,7 +50,6 @@ export const SavePanel = ({ setSubType, isSaveAsMetricEnabled, }: ISavedPanelProps) => { - const [options, setOptions] = useState([]); const [checked, setChecked] = useState(false); const [svpnlError, setSvpnlError] = useState(null); @@ -62,20 +61,6 @@ export const SavePanel = ({ dispatch(fetchPanels()); }, []); - const getCustomPabnelList = async (svobj: SavedObjects) => { - const optionRes = await svobj - .fetchCustomPanels() - .then((res: any) => { - return res; - }) - .catch((error: any) => setSvpnlError(error)); - setOptions(optionRes?.panels || []); - }; - - useEffect(() => { - getCustomPabnelList(savedObjects); - }, []); - const onToggleChange = (e: { target: { checked: React.SetStateAction } }) => { setChecked(e.target.checked); if (e.target.checked) { diff --git a/public/services/saved_objects/saved_object_savers/ppl/save_as_current_vis.ts b/public/services/saved_objects/saved_object_savers/ppl/save_as_current_vis.ts index d6708ae4f..7eb552586 100644 --- a/public/services/saved_objects/saved_object_savers/ppl/save_as_current_vis.ts +++ b/public/services/saved_objects/saved_object_savers/ppl/save_as_current_vis.ts @@ -3,6 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { + addVizToPanels, + uuidRx, +} from '../../../../../public/components/custom_panels/redux/panel_slice'; import { SavedQuerySaver } from './saved_query_saver'; export class SaveAsCurrentVisualization extends SavedQuerySaver { @@ -46,9 +50,14 @@ export class SaveAsCurrentVisualization extends SavedQuerySaver { } addToPanel({ selectedPanels, saveTitle, notifications, visId }) { + const { dispatch } = this.dispatchers; + const soPanels = selectedPanels.filter((panel) => uuidRx.test(panel.panel.id)); + const opsPanels = selectedPanels.filter((panel) => !uuidRx.test(panel.panel.id)); + dispatch(addVizToPanels(soPanels, visId)); + this.panelClient .updateBulk({ - selectedCustomPanels: selectedPanels, + selectedCustomPanels: opsPanels, savedVisualizationId: visId, }) .then((res: any) => { diff --git a/public/services/saved_objects/saved_object_savers/ppl/save_as_new_vis.ts b/public/services/saved_objects/saved_object_savers/ppl/save_as_new_vis.ts index b0c57d4c7..9d3821740 100644 --- a/public/services/saved_objects/saved_object_savers/ppl/save_as_new_vis.ts +++ b/public/services/saved_objects/saved_object_savers/ppl/save_as_new_vis.ts @@ -3,6 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { forEach } from 'lodash'; +import { + addVizToPanels, + fetchPanel, + uuidRx, +} from '../../../../../public/components/custom_panels/redux/panel_slice'; import { SAVED_OBJECT_ID, SAVED_OBJECT_TYPE, @@ -10,6 +16,7 @@ import { } from '../../../../../common/constants/explorer'; import { ISavedObjectsClient } from '../../saved_object_client/client_interface'; import { SavedQuerySaver } from './saved_query_saver'; +import { addVisualizationPanel } from '../../../../../public/components/custom_panels/helpers/add_visualization_helper'; export class SaveAsNewVisualization extends SavedQuerySaver { constructor( @@ -76,9 +83,14 @@ export class SaveAsNewVisualization extends SavedQuerySaver { } addToPanel({ selectedPanels, saveTitle, notifications, visId }) { + const { dispatch } = this.dispatchers; + const soPanels = selectedPanels.filter((panel) => uuidRx.test(panel.panel.id)); + const opsPanels = selectedPanels.filter((panel) => !uuidRx.test(panel.panel.id)); + + dispatch(addVizToPanels(soPanels, visId)); this.panelClient .updateBulk({ - selectedCustomPanels: selectedPanels, + selectedCustomPanels: opsPanels, savedVisualizationId: visId, }) .then((res: any) => {