reference-data.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. "use client";
  2. import { Table } from "@pythnetwork/component-library/Table";
  3. import { useMemo } from "react";
  4. import { useCollator } from "react-aria";
  5. import styles from "./reference-data.module.scss";
  6. import { Cluster } from "../../services/pyth";
  7. import { AssetClassBadge } from "../AssetClassBadge";
  8. import { LiveValue } from "../LivePrices";
  9. type Props = {
  10. feed: {
  11. symbol: string;
  12. feedKey: string;
  13. assetClass: string;
  14. base?: string | undefined;
  15. description: string;
  16. country?: string | undefined;
  17. quoteCurrency?: string | undefined;
  18. tenor?: string | undefined;
  19. cmsSymbol?: string | undefined;
  20. cqsSymbol?: string | undefined;
  21. nasdaqSymbol?: string | undefined;
  22. genericSymbol?: string | undefined;
  23. weeklySchedule?: string | undefined;
  24. schedule?: string | undefined;
  25. contractId?: string | undefined;
  26. displaySymbol: string;
  27. exponent: number;
  28. numComponentPrices: number;
  29. numQuoters: number;
  30. minPublishers: number;
  31. lastSlot: bigint;
  32. validSlot: bigint;
  33. };
  34. };
  35. export const ReferenceData = ({ feed }: Props) => {
  36. const collator = useCollator();
  37. const rows = useMemo(
  38. () =>
  39. [
  40. ...Object.entries({
  41. "Asset Type": <AssetClassBadge>{feed.assetClass}</AssetClassBadge>,
  42. Base: feed.base,
  43. Description: feed.description,
  44. Symbol: feed.symbol,
  45. Country: feed.country,
  46. "Quote Currency": feed.quoteCurrency,
  47. Tenor: feed.tenor,
  48. "CMS Symbol": feed.cmsSymbol,
  49. "CQS Symbol": feed.cqsSymbol,
  50. "NASDAQ Symbol": feed.nasdaqSymbol,
  51. "Generic Symbol": feed.genericSymbol,
  52. "Weekly Schedule": feed.weeklySchedule,
  53. Schedule: feed.schedule,
  54. "Contract ID": feed.contractId,
  55. "Display Symbol": feed.displaySymbol,
  56. }),
  57. ...Object.entries({
  58. Exponent: "exponent",
  59. "Price Components": "numComponentPrices",
  60. "Price Quoters": "numQuoters",
  61. "Minimum Publishers": "minPublishers",
  62. "Last Slot": "lastSlot",
  63. "Valid Slot": "validSlot",
  64. } as const).map(
  65. ([key, value]) =>
  66. [
  67. key,
  68. <span key={key} className={styles.value}>
  69. <LiveValue
  70. feedKey={feed.feedKey}
  71. field={value}
  72. defaultValue={feed[value]}
  73. cluster={Cluster.Pythnet}
  74. />
  75. </span>,
  76. ] as const,
  77. ),
  78. ]
  79. .map(([field, value]) =>
  80. value === undefined ? undefined : ([field, value] as const),
  81. )
  82. .filter((entry) => entry !== undefined)
  83. .sort(([a], [b]) => collator.compare(a, b))
  84. .map(([field, value]) => ({
  85. id: field,
  86. data: {
  87. field: <span className={styles.field}>{field}</span>,
  88. value:
  89. typeof value === "string" ? (
  90. <span className={styles.value}>{value}</span>
  91. ) : (
  92. value
  93. ),
  94. },
  95. })),
  96. [collator, feed],
  97. );
  98. return (
  99. <Table
  100. label="Reference Data"
  101. fill
  102. stickyHeader
  103. className={styles.referenceData ?? ""}
  104. columns={[
  105. {
  106. id: "field",
  107. name: "Field",
  108. alignment: "left",
  109. isRowHeader: true,
  110. sticky: true,
  111. },
  112. { id: "value", name: "Value", fill: true, alignment: "left" },
  113. ]}
  114. rows={rows}
  115. />
  116. );
  117. };