From 9296e2a195bbaf8d87269fcf5e14e93bea3331d4 Mon Sep 17 00:00:00 2001
From: Manoj Vivek
Date: Mon, 20 Jan 2025 15:56:05 +0530
Subject: [PATCH] ui: useURLStateCustom hook to parse and set custom objects
from the url params (#5446)
* useURLStateCustom hook to parse and set custom objects from the url params
* [pre-commit.ci lite] apply automatic fixes
* Fixes missing dependency
* Handled undefined
* [pre-commit.ci lite] apply automatic fixes
---------
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
---
.../components/src/hooks/URLState/index.tsx | 27 +++++++++++++++++++
ui/packages/shared/profile/package.json | 1 +
.../profile/src/MetricsGraphStrips/index.tsx | 3 ++-
ui/pnpm-lock.yaml | 3 +++
4 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/ui/packages/shared/components/src/hooks/URLState/index.tsx b/ui/packages/shared/components/src/hooks/URLState/index.tsx
index 6785033c2a2..7efb82cc835 100644
--- a/ui/packages/shared/components/src/hooks/URLState/index.tsx
+++ b/ui/packages/shared/components/src/hooks/URLState/index.tsx
@@ -130,4 +130,31 @@ export const useURLState = (
return [(value ?? defaultValue) as T, setParam];
};
+interface OptionsCustom {
+ parse: (val: ParamValue) => T;
+ stringify: (val: T) => ParamValue;
+}
+
+type ParamValueSetterCustom = (val: T) => void;
+
+export const useURLStateCustom = (
+ param: string,
+ {parse, stringify, ..._options}: Options & OptionsCustom
+): [T, ParamValueSetterCustom] => {
+ const [urlValue, setURLValue] = useURLState(param, _options);
+
+ const val = useMemo(() => {
+ return parse(urlValue);
+ }, [parse, urlValue]);
+
+ const setVal = useCallback(
+ (val: T) => {
+ setURLValue(stringify(val));
+ },
+ [setURLValue, stringify]
+ );
+
+ return [val, setVal];
+};
+
export default URLStateContext;
diff --git a/ui/packages/shared/profile/package.json b/ui/packages/shared/profile/package.json
index 683b529c997..927e7502ab7 100644
--- a/ui/packages/shared/profile/package.json
+++ b/ui/packages/shared/profile/package.json
@@ -32,6 +32,7 @@
"d3-scale-chromatic": "^3.1.0",
"d3-selection": "3.0.0",
"d3-shape": "^3.2.0",
+ "fast-deep-equal": "^3.1.3",
"framer-motion": "6.5.1",
"graphviz-wasm": "3.0.2",
"lodash.throttle": "^4.1.1",
diff --git a/ui/packages/shared/profile/src/MetricsGraphStrips/index.tsx b/ui/packages/shared/profile/src/MetricsGraphStrips/index.tsx
index 8910f135e56..66a8021e761 100644
--- a/ui/packages/shared/profile/src/MetricsGraphStrips/index.tsx
+++ b/ui/packages/shared/profile/src/MetricsGraphStrips/index.tsx
@@ -15,6 +15,7 @@ import {useMemo, useState} from 'react';
import {Icon} from '@iconify/react';
import * as d3 from 'd3';
+import isEqual from 'fast-deep-equal';
import {LabelSet} from '@parca/client';
@@ -119,7 +120,7 @@ export const MetricsGraphStrips = ({
width={width ?? 1468}
fill={color(labelStr) as string}
selectionBounds={
- cpu === selectedTimeframe?.labels ? selectedTimeframe.bounds : undefined
+ isEqual(cpu, selectedTimeframe?.labels) ? selectedTimeframe?.bounds : undefined
}
setSelectionBounds={bounds => {
onSelectedTimeframe(cpu, bounds);
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index 1d95f8c0dda..2957c96def8 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -738,6 +738,9 @@ importers:
d3-shape:
specifier: ^3.2.0
version: 3.2.0
+ fast-deep-equal:
+ specifier: ^3.1.3
+ version: 3.1.3
framer-motion:
specifier: 6.5.1
version: 6.5.1(react-dom@18.3.1)(react@18.3.1)