Skip to content

Commit

Permalink
Filter data feed table (smartcontractkit#1403)
Browse files Browse the repository at this point in the history
* filter data-feed by category

* pagination wip

* filter eth mainnet table

* add search input

* url sync with search

* update placeholder

* Token terminology update (smartcontractkit#1414)

* Vrf v2 cost calculator (smartcontractkit#1353)

* Create design of VRF v2 cost calculator

* Add checkbox to have user choose method and compute parameters to compute vrf request cost

* Finalize VRF Cost Calculator

* Fix API url link

* fix API URL issue when calling

* Fix total cost output bugs + Add chain icons next to chain name in dropdown + Solve dropdown issue that didn't show on click when input is filled

* Fix bug when previous data are not refreshed after changing chain and network in calculator

* Fix responsive design issues + Add icons next to network options in dropdown menu + Fix issue where data wre not fetched from API when changing vrf method

* Cost calculator edits

* Refactor rebase issues + Fix issues that make API calls for BNB fail

* Fix issue where gas price input was not taken into account in request cost computation + Add maxCost computation in subscription method depending on gas lane chosen

* Apply design suggestions + Fix gas price that formatted the value before the user finished typing

* Syntax fix

* Add verification gas row in cost table of subscription method + Apply small syntax suggestions

* Edits

* Add Caret svg to dropdown input

* Writer edits

* Lint fix

---------

Co-authored-by: Yacine Benichou <yacine@mb-q1g67f3cp6.lan>
Co-authored-by: Dwight Lyle <dwightjl@gmail.com>

* Fix issue where supported network link did not work for certain netwo… (smartcontractkit#1415)

* Fix issue where supported network link did not work for certain networks + Fix typos

* Edits

* Apply small syntax suggestion

---------

Co-authored-by: Yacine Benichou <yacine@mb-q1g67f3cp6.lan>

* fix tsconfig.json errors in vscode (smartcontractkit#1416)

* fix tsconfig.json errors in vscode

* fix compile errors in solana pricefeeds off-chain-read.ts

* Vrf v2 cost calculator (smartcontractkit#1418)

* Create design of VRF v2 cost calculator

* Finalize VRF Cost Calculator

* Fix total cost output bugs + Add chain icons next to chain name in dropdown + Solve dropdown issue that didn't show on click when input is filled

* Fix responsive design issues + Add icons next to network options in dropdown menu + Fix issue where data wre not fetched from API when changing vrf method

* Cost calculator edits

* Refactor rebase issues + Fix issues that make API calls for BNB fail

* Fix Arbitrum computation issue by adding LINK Premium and price feed + Add L1 Gas Price input field to table when network is Arbitrum

* Fix API url + edits

* Fix issue when L1 gas price estimate could be undefined when switching networks

* Writer edits

---------

Co-authored-by: Yacine Benichou <yacine@mb-q1g67f3cp6.lan>
Co-authored-by: Dwight Lyle <dwightjl@gmail.com>

* add query parameters

* close dropdown on click outside

* flexible search box

* reset search and categories on network select

* typecheck

* fix queryString usage

---------

Co-authored-by: Dwight Lyle <dwightjl@gmail.com>
Co-authored-by: yacine-benichou <78235417+yacine-benichou@users.noreply.github.com>
Co-authored-by: Yacine Benichou <yacine@mb-q1g67f3cp6.lan>
Co-authored-by: Amine E <aelmanaa@users.noreply.github.com>
  • Loading branch information
5 people authored and dorianbayart committed Dec 25, 2023
1 parent c3e35bd commit 0c5e840
Show file tree
Hide file tree
Showing 7 changed files with 388 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/features/data/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface Docs {
feedType?: string
hidden?: boolean
porAuditor?: string
porSource?: string
porType?: string
productSubType?: string
productType?: string
Expand Down
103 changes: 103 additions & 0 deletions src/features/feeds/components/FeedList.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,106 @@ div.shutDate > hr {
height: 32px;
transition: all 0.15s;
}

.filterDropdown_details {
position: relative;
cursor: pointer;
display: block;
margin: var(--space-0x) var(--space-2x) var(--space-2x) var(--space-6x);
margin-left: 0px;
width: 200px;
display: inline-block;
line-height: 0;
}

.filterDropdown_search {
display: inline-block;
padding: var(--space-2x) var(--space-4x) var(--space-2x) var(--space-2x);
position: relative;
}
.filterDropdown_searchInput {
height: 42px;
width: 200px;
border: var(--border-width-primary) solid var(--color-border-primary);
background-image: url(https://smartcontract.imgix.net/icons/searchIcon_blue_noborder.svg?auto=compress%2Cformat);
background-repeat: no-repeat;
background-position: left var(--space-2x) top 50%;
padding-left: var(--space-8x);
background-size: 16px;
}
.detailsLabel {
display: inline;
}

@media screen and (max-width: 450px) {
.filterDropdown_details,
.filterDropdown_search {
padding-left: 0px;
padding-top: 1px;
}
}

@media screen and (max-width: 450px) {
.detailsLabel {
display: block;
padding: 1px;
}
}

.filterDropdown_details summary {
color: var(--gray-900);
width: 100%;
padding: var(--space-3x) var(--space-3x) var(--space-3x) var(--space-4x);
border: var(--border-width-primary) solid var(--color-border-primary);
border-radius: var(--border-radius-primary);
background-image: url(https://smartcontract.imgix.net/icons/Caret.svg?auto=compress%2Cformat);
background-repeat: no-repeat;
background-position: right var(--space-2x) top 50%;
list-style: none;
}

.filterDropdown_details nav {
position: absolute;
border-radius: var(--border-radius-primary);
background: var(--white);
z-index: 1;
margin-top: var(--space-2x);
min-width: 165px;
width: 100%;
box-shadow: var(--shadow-mid-secondary);
border: var(--border-width-primary) solid var(--color-border-primary);
}
.filterDropdown_details ul {
list-style: none;
max-height: 280px;
overflow-y: scroll;
padding: 0 var(--space-2x);
}
.filterDropdown_details li button {
display: flex;
align-items: center;
justify-content: flex-start;
color: var(--color-text-primary);
-webkit-font-feature-settings: "liga" off;
font-feature-settings: "liga" off;
text-align: left;
text-decoration: none;
cursor: pointer;
white-space: nowrap;
padding: var(--space-4x) var(--space-2x);
margin: 0;
width: 100%;
}
.filterDropdown_details li button input {
width: auto;
margin-right: var(--space-2x);
}
.filterDropdown_details li button:hover {
color: var(--color-text-link-hover);
fill: var(--color-text-link-hover);
background-color: var(--blue-100);
font-weight: 500;
}
.filterDropdown_filter {
padding: var(--space-3x) var(--space-4x) var(--space-5x) var(--space-4x);
}
111 changes: 107 additions & 4 deletions src/features/feeds/components/FeedList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @jsxImportSource preact */
import { useEffect, useState } from "preact/hooks"
import { useEffect, useState, useRef } from "preact/hooks"
import { MainnetTable, TestnetTable } from "./Tables"
import feedList from "./FeedList.module.css"
import { clsx } from "~/lib"
Expand All @@ -8,6 +8,7 @@ import { Chain, CHAINS, ALL_CHAINS } from "~/features/data/chains"
import { useGetChainMetadata } from "./useGetChainMetadata"
import { ChainMetadata } from "../../data/api"
import useQueryString from "~/hooks/useQueryString"
import { RefObject } from "preact"

export type DataFeedType = "default" | "por" | "nftFloor" | "rates"
export const FeedList = ({
Expand All @@ -23,18 +24,68 @@ export const FeedList = ({
const chains = ecosystem === "deprecating" ? ALL_CHAINS : CHAINS

const [selectedChain, setSelectedChain] = useQueryString("network", chains[0].page)
const [searchValue, setSearchValue] = useQueryString("search", "")
const [selectedFeedCategories, setSelectedFeedCategories] = useQueryString("categories", [])
const [showCategoriesDropdown, setShowCategoriesDropdown] = useState<boolean>(false)
const [showExtraDetails, setShowExtraDetails] = useState(false)

const [currentPage, setCurrentPage] = useQueryString("page", "1")
const paginate = (pageNumber) => setCurrentPage(String(pageNumber))
const addrPerPage = 8
const lastAddr = Number(currentPage) * addrPerPage
const firstAddr = lastAddr - addrPerPage
const dataFeedCategory = ["verified", "monitored", "provisional", "custom", "specialized", "deprecating"]
const chainMetadata = useGetChainMetadata(chains.filter((chain) => chain.page === selectedChain)[0], { initialCache })
const wrapperRef = useRef(null)

function handleNetworkSelect(chain: Chain) {
setSelectedChain(chain.page)
setSearchValue("")
setSelectedFeedCategories([])
setCurrentPage("1")
}

const handleCategorySelection = (category) => {
paginate(1)
if (typeof selectedFeedCategories === "string" && selectedFeedCategories !== category) {
setSelectedFeedCategories([selectedFeedCategories, category])
} else if (typeof selectedFeedCategories === "string" && selectedFeedCategories === category) {
setSelectedFeedCategories([])
}
if (Array.isArray(selectedFeedCategories) && selectedFeedCategories.includes(category)) {
setSelectedFeedCategories(selectedFeedCategories.filter((item) => item !== category))
} else if (Array.isArray(selectedFeedCategories)) {
setSelectedFeedCategories([...selectedFeedCategories, category])
}
}

useEffect(() => {
updateTableOfContents()
}, [chainMetadata.processedData])
if (searchValue === "") {
const searchParams = new URLSearchParams(window.location.search)
searchParams.delete("search")
const newUrl = window.location.pathname + "?" + searchParams.toString()
window.history.replaceState({ path: newUrl }, "", newUrl)
const inputElement = document.getElementById("search") as HTMLInputElement
if (inputElement) {
inputElement.placeholder = "Search price feeds"
}
}
}, [chainMetadata.processedData, searchValue])

const useOutsideAlerter = (ref: RefObject<HTMLDivElement>) => {
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (ref.current && event.target instanceof Node && !ref.current.contains(event.target)) {
setShowCategoriesDropdown(false)
}
}
document.addEventListener("mousedown", handleClickOutside)
return () => {
document.removeEventListener("mousedown", handleClickOutside)
}
}, [ref])
}
useOutsideAlerter(wrapperRef)
const isPor = dataFeedType === "por"
const isNftFloor = dataFeedType === "nftFloor"
const isRates = dataFeedType === "rates"
Expand Down Expand Up @@ -128,7 +179,46 @@ export const FeedList = ({
<a href="/docs/data-feeds/l2-sequencer-feeds/">L2 Sequencer Uptime Feeds</a> page for examples.
</p>
)}
<label>

<details class={feedList.filterDropdown_details}>
<summary
class={feedList.filterDropdown_details}
className="text-200"
onClick={() => setShowCategoriesDropdown((prev) => !prev)}
>
Data Feed Categories
</summary>
<nav ref={wrapperRef} style={!showCategoriesDropdown ? { display: "none" } : {}}>
<ul>
{dataFeedCategory.map((category) => (
<li>
<button onClick={() => handleCategorySelection(category)}>
<input
type="checkbox"
checked={selectedFeedCategories?.includes(category)}
readonly
style="cursor:pointer;"
/>
<span> {category}</span>
</button>
</li>
))}
</ul>
</nav>
</details>

<div class={feedList.filterDropdown_search}>
<input
id="search"
class={feedList.filterDropdown_searchInput}
placeholder="Search price feeds"
onInput={(event) => {
setSearchValue((event.target as HTMLInputElement).value)
setCurrentPage("1")
}}
/>
</div>
<label class={feedList.detailsLabel}>
<input
type="checkbox"
style="width:15px;height:15px;display:inline;"
Expand All @@ -138,10 +228,23 @@ export const FeedList = ({
Show more details
</label>
<MainnetTable
selectedFeedCategories={
Array.isArray(selectedFeedCategories)
? selectedFeedCategories
: selectedFeedCategories
? [selectedFeedCategories]
: []
}
network={network}
showExtraDetails={showExtraDetails}
dataFeedType={dataFeedType}
ecosystem={ecosystem}
lastAddr={lastAddr}
firstAddr={firstAddr}
addrPerPage={addrPerPage}
currentPage={Number(currentPage)}
paginate={paginate}
searchValue={typeof searchValue === "string" ? searchValue : ""}
/>
</div>
) : (
Expand Down
55 changes: 54 additions & 1 deletion src/features/feeds/components/Tables.module.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
.table th[aria-hidden="true"],
.table td[aria-hidden="true"] {
.table td[aria-hidden="true"],
.mainnetTable th[aria-hidden="true"],
.mainnetTable td[aria-hidden="true"] {
display: none;
}

.mainnetTable {
table-layout: auto;
width: 100%;
overflowx: auto;
}

.mainnetTable th:nth-child(1),
.mainnetTable td:nth-child(1) {
width: 150px;
}

.mainnetTable th:nth-child(2),
.mainnetTable td:nth-child(2) {
width: 80px;
}
.mainnetTable th:nth-child(3),
.mainnetTable td:nth-child(3) {
width: 80px;
}
.mainnetTable th:nth-child(4),
.mainnetTable td:nth-child(4) {
width: 50px;
}

.heading {
font-family: var(--font-family-text);
line-height: 1.3;
Expand Down Expand Up @@ -48,3 +74,30 @@
align-items: center;
gap: var(--space-1x);
}

.pagination {
display: flex;
margin: 8px 0px 0px;
flex-wrap: wrap;
justify-content: space-between;
padding: 4px;
}

@media screen and (max-width: 500px) {
.pagination {
margin-top: 10px;
margin-bottom: 10px;
}
}

.pagination p {
text-align: center;
margin: 8px 0px 0px;
}

@media screen and (max-width: 500px) {
.pagination p {
order: 1;
width: 100%;
}
}
Loading

0 comments on commit 0c5e840

Please sign in to comment.