Skip to content

Commit 26e9d9f

Browse files
authored
Merge pull request #2211 from pyth-network/cprussin/add-test-feed-toggle
feat(insights): add a toggle to include test price components
2 parents 68c1b81 + 882fb38 commit 26e9d9f

File tree

16 files changed

+275
-521
lines changed

16 files changed

+275
-521
lines changed

apps/insights/src/components/PriceFeed/price-components-card.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import { Card } from "@pythnetwork/component-library/Card";
44
import { Paginator } from "@pythnetwork/component-library/Paginator";
5+
import { Switch } from "@pythnetwork/component-library/Switch";
56
import {
67
type RowConfig,
78
type SortDescriptor,
89
Table,
910
} from "@pythnetwork/component-library/Table";
10-
import { type ReactNode, Suspense, useMemo } from "react";
11+
import { type ReactNode, Suspense, useMemo, useState } from "react";
1112
import { useFilter, useCollator } from "react-aria";
1213

1314
import { useQueryParamFilterPagination } from "../../use-query-param-filter-pagination";
@@ -33,6 +34,7 @@ type PriceComponent = {
3334
deviationScore: number;
3435
stalledPenalty: number;
3536
stalledScore: number;
37+
isTest: boolean;
3638
};
3739

3840
export const PriceComponentsCard = ({
@@ -56,6 +58,16 @@ const ResolvedPriceComponentsCard = ({
5658
}: Props) => {
5759
const collator = useCollator();
5860
const filter = useFilter({ sensitivity: "base", usage: "search" });
61+
const [includeTestComponents, setIncludeTestComponents] = useState(false);
62+
63+
const filteredPriceComponents = useMemo(
64+
() =>
65+
includeTestComponents
66+
? priceComponents
67+
: priceComponents.filter((component) => !component.isTest),
68+
[includeTestComponents, priceComponents],
69+
);
70+
5971
const {
6072
search,
6173
sortDescriptor,
@@ -70,7 +82,7 @@ const ResolvedPriceComponentsCard = ({
7082
numPages,
7183
mkPageLink,
7284
} = useQueryParamFilterPagination(
73-
priceComponents,
85+
filteredPriceComponents,
7486
(priceComponent, search) =>
7587
filter.contains(priceComponent.id, search) ||
7688
(priceComponent.publisherNameAsString !== undefined &&
@@ -181,6 +193,8 @@ const ResolvedPriceComponentsCard = ({
181193

182194
return (
183195
<PriceComponentsCardContents
196+
includeTestComponents={includeTestComponents}
197+
setIncludeTestComponents={setIncludeTestComponents}
184198
numResults={numResults}
185199
search={search}
186200
sortDescriptor={sortDescriptor}
@@ -206,6 +220,8 @@ type PriceComponentsCardProps = Pick<
206220
| { isLoading: true }
207221
| {
208222
isLoading?: false;
223+
includeTestComponents: boolean;
224+
setIncludeTestComponents: (newValue: boolean) => void;
209225
numResults: number;
210226
search: string;
211227
sortDescriptor: SortDescriptor;
@@ -237,6 +253,18 @@ const PriceComponentsCardContents = ({
237253
<Card
238254
className={className}
239255
title="Price components"
256+
toolbar={
257+
<Switch
258+
{...(props.isLoading
259+
? { isPending: true }
260+
: {
261+
isSelected: props.includeTestComponents,
262+
onChange: props.setIncludeTestComponents,
263+
})}
264+
>
265+
Show test components
266+
</Switch>
267+
}
240268
{...(!props.isLoading && {
241269
footer: (
242270
<Paginator

apps/insights/src/components/PriceFeed/price-components.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const PriceComponents = async ({ children, params }: Props) => {
3131
id: ranking.publisher,
3232
publisherNameAsString: lookupPublisher(ranking.publisher)?.name,
3333
score: ranking.final_score,
34+
isTest: ranking.cluster === "pythtest-conformance",
3435
name: (
3536
<div className={styles.publisherName}>
3637
<PublisherTag publisherKey={ranking.publisher} />

apps/insights/src/components/PriceFeed/price-feed-select.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
border-color 100ms linear,
8787
outline-color 100ms linear,
8888
color 100ms linear;
89+
background-color: transparent;
8990

9091
&[data-hovered] {
9192
border-color: theme.color("forms", "input", "hover", "border");

apps/insights/src/components/PriceFeed/price-feed-select.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@ import {
1212
ListBoxItem,
1313
} from "@pythnetwork/component-library/unstyled/ListBox";
1414
import { Popover } from "@pythnetwork/component-library/unstyled/Popover";
15+
import { SearchField } from "@pythnetwork/component-library/unstyled/SearchField";
1516
import { Select } from "@pythnetwork/component-library/unstyled/Select";
16-
import {
17-
TextField,
18-
Input,
19-
} from "@pythnetwork/component-library/unstyled/TextField";
17+
import { Input } from "@pythnetwork/component-library/unstyled/TextField";
2018
import { type ReactNode, useMemo, useState } from "react";
2119
import { useCollator, useFilter } from "react-aria";
2220

@@ -66,7 +64,7 @@ export const PriceFeedSelect = ({ children, feeds }: Props) => {
6664
</Button>
6765
<Popover placement="bottom start" className={styles.popover ?? ""}>
6866
<Dialog aria-label="Price Feeds" className={styles.dialog ?? ""}>
69-
<TextField
67+
<SearchField
7068
value={search}
7169
onChange={setSearch}
7270
className={styles.searchField ?? ""}
@@ -78,7 +76,7 @@ export const PriceFeedSelect = ({ children, feeds }: Props) => {
7876
className={styles.searchInput ?? ""}
7977
placeholder="Symbol, asset class, or key"
8078
/>
81-
</TextField>
79+
</SearchField>
8280
<Virtualizer layout={new ListLayout()}>
8381
<ListBox
8482
items={filteredFeeds}

packages/component-library/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"postcss-loader": "catalog:",
5858
"prettier": "catalog:",
5959
"react": "catalog:",
60+
"react-dom": "catalog:",
6061
"sass": "catalog:",
6162
"sass-loader": "catalog:",
6263
"storybook": "catalog:",

packages/component-library/src/Drawer/index.stories.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ const meta = {
2626
category: "Contents",
2727
},
2828
},
29+
closeHref: {
30+
table: {
31+
disable: true,
32+
},
33+
},
2934
},
3035
} satisfies Meta<typeof DrawerComponent>;
3136
export default meta;

packages/component-library/src/MainNavTabs/index.stories.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ const meta = {
1111
disable: true,
1212
},
1313
},
14+
pathname: {
15+
table: {
16+
disable: true,
17+
},
18+
},
1419
},
1520
} satisfies Meta<typeof MainNavTabsComponent>;
1621
export default meta;

packages/component-library/src/SearchInput/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { MagnifyingGlass } from "@phosphor-icons/react/dist/ssr/MagnifyingGlass"
55
import { XCircle } from "@phosphor-icons/react/dist/ssr/XCircle";
66
import clsx from "clsx";
77
import { type CSSProperties, type ComponentProps } from "react";
8-
import { Input, SearchField } from "react-aria-components";
98

109
import styles from "./index.module.scss";
1110
import { Button } from "../unstyled/Button/index.js";
11+
import { SearchField } from "../unstyled/SearchField/index.js";
12+
import { Input } from "../unstyled/TextField/index.js";
1213

1314
export const SIZES = ["xs", "sm", "md", "lg"] as const;
1415

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
@use "../theme";
2+
3+
.switch {
4+
cursor: pointer;
5+
line-height: theme.spacing(4);
6+
7+
.indicator {
8+
flex: none;
9+
width: theme.spacing(6);
10+
height: theme.spacing(4);
11+
background: theme.color("border");
12+
border-radius: theme.border-radius("2xl");
13+
display: inline-flex;
14+
align-items: center;
15+
padding: 0 theme.spacing(0.5);
16+
margin-right: theme.spacing(2);
17+
justify-content: flex-start;
18+
transition-property: background-color, border-color, outline-color;
19+
transition-duration: 100ms;
20+
transition-timing-function: linear;
21+
border: 1px solid transparent;
22+
outline-offset: 0;
23+
outline: theme.spacing(1) solid transparent;
24+
25+
.dot {
26+
width: theme.spacing(2.5);
27+
height: theme.spacing(2.5);
28+
background-color: theme.color("background", "primary");
29+
border-radius: theme.border-radius("full");
30+
transition: background-color 100ms linear;
31+
}
32+
}
33+
34+
.label {
35+
@include theme.text("sm", "normal");
36+
37+
display: inline-block;
38+
}
39+
40+
&[data-hovered] {
41+
.indicator {
42+
background-color: theme.color("forms", "input", "hover", "border");
43+
}
44+
}
45+
46+
&[data-selected] {
47+
.indicator {
48+
justify-content: flex-end;
49+
background-color: theme.color(
50+
"button",
51+
"primary",
52+
"background",
53+
"normal"
54+
);
55+
}
56+
}
57+
58+
&[data-disabled],
59+
&[data-pending] {
60+
.indicator {
61+
background-color: theme.color("button", "disabled", "background");
62+
63+
.dot {
64+
background-color: theme.color("button", "disabled", "foreground");
65+
}
66+
}
67+
}
68+
69+
&[data-disabled] {
70+
cursor: not-allowed;
71+
}
72+
73+
&[data-pending] {
74+
cursor: wait;
75+
}
76+
77+
&[data-focus-visible] {
78+
.indicator {
79+
border-color: theme.color("focus");
80+
outline-color: theme.color("focus-dim");
81+
}
82+
}
83+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
3+
import { Switch as SwitchComponent } from "./index.js";
4+
5+
const meta = {
6+
component: SwitchComponent,
7+
argTypes: {
8+
isDisabled: {
9+
control: "boolean",
10+
table: {
11+
category: "State",
12+
},
13+
},
14+
isPending: {
15+
control: "boolean",
16+
table: {
17+
category: "State",
18+
},
19+
},
20+
onChange: {
21+
table: {
22+
category: "Behavior",
23+
},
24+
},
25+
children: {
26+
control: "text",
27+
table: {
28+
category: "Label",
29+
},
30+
},
31+
},
32+
} satisfies Meta<typeof SwitchComponent>;
33+
export default meta;
34+
35+
export const Switch = {
36+
args: {
37+
children: "Click me!",
38+
isDisabled: false,
39+
isPending: false,
40+
},
41+
} satisfies StoryObj<typeof SwitchComponent>;

0 commit comments

Comments
 (0)