Skip to content

Commit 8c551eb

Browse files
authored
Merge pull request #2398 from pyth-network/cprussin/ui-52-add-asset-class-to-publisher-feeds-table
feat(insights): add asset class to publisher's price feeds table
2 parents 6cc9b77 + daa8ef2 commit 8c551eb

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

apps/insights/src/components/PriceComponentsCard/index.tsx

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Select } from "@pythnetwork/component-library/Select";
1010
import { SingleToggleGroup } from "@pythnetwork/component-library/SingleToggleGroup";
1111
import {
1212
type RowConfig,
13+
type ColumnConfig,
1314
type SortDescriptor,
1415
Table,
1516
} from "@pythnetwork/component-library/Table";
@@ -37,7 +38,7 @@ import { Status as StatusComponent } from "../Status";
3738

3839
const SCORE_WIDTH = 32;
3940

40-
type Props<T extends PriceComponent> = {
41+
type Props<U extends string, T extends PriceComponent & Record<U, unknown>> = {
4142
className?: string | undefined;
4243
priceComponents: T[];
4344
metricsTime?: Date | undefined;
@@ -47,6 +48,8 @@ type Props<T extends PriceComponent> = {
4748
onPriceComponentAction: (component: T) => void;
4849
toolbarExtra?: ReactNode;
4950
assetClass?: string | undefined;
51+
extraColumns?: ColumnConfig<U>[] | undefined;
52+
nameWidth?: number | undefined;
5053
};
5154

5255
type PriceComponent = {
@@ -63,11 +66,14 @@ type PriceComponent = {
6366
nameAsString: string;
6467
};
6568

66-
export const PriceComponentsCard = <T extends PriceComponent>({
69+
export const PriceComponentsCard = <
70+
U extends string,
71+
T extends PriceComponent & Record<U, unknown>,
72+
>({
6773
priceComponents,
6874
onPriceComponentAction,
6975
...props
70-
}: Props<T>) => (
76+
}: Props<U, T>) => (
7177
<Suspense fallback={<PriceComponentsCardContents isLoading {...props} />}>
7278
<ResolvedPriceComponentsCard
7379
priceComponents={priceComponents}
@@ -77,11 +83,14 @@ export const PriceComponentsCard = <T extends PriceComponent>({
7783
</Suspense>
7884
);
7985

80-
export const ResolvedPriceComponentsCard = <T extends PriceComponent>({
86+
export const ResolvedPriceComponentsCard = <
87+
U extends string,
88+
T extends PriceComponent & Record<U, unknown>,
89+
>({
8190
priceComponents,
8291
onPriceComponentAction,
8392
...props
84-
}: Props<T>) => {
93+
}: Props<U, T>) => {
8594
const logger = useLogger();
8695
const collator = useCollator();
8796
const filter = useFilter({ sensitivity: "base", usage: "search" });
@@ -174,6 +183,12 @@ export const ResolvedPriceComponentsCard = <T extends PriceComponent>({
174183
id: component.id,
175184
data: {
176185
name: component.name,
186+
...Object.fromEntries(
187+
props.extraColumns?.map((column) => [
188+
column.id,
189+
component[column.id],
190+
]) ?? [],
191+
),
177192
...(showQuality
178193
? {
179194
score: component.score !== undefined && (
@@ -228,7 +243,7 @@ export const ResolvedPriceComponentsCard = <T extends PriceComponent>({
228243
onPriceComponentAction(component);
229244
},
230245
})),
231-
[paginatedItems, showQuality, onPriceComponentAction],
246+
[paginatedItems, showQuality, onPriceComponentAction, props.extraColumns],
232247
);
233248

234249
const updateStatus = useCallback(
@@ -273,15 +288,20 @@ export const ResolvedPriceComponentsCard = <T extends PriceComponent>({
273288
);
274289
};
275290

276-
type PriceComponentsCardProps<T extends PriceComponent> = Pick<
277-
Props<T>,
291+
type PriceComponentsCardProps<
292+
U extends string,
293+
T extends PriceComponent & Record<U, unknown>,
294+
> = Pick<
295+
Props<U, T>,
278296
| "className"
279297
| "metricsTime"
280298
| "nameLoadingSkeleton"
281299
| "label"
282300
| "searchPlaceholder"
283301
| "toolbarExtra"
284302
| "assetClass"
303+
| "extraColumns"
304+
| "nameWidth"
285305
> &
286306
(
287307
| { isLoading: true }
@@ -306,15 +326,20 @@ type PriceComponentsCardProps<T extends PriceComponent> = Pick<
306326
}
307327
);
308328

309-
export const PriceComponentsCardContents = <T extends PriceComponent>({
329+
export const PriceComponentsCardContents = <
330+
U extends string,
331+
T extends PriceComponent & Record<U, unknown>,
332+
>({
310333
className,
311334
metricsTime,
312335
nameLoadingSkeleton,
313336
label,
314337
searchPlaceholder,
315338
toolbarExtra,
339+
extraColumns,
340+
nameWidth,
316341
...props
317-
}: PriceComponentsCardProps<T>) => {
342+
}: PriceComponentsCardProps<U, T>) => {
318343
const collator = useCollator();
319344
return (
320345
<Card
@@ -408,7 +433,9 @@ export const PriceComponentsCardContents = <T extends PriceComponent>({
408433
isRowHeader: true,
409434
loadingSkeleton: nameLoadingSkeleton,
410435
allowsSorting: true,
436+
...(nameWidth !== undefined && { width: nameWidth }),
411437
},
438+
...(extraColumns ?? []),
412439
...otherColumns(props),
413440
{
414441
id: "status",

apps/insights/src/components/Publisher/price-feeds-card.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { type ComponentProps, useCallback } from "react";
55
import { useSelectPriceFeed } from "./price-feed-drawer-provider";
66
import { usePriceFeeds } from "../../hooks/use-price-feeds";
77
import type { Cluster } from "../../services/pyth";
8+
import { AssetClassTag } from "../AssetClassTag";
89
import { PriceComponentsCard } from "../PriceComponentsCard";
910
import { PriceFeedTag } from "../PriceFeedTag";
1011

@@ -37,6 +38,15 @@ export const PriceFeedsCard = ({
3738
return (
3839
<PriceComponentsCard
3940
onPriceComponentAction={onPriceComponentAction}
41+
extraColumns={[
42+
{
43+
id: "assetClass",
44+
name: "ASSET CLASS",
45+
alignment: "left",
46+
allowsSorting: true,
47+
},
48+
]}
49+
nameWidth={90}
4050
priceComponents={priceFeeds.map((feed) => {
4151
const contextFeed = feeds.get(feed.symbol);
4252
if (contextFeed) {
@@ -53,6 +63,7 @@ export const PriceFeedsCard = ({
5363
publisherKey,
5464
name: <PriceFeedTag compact symbol={feed.symbol} />,
5565
nameAsString: contextFeed.displaySymbol,
66+
assetClass: <AssetClassTag symbol={feed.symbol} />,
5667
};
5768
} else {
5869
throw new NoSuchFeedError(feed.symbol);

0 commit comments

Comments
 (0)