diff --git a/frontend/src/container/GridCardLayout/GridCard/index.tsx b/frontend/src/container/GridCardLayout/GridCard/index.tsx index 1cb4c183be..43f7768412 100644 --- a/frontend/src/container/GridCardLayout/GridCard/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/index.tsx @@ -35,7 +35,11 @@ function GridCardGraph({ }: GridCardGraphProps): JSX.Element { const dispatch = useDispatch(); const [errorMessage, setErrorMessage] = useState(); - const { toScrollWidgetId, setToScrollWidgetId } = useDashboard(); + const { + toScrollWidgetId, + setToScrollWidgetId, + variablesToGetUpdated, + } = useDashboard(); const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector< AppState, GlobalReducer @@ -90,7 +94,11 @@ function GridCardGraph({ const isEmptyWidget = widget?.id === PANEL_TYPES.EMPTY_WIDGET || isEmpty(widget); - const queryEnabledCondition = isVisible && !isEmptyWidget && isQueryEnabled; + const queryEnabledCondition = + isVisible && + !isEmptyWidget && + isQueryEnabled && + isEmpty(variablesToGetUpdated); const [requestData, setRequestData] = useState(() => { if (widget.panelTypes !== PANEL_TYPES.LIST) { diff --git a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx index f8ec103336..5f770e26d0 100644 --- a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx +++ b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx @@ -1,9 +1,9 @@ import { Row } from 'antd'; +import { isNull } from 'lodash-es'; import { useDashboard } from 'providers/Dashboard/Dashboard'; import { memo, useEffect, useState } from 'react'; import { IDashboardVariable } from 'types/api/dashboard/getAll'; -import { convertVariablesToDbFormat } from './util'; import VariableItem from './VariableItem'; function DashboardVariableSelection(): JSX.Element | null { @@ -11,15 +11,14 @@ function DashboardVariableSelection(): JSX.Element | null { selectedDashboard, setSelectedDashboard, updateLocalStorageDashboardVariables, + variablesToGetUpdated, + setVariablesToGetUpdated, } = useDashboard(); const { data } = selectedDashboard || {}; const { variables } = data || {}; - const [update, setUpdate] = useState(false); - const [lastUpdatedVar, setLastUpdatedVar] = useState(''); - const [variablesTableData, setVariablesTableData] = useState([]); useEffect(() => { @@ -45,8 +44,27 @@ function DashboardVariableSelection(): JSX.Element | null { }, [variables]); const onVarChanged = (name: string): void => { - setLastUpdatedVar(name); - setUpdate(!update); + /** + * this function takes care of adding the dependent variables to current update queue and removing + * the updated variable name from the queue + */ + const dependentVariables = variablesTableData + ?.map((variable: any) => { + if (variable.type === 'QUERY') { + const re = new RegExp(`\\{\\{\\s*?\\.${name}\\s*?\\}\\}`); // regex for `{{.var}}` + const queryValue = variable.queryValue || ''; + const dependVarReMatch = queryValue.match(re); + if (dependVarReMatch !== null && dependVarReMatch.length > 0) { + return variable.name; + } + } + return null; + }) + .filter((val: string | null) => !isNull(val)); + setVariablesToGetUpdated((prev) => [ + ...prev.filter((v) => v !== name), + ...dependentVariables, + ]); }; const onValueUpdate = ( @@ -56,37 +74,31 @@ function DashboardVariableSelection(): JSX.Element | null { allSelected: boolean, ): void => { if (id) { - const newVariablesArr = variablesTableData.map( - (variable: IDashboardVariable) => { - const variableCopy = { ...variable }; - - if (variableCopy.id === id) { - variableCopy.selectedValue = value; - variableCopy.allSelected = allSelected; - } - - return variableCopy; - }, - ); updateLocalStorageDashboardVariables(name, value, allSelected); - const variables = convertVariablesToDbFormat(newVariablesArr); - if (selectedDashboard) { - setSelectedDashboard({ - ...selectedDashboard, - data: { - ...selectedDashboard?.data, - variables: { - ...variables, - }, - }, + setSelectedDashboard((prev) => { + if (prev) { + return { + ...prev, + data: { + ...prev?.data, + variables: { + ...prev?.data.variables, + [id]: { + ...prev.data.variables[id], + selectedValue: value, + allSelected, + }, + }, + }, + }; + } + return prev; }); } onVarChanged(name); - - setUpdate(!update); } }; @@ -107,13 +119,12 @@ function DashboardVariableSelection(): JSX.Element | null { ))} diff --git a/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.test.tsx b/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.test.tsx index c279880855..cd8b23ea46 100644 --- a/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.test.tsx +++ b/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.test.tsx @@ -53,7 +53,7 @@ describe('VariableItem', () => { variableData={mockVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); @@ -68,7 +68,7 @@ describe('VariableItem', () => { variableData={mockVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); @@ -82,7 +82,7 @@ describe('VariableItem', () => { variableData={mockVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); @@ -110,7 +110,7 @@ describe('VariableItem', () => { variableData={mockCustomVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); @@ -131,7 +131,7 @@ describe('VariableItem', () => { variableData={customVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); @@ -146,7 +146,7 @@ describe('VariableItem', () => { variableData={mockCustomVariableData} existingVariables={{}} onValueUpdate={mockOnValueUpdate} - lastUpdatedVar="" + variablesToGetUpdated={[]} /> , ); diff --git a/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.tsx b/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.tsx index 9f54305b1e..fdfb821267 100644 --- a/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.tsx +++ b/frontend/src/container/NewDashboard/DashboardVariablesSelection/VariableItem.tsx @@ -32,7 +32,7 @@ interface VariableItemProps { arg1: IDashboardVariable['selectedValue'], allSelected: boolean, ) => void; - lastUpdatedVar: string; + variablesToGetUpdated: string[]; } const getSelectValue = ( @@ -49,7 +49,7 @@ function VariableItem({ variableData, existingVariables, onValueUpdate, - lastUpdatedVar, + variablesToGetUpdated, }: VariableItemProps): JSX.Element { const [optionsData, setOptionsData] = useState<(string | number | boolean)[]>( [], @@ -108,16 +108,10 @@ function VariableItem({ if (!areArraysEqual(newOptionsData, oldOptionsData)) { /* eslint-disable no-useless-escape */ - const re = new RegExp(`\\{\\{\\s*?\\.${lastUpdatedVar}\\s*?\\}\\}`); // regex for `{{.var}}` - // If the variable is dependent on the last updated variable - // and contains the last updated variable in its query (of the form `{{.var}}`) - // then we need to update the value of the variable - const queryValue = variableData.queryValue || ''; - const dependVarReMatch = queryValue.match(re); if ( variableData.type === 'QUERY' && - dependVarReMatch !== null && - dependVarReMatch.length > 0 + variableData.name && + variablesToGetUpdated.includes(variableData.name) ) { let value = variableData.selectedValue; let allSelected = false; diff --git a/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx b/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx index 965f1d70c5..2f83a9ae9b 100644 --- a/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx +++ b/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx @@ -67,30 +67,32 @@ export const useDashboardVariablesFromLocalStorage = ( setCurrentDashboard(defaultTo(localStoreDashboardVariables[dashboardId], {})); }, [dashboardId]); + useEffect(() => { + try { + const serializedData = JSON.stringify(allDashboards); + setLocalStorageKey(LOCALSTORAGE.DASHBOARD_VARIABLES, serializedData); + } catch { + console.error('Failed to set dashboards in local storage'); + } + }, [allDashboards]); + + useEffect(() => { + setAllDashboards((prev) => ({ + ...prev, + [dashboardId]: { ...currentDashboard }, + })); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentDashboard]); + const updateLocalStorageDashboardVariables = ( id: string, selectedValue: IDashboardVariable['selectedValue'], allSelected: boolean, ): void => { - const newCurrentDashboard = { - ...currentDashboard, + setCurrentDashboard((prev) => ({ + ...prev, [id]: { selectedValue, allSelected }, - }; - - const newAllDashboards = { - ...allDashboards, - [dashboardId]: newCurrentDashboard, - }; - - try { - const serializedData = JSON.stringify(newAllDashboards); - setLocalStorageKey(LOCALSTORAGE.DASHBOARD_VARIABLES, serializedData); - } catch { - console.error('Failed to set dashboards in local storage'); - } - - setAllDashboards(newAllDashboards); - setCurrentDashboard(newCurrentDashboard); + })); }; return { diff --git a/frontend/src/providers/Dashboard/Dashboard.tsx b/frontend/src/providers/Dashboard/Dashboard.tsx index 326a4aae83..9a6fe62a1c 100644 --- a/frontend/src/providers/Dashboard/Dashboard.tsx +++ b/frontend/src/providers/Dashboard/Dashboard.tsx @@ -53,6 +53,8 @@ const DashboardContext = createContext({ toScrollWidgetId: '', setToScrollWidgetId: () => {}, updateLocalStorageDashboardVariables: () => {}, + variablesToGetUpdated: [], + setVariablesToGetUpdated: () => {}, }); interface Props { @@ -86,6 +88,10 @@ export function DashboardProvider({ exact: true, }); + const [variablesToGetUpdated, setVariablesToGetUpdated] = useState( + [], + ); + const [layouts, setLayouts] = useState([]); const { isLoggedIn } = useSelector((state) => state.app); @@ -171,6 +177,7 @@ export function DashboardProvider({ return data; }; + console.log(variablesToGetUpdated); const dashboardResponse = useQuery( [REACT_QUERY_KEY.DASHBOARD_BY_ID, isDashboardPage?.params], { @@ -323,6 +330,8 @@ export function DashboardProvider({ updatedTimeRef, setToScrollWidgetId, updateLocalStorageDashboardVariables, + variablesToGetUpdated, + setVariablesToGetUpdated, }), // eslint-disable-next-line react-hooks/exhaustive-deps [ @@ -335,6 +344,8 @@ export function DashboardProvider({ toScrollWidgetId, updateLocalStorageDashboardVariables, currentDashboard, + variablesToGetUpdated, + setVariablesToGetUpdated, ], ); diff --git a/frontend/src/providers/Dashboard/types.ts b/frontend/src/providers/Dashboard/types.ts index 1f171cb621..f822fd39a6 100644 --- a/frontend/src/providers/Dashboard/types.ts +++ b/frontend/src/providers/Dashboard/types.ts @@ -30,4 +30,6 @@ export interface IDashboardContext { | undefined, allSelected: boolean, ) => void; + variablesToGetUpdated: string[]; + setVariablesToGetUpdated: React.Dispatch>; }