diff --git a/frontend/src/components/ResizeTable/DynamicColumnTable.syles.scss b/frontend/src/components/ResizeTable/DynamicColumnTable.syles.scss
index 2bd0606abd..31026f4f12 100644
--- a/frontend/src/components/ResizeTable/DynamicColumnTable.syles.scss
+++ b/frontend/src/components/ResizeTable/DynamicColumnTable.syles.scss
@@ -1,25 +1,31 @@
.DynamicColumnTable {
- display: flex;
- flex-direction: column;
- width: 100%;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
- .dynamicColumnTable-button {
- align-self: flex-end;
- margin: 10px 0;
- }
+ .dynamicColumnTable-button {
+ align-self: flex-end;
+ margin: 10px 0;
+
+ &.filter-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
}
.dynamicColumnsTable-items {
- display: flex;
- width: 10.625rem;
- justify-content: space-between;
- align-items: center;
+ display: flex;
+ width: 10.625rem;
+ justify-content: space-between;
+ align-items: center;
}
@media (max-width: 768px) {
- .dynamicColumnsTable-items {
- flex-direction: column;
- width: auto;
- text-align: center;
- }
-}
\ No newline at end of file
+ .dynamicColumnsTable-items {
+ flex-direction: column;
+ width: auto;
+ text-align: center;
+ }
+}
diff --git a/frontend/src/components/ResizeTable/DynamicColumnTable.tsx b/frontend/src/components/ResizeTable/DynamicColumnTable.tsx
index c0d77c967b..401517206f 100644
--- a/frontend/src/components/ResizeTable/DynamicColumnTable.tsx
+++ b/frontend/src/components/ResizeTable/DynamicColumnTable.tsx
@@ -1,9 +1,9 @@
/* eslint-disable react/jsx-props-no-spreading */
import './DynamicColumnTable.syles.scss';
-import { SettingOutlined } from '@ant-design/icons';
import { Button, Dropdown, MenuProps, Switch } from 'antd';
import { ColumnsType } from 'antd/lib/table';
+import { SlidersHorizontal } from 'lucide-react';
import { memo, useEffect, useState } from 'react';
import { popupContainer } from 'utils/selectPopupContainer';
@@ -90,9 +90,9 @@ function DynamicColumnTable({
trigger={['click']}
>
}
+ icon={}
/>
)}
diff --git a/frontend/src/constants/localStorage.ts b/frontend/src/constants/localStorage.ts
index 2788e93943..296735b286 100644
--- a/frontend/src/constants/localStorage.ts
+++ b/frontend/src/constants/localStorage.ts
@@ -15,4 +15,5 @@ export enum LOCALSTORAGE {
LOGGED_IN_USER_EMAIL = 'LOGGED_IN_USER_EMAIL',
CHAT_SUPPORT = 'CHAT_SUPPORT',
IS_IDENTIFIED_USER = 'IS_IDENTIFIED_USER',
+ DASHBOARD_VARIABLES = 'DASHBOARD_VARIABLES',
}
diff --git a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx
index db7259559a..8ced5b2b22 100644
--- a/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx
+++ b/frontend/src/container/NewDashboard/DashboardVariablesSelection/DashboardVariableSelection.tsx
@@ -1,18 +1,22 @@
import { Row } from 'antd';
-import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
-import { useNotifications } from 'hooks/useNotifications';
+import { useDashboardVariablesFromLocalStorage } from 'hooks/dashboard/useDashboardFromLocalStorage';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { memo, useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
-import { AppState } from 'store/reducers';
-import { Dashboard, IDashboardVariable } from 'types/api/dashboard/getAll';
-import AppReducer from 'types/reducer/app';
+import { IDashboardVariable } from 'types/api/dashboard/getAll';
import { convertVariablesToDbFormat } from './util';
import VariableItem from './VariableItem';
function DashboardVariableSelection(): JSX.Element | null {
- const { selectedDashboard, setSelectedDashboard } = useDashboard();
+ const {
+ selectedDashboard,
+ setSelectedDashboard,
+ dashboardId,
+ } = useDashboard();
+
+ const {
+ updateLocalStorageDashboardVariables,
+ } = useDashboardVariablesFromLocalStorage(dashboardId);
const { data } = selectedDashboard || {};
@@ -23,8 +27,6 @@ function DashboardVariableSelection(): JSX.Element | null {
const [variablesTableData, setVariablesTableData] = useState([]);
- const { role } = useSelector((state) => state.app);
-
useEffect(() => {
if (variables) {
const tableRowData = [];
@@ -52,40 +54,6 @@ function DashboardVariableSelection(): JSX.Element | null {
setUpdate(!update);
};
- const updateMutation = useUpdateDashboard();
- const { notifications } = useNotifications();
-
- const updateVariables = (
- name: string,
- updatedVariablesData: Dashboard['data']['variables'],
- ): void => {
- if (!selectedDashboard) {
- return;
- }
-
- updateMutation.mutateAsync(
- {
- ...selectedDashboard,
- data: {
- ...selectedDashboard.data,
- variables: updatedVariablesData,
- },
- },
- {
- onSuccess: (updatedDashboard) => {
- if (updatedDashboard.payload) {
- setSelectedDashboard(updatedDashboard.payload);
- }
- },
- onError: () => {
- notifications.error({
- message: `Error updating ${name} variable`,
- });
- },
- },
- );
- };
-
const onValueUpdate = (
name: string,
id: string,
@@ -105,12 +73,22 @@ function DashboardVariableSelection(): JSX.Element | null {
return variableCopy;
},
);
+ updateLocalStorageDashboardVariables(id, value, allSelected);
const variables = convertVariablesToDbFormat(newVariablesArr);
- if (role !== 'VIEWER' && selectedDashboard) {
- updateVariables(name, variables);
+ if (selectedDashboard) {
+ setSelectedDashboard({
+ ...selectedDashboard,
+ data: {
+ ...selectedDashboard?.data,
+ variables: {
+ ...variables,
+ },
+ },
+ });
}
+
onVarChanged(name);
setUpdate(!update);
diff --git a/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx b/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx
new file mode 100644
index 0000000000..965f1d70c5
--- /dev/null
+++ b/frontend/src/hooks/dashboard/useDashboardFromLocalStorage.tsx
@@ -0,0 +1,100 @@
+import getLocalStorageKey from 'api/browser/localstorage/get';
+import setLocalStorageKey from 'api/browser/localstorage/set';
+import { LOCALSTORAGE } from 'constants/localStorage';
+import { defaultTo } from 'lodash-es';
+import { useEffect, useState } from 'react';
+import { IDashboardVariable } from 'types/api/dashboard/getAll';
+
+interface LocalStoreDashboardVariables {
+ [id: string]: {
+ selectedValue: IDashboardVariable['selectedValue'];
+ allSelected: boolean;
+ };
+}
+interface DashboardLocalStorageVariables {
+ [id: string]: LocalStoreDashboardVariables;
+}
+
+interface UseDashboardVariablesFromLocalStorageReturn {
+ currentDashboard: LocalStoreDashboardVariables;
+ updateLocalStorageDashboardVariables: (
+ id: string,
+ selectedValue: IDashboardVariable['selectedValue'],
+ allSelected: boolean,
+ ) => void;
+}
+
+export const useDashboardVariablesFromLocalStorage = (
+ dashboardId: string,
+): UseDashboardVariablesFromLocalStorageReturn => {
+ const [
+ allDashboards,
+ setAllDashboards,
+ ] = useState({});
+
+ const [
+ currentDashboard,
+ setCurrentDashboard,
+ ] = useState({});
+
+ useEffect(() => {
+ const localStoreDashboardVariablesString = getLocalStorageKey(
+ LOCALSTORAGE.DASHBOARD_VARIABLES,
+ );
+ let localStoreDashboardVariables: DashboardLocalStorageVariables = {};
+ if (localStoreDashboardVariablesString === null) {
+ try {
+ const serialzedData = JSON.stringify({
+ [dashboardId]: {},
+ });
+
+ setLocalStorageKey(LOCALSTORAGE.DASHBOARD_VARIABLES, serialzedData);
+ } catch {
+ console.error('Failed to seralise the data');
+ }
+ } else {
+ try {
+ localStoreDashboardVariables = JSON.parse(
+ localStoreDashboardVariablesString,
+ );
+ } catch {
+ console.error('Failed to parse dashboards from local storage');
+ localStoreDashboardVariables = {};
+ } finally {
+ setAllDashboards(localStoreDashboardVariables);
+ }
+ }
+ setCurrentDashboard(defaultTo(localStoreDashboardVariables[dashboardId], {}));
+ }, [dashboardId]);
+
+ const updateLocalStorageDashboardVariables = (
+ id: string,
+ selectedValue: IDashboardVariable['selectedValue'],
+ allSelected: boolean,
+ ): void => {
+ const newCurrentDashboard = {
+ ...currentDashboard,
+ [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 {
+ currentDashboard,
+ updateLocalStorageDashboardVariables,
+ };
+};
diff --git a/frontend/src/providers/Dashboard/Dashboard.tsx b/frontend/src/providers/Dashboard/Dashboard.tsx
index 20c54d2eba..158374ec3c 100644
--- a/frontend/src/providers/Dashboard/Dashboard.tsx
+++ b/frontend/src/providers/Dashboard/Dashboard.tsx
@@ -6,6 +6,7 @@ import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import ROUTES from 'constants/routes';
import { getMinMax } from 'container/TopNav/AutoRefresh/config';
import dayjs, { Dayjs } from 'dayjs';
+import { useDashboardVariablesFromLocalStorage } from 'hooks/dashboard/useDashboardFromLocalStorage';
import useAxiosError from 'hooks/useAxiosError';
import useTabVisibility from 'hooks/useTabFocus';
import { getUpdatedLayout } from 'lib/dashboard/getUpdatedLayout';
@@ -95,6 +96,10 @@ export function DashboardProvider({
const [selectedDashboard, setSelectedDashboard] = useState();
+ const { currentDashboard } = useDashboardVariablesFromLocalStorage(
+ dashboardId,
+ );
+
const updatedTimeRef = useRef(null); // Using ref to store the updated time
const modalRef = useRef(null);
@@ -103,11 +108,33 @@ export function DashboardProvider({
const { t } = useTranslation(['dashboard']);
const dashboardRef = useRef();
+ const mergeDBWithLocalStorage = (
+ data: Dashboard,
+ localStorageVariables: any,
+ ): Dashboard => {
+ const updatedData = data;
+ if (data && localStorageVariables) {
+ const updatedVariables = data.data.variables;
+ Object.keys(data.data.variables).forEach((variable) => {
+ const updatedVariable = {
+ ...data.data.variables[variable],
+ ...localStorageVariables[variable as any],
+ };
+
+ updatedVariables[variable] = updatedVariable;
+ });
+ updatedData.data.variables = updatedVariables;
+ }
+ return updatedData;
+ };
// As we do not have order and ID's in the variables object, we have to process variables to add order and ID if they do not exist in the variables object
// eslint-disable-next-line sonarjs/cognitive-complexity
const transformDashboardVariables = (data: Dashboard): Dashboard => {
if (data && data.data && data.data.variables) {
- const clonedDashboardData = JSON.parse(JSON.stringify(data));
+ const clonedDashboardData = mergeDBWithLocalStorage(
+ JSON.parse(JSON.stringify(data)),
+ currentDashboard,
+ );
const { variables } = clonedDashboardData.data;
const existingOrders: Set = new Set();