From 7bfddabf3ef6caff9f8308c653716f7bb25e2930 Mon Sep 17 00:00:00 2001 From: Anan Zhuang Date: Tue, 30 Apr 2024 09:40:12 -0700 Subject: [PATCH] [BUG] Allow Save in Top Nav Menu to capture filter and query (#6636) Before this PR, can't save when filter or query change. After this PR, if the canvas is not empty, can save filter and query updates. Issue Resolve https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5645 Signed-off-by: Anan Zhuang --- changelogs/fragments/6636.yml | 2 ++ .../public/application/components/top_nav.tsx | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/6636.yml diff --git a/changelogs/fragments/6636.yml b/changelogs/fragments/6636.yml new file mode 100644 index 000000000000..2434dd458b9f --- /dev/null +++ b/changelogs/fragments/6636.yml @@ -0,0 +1,2 @@ +fix: +- [BUG] Allow Save in Top Nav Menu to capture filter and query ([#6636](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6636)) \ No newline at end of file diff --git a/src/plugins/vis_builder/public/application/components/top_nav.tsx b/src/plugins/vis_builder/public/application/components/top_nav.tsx index 768f2db35465..a46feadb35cb 100644 --- a/src/plugins/vis_builder/public/application/components/top_nav.tsx +++ b/src/plugins/vis_builder/public/application/components/top_nav.tsx @@ -3,7 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; +import { isEqual } from 'lodash'; import { useParams } from 'react-router-dom'; import { useUnmount } from 'react-use'; import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public'; @@ -19,11 +20,21 @@ import { saveStateToSavedObject } from '../../saved_visualizations/transforms'; import { TopNavMenuData } from '../../../../navigation/public'; import { opensearchFilters, connectStorageToQueryState } from '../../../../data/public'; +function useDeepEffect(callback, dependencies) { + const currentDepsRef = useRef(dependencies); + + if (!isEqual(currentDepsRef.current, dependencies)) { + callback(); + currentDepsRef.current = dependencies; + } +} + export const TopNav = () => { // id will only be set for the edit route const { id: visualizationIdFromUrl } = useParams<{ id: string }>(); const { services } = useOpenSearchDashboards(); const { + data, setHeaderActionMenu, navigation: { ui: { TopNavMenu }, @@ -33,6 +44,10 @@ export const TopNav = () => { const rootState = useTypedSelector((state) => state); const dispatch = useTypedDispatch(); + useDeepEffect(() => { + dispatch(setEditorState({ state: 'dirty' })); + }, [data.query.queryString.getQuery(), data.query.filterManager.getFilters()]); + const saveDisabledReason = useCanSave(); const savedVisBuilderVis = useSavedVisBuilderVis(visualizationIdFromUrl); connectStorageToQueryState(services.data.query, services.osdUrlStateStorage, {