From 2f2d3af7982165975b8d55b105914c0ac3f74031 Mon Sep 17 00:00:00 2001 From: Nicholas Barnett Date: Mon, 28 Oct 2024 13:43:10 -0500 Subject: [PATCH] feat: wp --- .../time-filter/DateInputRangeForm.tsx | 16 - .../_components/time-filter/TimeFilter.tsx | 628 +++++++++--------- src/app/signers/CycleFilter.tsx | 51 +- src/app/signers/SignersTable.tsx | 82 ++- src/app/signers/consts.ts | 11 +- src/common/components/Section.tsx | 5 +- 6 files changed, 400 insertions(+), 393 deletions(-) diff --git a/src/app/_components/time-filter/DateInputRangeForm.tsx b/src/app/_components/time-filter/DateInputRangeForm.tsx index 1b0d3068c..5ce4b33f9 100644 --- a/src/app/_components/time-filter/DateInputRangeForm.tsx +++ b/src/app/_components/time-filter/DateInputRangeForm.tsx @@ -63,14 +63,6 @@ export function DateInputRangeForm({ onChange={handleChange} placeholder={startPlaceholder} type={type} - // name="value" - // type={type} - // placeholder={startPlaceholder} - // value={form.values.startDate} - // onChange={e => { - // form.setFieldValue('startDate', e.target.value); - // }} - // {...field} /> )} @@ -85,14 +77,6 @@ export function DateInputRangeForm({ onChange={handleChange} placeholder={endPlaceholder} type={type} - // name="end" - // type={type} - // placeholder={endPlaceholder} - // value={form.values.endDate} - // onChange={e => { - // form.setFieldValue('endDate', e.target.value); - // }} - // {...field} /> )} diff --git a/src/app/_components/time-filter/TimeFilter.tsx b/src/app/_components/time-filter/TimeFilter.tsx index ff1ef8603..1ca44c8d7 100644 --- a/src/app/_components/time-filter/TimeFilter.tsx +++ b/src/app/_components/time-filter/TimeFilter.tsx @@ -1,338 +1,338 @@ -import { Stack } from '@/ui/Stack'; -import { useColorModeValue } from '@chakra-ui/react'; -import { CaretDown } from '@phosphor-icons/react'; -import { ReactNode, useEffect, useMemo, useState } from 'react'; +// import { Stack } from '@/ui/Stack'; +// import { useColorModeValue } from '@chakra-ui/react'; +// import { CaretDown } from '@phosphor-icons/react'; +// import { ReactNode, useEffect, useMemo, useState } from 'react'; -import { Badge } from '../../../common/components/Badge'; -import { Button } from '../../../ui/Button'; -import { Flex } from '../../../ui/Flex'; -import { Icon } from '../../../ui/Icon'; -import { Popover } from '../../../ui/Popover'; -import { PopoverContent } from '../../../ui/PopoverContent'; -import { PopoverTrigger } from '../../../ui/PopoverTrigger'; -import { Text } from '../../../ui/Text'; -import { useDisclosure } from '../../../ui/hooks/useDisclosure'; -import { DateInputForm, DateInputFormValues } from './DateInputForm'; -import { DateInputRangeForm, DateInputRangeFormValues } from './DateInputRangeForm'; -import { DatePickerForm, DatePickerFormValues } from './DatePickerForm'; -import { DatePickerRangeForm, DatePickerRangeFormValues } from './DatePickerRangeForm'; +// import { Badge } from '../../../common/components/Badge'; +// import { Button } from '../../../ui/Button'; +// import { Flex } from '../../../ui/Flex'; +// import { Icon } from '../../../ui/Icon'; +// import { Popover } from '../../../ui/Popover'; +// import { PopoverContent } from '../../../ui/PopoverContent'; +// import { PopoverTrigger } from '../../../ui/PopoverTrigger'; +// import { Text } from '../../../ui/Text'; +// import { useDisclosure } from '../../../ui/hooks/useDisclosure'; +// import { DateInputForm, DateInputFormValues } from './DateInputForm'; +// import { DateInputRangeForm, DateInputRangeFormValues } from './DateInputRangeForm'; +// import { DatePickerForm, DatePickerFormValues } from './DatePickerForm'; +// import { DatePickerRangeForm, DatePickerRangeFormValues } from './DatePickerRangeForm'; -const cyclefilterToFormattedValueMap: Record string> = { - endTime: (value: string) => value, - startTime: (value: string) => value, -}; +// const cyclefilterToFormattedValueMap: Record string> = { +// endTime: (value: string) => value, +// startTime: (value: string) => value, +// }; -// endTime: formatTimestamp, -// startTime: formatTimestamp, +// // endTime: formatTimestamp, +// // startTime: formatTimestamp, -type TimeFilterType = 'range' | 'before' | 'after' | 'on' | null; +// type TimeFilterType = 'range' | 'before' | 'after' | 'on' | null; -type filterToFormattedValueMap = {}; +// type filterToFormattedValueMap = {}; -function FilterTypeButton({ - // TODO: move to separate file - isSelected, - setSelected, - children, -}: { - isSelected?: boolean; - setSelected?: () => void; - children: ReactNode; -}) { - const purpleBadgeColor = useColorModeValue('purple.600', 'purple.300'); - const purpleBadgeBg = useColorModeValue('purple.100', 'purple.900'); - const badgeBorder = useColorModeValue('purple.300', 'purple.700'); +// function FilterTypeButton({ +// // TODO: move to separate file +// isSelected, +// setSelected, +// children, +// }: { +// isSelected?: boolean; +// setSelected?: () => void; +// children: ReactNode; +// }) { +// const purpleBadgeColor = useColorModeValue('purple.600', 'purple.300'); +// const purpleBadgeBg = useColorModeValue('purple.100', 'purple.900'); +// const badgeBorder = useColorModeValue('purple.300', 'purple.700'); - return ( - - {children} - - ); -} - -interface DateFilterProps { - defaultStartTime?: string; - defaultEndTime?: string; - defaultOnTime?: string; - hasRange?: boolean; - hasBefore?: boolean; - hasAfter?: boolean; - hasOn?: boolean; - formatOn?: (value: string) => string; - formatBefore?: (value: string) => string; - formatAfter?: (value: string) => string; - datePickerRangeOnSubmit?: (values: DatePickerRangeFormValues) => void; - dateInputRangeOnSubmit?: (values: DateInputRangeFormValues) => void; - datePickerOnSubmit?: (values: DatePickerFormValues) => void; - dateInputOnSubmit?: (values: DateInputFormValues) => void; - beforeOnSubmit?: (values: DateInputFormValues) => void; - afterOnSubmit?: (values: DateInputFormValues) => void; - onOnSubmit?: (values: DateInputFormValues) => void; - rangeOnSubmit?: (values: DateInputRangeFormValues) => void; - formType: TimeFilterFormType; - defaultButtonText?: string; -} +// return ( +// +// {children} +// +// ); +// } -type TimeFilterFormType = 'date-picker' | 'input'; +// interface DateFilterProps { +// defaultStartTime?: string; +// defaultEndTime?: string; +// defaultOnTime?: string; +// hasRange?: boolean; +// hasBefore?: boolean; +// hasAfter?: boolean; +// hasOn?: boolean; +// formatOn?: (value: string) => string; +// formatBefore?: (value: string) => string; +// formatAfter?: (value: string) => string; +// datePickerRangeOnSubmit?: (values: DatePickerRangeFormValues) => void; +// dateInputRangeOnSubmit?: (values: DateInputRangeFormValues) => void; +// datePickerOnSubmit?: (values: DatePickerFormValues) => void; +// dateInputOnSubmit?: (values: DateInputFormValues) => void; +// beforeOnSubmit?: (values: DateInputFormValues) => void; +// afterOnSubmit?: (values: DateInputFormValues) => void; +// onOnSubmit?: (values: DateInputFormValues) => void; +// rangeOnSubmit?: (values: DateInputRangeFormValues) => void; +// formType: TimeFilterFormType; +// defaultButtonText?: string; +// } -export function TimeFilter({ - defaultStartTime, - defaultEndTime, - defaultOnTime, - hasRange = true, - hasBefore = true, - hasAfter = true, - hasOn = true, - formatOn, - formatBefore, - formatAfter, - datePickerRangeOnSubmit, - dateInputRangeOnSubmit, - datePickerOnSubmit, - dateInputOnSubmit, - beforeOnSubmit, - afterOnSubmit, - onOnSubmit, - rangeOnSubmit, - formType, - defaultButtonText = 'Date', -}: DateFilterProps) { - const { onOpen, onClose, isOpen } = useDisclosure(); - const defaultStartTimeNumber = isNaN(Number(defaultStartTime)) - ? undefined - : Number(defaultStartTime); - const defaultEndTimeNumber = isNaN(Number(defaultEndTime)) ? undefined : Number(defaultEndTime); - const defaultOnTimeNumber = isNaN(Number(defaultEndTime)) ? undefined : Number(defaultEndTime); +// type TimeFilterFormType = 'date-picker' | 'input'; - const populatedFilter: TimeFilterType = // TODO: these props arent changin anymore. i need a new way to determine which filter is populated and waht theat value is so I can display it in the button - defaultStartTime && defaultEndTime - ? 'range' - : defaultStartTime - ? 'after' - : defaultEndTime - ? 'before' - : defaultOnTime - ? 'on' - : null; +// export function TimeFilter({ +// defaultStartTime, +// defaultEndTime, +// defaultOnTime, +// hasRange = true, +// hasBefore = true, +// hasAfter = true, +// hasOn = true, +// formatOn, +// formatBefore, +// formatAfter, +// datePickerRangeOnSubmit, +// dateInputRangeOnSubmit, +// datePickerOnSubmit, +// dateInputOnSubmit, +// beforeOnSubmit, +// afterOnSubmit, +// onOnSubmit, +// rangeOnSubmit, +// formType, +// defaultButtonText = 'Date', +// }: DateFilterProps) { +// const { onOpen, onClose, isOpen } = useDisclosure(); +// const defaultStartTimeNumber = isNaN(Number(defaultStartTime)) +// ? undefined +// : Number(defaultStartTime); +// const defaultEndTimeNumber = isNaN(Number(defaultEndTime)) ? undefined : Number(defaultEndTime); +// const defaultOnTimeNumber = isNaN(Number(defaultEndTime)) ? undefined : Number(defaultEndTime); - const buttonText = !populatedFilter - ? defaultButtonText - : populatedFilter === 'range' - ? 'Range:' - : populatedFilter === 'before' - ? 'Before:' - : populatedFilter === 'after' - ? 'After:' - : 'Date'; +// const populatedFilter: TimeFilterType = // TODO: these props arent changin anymore. i need a new way to determine which filter is populated and waht theat value is so I can display it in the button +// defaultStartTime && defaultEndTime +// ? 'range' +// : defaultStartTime +// ? 'after' +// : defaultEndTime +// ? 'before' +// : defaultOnTime +// ? 'on' +// : null; - const firstFilterType = hasRange - ? 'range' - : hasBefore - ? 'before' - : hasAfter - ? 'after' - : hasOn - ? 'on' - : null; +// const buttonText = !populatedFilter +// ? defaultButtonText +// : populatedFilter === 'range' +// ? 'Range:' +// : populatedFilter === 'before' +// ? 'Before:' +// : populatedFilter === 'after' +// ? 'After:' +// : 'Date'; - if (!firstFilterType) { - // Should never be thrown - throw new Error('No filter type found'); - } +// const firstFilterType = hasRange +// ? 'range' +// : hasBefore +// ? 'before' +// : hasAfter +// ? 'after' +// : hasOn +// ? 'on' +// : null; - const [selectedFilterType, setSelectedFilterType] = useState( - populatedFilter || firstFilterType - ); +// if (!firstFilterType) { +// // Should never be thrown +// throw new Error('No filter type found'); +// } - useEffect(() => { - setSelectedFilterType(populatedFilter || firstFilterType); - }, [populatedFilter, firstFilterType]); +// const [selectedFilterType, setSelectedFilterType] = useState( +// populatedFilter || firstFilterType +// ); - const datePickerRangeOnSubmitHandler = useMemo( - () => (values: DatePickerRangeFormValues) => { - datePickerRangeOnSubmit?.(values); - onClose(); - }, - [datePickerRangeOnSubmit, onClose] - ); +// useEffect(() => { +// setSelectedFilterType(populatedFilter || firstFilterType); +// }, [populatedFilter, firstFilterType]); - const dateInputRangeOnSubmitHandler = useMemo( - () => (values: DateInputRangeFormValues) => { - dateInputRangeOnSubmit?.(values); - onClose(); - }, - [dateInputRangeOnSubmit, onClose] - ); +// const datePickerRangeOnSubmitHandler = useMemo( +// () => (values: DatePickerRangeFormValues) => { +// datePickerRangeOnSubmit?.(values); +// onClose(); +// }, +// [datePickerRangeOnSubmit, onClose] +// ); - const datePickerOnSubmitHandler = useMemo( - () => (values: DatePickerFormValues) => { - datePickerOnSubmit?.(values); - onClose(); - }, - [datePickerOnSubmit, onClose] - ); +// const dateInputRangeOnSubmitHandler = useMemo( +// () => (values: DateInputRangeFormValues) => { +// dateInputRangeOnSubmit?.(values); +// onClose(); +// }, +// [dateInputRangeOnSubmit, onClose] +// ); - const dateInputOnSubmitHandler = useMemo( - () => (values: DateInputFormValues) => { - dateInputOnSubmit?.(values); - onClose(); - }, - [dateInputOnSubmit, onClose] - ); +// const datePickerOnSubmitHandler = useMemo( +// () => (values: DatePickerFormValues) => { +// datePickerOnSubmit?.(values); +// onClose(); +// }, +// [datePickerOnSubmit, onClose] +// ); - console.log({ populatedFilter }); +// const dateInputOnSubmitHandler = useMemo( +// () => (values: DateValue) => { +// dateInputOnSubmit?.(values); +// onClose(); +// }, +// [dateInputOnSubmit, onClose] +// ); - return ( - - - - - - - - {[ - { type: 'range', label: 'Range', condition: hasRange }, - { type: 'before', label: 'Before', condition: hasBefore }, - { type: 'after', label: 'After', condition: hasAfter }, - { type: 'on', label: 'On', condition: hasOn }, - ].map( - ({ type, label, condition }) => - condition && ( - setSelectedFilterType(type as TimeFilterType)} - > - {label} - - ) - )} - - {selectedFilterType === 'range' ? ( - formType === 'date-picker' ? ( - - ) : ( - - ) - ) : selectedFilterType === 'before' ? ( - formType === 'date-picker' ? ( - - ) : ( - - ) - ) : selectedFilterType === 'after' ? ( - formType === 'date-picker' ? ( - - ) : ( - - ) - ) : selectedFilterType === 'on' ? ( - formType === 'date-picker' ? ( - - ) : ( - - ) - ) : null} - - - - ); -} +// console.log({ populatedFilter }); -// function getFormType( -// formType: TimeFilterFormType, -// initialDate: number, -// onSubmitHandler: (values: any) => void -// ) { -// return formType === 'date-picker' ? ( -// -// ) : ( -// +// return ( +// +// +// +// +// +// +// +// {[ +// { type: 'range', label: 'Range', condition: hasRange }, +// { type: 'before', label: 'Before', condition: hasBefore }, +// { type: 'after', label: 'After', condition: hasAfter }, +// { type: 'on', label: 'On', condition: hasOn }, +// ].map( +// ({ type, label, condition }) => +// condition && ( +// setSelectedFilterType(type as TimeFilterType)} +// > +// {label} +// +// ) +// )} +// +// {selectedFilterType === 'range' ? ( +// formType === 'date-picker' ? ( +// +// ) : ( +// +// ) +// ) : selectedFilterType === 'before' ? ( +// formType === 'date-picker' ? ( +// +// ) : ( +// +// ) +// ) : selectedFilterType === 'after' ? ( +// formType === 'date-picker' ? ( +// +// ) : ( +// +// ) +// ) : selectedFilterType === 'on' ? ( +// formType === 'date-picker' ? ( +// +// ) : ( +// dateInputOnSubmitHandler(values)} +// type="number" // TODO: make this dynamic +// name="on" +// /> +// ) +// ) : null} +// +// +// // ); // } + +// // function getFormType( +// // formType: TimeFilterFormType, +// // initialDate: number, +// // onSubmitHandler: (values: any) => void +// // ) { +// // return formType === 'date-picker' ? ( +// // +// // ) : ( +// // +// // ); +// // } diff --git a/src/app/signers/CycleFilter.tsx b/src/app/signers/CycleFilter.tsx index 6d76543e1..d190847b0 100644 --- a/src/app/signers/CycleFilter.tsx +++ b/src/app/signers/CycleFilter.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, IconButton, Input } from '@chakra-ui/react'; +import { Flex, IconButton, Input } from '@chakra-ui/react'; import { CaretLeft, CaretRight } from '@phosphor-icons/react'; import { Field, Form, Formik } from 'formik'; import { useCallback, useState } from 'react'; @@ -26,18 +26,18 @@ export function CycleFilter({ handleCycleChange(values.cycle)}> {({ values, setFieldValue, submitForm }) => (
- - - } - onClick={() => { - const newCycleId = String(Number(values.cycle) - 1); - setFieldValue('cycle', newCycleId); - submitForm(); - }} - /> - + + } + onClick={() => { + const newCycleId = String(Number(values.cycle) - 1); + setFieldValue('cycle', newCycleId); + submitForm(); + }} + h={5} + w={5} + /> {({ field }: any) => ( )} - - } - onClick={() => { - const newCycleId = String(Number(values.cycle) + 1); - setFieldValue('cycle', newCycleId); - submitForm(); - }} - isDisabled={cycleId === currentCycleId} - /> - + } + onClick={() => { + const newCycleId = String(Number(values.cycle) + 1); + setFieldValue('cycle', newCycleId); + submitForm(); + }} + isDisabled={cycleId === currentCycleId} + h={5} + w={5} + /> )} diff --git a/src/app/signers/SignersTable.tsx b/src/app/signers/SignersTable.tsx index 61c74ac79..4f77b01ab 100644 --- a/src/app/signers/SignersTable.tsx +++ b/src/app/signers/SignersTable.tsx @@ -3,12 +3,12 @@ import styled from '@emotion/styled'; import { UseQueryResult, useQueries, useQueryClient } from '@tanstack/react-query'; import React, { ReactNode, Suspense, useCallback, useMemo, useState } from 'react'; +import { CopyButton } from '../../common/components/CopyButton'; import { AddressLink } from '../../common/components/ExplorerLinks'; import { Section } from '../../common/components/Section'; import { ApiResponseWithResultsOffset } from '../../common/types/api'; import { truncateMiddle } from '../../common/utils/utils'; import { Flex } from '../../ui/Flex'; -import { Show } from '../../ui/Show'; import { Table } from '../../ui/Table'; import { Tbody } from '../../ui/Tbody'; import { Td } from '../../ui/Td'; @@ -19,8 +19,6 @@ import { Tr } from '../../ui/Tr'; import { ScrollableBox } from '../_components/BlockList/ScrollableDiv'; import { ExplorerErrorBoundary } from '../_components/ErrorBoundary'; import { useSuspenseCurrentStackingCycle } from '../_components/Stats/CurrentStackingCycle/useCurrentStackingCycle'; -import { DateInputFormValues } from '../_components/time-filter/DateInputForm'; -import { TimeFilter } from '../_components/time-filter/TimeFilter'; import { CycleFilter } from './CycleFilter'; import { removeStackingDaoFromName } from './SignerDistributionLegend'; import { SortByVotingPowerFilter, VotingPowerSortOrder } from './SortByVotingPowerFilter'; @@ -56,6 +54,8 @@ export const SignersTableHeader = ({ sx={isFirst ? mobileBorderCss : {}} width="fit-content" position={isFirst ? 'sticky' : 'unset'} + left={0} + bg="surface" > { + const [isSignerKeyHovered, setIsSignerKeyHovered] = useState(false); + return ( - - - {truncateMiddle(signerKey)} - {truncateMiddle(signerKey)} - + + setIsSignerKeyHovered(true)} + onMouseLeave={() => setIsSignerKeyHovered(false)} + > + + {truncateMiddle(signerKey)} + + + @@ -198,7 +216,6 @@ export function SignersTableLayout({ signersTableRows, votingPowerSortOrder, setVotingPowerSortOrder, - onSubmitHandler, cycleFilterOnSubmitHandler, selectedCycle, currentCycleId, @@ -208,7 +225,6 @@ export function SignersTableLayout({ signersTableRows: ReactNode; votingPowerSortOrder: VotingPowerSortOrder; setVotingPowerSortOrder: (order: VotingPowerSortOrder) => void; - onSubmitHandler: (values: DateInputFormValues) => void; cycleFilterOnSubmitHandler: (cycle: string) => void; selectedCycle: string; currentCycleId: string; @@ -217,24 +233,30 @@ export function SignersTableLayout({
+ - - + + Cycle: + + } > @@ -279,13 +301,6 @@ const SignersTableBase = () => { const { currentCycleId } = useSuspenseCurrentStackingCycle(); const [selectedCycle, setSelectedCycle] = useState(currentCycleId.toString()); - const onSubmitHandler = useCallback( - (cycle: string) => { - setSelectedCycle(cycle); - }, - [setSelectedCycle] - ); - const cycleFilterOnSubmitHandler = useCallback( (cycle: string) => { setSelectedCycle(cycle); @@ -307,13 +322,13 @@ const SignersTableBase = () => { const signersStackersQueries = useMemo(() => { return { queries: signers.map(signer => { - return getQuery(currentCycleId, signer.signing_key); + return getQuery(parseInt(selectedCycle), signer.signing_key); }), combine: ( response: UseQueryResult, Error>[] ) => response.map(r => r.data?.results ?? []), }; - }, [signers, getQuery, currentCycleId]); + }, [signers, getQuery, selectedCycle]); const signersStackers = useQueries(signersStackersQueries, queryClient); const signersData = useMemo( () => @@ -346,7 +361,6 @@ const SignersTableBase = () => { isLast={i === signers.length - 1} /> ))} - onSubmitHandler={onSubmitHandler} cycleFilterOnSubmitHandler={cycleFilterOnSubmitHandler} selectedCycle={selectedCycle} currentCycleId={currentCycleId.toString()} diff --git a/src/app/signers/consts.ts b/src/app/signers/consts.ts index dd65b0194..a5dc251bf 100644 --- a/src/app/signers/consts.ts +++ b/src/app/signers/consts.ts @@ -77,7 +77,14 @@ export const SIGNER_KEY_MAP: Record {title ? ( typeof title === 'string' ? ( - + {title} ) : (