Преглед на файлове

feat(insights): improve some minor table search UX items

- Fix column widths so they don't change when the table is empty
- Add empty states to some tables that were missing them
- Add more useful search placeholders
Connor Prussin преди 10 месеца
родител
ревизия
b10f5694d0

+ 16 - 6
apps/insights/src/components/PriceFeed/publishers-card.tsx

@@ -18,6 +18,7 @@ import { useFilter, useCollator } from "react-aria";
 import styles from "./publishers-card.module.scss";
 import { useQueryParamFilterPagination } from "../../use-query-param-filter-pagination";
 import { FormattedNumber } from "../FormattedNumber";
+import { NoResults } from "../NoResults";
 import { PublisherTag } from "../PublisherTag";
 import rootStyles from "../Root/index.module.scss";
 import { Score } from "../Score";
@@ -284,7 +285,8 @@ const PriceComponentsCardContents = ({
         </Switch>
         <SearchInput
           size="sm"
-          width={40}
+          width={60}
+          placeholder="Publisher key or name"
           {...(props.isLoading
             ? { isPending: true, isDisabled: true }
             : {
@@ -334,35 +336,35 @@ const PriceComponentsCardContents = ({
           id: "uptimeScore",
           name: "UPTIME SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "deviationScore",
           name: "DEVIATION SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "deviationPenalty",
           name: "DEVIATION PENALTY",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "stalledScore",
           name: "STALLED SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "stalledPenalty",
           name: "STALLED PENALTY",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
       ]}
@@ -372,6 +374,14 @@ const PriceComponentsCardContents = ({
             rows: props.rows,
             sortDescriptor: props.sortDescriptor,
             onSortChange: props.onSortChange,
+            renderEmptyState: () => (
+              <NoResults
+                query={props.search}
+                onClearSearch={() => {
+                  props.onSearchChange("");
+                }}
+              />
+            ),
           })}
     />
   </Card>

+ 18 - 4
apps/insights/src/components/PriceFeeds/coming-soon-list.tsx

@@ -8,6 +8,7 @@ import { type ReactNode, useMemo, useState } from "react";
 import { useCollator, useFilter } from "react-aria";
 
 import styles from "./coming-soon-list.module.scss";
+import { NoResults } from "../NoResults";
 import { PriceFeedTag } from "../PriceFeedTag";
 
 type Props = {
@@ -78,9 +79,10 @@ export const ComingSoonList = ({ comingSoonFeeds }: Props) => {
       <div className={styles.searchBar}>
         <SearchInput
           size="sm"
-          defaultValue={search}
+          value={search}
           onChange={setSearch}
-          width={40}
+          width={50}
+          placeholder="Feed symbol"
         />
         <Select
           optionGroups={[
@@ -104,15 +106,27 @@ export const ComingSoonList = ({ comingSoonFeeds }: Props) => {
         stickyHeader
         label="Coming Soon"
         className={styles.priceFeeds ?? ""}
+        renderEmptyState={() => (
+          <NoResults
+            query={search}
+            onClearSearch={() => {
+              setSearch("");
+            }}
+          />
+        )}
         columns={[
           {
             id: "priceFeedName",
             name: "PRICE FEED",
             isRowHeader: true,
-            fill: true,
             alignment: "left",
           },
-          { id: "assetClass", name: "ASSET CLASS", alignment: "right" },
+          {
+            id: "assetClass",
+            name: "ASSET CLASS",
+            alignment: "right",
+            width: 40,
+          },
         ]}
         rows={rows}
       />

+ 2 - 1
apps/insights/src/components/PriceFeeds/price-feeds-card.tsx

@@ -261,7 +261,8 @@ const PriceFeedsCardContents = ({ id, ...props }: PriceFeedsCardContents) => (
         />
         <SearchInput
           size="sm"
-          width={40}
+          width={50}
+          placeholder="Feed symbol"
           {...(props.isLoading
             ? { isPending: true, isDisabled: true }
             : {

+ 5 - 6
apps/insights/src/components/Publisher/performance.tsx

@@ -51,7 +51,7 @@ export const Performance = async ({ params }: Props) => {
             {
               id: "ranking",
               name: "RANKING",
-              width: 30,
+              width: 25,
             },
             {
               id: "name",
@@ -63,13 +63,13 @@ export const Performance = async ({ params }: Props) => {
               id: "activeFeeds",
               name: "ACTIVE FEEDS",
               alignment: "center",
-              width: 40,
+              width: 30,
             },
             {
               id: "inactiveFeeds",
               name: "INACTIVE FEEDS",
               alignment: "center",
-              width: 45,
+              width: 30,
             },
             {
               id: "medianScore",
@@ -148,20 +148,19 @@ const feedColumns = [
     id: "score" as const,
     name: "SCORE",
     alignment: "left" as const,
-    width: 40,
+    width: PUBLISHER_SCORE_WIDTH,
   },
   {
     id: "asset" as const,
     name: "ASSET",
     isRowHeader: true,
     alignment: "left" as const,
-    fill: true,
   },
   {
     id: "assetClass" as const,
     name: "ASSET CLASS",
     alignment: "right" as const,
-    width: 50,
+    width: 40,
   },
 ];
 

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

@@ -13,6 +13,7 @@ import { useFilter, useCollator } from "react-aria";
 
 import { useQueryParamFilterPagination } from "../../use-query-param-filter-pagination";
 import { FormattedNumber } from "../FormattedNumber";
+import { NoResults } from "../NoResults";
 import { PriceFeedTag } from "../PriceFeedTag";
 import rootStyles from "../Root/index.module.scss";
 import { Score } from "../Score";
@@ -222,7 +223,8 @@ const PriceComponentsCardContents = ({
     toolbar={
       <SearchInput
         size="sm"
-        width={40}
+        width={60}
+        placeholder="Feed symbol"
         {...(props.isLoading
           ? { isPending: true, isDisabled: true }
           : {
@@ -271,35 +273,35 @@ const PriceComponentsCardContents = ({
           id: "uptimeScore",
           name: "UPTIME SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "deviationScore",
           name: "DEVIATION SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "deviationPenalty",
           name: "DEVIATION PENALTY",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "stalledScore",
           name: "STALLED SCORE",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
         {
           id: "stalledPenalty",
           name: "STALLED PENALTY",
           alignment: "center",
-          width: 40,
+          width: 35,
           allowsSorting: true,
         },
       ]}
@@ -309,6 +311,14 @@ const PriceComponentsCardContents = ({
             rows: props.rows,
             sortDescriptor: props.sortDescriptor,
             onSortChange: props.onSortChange,
+            renderEmptyState: () => (
+              <NoResults
+                query={props.search}
+                onClearSearch={() => {
+                  props.onSearchChange("");
+                }}
+              />
+            ),
           })}
     />
   </Card>

+ 5 - 4
apps/insights/src/components/Publishers/publishers-card.tsx

@@ -194,7 +194,8 @@ const PublishersCardContents = ({
     toolbar={
       <SearchInput
         size="sm"
-        width={40}
+        width={60}
+        placeholder="Publisher key or name"
         {...(props.isLoading
           ? { isPending: true, isDisabled: true }
           : {
@@ -226,7 +227,7 @@ const PublishersCardContents = ({
         {
           id: "ranking",
           name: "RANKING",
-          width: 30,
+          width: 25,
           loadingSkeleton: <Ranking isLoading />,
           allowsSorting: true,
         },
@@ -242,14 +243,14 @@ const PublishersCardContents = ({
           id: "activeFeeds",
           name: "ACTIVE FEEDS",
           alignment: "center",
-          width: 40,
+          width: 30,
           allowsSorting: true,
         },
         {
           id: "inactiveFeeds",
           name: "INACTIVE FEEDS",
           alignment: "center",
-          width: 45,
+          width: 30,
           allowsSorting: true,
         },
         {

+ 3 - 1
packages/component-library/src/SearchInput/index.tsx

@@ -18,6 +18,7 @@ type Props = ComponentProps<typeof SearchField> & {
   size?: (typeof SIZES)[number] | undefined;
   width: number;
   isPending?: boolean | undefined;
+  placeholder?: string;
 };
 
 export const SearchInput = ({
@@ -26,6 +27,7 @@ export const SearchInput = ({
   width,
   className,
   isPending,
+  placeholder = "Search",
   ...props
 }: Props) => (
   <SearchField
@@ -36,7 +38,7 @@ export const SearchInput = ({
     {...(isPending && { "data-pending": "" })}
     {...props}
   >
-    <Input className={styles.input ?? ""} placeholder="Search" />
+    <Input className={styles.input ?? ""} placeholder={placeholder} />
     <MagnifyingGlass className={styles.searchIcon} />
     <CircleNotch className={styles.loadingIcon} />
     <Button className={styles.clearButton ?? ""}>

+ 1 - 1
packages/component-library/src/Table/index.module.scss

@@ -43,7 +43,7 @@
       white-space: nowrap;
       border: 0;
       outline: theme.spacing(0.5) solid transparent;
-      width: calc(theme.spacing(1) * var(--width));
+      width: calc((theme.spacing(1) * var(--width)) + theme.spacing(8));
       outline-offset: -#{theme.spacing(0.5)};
       background-color: theme.color("background", "primary");
       transition: outline-color 100ms linear;