Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
7025b758
Commit
7025b758
authored
Mar 11, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advanced filters page
parent
7e97c811
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
319 additions
and
286 deletions
+319
-286
eslint.config.mjs
eslint.config.mjs
+1
-0
advanced-filter.tsx
pages/advanced-filter.tsx
+2
-2
[id].tsx
pages/validators/[id].tsx
+7
-7
semanticTokens.ts
theme/foundations/semanticTokens.ts
+1
-1
checkbox.tsx
toolkit/chakra/checkbox.tsx
+2
-1
select.tsx
toolkit/chakra/select.tsx
+31
-1
borders.ts
toolkit/theme/foundations/borders.ts
+4
-2
zIndex.ts
toolkit/theme/foundations/zIndex.ts
+4
-2
checkbox.recipe.ts
toolkit/theme/recipes/checkbox.recipe.ts
+1
-0
ColumnsButton.tsx
ui/advancedFilter/ColumnsButton.tsx
+23
-30
ExportCSV.tsx
ui/advancedFilter/ExportCSV.tsx
+5
-10
FilterByColumn.tsx
ui/advancedFilter/FilterByColumn.tsx
+8
-8
ItemByColumn.tsx
ui/advancedFilter/ItemByColumn.tsx
+9
-9
constants.ts
ui/advancedFilter/constants.ts
+1
-1
AddressFilter.tsx
ui/advancedFilter/filters/AddressFilter.tsx
+29
-23
AddressRelationFilter.tsx
ui/advancedFilter/filters/AddressRelationFilter.tsx
+8
-8
AgeFilter.tsx
ui/advancedFilter/filters/AgeFilter.tsx
+14
-11
AmountFilter.tsx
ui/advancedFilter/filters/AmountFilter.tsx
+22
-20
AssetFilter.tsx
ui/advancedFilter/filters/AssetFilter.tsx
+33
-35
MethodFilter.tsx
ui/advancedFilter/filters/MethodFilter.tsx
+17
-21
TypeFilter.tsx
ui/advancedFilter/filters/TypeFilter.tsx
+22
-21
AdvancedFilter.tsx
ui/pages/AdvancedFilter.tsx
+53
-54
RawInputData.tsx
ui/shared/RawInputData.tsx
+1
-1
AddressIconDelegated.tsx
ui/shared/entities/address/AddressIconDelegated.tsx
+3
-1
ValidatorEntity.tsx
ui/shared/entities/validator/ValidatorEntity.tsx
+4
-6
TableColumnFilter.tsx
ui/shared/filters/TableColumnFilter.tsx
+1
-1
TableColumnFilterWrapper.tsx
ui/shared/filters/TableColumnFilterWrapper.tsx
+2
-8
TagGroupSelect.tsx
ui/shared/tagGroupSelect/TagGroupSelect.tsx
+2
-2
Tag.tsx
ui/showcases/Tag.tsx
+9
-0
No files found.
eslint.config.mjs
View file @
7025b758
...
@@ -37,6 +37,7 @@ const RESTRICTED_MODULES = {
...
@@ -37,6 +37,7 @@ const RESTRICTED_MODULES = {
'
Tag
'
,
'
Switch
'
,
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
Tag
'
,
'
Switch
'
,
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
'
Select
'
,
'
SelectRoot
'
,
'
SelectControl
'
,
'
SelectContent
'
,
'
SelectItem
'
,
'
SelectValueText
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Show
'
,
'
Hide
'
,
'
Checkbox
'
,
'
CheckboxGroup
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Show
'
,
'
Hide
'
,
'
Checkbox
'
,
'
CheckboxGroup
'
,
'
Table
'
,
'
TableRoot
'
,
'
TableBody
'
,
'
TableHeader
'
,
'
TableRow
'
,
'
TableCell
'
,
'
Table
'
,
'
TableRoot
'
,
'
TableBody
'
,
'
TableHeader
'
,
'
TableRow
'
,
'
TableCell
'
,
'
Menu
'
,
'
MenuRoot
'
,
'
MenuTrigger
'
,
'
MenuContent
'
,
'
MenuItem
'
,
'
MenuTriggerItem
'
,
'
MenuRadioItemGroup
'
,
'
MenuContextTrigger
'
,
'
Menu
'
,
'
MenuRoot
'
,
'
MenuTrigger
'
,
'
MenuContent
'
,
'
MenuItem
'
,
'
MenuTriggerItem
'
,
'
MenuRadioItemGroup
'
,
'
MenuContextTrigger
'
,
...
...
pages/advanced-filter.tsx
View file @
7025b758
...
@@ -3,12 +3,12 @@ import React from 'react';
...
@@ -3,12 +3,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import AdvancedFilter from 'ui/pages/AdvancedFilter';
import
AdvancedFilter
from
'
ui/pages/AdvancedFilter
'
;
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/advanced-filter"
>
<
PageNextJs
pathname=
"/advanced-filter"
>
{
/* <AdvancedFilter/> */
}
<
AdvancedFilter
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/validators/[id].tsx
View file @
7025b758
...
@@ -9,18 +9,18 @@ import config from 'configs/app';
...
@@ -9,18 +9,18 @@ import config from 'configs/app';
const
validatorsFeature
=
config
.
features
.
validators
;
const
validatorsFeature
=
config
.
features
.
validators
;
//
const ValidatorDetails = dynamic(() => {
const
ValidatorDetails
=
dynamic
(()
=>
{
//
if (validatorsFeature.isEnabled && validatorsFeature.chainType === 'zilliqa') {
if
(
validatorsFeature
.
isEnabled
&&
validatorsFeature
.
chainType
===
'
zilliqa
'
)
{
//
return import('ui/pages/ValidatorZilliqa');
return
import
(
'
ui/pages/ValidatorZilliqa
'
);
//
}
}
//
throw new Error('Validators feature is not enabled.');
throw
new
Error
(
'
Validators feature is not enabled.
'
);
//
}, { ssr: false });
},
{
ssr
:
false
});
const
Page
:
NextPage
<
Props
>
=
(
props
)
=>
{
const
Page
:
NextPage
<
Props
>
=
(
props
)
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/validators/[id]"
query=
{
props
.
query
}
>
<
PageNextJs
pathname=
"/validators/[id]"
query=
{
props
.
query
}
>
{
/* <ValidatorDetails/> */
}
<
ValidatorDetails
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
theme/foundations/semanticTokens.ts
View file @
7025b758
...
@@ -31,7 +31,7 @@ const semanticTokens = {
...
@@ -31,7 +31,7 @@ const semanticTokens = {
'
default
'
:
'
red.500
'
,
'
default
'
:
'
red.500
'
,
_dark
:
'
red.500
'
,
_dark
:
'
red.500
'
,
},
},
dialog
.
bg
:
{
dialog
_
bg
:
{
'
default
'
:
'
white
'
,
'
default
'
:
'
white
'
,
_dark
:
'
gray.900
'
,
_dark
:
'
gray.900
'
,
},
},
...
...
toolkit/chakra/checkbox.tsx
View file @
7025b758
import
type
{
Checkbox
as
ArkCheckbox
}
from
'
@ark-ui/react/checkbox
'
;
import
type
{
Checkbox
as
ArkCheckbox
}
from
'
@ark-ui/react/checkbox
'
;
import
type
{
HTMLChakraProps
}
from
'
@chakra-ui/react
'
;
import
{
Checkbox
as
ChakraCheckbox
,
CheckboxGroup
as
ChakraCheckboxGroup
}
from
'
@chakra-ui/react
'
;
import
{
Checkbox
as
ChakraCheckbox
,
CheckboxGroup
as
ChakraCheckboxGroup
}
from
'
@chakra-ui/react
'
;
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
...
@@ -25,7 +26,7 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
...
@@ -25,7 +26,7 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
},
},
);
);
export
interface
CheckboxGroupProps
extends
ArkCheckbox
.
GroupProps
{
export
interface
CheckboxGroupProps
extends
HTMLChakraProps
<
'
div
'
,
ArkCheckbox
.
GroupProps
>
{
orientation
?:
'
vertical
'
|
'
horizontal
'
;
orientation
?:
'
vertical
'
|
'
horizontal
'
;
}
}
...
...
toolkit/chakra/select.tsx
View file @
7025b758
'
use client
'
;
'
use client
'
;
import
type
{
CollectionItem
}
from
'
@chakra-ui/react
'
;
import
type
{
CollectionItem
,
ListCollection
}
from
'
@chakra-ui/react
'
;
import
{
Select
as
ChakraSelect
,
Portal
,
useSelectContext
}
from
'
@chakra-ui/react
'
;
import
{
Select
as
ChakraSelect
,
Portal
,
useSelectContext
}
from
'
@chakra-ui/react
'
;
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
...
@@ -173,3 +173,33 @@ export const SelectItemGroup = React.forwardRef<
...
@@ -173,3 +173,33 @@ export const SelectItemGroup = React.forwardRef<
export
const
SelectLabel
=
ChakraSelect
.
Label
;
export
const
SelectLabel
=
ChakraSelect
.
Label
;
export
const
SelectItemText
=
ChakraSelect
.
ItemText
;
export
const
SelectItemText
=
ChakraSelect
.
ItemText
;
export
interface
SelectProps
extends
SelectRootProps
{
collection
:
ListCollection
<
CollectionItem
>
;
placeholder
:
string
;
portalled
?:
boolean
;
}
// TODO @tom2drum refactor selects
export
const
Select
=
React
.
forwardRef
<
HTMLDivElement
,
SelectProps
>
((
props
,
ref
)
=>
{
const
{
collection
,
placeholder
,
portalled
=
true
,
...
rest
}
=
props
;
return
(
<
SelectRoot
ref=
{
ref
}
collection=
{
collection
}
variant=
"outline"
{
...
rest
}
>
<
SelectControl
>
<
SelectValueText
placeholder=
{
placeholder
}
/>
</
SelectControl
>
<
SelectContent
portalled=
{
portalled
}
>
{
collection
.
items
.
map
((
item
)
=>
(
<
SelectItem
item=
{
item
}
key=
{
item
.
value
}
>
{
item
.
label
}
</
SelectItem
>
))
}
</
SelectContent
>
</
SelectRoot
>
);
});
toolkit/theme/foundations/borders.ts
View file @
7025b758
import
type
{
T
okenDefinition
}
from
'
@chakra-ui/react/dist/types/styled-system/types
'
;
import
type
{
T
hemingConfig
}
from
'
@chakra-ui/react
'
;
export
const
radii
:
TokenDefinition
[
'
radii
'
]
=
{
import
type
{
ExcludeUndefined
}
from
'
types/utils
'
;
export
const
radii
:
ExcludeUndefined
<
ThemingConfig
[
'
tokens
'
]
>
[
'
radii
'
]
=
{
none
:
{
value
:
'
0
'
},
none
:
{
value
:
'
0
'
},
sm
:
{
value
:
'
4px
'
},
sm
:
{
value
:
'
4px
'
},
base
:
{
value
:
'
8px
'
},
base
:
{
value
:
'
8px
'
},
...
...
toolkit/theme/foundations/zIndex.ts
View file @
7025b758
import
type
{
T
okenDefinition
}
from
'
@chakra-ui/react/dist/types/styled-system/types
'
;
import
type
{
T
hemingConfig
}
from
'
@chakra-ui/react
'
;
export
const
zIndex
:
TokenDefinition
[
'
zIndex
'
]
=
{
import
type
{
ExcludeUndefined
}
from
'
types/utils
'
;
export
const
zIndex
:
ExcludeUndefined
<
ThemingConfig
[
'
tokens
'
]
>
[
'
zIndex
'
]
=
{
hide
:
{
value
:
-
1
},
hide
:
{
value
:
-
1
},
auto
:
{
value
:
'
auto
'
},
auto
:
{
value
:
'
auto
'
},
base
:
{
value
:
0
},
base
:
{
value
:
0
},
...
...
toolkit/theme/recipes/checkbox.recipe.ts
View file @
7025b758
...
@@ -26,6 +26,7 @@ export const recipe = defineSlotRecipe({
...
@@ -26,6 +26,7 @@ export const recipe = defineSlotRecipe({
label
:
{
label
:
{
fontWeight
:
'
normal
'
,
fontWeight
:
'
normal
'
,
userSelect
:
'
none
'
,
userSelect
:
'
none
'
,
flexGrow
:
1
,
_disabled
:
{
_disabled
:
{
opacity
:
'
control.disabled
'
,
opacity
:
'
control.disabled
'
,
},
},
...
...
ui/advancedFilter/ColumnsButton.tsx
View file @
7025b758
import
{
Button
,
Grid
,
PopoverTrigger
,
PopoverContent
,
PopoverBody
,
useDisclosure
,
Checkbox
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Checkbox
,
CheckboxGroup
}
from
'
toolkit/chakra/checkbox
'
;
import
{
PopoverBody
,
PopoverContent
,
PopoverRoot
,
PopoverTrigger
}
from
'
toolkit/chakra/popover
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
{
TABLE_COLUMNS
}
from
'
ui/advancedFilter/constants
'
;
import
{
TABLE_COLUMNS
}
from
'
ui/advancedFilter/constants
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
interface
Props
{
interface
Props
{
...
@@ -21,46 +13,47 @@ interface Props {
...
@@ -21,46 +13,47 @@ interface Props {
}
}
const
ColumnsButton
=
({
columns
,
onChange
}:
Props
)
=>
{
const
ColumnsButton
=
({
columns
,
onChange
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
handleValueChange
=
React
.
useCallback
((
value
:
Array
<
string
>
)
=>
{
const
newCols
=
value
.
reduce
((
acc
,
key
)
=>
{
const
onCheckboxClick
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
acc
[
key
as
ColumnsIds
]
=
true
;
const
newCols
=
{
...
columns
};
return
acc
;
const
id
=
event
.
target
.
id
as
ColumnsIds
;
},
{}
as
Record
<
ColumnsIds
,
boolean
>
);
newCols
[
id
]
=
event
.
target
.
checked
;
onChange
(
newCols
);
onChange
(
newCols
);
},
[
onChange
,
columns
]);
},
[
onChange
]);
return
(
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
Popover
Root
>
<
PopoverTrigger
>
<
PopoverTrigger
>
<
Button
<
Button
onClick=
{
onToggle
}
variant=
"dropdown"
variant=
"outline"
colorScheme=
"gray"
size=
"sm"
size=
"sm"
leftIcon=
{
<
IconSvg
name=
"columns"
boxSize=
{
5
}
color=
"inherit"
/>
}
>
>
<
IconSvg
name=
"columns"
boxSize=
{
5
}
color=
"inherit"
/>
Columns
Columns
</
Button
>
</
Button
>
</
PopoverTrigger
>
</
PopoverTrigger
>
<
PopoverContent
>
<
PopoverContent
>
<
PopoverBody
px=
{
4
}
py=
{
6
}
display=
"flex"
flexDir=
"column"
rowGap=
{
5
}
>
<
PopoverBody
px=
{
4
}
py=
{
6
}
display=
"flex"
flexDir=
"column"
rowGap=
{
5
}
>
<
Grid
gridTemplateColumns=
"160px 160px"
gap=
{
3
}
>
<
CheckboxGroup
defaultValue=
{
Object
.
keys
(
columns
).
filter
((
key
)
=>
columns
[
key
as
ColumnsIds
])
}
onValueChange=
{
handleValueChange
}
display=
"grid"
gridTemplateColumns=
"160px 160px"
gap=
{
3
}
>
{
TABLE_COLUMNS
.
map
(
col
=>
(
{
TABLE_COLUMNS
.
map
(
col
=>
(
<
Checkbox
<
Checkbox
key=
{
col
.
id
}
key=
{
col
.
id
}
defaultChecked=
{
columns
[
col
.
id
]
}
value=
{
col
.
id
}
onChange=
{
onCheckboxClick
}
size=
"md"
id=
{
col
.
id
}
size=
"lg"
>
>
{
col
.
id
===
'
or_and
'
?
'
And/Or
'
:
col
.
name
}
{
col
.
id
===
'
or_and
'
?
'
And/Or
'
:
col
.
name
}
</
Checkbox
>
</
Checkbox
>
))
}
))
}
</
Grid
>
</
CheckboxGroup
>
</
PopoverBody
>
</
PopoverBody
>
</
PopoverContent
>
</
PopoverContent
>
</
Popover
>
</
Popover
Root
>
);
);
};
};
...
...
ui/advancedFilter/ExportCSV.tsx
View file @
7025b758
import
{
Button
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
...
@@ -7,7 +6,8 @@ import config from 'configs/app';
...
@@ -7,7 +6,8 @@ import config from 'configs/app';
import
buildUrl
from
'
lib/api/buildUrl
'
;
import
buildUrl
from
'
lib/api/buildUrl
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
downloadBlob
from
'
lib/downloadBlob
'
;
import
downloadBlob
from
'
lib/downloadBlob
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
toaster
}
from
'
toolkit/chakra/toaster
'
;
import
ReCaptcha
from
'
ui/shared/reCaptcha/ReCaptcha
'
;
import
ReCaptcha
from
'
ui/shared/reCaptcha/ReCaptcha
'
;
import
useReCaptcha
from
'
ui/shared/reCaptcha/useReCaptcha
'
;
import
useReCaptcha
from
'
ui/shared/reCaptcha/useReCaptcha
'
;
...
@@ -17,7 +17,6 @@ type Props = {
...
@@ -17,7 +17,6 @@ type Props = {
const
ExportCSV
=
({
filters
}:
Props
)
=>
{
const
ExportCSV
=
({
filters
}:
Props
)
=>
{
const
recaptcha
=
useReCaptcha
();
const
recaptcha
=
useReCaptcha
();
const
toast
=
useToast
();
const
[
isLoading
,
setIsLoading
]
=
React
.
useState
(
false
);
const
[
isLoading
,
setIsLoading
]
=
React
.
useState
(
false
);
const
handleExportCSV
=
React
.
useCallback
(
async
()
=>
{
const
handleExportCSV
=
React
.
useCallback
(
async
()
=>
{
...
@@ -49,18 +48,14 @@ const ExportCSV = ({ filters }: Props) => {
...
@@ -49,18 +48,14 @@ const ExportCSV = ({ filters }: Props) => {
downloadBlob
(
blob
,
fileName
);
downloadBlob
(
blob
,
fileName
);
}
catch
(
error
)
{
}
catch
(
error
)
{
toast
({
toaster
.
error
({
position
:
'
top-right
'
,
title
:
'
Error
'
,
title
:
'
Error
'
,
description
:
(
error
as
Error
)?.
message
||
'
Something went wrong. Try again later.
'
,
description
:
(
error
as
Error
)?.
message
||
'
Something went wrong. Try again later.
'
,
status
:
'
error
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
});
}
finally
{
}
finally
{
setIsLoading
(
false
);
setIsLoading
(
false
);
}
}
},
[
toast
,
filters
,
recaptcha
]);
},
[
filters
,
recaptcha
]);
if
(
!
config
.
services
.
reCaptchaV2
.
siteKey
)
{
if
(
!
config
.
services
.
reCaptchaV2
.
siteKey
)
{
return
null
;
return
null
;
...
@@ -71,7 +66,7 @@ const ExportCSV = ({ filters }: Props) => {
...
@@ -71,7 +66,7 @@ const ExportCSV = ({ filters }: Props) => {
<
Button
<
Button
onClick=
{
handleExportCSV
}
onClick=
{
handleExportCSV
}
variant=
"outline"
variant=
"outline"
isL
oading=
{
isLoading
}
l
oading=
{
isLoading
}
size=
"sm"
size=
"sm"
mr=
{
3
}
mr=
{
3
}
>
>
...
...
ui/advancedFilter/FilterByColumn.tsx
View file @
7025b758
...
@@ -34,7 +34,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -34,7 +34,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Type"
columnName=
"Type"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
&&
value
.
length
)
}
selected
=
{
Boolean
(
value
&&
value
.
length
)
}
>
>
<
TypeFilter
{
...
commonProps
}
value=
{
value
}
/>
<
TypeFilter
{
...
commonProps
}
value=
{
value
}
/>
</
TableColumnFilterWrapper
>
</
TableColumnFilterWrapper
>
...
@@ -46,7 +46,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -46,7 +46,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Method"
columnName=
"Method"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
&&
value
.
length
)
}
selected
=
{
Boolean
(
value
&&
value
.
length
)
}
w=
"350px"
w=
"350px"
>
>
<
MethodFilter
{
...
commonProps
}
value=
{
value
}
/>
<
MethodFilter
{
...
commonProps
}
value=
{
value
}
/>
...
@@ -59,7 +59,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -59,7 +59,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Age"
columnName=
"Age"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
.
from
||
value
.
to
||
value
.
age
)
}
selected
=
{
Boolean
(
value
.
from
||
value
.
to
||
value
.
age
)
}
w=
"382px"
w=
"382px"
>
>
<
AgeFilter
{
...
commonProps
}
value=
{
value
}
/>
<
AgeFilter
{
...
commonProps
}
value=
{
value
}
/>
...
@@ -71,7 +71,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -71,7 +71,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"And/Or"
columnName=
"And/Or"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
false
}
selected
=
{
false
}
w=
"106px"
w=
"106px"
value=
{
filters
.
address_relation
===
'
and
'
?
'
AND
'
:
'
OR
'
}
value=
{
filters
.
address_relation
===
'
and
'
?
'
AND
'
:
'
OR
'
}
>
>
...
@@ -88,7 +88,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -88,7 +88,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Address from"
columnName=
"Address from"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
.
length
)
}
selected
=
{
Boolean
(
value
.
length
)
}
w=
"480px"
w=
"480px"
>
>
<
AddressFilter
{
...
commonProps
}
type=
"from"
value=
{
value
}
/>
<
AddressFilter
{
...
commonProps
}
type=
"from"
value=
{
value
}
/>
...
@@ -105,7 +105,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -105,7 +105,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Address to"
columnName=
"Address to"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
.
length
)
}
selected
=
{
Boolean
(
value
.
length
)
}
w=
"480px"
w=
"480px"
>
>
<
AddressFilter
{
...
commonProps
}
type=
"to"
value=
{
value
}
/>
<
AddressFilter
{
...
commonProps
}
type=
"to"
value=
{
value
}
/>
...
@@ -118,7 +118,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -118,7 +118,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Amount"
columnName=
"Amount"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
.
from
||
value
.
to
)
}
selected
=
{
Boolean
(
value
.
from
||
value
.
to
)
}
w=
"382px"
w=
"382px"
>
>
<
AmountFilter
{
...
commonProps
}
value=
{
value
}
/>
<
AmountFilter
{
...
commonProps
}
value=
{
value
}
/>
...
@@ -145,7 +145,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
...
@@ -145,7 +145,7 @@ const FilterByColumn = ({ column, filters, columnName, handleFilterChange, searc
<
TableColumnFilterWrapper
<
TableColumnFilterWrapper
columnName=
"Asset"
columnName=
"Asset"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
isActive
=
{
Boolean
(
value
.
length
)
}
selected
=
{
Boolean
(
value
.
length
)
}
w=
"382px"
w=
"382px"
>
>
<
AssetFilter
{
...
commonProps
}
value=
{
value
}
/>
<
AssetFilter
{
...
commonProps
}
value=
{
value
}
/>
...
...
ui/advancedFilter/ItemByColumn.tsx
View file @
7025b758
...
@@ -5,10 +5,10 @@ import type { AdvancedFilterResponseItem } from 'types/api/advancedFilter';
...
@@ -5,10 +5,10 @@ import type { AdvancedFilterResponseItem } from 'types/api/advancedFilter';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
getCurrencyValue
from
'
lib/getCurrencyValue
'
;
import
getCurrencyValue
from
'
lib/getCurrencyValue
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
AddressFromToIcon
from
'
ui/shared/address/AddressFromToIcon
'
;
import
AddressFromToIcon
from
'
ui/shared/address/AddressFromToIcon
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
import
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
...
@@ -31,10 +31,10 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
...
@@ -31,10 +31,10 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
if
(
!
type
)
{
if
(
!
type
)
{
return
null
;
return
null
;
}
}
return
<
Tag
isLoading=
{
isLoading
}
>
{
type
.
name
}
</
Tag
>;
return
<
Badge
loading=
{
isLoading
}
>
{
type
.
name
}
</
Badge
>;
}
}
case
'
method
'
:
case
'
method
'
:
return
item
.
method
?
<
Tag
isLoading=
{
isLoading
}
isTruncated
colorScheme=
"gray"
>
{
item
.
method
}
</
Tag
>
:
null
;
return
item
.
method
?
<
Badge
loading=
{
isLoading
}
truncated
>
{
item
.
method
}
</
Badge
>
:
null
;
case
'
age
'
:
case
'
age
'
:
return
<
TimeAgoWithTooltip
timestamp=
{
item
.
timestamp
}
isLoading=
{
isLoading
}
color=
"text_secondary"
fontWeight=
{
400
}
/>;
return
<
TimeAgoWithTooltip
timestamp=
{
item
.
timestamp
}
isLoading=
{
isLoading
}
color=
"text_secondary"
fontWeight=
{
400
}
/>;
case
'
from
'
:
case
'
from
'
:
...
@@ -63,18 +63,18 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
...
@@ -63,18 +63,18 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
);
);
case
'
amount
'
:
{
case
'
amount
'
:
{
if
(
item
.
token
?.
type
===
'
ERC-721
'
)
{
if
(
item
.
token
?.
type
===
'
ERC-721
'
)
{
return
<
Skeleton
isLoaded=
{
!
isLoading
}
>
1
</
Skeleton
>;
return
<
Skeleton
loading=
{
isLoading
}
>
1
</
Skeleton
>;
}
}
if
(
item
.
total
)
{
if
(
item
.
total
)
{
return
(
return
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
{
getCurrencyValue
({
value
:
item
.
total
?.
value
,
decimals
:
item
.
total
.
decimals
,
accuracy
:
8
}).
valueStr
}
{
getCurrencyValue
({
value
:
item
.
total
?.
value
,
decimals
:
item
.
total
.
decimals
,
accuracy
:
8
}).
valueStr
}
</
Skeleton
>
</
Skeleton
>
);
);
}
}
if
(
item
.
value
)
{
if
(
item
.
value
)
{
return
(
return
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
{
getCurrencyValue
({
value
:
item
.
value
,
decimals
:
config
.
chain
.
currency
.
decimals
.
toString
(),
accuracy
:
8
}).
valueStr
}
{
getCurrencyValue
({
value
:
item
.
value
,
decimals
:
config
.
chain
.
currency
.
decimals
.
toString
(),
accuracy
:
8
}).
valueStr
}
</
Skeleton
>
</
Skeleton
>
);
);
...
@@ -84,9 +84,9 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
...
@@ -84,9 +84,9 @@ const ItemByColumn = ({ item, column, isLoading }: Props) => {
case
'
asset
'
:
case
'
asset
'
:
return
item
.
token
?
return
item
.
token
?
<
TokenEntity
token=
{
item
.
token
}
isLoading=
{
isLoading
}
fontWeight=
{
700
}
onlySymbol
noCopy
/>
:
<
TokenEntity
token=
{
item
.
token
}
isLoading=
{
isLoading
}
fontWeight=
{
700
}
onlySymbol
noCopy
/>
:
<
Skeleton
isLoaded=
{
!
isLoading
}
fontWeight=
{
700
}
>
{
config
.
chain
.
currency
.
symbol
}
</
Skeleton
>;
<
Skeleton
loading=
{
isLoading
}
fontWeight=
{
700
}
>
{
config
.
chain
.
currency
.
symbol
}
</
Skeleton
>;
case
'
fee
'
:
case
'
fee
'
:
return
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
item
.
fee
?
getCurrencyValue
({
value
:
item
.
fee
,
accuracy
:
8
}).
valueStr
:
'
-
'
}
</
Skeleton
>;
return
<
Skeleton
loading=
{
isLoading
}
>
{
item
.
fee
?
getCurrencyValue
({
value
:
item
.
fee
,
accuracy
:
8
}).
valueStr
:
'
-
'
}
</
Skeleton
>;
default
:
default
:
return
null
;
return
null
;
}
}
...
...
ui/advancedFilter/constants.ts
View file @
7025b758
...
@@ -40,7 +40,7 @@ export const TABLE_COLUMNS: Array<TxTableColumn> = [
...
@@ -40,7 +40,7 @@ export const TABLE_COLUMNS: Array<TxTableColumn> = [
{
{
id
:
'
or_and
'
,
id
:
'
or_and
'
,
name
:
''
,
name
:
''
,
width
:
'
6
0
px
'
,
width
:
'
6
5
px
'
,
},
},
{
{
id
:
'
to
'
,
id
:
'
to
'
,
...
...
ui/advancedFilter/filters/AddressFilter.tsx
View file @
7025b758
import
{
Flex
,
Select
,
Input
,
InputGroup
,
InputRightElement
,
VStack
,
IconButton
}
from
'
@chakra-ui/react
'
;
import
{
createListCollection
,
Flex
,
VStack
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Input
}
from
'
toolkit/chakra/input
'
;
import
{
InputGroup
}
from
'
toolkit/chakra/input-group
'
;
import
{
Select
}
from
'
toolkit/chakra/select
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -16,6 +20,13 @@ const FILTER_PARAM_FROM_EXCLUDE = 'from_address_hashes_to_exclude';
...
@@ -16,6 +20,13 @@ const FILTER_PARAM_FROM_EXCLUDE = 'from_address_hashes_to_exclude';
export
type
AddressFilterMode
=
'
include
'
|
'
exclude
'
;
export
type
AddressFilterMode
=
'
include
'
|
'
exclude
'
;
const
collection
=
createListCollection
({
items
:
[
{
label
:
'
Include
'
,
value
:
'
include
'
},
{
label
:
'
Exclude
'
,
value
:
'
exclude
'
},
],
});
type
Value
=
Array
<
{
address
:
string
;
mode
:
AddressFilterMode
}
>
;
type
Value
=
Array
<
{
address
:
string
;
mode
:
AddressFilterMode
}
>
;
type
Props
=
{
type
Props
=
{
...
@@ -24,14 +35,13 @@ type Props = {
...
@@ -24,14 +35,13 @@ type Props = {
columnName
:
string
;
columnName
:
string
;
type
:
'
from
'
|
'
to
'
;
type
:
'
from
'
|
'
to
'
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
onClose
?:
()
=>
void
;
};
};
type
InputProps
=
{
type
InputProps
=
{
address
?:
string
;
address
?:
string
;
mode
?:
AddressFilterMode
;
mode
?:
AddressFilterMode
;
isLast
:
boolean
;
isLast
:
boolean
;
onModeChange
:
(
event
:
ChangeEvent
<
HTMLSelectElement
>
)
=>
void
;
onModeChange
:
(
{
value
}:
{
value
:
Array
<
string
>
}
)
=>
void
;
onChange
:
(
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
void
;
onChange
:
(
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
void
;
onClear
:
()
=>
void
;
onClear
:
()
=>
void
;
onAddFieldClick
:
()
=>
void
;
onAddFieldClick
:
()
=>
void
;
...
@@ -50,22 +60,19 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
...
@@ -50,22 +60,19 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
return
(
return
(
<
Flex
alignItems=
"center"
w=
"100%"
>
<
Flex
alignItems=
"center"
w=
"100%"
>
<
Select
<
Select
size=
"xs"
collection=
{
collection
}
borderRadius=
"bas
e"
placeholder=
"Select mod
e"
value=
{
mode
||
'
include
'
}
defaultValue=
{
[
mode
||
'
include
'
]
}
onChange=
{
onModeChange
}
on
Value
Change=
{
onModeChange
}
minW=
"105px"
portalled=
{
false
}
w=
"105px"
w=
"105px"
mr=
{
3
}
mr=
{
3
}
/>
<
InputGroup
flexGrow=
{
1
}
endElement=
{
<
ClearButton
onClick=
{
onClear
}
isDisabled=
{
!
address
}
/>
}
>
>
<
option
value=
"include"
>
Include
</
option
>
<
Input
value=
{
address
}
onChange=
{
onChange
}
placeholder=
"Smart contract / Address (0x...)*"
size=
"sm"
autoComplete=
"off"
/>
<
option
value=
"exclude"
>
Exclude
</
option
>
</
Select
>
<
InputGroup
size=
"xs"
flexGrow=
{
1
}
>
<
Input
value=
{
address
}
onChange=
{
onChange
}
placeholder=
"Smart contract / Address (0x...)*"
size=
"xs"
autoComplete=
"off"
/>
<
InputRightElement
>
<
ClearButton
onClick=
{
onClear
}
isDisabled=
{
!
address
}
/>
</
InputRightElement
>
</
InputGroup
>
</
InputGroup
>
{
isLast
&&
(
{
isLast
&&
(
<
IconButton
<
IconButton
...
@@ -76,8 +83,9 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
...
@@ -76,8 +83,9 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
h=
"30px"
h=
"30px"
ml=
{
2
}
ml=
{
2
}
onClick=
{
onAddFieldClick
}
onClick=
{
onAddFieldClick
}
icon=
{
<
IconSvg
name=
"plus"
w=
"20px"
h=
"20px"
/>
}
>
/>
<
IconSvg
name=
"plus"
w=
"20px"
h=
"20px"
/>
</
IconButton
>
)
}
)
}
</
Flex
>
</
Flex
>
);
);
...
@@ -85,14 +93,13 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
...
@@ -85,14 +93,13 @@ const AddressFilterInput = ({ address, mode, onModeChange, onChange, onClear, is
const
emptyItem
=
{
address
:
''
,
mode
:
'
include
'
as
AddressFilterMode
};
const
emptyItem
=
{
address
:
''
,
mode
:
'
include
'
as
AddressFilterMode
};
const
AddressFilter
=
({
type
,
value
=
[],
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
AddressFilter
=
({
type
,
value
=
[],
handleFilterChange
}:
Props
)
=>
{
const
[
currentValue
,
setCurrentValue
]
=
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Array
<
AddressFilter
>>
([
...
value
,
emptyItem
]);
React
.
useState
<
Array
<
AddressFilter
>>
([
...
value
,
emptyItem
]);
const
handleModeSelectChange
=
React
.
useCallback
((
index
:
number
)
=>
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
=>
{
const
handleModeSelectChange
=
React
.
useCallback
((
index
:
number
)
=>
({
value
}:
{
value
:
Array
<
string
>
})
=>
{
const
value
=
event
.
target
.
value
as
AddressFilterMode
;
setCurrentValue
(
prev
=>
{
setCurrentValue
(
prev
=>
{
prev
[
index
]
=
{
...
prev
[
index
],
mode
:
value
};
prev
[
index
]
=
{
...
prev
[
index
],
mode
:
value
[
0
]
as
AddressFilterMode
};
return
[
...
prev
];
return
[
...
prev
];
});
});
},
[]);
},
[]);
...
@@ -138,7 +145,6 @@ const AddressFilter = ({ type, value = [], handleFilterChange, onClose }: Props)
...
@@ -138,7 +145,6 @@ const AddressFilter = ({ type, value = [], handleFilterChange, onClose }: Props)
isTouched=
{
!
isEqual
(
currentValue
.
filter
(
i
=>
i
.
address
).
map
(
addressFilterToKey
).
sort
(),
value
.
map
(
addressFilterToKey
).
sort
())
}
isTouched=
{
!
isEqual
(
currentValue
.
filter
(
i
=>
i
.
address
).
map
(
addressFilterToKey
).
sort
(),
value
.
map
(
addressFilterToKey
).
sort
())
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
VStack
gap=
{
2
}
>
<
VStack
gap=
{
2
}
>
...
...
ui/advancedFilter/filters/AddressRelationFilter.tsx
View file @
7025b758
import
{
Radio
,
RadioGroup
,
Stack
,
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
type
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
{
type
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
{
Radio
,
RadioGroup
}
from
'
toolkit/chakra/radio
'
;
const
FILTER_PARAM
=
'
address_relation
'
;
const
FILTER_PARAM
=
'
address_relation
'
;
type
Value
=
'
or
'
|
'
and
'
;
type
Value
=
'
or
'
|
'
and
'
;
...
@@ -18,18 +20,16 @@ type Props = {
...
@@ -18,18 +20,16 @@ type Props = {
};
};
const
AddressRelationFilter
=
({
value
=
DEFAULT_VALUE
,
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
AddressRelationFilter
=
({
value
=
DEFAULT_VALUE
,
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
onFilter
=
React
.
useCallback
((
val
:
Value
)
=>
{
const
onFilter
=
React
.
useCallback
((
{
value
}:
{
value
:
string
}
)
=>
{
onClose
&&
onClose
();
onClose
&&
onClose
();
handleFilterChange
(
FILTER_PARAM
,
val
);
handleFilterChange
(
FILTER_PARAM
,
val
ue
as
Value
);
},
[
handleFilterChange
,
onClose
]);
},
[
handleFilterChange
,
onClose
]);
return
(
return
(
<
Box
w=
"120px"
>
<
Box
w=
"120px"
>
<
RadioGroup
onChange=
{
onFilter
}
value=
{
value
}
>
<
RadioGroup
onValueChange=
{
onFilter
}
value=
{
value
}
orientation=
"vertical"
>
<
Stack
direction=
"column"
>
<
Radio
value=
"or"
>
OR
</
Radio
>
<
Radio
value=
"or"
>
OR
</
Radio
>
<
Radio
value=
"and"
>
AND
</
Radio
>
<
Radio
value=
"and"
>
AND
</
Radio
>
</
Stack
>
</
RadioGroup
>
</
RadioGroup
>
</
Box
>
</
Box
>
);
);
...
...
ui/advancedFilter/filters/AgeFilter.tsx
View file @
7025b758
import
{
Flex
,
Input
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -7,6 +7,8 @@ import { ADVANCED_FILTER_AGES, type AdvancedFilterAge, type AdvancedFilterParams
...
@@ -7,6 +7,8 @@ import { ADVANCED_FILTER_AGES, type AdvancedFilterAge, type AdvancedFilterParams
import
dayjs
from
'
lib/date/dayjs
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
{
ndash
}
from
'
lib/html-entities
'
;
import
{
ndash
}
from
'
lib/html-entities
'
;
import
{
Input
}
from
'
toolkit/chakra/input
'
;
import
{
PopoverCloseTriggerWrapper
}
from
'
toolkit/chakra/popover
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TagGroupSelect
from
'
ui/shared/tagGroupSelect/TagGroupSelect
'
;
import
TagGroupSelect
from
'
ui/shared/tagGroupSelect/TagGroupSelect
'
;
...
@@ -48,8 +50,8 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
...
@@ -48,8 +50,8 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
const
to
=
dayjs
().
toISOString
();
const
to
=
dayjs
().
toISOString
();
handleFilterChange
(
FILTER_PARAM_TO
,
to
);
handleFilterChange
(
FILTER_PARAM_TO
,
to
);
handleFilterChange
(
FILTER_PARAM_AGE
,
age
);
handleFilterChange
(
FILTER_PARAM_AGE
,
age
);
onClose
&&
onClose
();
onClose
?.
();
},
[
onClose
,
handleFilterChang
e
]);
},
[
handleFilterChange
,
onClos
e
]);
const
onReset
=
React
.
useCallback
(()
=>
setCurrentValue
(
defaultValue
),
[]);
const
onReset
=
React
.
useCallback
(()
=>
setCurrentValue
(
defaultValue
),
[]);
...
@@ -76,15 +78,16 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
...
@@ -76,15 +78,16 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
isTouched=
{
value
.
age
?
value
.
age
!==
currentValue
.
age
:
!
isEqual
(
currentValue
,
value
)
}
isTouched=
{
value
.
age
?
value
.
age
!==
currentValue
.
age
:
!
isEqual
(
currentValue
,
value
)
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
Flex
gap=
{
3
}
>
<
Flex
gap=
{
3
}
>
<
TagGroupSelect
<
AdvancedFilterAge
>
<
PopoverCloseTriggerWrapper
>
items=
{
ADVANCED_FILTER_AGES
.
map
(
val
=>
({
id
:
val
,
title
:
val
}))
}
<
TagGroupSelect
<
AdvancedFilterAge
>
onChange=
{
onPresetChange
}
items=
{
ADVANCED_FILTER_AGES
.
map
(
val
=>
({
id
:
val
,
title
:
val
}))
}
value=
{
currentValue
.
age
||
undefined
}
onChange=
{
onPresetChange
}
/
>
value=
{
currentValue
.
age
||
undefined
}
/
>
</
PopoverCloseTriggerWrapper
>
</
Flex
>
</
Flex
>
<
Flex
mt=
{
3
}
>
<
Flex
mt=
{
3
}
>
<
Input
<
Input
...
@@ -92,7 +95,7 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
...
@@ -92,7 +95,7 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
onChange=
{
handleFromChange
}
onChange=
{
handleFromChange
}
placeholder=
"From"
placeholder=
"From"
type=
"date"
type=
"date"
size=
"
xs
"
size=
"
sm
"
/>
/>
<
Text
mx=
{
3
}
>
{
ndash
}
</
Text
>
<
Text
mx=
{
3
}
>
{
ndash
}
</
Text
>
<
Input
<
Input
...
@@ -100,7 +103,7 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
...
@@ -100,7 +103,7 @@ const AgeFilter = ({ value = defaultValue, handleFilterChange, onClose }: Props)
onChange=
{
handleToChange
}
onChange=
{
handleToChange
}
placeholder=
"To"
placeholder=
"To"
type=
"date"
type=
"date"
size=
"
xs
"
size=
"
sm
"
/>
/>
</
Flex
>
</
Flex
>
</
TableColumnFilter
>
</
TableColumnFilter
>
...
...
ui/advancedFilter/filters/AmountFilter.tsx
View file @
7025b758
import
{
Flex
,
Input
,
Tag
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -6,6 +6,9 @@ import React from 'react';
...
@@ -6,6 +6,9 @@ import React from 'react';
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
type
{
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
{
ndash
}
from
'
lib/html-entities
'
;
import
{
ndash
}
from
'
lib/html-entities
'
;
import
{
Input
}
from
'
toolkit/chakra/input
'
;
import
{
PopoverCloseTriggerWrapper
}
from
'
toolkit/chakra/popover
'
;
import
{
Tag
}
from
'
toolkit/chakra/tag
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
const
FILTER_PARAM_FROM
=
'
amount_from
'
;
const
FILTER_PARAM_FROM
=
'
amount_from
'
;
...
@@ -44,10 +47,9 @@ type AmountValue = { from?: string; to?: string };
...
@@ -44,10 +47,9 @@ type AmountValue = { from?: string; to?: string };
type
Props
=
{
type
Props
=
{
value
?:
AmountValue
;
value
?:
AmountValue
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
value
?:
string
)
=>
void
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
value
?:
string
)
=>
void
;
onClose
?:
()
=>
void
;
};
};
const
AmountFilter
=
({
value
=
{},
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
AmountFilter
=
({
value
=
{},
handleFilterChange
}:
Props
)
=>
{
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
AmountValue
>
(
value
||
defaultValue
);
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
AmountValue
>
(
value
||
defaultValue
);
const
handleFromChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleFromChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
...
@@ -69,8 +71,7 @@ const AmountFilter = ({ value = {}, handleFilterChange, onClose }: Props) => {
...
@@ -69,8 +71,7 @@ const AmountFilter = ({ value = {}, handleFilterChange, onClose }: Props) => {
const
to
=
(
event
.
currentTarget
as
HTMLDivElement
).
getAttribute
(
'
data-id
'
)
as
string
;
const
to
=
(
event
.
currentTarget
as
HTMLDivElement
).
getAttribute
(
'
data-id
'
)
as
string
;
handleFilterChange
(
FILTER_PARAM_FROM
,
''
);
handleFilterChange
(
FILTER_PARAM_FROM
,
''
);
handleFilterChange
(
FILTER_PARAM_TO
,
to
);
handleFilterChange
(
FILTER_PARAM_TO
,
to
);
onClose
&&
onClose
();
},
[
handleFilterChange
]);
},
[
handleFilterChange
,
onClose
]);
return
(
return
(
<
TableColumnFilter
<
TableColumnFilter
...
@@ -79,25 +80,26 @@ const AmountFilter = ({ value = {}, handleFilterChange, onClose }: Props) => {
...
@@ -79,25 +80,26 @@ const AmountFilter = ({ value = {}, handleFilterChange, onClose }: Props) => {
isTouched=
{
!
isEqual
(
currentValue
,
value
)
}
isTouched=
{
!
isEqual
(
currentValue
,
value
)
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
Flex
gap=
{
3
}
>
<
PopoverCloseTriggerWrapper
>
{
PRESETS
.
map
(
preset
=>
(
<
Flex
gap=
{
3
}
>
<
Tag
{
PRESETS
.
map
(
preset
=>
(
key=
{
preset
.
value
}
<
Tag
data
-
id=
{
preset
.
value
}
key=
{
preset
.
value
}
onClick=
{
onPresetClick
}
data
-
id=
{
preset
.
value
}
variant=
"select"
onClick=
{
onPresetClick
}
>
variant=
"select"
{
preset
.
name
}
>
</
Tag
>
{
preset
.
name
}
))
}
</
Tag
>
</
Flex
>
))
}
</
Flex
>
</
PopoverCloseTriggerWrapper
>
<
Flex
mt=
{
3
}
alignItems=
"center"
>
<
Flex
mt=
{
3
}
alignItems=
"center"
>
<
Input
value=
{
currentValue
.
from
}
onChange=
{
handleFromChange
}
placeholder=
"From"
type=
"number"
size=
"
xs
"
/>
<
Input
value=
{
currentValue
.
from
}
onChange=
{
handleFromChange
}
placeholder=
"From"
type=
"number"
size=
"
sm
"
/>
<
Text
mx=
{
3
}
>
{
ndash
}
</
Text
>
<
Text
mx=
{
3
}
>
{
ndash
}
</
Text
>
<
Input
value=
{
currentValue
.
to
}
onChange=
{
handleToChange
}
placeholder=
"To"
type=
"number"
size=
"
xs
"
/>
<
Input
value=
{
currentValue
.
to
}
onChange=
{
handleToChange
}
placeholder=
"To"
type=
"number"
size=
"
sm
"
/>
</
Flex
>
</
Flex
>
</
TableColumnFilter
>
</
TableColumnFilter
>
);
);
...
...
ui/advancedFilter/filters/AssetFilter.tsx
View file @
7025b758
import
{
Flex
,
Checkbox
,
CheckboxGroup
,
Text
,
Spinner
,
Select
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
,
Spinner
,
createListCollection
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
{
isEqual
}
from
'
es-toolkit
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -7,7 +7,9 @@ import type { TokenInfo } from 'types/api/token';
...
@@ -7,7 +7,9 @@ import type { TokenInfo } from 'types/api/token';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Checkbox
,
CheckboxGroup
}
from
'
toolkit/chakra/checkbox
'
;
import
{
Select
}
from
'
toolkit/chakra/select
'
;
import
{
Tag
}
from
'
toolkit/chakra/tag
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
import
ClearButton
from
'
ui/shared/ClearButton
'
;
import
*
as
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
import
*
as
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
import
FilterInput
from
'
ui/shared/filters/FilterInput
'
;
import
FilterInput
from
'
ui/shared/filters/FilterInput
'
;
...
@@ -23,6 +25,13 @@ const NAME_PARAM_EXCLUDE = 'token_contract_symbols_to_exclude';
...
@@ -23,6 +25,13 @@ const NAME_PARAM_EXCLUDE = 'token_contract_symbols_to_exclude';
export
type
AssetFilterMode
=
'
include
'
|
'
exclude
'
;
export
type
AssetFilterMode
=
'
include
'
|
'
exclude
'
;
const
collection
=
createListCollection
({
items
:
[
{
label
:
'
Include
'
,
value
:
'
include
'
},
{
label
:
'
Exclude
'
,
value
:
'
exclude
'
},
],
});
// add native token
// add native token
type
Value
=
Array
<
{
token
:
TokenInfo
;
mode
:
AssetFilterMode
}
>
;
type
Value
=
Array
<
{
token
:
TokenInfo
;
mode
:
AssetFilterMode
}
>
;
...
@@ -31,10 +40,9 @@ type Props = {
...
@@ -31,10 +40,9 @@ type Props = {
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
val
:
Array
<
string
>
)
=>
void
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
val
:
Array
<
string
>
)
=>
void
;
columnName
:
string
;
columnName
:
string
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
onClose
?:
()
=>
void
;
};
};
const
AssetFilter
=
({
value
=
[],
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
AssetFilter
=
({
value
=
[],
handleFilterChange
}:
Props
)
=>
{
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Value
>
([
...
value
]);
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Value
>
([
...
value
]);
const
[
searchTerm
,
setSearchTerm
]
=
React
.
useState
<
string
>
(
''
);
const
[
searchTerm
,
setSearchTerm
]
=
React
.
useState
<
string
>
(
''
);
const
debouncedSearchTerm
=
useDebounce
(
searchTerm
,
300
);
const
debouncedSearchTerm
=
useDebounce
(
searchTerm
,
300
);
...
@@ -43,11 +51,10 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -43,11 +51,10 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
setSearchTerm
(
value
);
setSearchTerm
(
value
);
},
[]);
},
[]);
const
handleModeSelectChange
=
React
.
useCallback
((
index
:
number
)
=>
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
=>
{
const
handleModeSelectChange
=
React
.
useCallback
((
index
:
number
)
=>
({
value
}:
{
value
:
Array
<
string
>
})
=>
{
const
value
=
event
.
target
.
value
as
AssetFilterMode
;
setCurrentValue
(
prev
=>
{
setCurrentValue
(
prev
=>
{
const
newValue
=
[
...
prev
];
const
newValue
=
[
...
prev
];
newValue
[
index
]
=
{
...
prev
[
index
],
mode
:
value
};
newValue
[
index
]
=
{
...
prev
[
index
],
mode
:
value
[
0
]
as
AssetFilterMode
};
return
newValue
;
return
newValue
;
});
});
},
[]);
},
[]);
...
@@ -88,11 +95,10 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -88,11 +95,10 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
isTouched=
{
!
isEqual
(
currentValue
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
(),
value
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
())
}
isTouched=
{
!
isEqual
(
currentValue
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
(),
value
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
())
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
FilterInput
<
FilterInput
size=
"
xs
"
size=
"
sm
"
onChange=
{
onSearchChange
}
onChange=
{
onSearchChange
}
placeholder=
"Token name or symbol"
placeholder=
"Token name or symbol"
initialValue=
{
searchTerm
}
initialValue=
{
searchTerm
}
...
@@ -100,17 +106,15 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -100,17 +106,15 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
{
!
searchTerm
&&
currentValue
.
map
((
item
,
index
)
=>
(
{
!
searchTerm
&&
currentValue
.
map
((
item
,
index
)
=>
(
<
Flex
key=
{
item
.
token
.
address
}
alignItems=
"center"
>
<
Flex
key=
{
item
.
token
.
address
}
alignItems=
"center"
>
<
Select
<
Select
size=
"xs"
size=
"sm"
borderRadius=
"base"
value=
{
[
item
.
mode
]
}
value=
{
item
.
mode
}
onValueChange=
{
handleModeSelectChange
(
index
)
}
onChange=
{
handleModeSelectChange
(
index
)
}
collection=
{
collection
}
placeholder=
"Select mode"
minW=
"105px"
minW=
"105px"
w=
"105px"
w=
"105px"
mr=
{
3
}
mr=
{
3
}
>
/>
<
option
value=
"include"
>
Include
</
option
>
<
option
value=
"exclude"
>
Exclude
</
option
>
</
Select
>
<
TokenEntity
.
default
token=
{
item
.
token
}
noLink
noCopy
flexGrow=
{
1
}
/>
<
TokenEntity
.
default
token=
{
item
.
token
}
noLink
noCopy
flexGrow=
{
1
}
/>
<
ClearButton
onClick=
{
handleRemove
(
index
)
}
/>
<
ClearButton
onClick=
{
handleRemove
(
index
)
}
/>
</
Flex
>
</
Flex
>
...
@@ -139,25 +143,19 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -139,25 +143,19 @@ const AssetFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
{
searchTerm
&&
tokensQuery
.
data
&&
!
tokensQuery
.
data
?.
items
.
length
&&
<
Text
>
No tokens found
</
Text
>
}
{
searchTerm
&&
tokensQuery
.
data
&&
!
tokensQuery
.
data
?.
items
.
length
&&
<
Text
>
No tokens found
</
Text
>
}
{
searchTerm
&&
tokensQuery
.
data
&&
Boolean
(
tokensQuery
.
data
?.
items
.
length
)
&&
(
{
searchTerm
&&
tokensQuery
.
data
&&
Boolean
(
tokensQuery
.
data
?.
items
.
length
)
&&
(
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
maxH=
"250px"
overflowY=
"scroll"
mt=
{
3
}
ml=
"-4px"
>
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
maxH=
"250px"
overflowY=
"scroll"
mt=
{
3
}
ml=
"-4px"
>
<
CheckboxGroup
value=
{
currentValue
.
map
(
i
=>
i
.
token
.
address
)
}
>
<
CheckboxGroup
value=
{
currentValue
.
map
(
i
=>
i
.
token
.
address
)
}
orientation=
"vertical"
>
{
tokensQuery
.
data
.
items
.
map
(
token
=>
(
{
tokensQuery
.
data
.
items
.
map
(
token
=>
(
<
Flex
key=
{
token
.
address
}
>
<
Checkbox
<
Checkbox
key=
{
token
.
address
}
value=
{
token
.
address
}
value=
{
token
.
address
}
id=
{
token
.
address
}
id=
{
token
.
address
}
onChange=
{
onTokenClick
(
token
)
}
onChange=
{
onTokenClick
(
token
)
}
overflow=
"hidden"
overflow=
"hidden"
w=
"100%"
w=
"100%"
pl=
{
1
}
pl=
{
1
}
sx=
{
{
>
'
.chakra-checkbox__label
'
:
{
<
TokenEntity
.
default
token=
{
token
}
noLink
noCopy
/>
flexGrow
:
1
,
</
Checkbox
>
},
}
}
>
<
TokenEntity
.
default
token=
{
token
}
noLink
noCopy
/>
</
Checkbox
>
</
Flex
>
))
}
))
}
</
CheckboxGroup
>
</
CheckboxGroup
>
</
Flex
>
</
Flex
>
...
...
ui/advancedFilter/filters/MethodFilter.tsx
View file @
7025b758
import
{
Flex
,
Checkbox
,
CheckboxGroup
,
Spinner
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Spinner
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
,
differenceBy
}
from
'
es-toolkit
'
;
import
{
isEqual
,
differenceBy
}
from
'
es-toolkit
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
AdvancedFilterMethodInfo
,
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
type
{
AdvancedFilterMethodInfo
,
AdvancedFilterParams
}
from
'
types/api/advancedFilter
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
import
{
Checkbox
,
CheckboxGroup
}
from
'
toolkit/chakra/checkbox
'
;
import
FilterInput
from
'
ui/shared/filters/FilterInput
'
;
import
FilterInput
from
'
ui/shared/filters/FilterInput
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
...
@@ -19,10 +19,9 @@ const NAMES_PARAM = 'methods_names';
...
@@ -19,10 +19,9 @@ const NAMES_PARAM = 'methods_names';
type
Props
=
{
type
Props
=
{
value
?:
Array
<
AdvancedFilterMethodInfo
>
;
value
?:
Array
<
AdvancedFilterMethodInfo
>
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
val
:
Array
<
string
>
)
=>
void
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
val
:
Array
<
string
>
)
=>
void
;
onClose
?:
()
=>
void
;
};
};
const
MethodFilter
=
({
value
=
[],
handleFilterChange
,
onClose
}:
Props
)
=>
{
const
MethodFilter
=
({
value
=
[],
handleFilterChange
}:
Props
)
=>
{
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Array
<
AdvancedFilterMethodInfo
>>
([
...
value
]);
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Array
<
AdvancedFilterMethodInfo
>>
([
...
value
]);
const
[
searchTerm
,
setSearchTerm
]
=
React
.
useState
<
string
>
(
''
);
const
[
searchTerm
,
setSearchTerm
]
=
React
.
useState
<
string
>
(
''
);
const
debouncedSearchTerm
=
useDebounce
(
searchTerm
,
300
);
const
debouncedSearchTerm
=
useDebounce
(
searchTerm
,
300
);
...
@@ -43,9 +42,10 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -43,9 +42,10 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
}
}
},
[
methodsQuery
.
data
,
value
,
methodsList
]);
},
[
methodsQuery
.
data
,
value
,
methodsList
]);
const
handleChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
:
React
.
FormEventHandler
<
HTMLLabelElement
>
=
React
.
useCallback
((
event
)
=>
{
const
checked
=
event
.
target
.
checked
;
const
checked
=
(
event
.
target
as
HTMLInputElement
).
checked
;
const
id
=
event
.
target
.
id
as
string
|
typeof
RESET_VALUE
;
const
id
=
event
.
currentTarget
.
getAttribute
(
'
data-id
'
);
if
(
id
===
RESET_VALUE
)
{
if
(
id
===
RESET_VALUE
)
{
setCurrentValue
([]);
setCurrentValue
([]);
setMethodsList
(
methodsQuery
.
data
||
[]);
setMethodsList
(
methodsQuery
.
data
||
[]);
...
@@ -75,11 +75,10 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -75,11 +75,10 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
isTouched=
{
!
isEqual
(
currentValue
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
(),
value
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
())
}
isTouched=
{
!
isEqual
(
currentValue
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
(),
value
.
map
(
i
=>
JSON
.
stringify
(
i
)).
sort
())
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
FilterInput
<
FilterInput
size=
"
xs
"
size=
"
sm
"
onChange=
{
onSearchChange
}
onChange=
{
onSearchChange
}
placeholder=
"Find by function name/ method ID"
placeholder=
"Find by function name/ method ID"
mb=
{
3
}
mb=
{
3
}
...
@@ -89,26 +88,23 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
...
@@ -89,26 +88,23 @@ const MethodFilter = ({ value = [], handleFilterChange, onClose }: Props) => {
{
Boolean
(
searchTerm
)
&&
methodsQuery
.
data
?.
length
===
0
&&
<
span
>
No results found.
</
span
>
}
{
Boolean
(
searchTerm
)
&&
methodsQuery
.
data
?.
length
===
0
&&
<
span
>
No results found.
</
span
>
}
{
methodsQuery
.
data
&&
(
{
methodsQuery
.
data
&&
(
// added negative margin because of checkbox focus styles & overflow hidden
// added negative margin because of checkbox focus styles & overflow hidden
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
maxH=
"250px"
overflowY=
"scroll"
ml=
"-4px"
>
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
maxH=
"250px"
overflowY=
"scroll"
>
<
CheckboxGroup
value=
{
currentValue
.
length
?
currentValue
.
map
(
i
=>
i
.
method_id
)
:
[
RESET_VALUE
]
}
>
<
CheckboxGroup
value=
{
currentValue
.
length
?
currentValue
.
map
(
i
=>
i
.
method_id
)
:
[
]
}
orientation=
"vertical"
>
{
(
searchTerm
?
methodsQuery
.
data
:
(
methodsList
||
[])).
map
(
method
=>
(
{
(
searchTerm
?
methodsQuery
.
data
:
(
methodsList
||
[])).
map
(
method
=>
(
<
Checkbox
<
Checkbox
key=
{
method
.
method_id
}
key=
{
method
.
method_id
}
value=
{
method
.
method_id
}
value=
{
method
.
method_id
}
id=
{
method
.
method_id
}
data
-
id=
{
method
.
method_id
}
onChange=
{
handleChange
}
onChange=
{
handleChange
}
pl=
{
1
}
sx=
{
{
'
.chakra-checkbox__label
'
:
{
flexGrow
:
1
,
},
}
}
>
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
id=
{
method
.
method_id
}
>
<
Flex
justifyContent=
"space-between"
alignItems=
"center"
id=
{
method
.
method_id
}
>
<
chakra
.
span
overflow=
"hidden"
whiteSpace=
"nowrap"
textOverflow=
"ellipsis"
>
{
method
.
name
||
method
.
method_id
}
</
chakra
.
span
>
<
chakra
.
span
overflow=
"hidden"
whiteSpace=
"nowrap"
textOverflow=
"ellipsis"
>
{
method
.
name
||
method
.
method_id
}
</
chakra
.
span
>
<
Tag
colorScheme=
"gray"
isTruncated
ml=
{
2
}
>
<
Badge
colorPalette=
"gray"
truncated
ml=
"auto"
>
{
method
.
method_id
}
{
method
.
method_id
}
</
Tag
>
</
Badge
>
</
Flex
>
</
Flex
>
</
Checkbox
>
</
Checkbox
>
))
}
))
}
...
...
ui/advancedFilter/filters/TypeFilter.tsx
View file @
7025b758
import
{
Flex
,
Checkbox
,
CheckboxGroup
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
{
isEqual
,
without
}
from
'
es-toolkit
'
;
import
{
isEqual
,
without
}
from
'
es-toolkit
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
AdvancedFilterParams
,
AdvancedFilterType
}
from
'
types/api/advancedFilter
'
;
import
type
{
AdvancedFilterParams
,
AdvancedFilterType
}
from
'
types/api/advancedFilter
'
;
import
{
Checkbox
,
CheckboxGroup
}
from
'
toolkit/chakra/checkbox
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
TableColumnFilter
from
'
ui/shared/filters/TableColumnFilter
'
;
import
{
ADVANCED_FILTER_TYPES_WITH_ALL
}
from
'
../constants
'
;
import
{
ADVANCED_FILTER_TYPES_WITH_ALL
}
from
'
../constants
'
;
...
@@ -14,48 +14,49 @@ const RESET_VALUE = 'all';
...
@@ -14,48 +14,49 @@ const RESET_VALUE = 'all';
const
FILTER_PARAM
=
'
transaction_types
'
;
const
FILTER_PARAM
=
'
transaction_types
'
;
type
Props
=
{
type
Props
=
{
value
?:
Array
<
AdvancedFilterType
>
;
value
?:
Array
<
AdvancedFilterType
|
typeof
RESET_VALUE
>
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
value
:
Array
<
AdvancedFilterType
>
)
=>
void
;
handleFilterChange
:
(
filed
:
keyof
AdvancedFilterParams
,
value
:
Array
<
AdvancedFilterType
>
)
=>
void
;
onClose
?:
()
=>
void
;
};
};
const
TypeFilter
=
({
value
=
[
],
handleFilterChange
,
onClos
e
}:
Props
)
=>
{
const
TypeFilter
=
({
value
=
[
RESET_VALUE
],
handleFilterChang
e
}:
Props
)
=>
{
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Array
<
AdvancedFilterType
>>
([
...
value
]);
const
[
currentValue
,
setCurrentValue
]
=
React
.
useState
<
Array
<
AdvancedFilterType
|
typeof
RESET_VALUE
>>
([
...
value
]);
const
handleChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
React
.
useCallback
((
value
:
Array
<
string
>
)
=>
{
const
checked
=
event
.
target
.
checked
;
setCurrentValue
((
prev
)
=>
{
const
id
=
event
.
target
.
id
as
AdvancedFilterType
|
typeof
RESET_VALUE
;
if
(
value
.
length
===
0
)
{
if
(
id
===
RESET_VALUE
)
{
return
[
RESET_VALUE
];
setCurrentValue
([]);
}
}
else
{
setCurrentValue
(
prev
=>
checked
?
[
...
prev
,
id
]
:
without
(
prev
,
id
));
const
diff
=
value
.
filter
(
item
=>
!
prev
.
includes
(
item
));
}
if
(
diff
.
includes
(
RESET_VALUE
))
{
return
[
RESET_VALUE
];
}
return
without
(
value
as
Array
<
AdvancedFilterType
>
,
RESET_VALUE
);
});
},
[]);
},
[]);
const
onReset
=
React
.
useCallback
(()
=>
setCurrentValue
([]),
[]);
const
onReset
=
React
.
useCallback
(()
=>
setCurrentValue
([
RESET_VALUE
]),
[]);
const
onFilter
=
React
.
useCallback
(()
=>
{
const
onFilter
=
React
.
useCallback
(()
=>
{
handleFilterChange
(
FILTER_PARAM
,
currentValue
);
handleFilterChange
(
FILTER_PARAM
,
currentValue
.
filter
(
item
=>
item
!==
RESET_VALUE
)
);
},
[
handleFilterChange
,
currentValue
]);
},
[
handleFilterChange
,
currentValue
]);
return
(
return
(
<
TableColumnFilter
<
TableColumnFilter
title=
"Type of transfer"
title=
"Type of transfer"
isFilled=
{
currentValue
.
length
>
0
}
isFilled=
{
!
(
currentValue
.
length
===
1
&&
currentValue
[
0
]
===
RESET_VALUE
)
}
isTouched=
{
!
isEqual
(
currentValue
.
sort
(),
value
.
sort
())
}
isTouched=
{
!
isEqual
(
currentValue
.
sort
(),
value
.
sort
())
}
onFilter=
{
onFilter
}
onFilter=
{
onFilter
}
onReset=
{
onReset
}
onReset=
{
onReset
}
onClose=
{
onClose
}
hasReset
hasReset
>
>
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
>
<
Flex
display=
"flex"
flexDir=
"column"
rowGap=
{
3
}
>
<
CheckboxGroup
value=
{
currentValue
.
length
?
currentValue
:
[
RESET_VALUE
]
}
>
<
CheckboxGroup
value=
{
currentValue
}
onValueChange=
{
handleChange
}
orientation=
"vertical"
>
{
ADVANCED_FILTER_TYPES_WITH_ALL
.
map
(
type
=>
(
{
ADVANCED_FILTER_TYPES_WITH_ALL
.
map
(
type
=>
(
<
Checkbox
<
Checkbox
key=
{
type
.
id
}
key=
{
type
.
id
}
value=
{
type
.
id
}
value=
{
type
.
id
}
id=
{
type
.
id
}
onChange=
{
handleChange
}
>
>
{
type
.
name
}
{
type
.
name
}
</
Checkbox
>
</
Checkbox
>
...
...
ui/pages/AdvancedFilter.tsx
View file @
7025b758
import
{
import
{
Table
,
Tbody
,
Tr
,
Th
,
Td
,
Thead
,
Box
,
Box
,
Text
,
Text
,
Tag
,
TagCloseButton
,
chakra
,
chakra
,
Flex
,
Flex
,
TagLabel
,
HStack
,
HStack
,
Link
,
}
from
'
@chakra-ui/react
'
;
}
from
'
@chakra-ui/react
'
;
import
{
omit
}
from
'
es-toolkit
'
;
import
{
omit
}
from
'
es-toolkit
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
...
@@ -31,6 +21,9 @@ import getValuesArrayFromQuery from 'lib/getValuesArrayFromQuery';
...
@@ -31,6 +21,9 @@ import getValuesArrayFromQuery from 'lib/getValuesArrayFromQuery';
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
ADVANCED_FILTER_ITEM
}
from
'
stubs/advancedFilter
'
;
import
{
ADVANCED_FILTER_ITEM
}
from
'
stubs/advancedFilter
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
TableBody
,
TableCell
,
TableColumnHeader
,
TableHeaderSticky
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
{
Tag
}
from
'
toolkit/chakra/tag
'
;
import
ColumnsButton
from
'
ui/advancedFilter/ColumnsButton
'
;
import
ColumnsButton
from
'
ui/advancedFilter/ColumnsButton
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
type
{
ColumnsIds
}
from
'
ui/advancedFilter/constants
'
;
import
{
TABLE_COLUMNS
}
from
'
ui/advancedFilter/constants
'
;
import
{
TABLE_COLUMNS
}
from
'
ui/advancedFilter/constants
'
;
...
@@ -145,12 +138,12 @@ const AdvancedFilter = () => {
...
@@ -145,12 +138,12 @@ const AdvancedFilter = () => {
const content = (
const content = (
<
AddressHighlightProvider
>
<
AddressHighlightProvider
>
<
Box
maxW=
"100%"
overflowX=
"scroll"
whiteSpace=
"nowrap"
>
<
Box
maxW=
"100%"
overflowX=
"scroll"
whiteSpace=
"nowrap"
>
<
Table
style=
{
{
tableLayout
:
'
fixed
'
}
}
minWidth=
"950px"
w=
"100%"
>
<
Table
Root
tableLayout=
"fixed"
minWidth=
"950px"
w=
"100%"
>
<
T
head
w=
"100%"
display=
"table"
>
<
T
ableHeaderSticky
>
<
T
r
>
<
T
ableRow
>
{
columnsToShow
.
map
(
column
=>
{
{
columnsToShow
.
map
(
column
=>
{
return
(
return
(
<
T
h
<
T
ableColumnHeader
key=
{
column
.
id
}
key=
{
column
.
id
}
isNumeric=
{
column
.
isNumeric
}
isNumeric=
{
column
.
isNumeric
}
minW=
{
column
.
width
}
minW=
{
column
.
width
}
...
@@ -167,33 +160,45 @@ const AdvancedFilter = () => {
...
@@ -167,33 +160,45 @@ const AdvancedFilter = () => {
searchParams=
{
data
?.
search_params
}
searchParams=
{
data
?.
search_params
}
isLoading=
{
isPlaceholderData
}
isLoading=
{
isPlaceholderData
}
/>
/>
</
T
h
>
</
T
ableColumnHeader
>
);
);
})
}
})
}
</
T
r
>
</
T
ableRow
>
</
T
head
>
</
T
ableHeaderSticky
>
<
T
body
w=
"100%"
display=
"table"
>
<
T
ableBody
>
{
data
?.
items
.
map
((
item
,
index
)
=>
(
{
data
?.
items
.
map
((
item
,
index
)
=>
(
<
Tr
key=
{
item
.
hash
+
String
(
index
)
}
>
<
TableRow
key=
{
item
.
hash
+
String
(
index
)
}
>
{
columnsToShow
.
map
(
column
=>
(
{
columnsToShow
.
map
(
column
=>
{
<
Td
const
textAlign
=
(()
=>
{
key=
{
item
.
hash
+
column
.
id
}
if
(
column
.
id
===
'
or_and
'
)
{
isNumeric=
{
column
.
isNumeric
}
return
'
center
'
;
minW=
{
column
.
width
}
}
maxW=
{
column
.
width
}
if
(
column
.
isNumeric
)
{
w=
{
column
.
width
}
return
'
right
'
;
wordBreak=
"break-word"
}
whiteSpace=
"nowrap"
return
'
start
'
;
overflow=
"hidden"
})();
textAlign=
{
column
.
id
===
'
or_and
'
?
'
center
'
:
'
start
'
}
>
return
(
<
ItemByColumn
item=
{
item
}
column=
{
column
.
id
}
isLoading=
{
isPlaceholderData
}
/>
<
TableCell
</
Td
>
key=
{
item
.
hash
+
column
.
id
}
))
}
isNumeric=
{
column
.
isNumeric
}
</
Tr
>
minW=
{
column
.
width
}
maxW=
{
column
.
width
}
w=
{
column
.
width
}
wordBreak=
"break-word"
whiteSpace=
"nowrap"
overflow=
"hidden"
textAlign=
{
textAlign
}
>
<
ItemByColumn
item=
{
item
}
column=
{
column
.
id
}
isLoading=
{
isPlaceholderData
}
/>
</
TableCell
>
);
})
}
</
TableRow
>
))
}
))
}
</
T
b
ody
>
</
T
ableB
ody
>
</
Table
>
</
Table
Root
>
</
Box
>
</
Box
>
</
AddressHighlightProvider
>
</
AddressHighlightProvider
>
);
);
...
@@ -223,42 +228,36 @@ const AdvancedFilter = () => {
...
@@ -223,42 +228,36 @@ const AdvancedFilter = () => {
</
Flex
>
</
Flex
>
<
HStack
gap=
{
2
}
flexWrap=
"wrap"
mb=
{
6
}
>
<
HStack
gap=
{
2
}
flexWrap=
"wrap"
mb=
{
6
}
>
{
filterTags
.
map
(
t
=>
(
{
filterTags
.
map
(
t
=>
(
<
Tag
key=
{
t
.
name
}
colorScheme=
"blue"
display=
"inline-flex"
>
<
Tag
key=
{
t
.
name
}
colorScheme=
"blue"
display=
"inline-flex"
onClose=
{
onClearFilter
(
t
.
key
)
}
closable
>
<
TagLabel
>
<
chakra
.
span
color=
"text_secondary"
>
{
t
.
name
}
:
</
chakra
.
span
>
<
chakra
.
span
color=
"text_secondary"
>
{
t
.
name
}
:
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
{
t
.
value
}
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
{
t
.
value
}
</
chakra
.
span
>
</
TagLabel
>
<
TagCloseButton
onClick=
{
onClearFilter
(
t
.
key
)
}
/>
</
Tag
>
</
Tag
>
))
}
))
}
{
filterTags
.
length
===
0
&&
(
{
filterTags
.
length
===
0
&&
(
<>
<>
<
Tag
colorScheme=
"blue"
display=
"inline-flex"
>
<
Tag
colorScheme=
"blue"
display=
"inline-flex"
>
<
TagLabel
>
<
chakra
.
span
color=
"text_secondary"
>
Type:
</
chakra
.
span
>
<
chakra
.
span
color=
"text_secondary"
>
Type:
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
All
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
All
</
chakra
.
span
>
</
TagLabel
>
</
Tag
>
</
Tag
>
<
Tag
colorScheme=
"blue"
display=
"inline-flex"
>
<
Tag
colorScheme=
"blue"
display=
"inline-flex"
>
<
TagLabel
>
<
chakra
.
span
color=
"text_secondary"
>
Age:
</
chakra
.
span
>
<
chakra
.
span
color=
"text_secondary"
>
Age:
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
7d
</
chakra
.
span
>
<
chakra
.
span
color=
"text"
>
7d
</
chakra
.
span
>
</
TagLabel
>
</
Tag
>
</
Tag
>
</>
</>
)
}
)
}
</
HStack
>
</
HStack
>
<
DataListDisplay
<
DataListDisplay
isError=
{
isError
}
isError=
{
isError
}
items
=
{
data
?.
items
}
items
Num=
{
data
?.
items
.
length
}
emptyText=
"There are no transactions."
emptyText=
"There are no transactions."
content=
{
content
}
actionBar=
{
actionBar
}
actionBar=
{
actionBar
}
filterProps=
{
{
filterProps=
{
{
hasActiveFilters
:
Object
.
values
(
filters
).
some
(
Boolean
),
hasActiveFilters
:
Object
.
values
(
filters
).
some
(
Boolean
),
emptyFilteredText
:
'
No match found for current filter
'
,
emptyFilteredText
:
'
No match found for current filter
'
,
}
}
}
}
/>
>
{
content
}
</
DataListDisplay
>
</>
</>
);
);
};
};
...
...
ui/shared/RawInputData.tsx
View file @
7025b758
...
@@ -43,7 +43,7 @@ const RawInputData = ({ hex, rightSlot: rightSlotProp, defaultDataType = 'Hex',
...
@@ -43,7 +43,7 @@ const RawInputData = ({ hex, rightSlot: rightSlotProp, defaultDataType = 'Hex',
mr=
"auto"
mr=
"auto"
>
>
<
SelectControl
loading=
{
isLoading
}
>
<
SelectControl
loading=
{
isLoading
}
>
<
SelectValueText
placeholder=
"Select
framework
"
/>
<
SelectValueText
placeholder=
"Select
type
"
/>
</
SelectControl
>
</
SelectControl
>
<
SelectContent
>
<
SelectContent
>
{
collection
.
items
.
map
((
item
)
=>
(
{
collection
.
items
.
map
((
item
)
=>
(
...
...
ui/shared/entities/address/AddressIconDelegated.tsx
View file @
7025b758
import
{
Box
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
interface
Props
{
interface
Props
{
isVerified
:
boolean
;
isVerified
:
boolean
;
}
}
...
...
ui/shared/entities/validator/ValidatorEntity.tsx
View file @
7025b758
import
type
{
As
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -60,21 +59,20 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
...
@@ -60,21 +59,20 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
id
:
string
;
id
:
string
;
}
}
const
UserOp
Entity
=
(
props
:
EntityProps
)
=>
{
const
Validator
Entity
=
(
props
:
EntityProps
)
=>
{
const
partsProps
=
distributeEntityProps
(
props
);
const
partsProps
=
distributeEntityProps
(
props
);
const
content
=
<
Content
{
...
partsProps
.
content
}
/>;
return
(
return
(
<
Container
{
...
partsProps
.
container
}
>
<
Container
{
...
partsProps
.
container
}
>
<
Icon
{
...
partsProps
.
icon
}
/>
<
Icon
{
...
partsProps
.
icon
}
/>
<
Link
{
...
partsProps
.
link
}
>
{
props
.
noLink
?
content
:
<
Link
{
...
partsProps
.
link
}
>
{
content
}
</
Link
>
}
<
Content
{
...
partsProps
.
content
}
/>
</
Link
>
<
Copy
{
...
partsProps
.
copy
}
/>
<
Copy
{
...
partsProps
.
copy
}
/>
</
Container
>
</
Container
>
);
);
};
};
export
default
React
.
memo
(
chakra
<
As
,
EntityProps
>
(
UserOp
Entity
));
export
default
React
.
memo
(
chakra
(
Validator
Entity
));
export
{
export
{
Container
,
Container
,
...
...
ui/shared/filters/TableColumnFilter.tsx
View file @
7025b758
...
@@ -24,7 +24,7 @@ const TableColumnFilter = ({ title, isFilled, isTouched, hasReset, onFilter, onR
...
@@ -24,7 +24,7 @@ const TableColumnFilter = ({ title, isFilled, isTouched, hasReset, onFilter, onR
},
[
onFilter
]);
},
[
onFilter
]);
return
(
return
(
<>
<>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
columnGap=
{
6
}
>
<
Text
color=
"text.secondary"
fontWeight=
"600"
>
{
title
}
</
Text
>
<
Text
color=
"text.secondary"
fontWeight=
"600"
>
{
title
}
</
Text
>
{
hasReset
&&
(
{
hasReset
&&
(
<
Button
<
Button
...
...
ui/shared/filters/TableColumnFilterWrapper.tsx
View file @
7025b758
...
@@ -19,6 +19,7 @@ const TableColumnFilterWrapper = ({ columnName, className, children, isLoading,
...
@@ -19,6 +19,7 @@ const TableColumnFilterWrapper = ({ columnName, className, children, isLoading,
<
PopoverRoot
>
<
PopoverRoot
>
<
PopoverTrigger
>
<
PopoverTrigger
>
<
Button
<
Button
display=
"inline-flex"
aria
-
label=
{
`filter by ${ columnName }`
}
aria
-
label=
{
`filter by ${ columnName }`
}
variant=
"dropdown"
variant=
"dropdown"
borderWidth=
"0"
borderWidth=
"0"
...
@@ -28,16 +29,9 @@ const TableColumnFilterWrapper = ({ columnName, className, children, isLoading,
...
@@ -28,16 +29,9 @@ const TableColumnFilterWrapper = ({ columnName, className, children, isLoading,
selected=
{
selected
}
selected=
{
selected
}
borderRadius=
"4px"
borderRadius=
"4px"
size=
"sm"
size=
"sm"
textStyle=
"sm"
fontWeight=
{
500
}
fontWeight=
{
500
}
padding=
{
0
}
padding=
{
0
}
css=
{
{
'
span:only-child
'
:
{
mx
:
0
,
},
'
span:not(:only-child)
'
:
{
mr
:
'
2px
'
,
},
}
}
>
>
<
IconSvg
name=
"filter"
w=
"19px"
h=
"19px"
/>
<
IconSvg
name=
"filter"
w=
"19px"
h=
"19px"
/>
{
Boolean
(
value
)
&&
<
chakra
.
span
>
{
value
}
</
chakra
.
span
>
}
{
Boolean
(
value
)
&&
<
chakra
.
span
>
{
value
}
</
chakra
.
span
>
}
...
...
ui/shared/tagGroupSelect/TagGroupSelect.tsx
View file @
7025b758
...
@@ -19,7 +19,7 @@ type Props<T extends string> = {
...
@@ -19,7 +19,7 @@ type Props<T extends string> = {
}
}
);
);
const
TagGroupSelect
=
<
T
extends
string
>
(
{
items
,
value
,
isMulti
,
onChange
,
tagSize
}
: Props
<
T
>
) =
>
{
const
TagGroupSelect
=
<
T
extends
string
>
(
{
items
,
value
,
isMulti
,
onChange
,
tagSize
,
...
rest
}
: Props
<
T
>
) =
>
{
const
onItemClick
=
React
.
useCallback
((
event
:
React
.
SyntheticEvent
)
=>
{
const
onItemClick
=
React
.
useCallback
((
event
:
React
.
SyntheticEvent
)
=>
{
const
itemValue
=
(
event
.
currentTarget
as
HTMLDivElement
).
getAttribute
(
'
data-id
'
)
as
T
;
const
itemValue
=
(
event
.
currentTarget
as
HTMLDivElement
).
getAttribute
(
'
data-id
'
)
as
T
;
if
(
isMulti
)
{
if
(
isMulti
)
{
...
@@ -36,7 +36,7 @@ const TagGroupSelect = <T extends string>({ items, value, isMulti, onChange, tag
...
@@ -36,7 +36,7 @@ const TagGroupSelect = <T extends string>({ items, value, isMulti, onChange, tag
},
[
isMulti
,
onChange
,
value
]);
},
[
isMulti
,
onChange
,
value
]);
return
(
return
(
<
HStack
>
<
HStack
{
...
rest
}
>
{
items
.
map
(
item
=>
{
{
items
.
map
(
item
=>
{
const
isSelected
=
isMulti
?
value
.
includes
(
item
.
id
)
:
value
===
item
.
id
;
const
isSelected
=
isMulti
?
value
.
includes
(
item
.
id
)
:
value
===
item
.
id
;
return
(
return
(
...
...
ui/showcases/Tag.tsx
View file @
7025b758
...
@@ -47,6 +47,15 @@ const TagShowcase = () => {
...
@@ -47,6 +47,15 @@ const TagShowcase = () => {
</
SamplesStack
>
</
SamplesStack
>
</
Section
>
</
Section
>
<
Section
>
<
SectionHeader
>
Closable
</
SectionHeader
>
<
SamplesStack
>
<
Sample
label=
"closable: true"
>
<
Tag
closable
>
My tag
</
Tag
>
</
Sample
>
</
SamplesStack
>
</
Section
>
<
Section
>
<
Section
>
<
SectionHeader
>
Loading
</
SectionHeader
>
<
SectionHeader
>
Loading
</
SectionHeader
>
<
SamplesStack
>
<
SamplesStack
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment