feat: added user-friendly format to dashboard variable url

"
This commit is contained in:
SagarRajput-7 2025-05-20 10:52:30 +05:30
parent 4fe1d1b3f7
commit 5f4c1d151a
7 changed files with 42 additions and 32 deletions

View File

@ -27,6 +27,7 @@ import { popupContainer } from 'utils/selectPopupContainer';
import { CustomMultiSelectProps, CustomTagProps, OptionData } from './types';
import {
ALL_SELECTED_VALUE,
filterOptionsBySearch,
handleScrollToBottom,
prioritizeOrAddOptionForMultiSelect,
@ -38,8 +39,6 @@ enum ToggleTagValue {
All = 'All',
}
const ALL_SELECTED_VALUE = '__ALL__'; // Constant for the special value
const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
placeholder = 'Search...',
className,
@ -1833,6 +1832,7 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
onSearch={handleSearch}
value={displayValue}
onChange={(newValue): void => {
console.log('newValue', newValue);
handleInternalChange(newValue, false);
}}
onClear={onClearHandler}

View File

@ -3,6 +3,8 @@ import { OptionData } from './types';
export const SPACEKEY = ' ';
export const ALL_SELECTED_VALUE = '__ALL__'; // Constant for the special value
export const prioritizeOrAddOptionForSingleSelect = (
options: OptionData[],
value: string,

View File

@ -50,4 +50,5 @@ export enum QueryParams {
thresholds = 'thresholds',
selectedExplorerView = 'selectedExplorerView',
variableConfigs = 'variableConfigs',
variables = 'variables',
}

View File

@ -1,4 +1,5 @@
import { Row } from 'antd';
import { ALL_SELECTED_VALUE } from 'components/NewSelect/utils';
import useVariablesFromUrl from 'hooks/dashboard/useVariablesFromUrl';
import { isEmpty } from 'lodash-es';
import { useDashboard } from 'providers/Dashboard/Dashboard';
@ -116,7 +117,11 @@ function DashboardVariableSelection(): JSX.Element | null {
if (id) {
updateLocalStorageDashboardVariables(name, value, allSelected);
updateUrlVariable(id, value, allSelected);
if (allSelected) {
updateUrlVariable(name || id, ALL_SELECTED_VALUE);
} else {
updateUrlVariable(name || id, value);
}
if (selectedDashboard) {
setSelectedDashboard((prev) => {

View File

@ -5,19 +5,17 @@ import { useHistory } from 'react-router-dom';
import { IDashboardVariable } from 'types/api/dashboard/getAll';
interface LocalStoreDashboardVariables {
[id: string]: {
selectedValue: IDashboardVariable['selectedValue'];
allSelected: boolean;
};
[name: string]:
| IDashboardVariable['selectedValue'][]
| IDashboardVariable['selectedValue'];
}
interface UseVariablesFromUrlReturn {
getUrlVariables: () => LocalStoreDashboardVariables;
setUrlVariables: (variables: LocalStoreDashboardVariables) => void;
updateUrlVariable: (
id: string,
name: string,
selectedValue: IDashboardVariable['selectedValue'],
allSelected: boolean,
) => void;
clearUrlVariables: () => void;
}
@ -27,14 +25,14 @@ const useVariablesFromUrl = (): UseVariablesFromUrlReturn => {
const history = useHistory();
const getUrlVariables = useCallback((): LocalStoreDashboardVariables => {
const variableConfigsParam = urlQuery.get(QueryParams.variableConfigs);
const variablesParam = urlQuery.get(QueryParams.variables);
if (!variableConfigsParam) {
if (!variablesParam) {
return {};
}
try {
return JSON.parse(decodeURIComponent(variableConfigsParam));
return JSON.parse(decodeURIComponent(variablesParam));
} catch (error) {
console.error('Failed to parse variables from URL:', error);
return {};
@ -46,11 +44,11 @@ const useVariablesFromUrl = (): UseVariablesFromUrlReturn => {
const params = new URLSearchParams(urlQuery.toString());
if (Object.keys(variables).length === 0) {
params.delete(QueryParams.variableConfigs);
params.delete(QueryParams.variables);
} else {
try {
const encodedVariables = encodeURIComponent(JSON.stringify(variables));
params.set(QueryParams.variableConfigs, encodedVariables);
params.set(QueryParams.variables, encodedVariables);
} catch (error) {
console.error('Failed to serialize variables for URL:', error);
}
@ -65,7 +63,7 @@ const useVariablesFromUrl = (): UseVariablesFromUrlReturn => {
const clearUrlVariables = useCallback((): void => {
const params = new URLSearchParams(urlQuery.toString());
params.delete(QueryParams.variableConfigs);
params.delete(QueryParams.variables);
params.delete('options');
history.replace({
@ -74,19 +72,15 @@ const useVariablesFromUrl = (): UseVariablesFromUrlReturn => {
}, [history, urlQuery]);
const updateUrlVariable = useCallback(
(
id: string,
selectedValue: IDashboardVariable['selectedValue'],
allSelected: boolean,
): void => {
(name: string, selectedValue: IDashboardVariable['selectedValue']): void => {
const currentVariables = getUrlVariables();
const updatedVariables = {
...currentVariables,
[id]: { selectedValue, allSelected },
[name]: selectedValue,
};
setUrlVariables(updatedVariables);
setUrlVariables(updatedVariables as LocalStoreDashboardVariables);
},
[getUrlVariables, setUrlVariables],
);

View File

@ -2,6 +2,7 @@
import { Modal } from 'antd';
import getDashboard from 'api/v1/dashboards/id/get';
import locked from 'api/v1/dashboards/id/lock';
import { ALL_SELECTED_VALUE } from 'components/NewSelect/utils';
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import ROUTES from 'constants/routes';
import { getMinMax } from 'container/TopNav/AutoRefresh/config';
@ -234,8 +235,11 @@ export function DashboardProvider({
Object.keys(data.data.variables).forEach((variable) => {
const variableData = data.data.variables[variable];
const variablesFromUrl = getUrlVariables();
// values from url
const urlVariable = getUrlVariables()[variableData.id];
const urlVariable = variableData?.name
? variablesFromUrl[variableData?.name] || variablesFromUrl[variableData.id]
: variablesFromUrl[variableData.id];
let updatedVariable = {
...data.data.variables[variable],
@ -246,7 +250,9 @@ export function DashboardProvider({
if (urlVariable) {
updatedVariable = {
...updatedVariable,
...urlVariable,
...(urlVariable !== ALL_SELECTED_VALUE &&
updatedVariable?.showALLOption && { selectedValue: urlVariable }),
...(urlVariable === ALL_SELECTED_VALUE && { allSelected: true }),
};
}

View File

@ -1,3 +1,4 @@
import { ALL_SELECTED_VALUE } from 'components/NewSelect/utils';
import { IDashboardVariable } from 'types/api/dashboard/getAll';
import { commaValuesParser } from '../../lib/dashbaordVariables/customCommaValuesParser';
@ -18,28 +19,29 @@ export const initializeDefaultVariables = (
variables: Record<string, IDashboardVariable>,
getUrlVariables: () => UrlVariables | undefined,
updateUrlVariable: (
id: string,
name: string,
selectedValue: IDashboardVariable['selectedValue'],
allSelected: boolean,
) => void,
): void => {
if (!variables) return;
Object.values(variables).forEach((variable) => {
const { id, name } = variable;
const { id, name, allSelected, showALLOption } = variable;
const urlVariables = getUrlVariables();
// Check if either id or name is available in URL variables
const existsInUrl =
(id && urlVariables?.[id]) || (name && urlVariables?.[name]);
const value =
variable.type === 'CUSTOM'
? commaValuesParser(variable?.customValue || '')
: variable?.selectedValue || variable?.defaultValue;
if (!existsInUrl) {
updateUrlVariable(
id,
variable.type === 'CUSTOM'
? commaValuesParser(variable?.customValue || '')
: variable?.selectedValue || variable?.defaultValue,
variable.allSelected || false,
name || id,
allSelected && showALLOption ? ALL_SELECTED_VALUE : value,
);
}
});