Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feature) Summary by asset: configurable balances representation #753

Merged
merged 69 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
471d8d1
Merge pull request #752 from bitfinexcom/staging
prdn Jan 10, 2024
b760037
Add filter summary icon
alexstotsky Dec 14, 2023
97ef3d7
Add minimum balance related keys/descriptions
alexstotsky Dec 14, 2023
1a2f75b
Actualize icons export
alexstotsky Dec 14, 2023
b05b520
Update summary by asset constants
alexstotsky Jan 4, 2024
e240b5d
Add setMinimumBalance action
alexstotsky Jan 4, 2024
f96efe7
Actualize reducers handling cases, update initial state
alexstotsky Jan 4, 2024
9290f60
Implement minimum balance selector
alexstotsky Jan 4, 2024
11c8815
Enhance input type number appearance
alexstotsky Jan 4, 2024
96afcf3
[wip] Summary by asset filters
alexstotsky Jan 4, 2024
b33d1c6
Add filters to summary by asset section
alexstotsky Jan 4, 2024
03ac2fb
Update summary filter icon
alexstotsky Jan 4, 2024
a395993
Fix minimum balance getter
alexstotsky Jan 4, 2024
ff3c331
Adjust summary filters positioning
alexstotsky Jan 4, 2024
346e194
Adjust summery filters row
alexstotsky Jan 4, 2024
1266ecc
Update summary constants
alexstotsky Jan 4, 2024
70abf66
Add min balance usage action
alexstotsky Jan 4, 2024
cd88dab
Update summary by asset reducers
alexstotsky Jan 4, 2024
37612ed
Add getUseMinBalance selector
alexstotsky Jan 4, 2024
eeeeb88
[wip] Summary filters handlers
alexstotsky Jan 4, 2024
414bf32
Adjust summary filter icon
alexstotsky Jan 5, 2024
d0d93a0
Add summery filters btn styling
alexstotsky Jan 5, 2024
394370f
Add summary filter button
alexstotsky Jan 5, 2024
1d9c02f
Improve filters icon positioning and styling
alexstotsky Jan 5, 2024
bbf6515
Actualize colors and on hover behavior
alexstotsky Jan 5, 2024
b3a8138
Rework and improve summary by asset titles section
alexstotsky Jan 5, 2024
3ba54e7
Fix summary filters modal positioning
alexstotsky Jan 5, 2024
9f1416c
Fix filter flickering on refresh
alexstotsky Jan 8, 2024
fc8b38b
Adjust icon config
alexstotsky Jan 8, 2024
94cce80
Actualize filters active state styling
alexstotsky Jan 8, 2024
4359efc
Add summary filters popover menu styling
alexstotsky Jan 8, 2024
398799f
Switch row and title styling
alexstotsky Jan 8, 2024
6fb2b50
Add summary filters row and title
alexstotsky Jan 8, 2024
761611f
Add min balance imput label
alexstotsky Jan 8, 2024
9f9badc
Actualize imput label styling
alexstotsky Jan 8, 2024
8b8eb70
Add balance usage switch, update positioning
alexstotsky Jan 8, 2024
c4c700a
Update themes
alexstotsky Jan 8, 2024
46d7ee4
Actualize switch btn representation
alexstotsky Jan 8, 2024
da2b085
Update swicth config
alexstotsky Jan 8, 2024
d05e0b9
Fix indicator alignment
alexstotsky Jan 8, 2024
e1c0d45
Rework toggling min balance action
alexstotsky Jan 8, 2024
c8580cd
Update by asset constants
alexstotsky Jan 8, 2024
d03585a
Implement minimum balance usage toggling
alexstotsky Jan 8, 2024
6c9d33b
Actualize summary by asset reducers cases
alexstotsky Jan 8, 2024
7342436
Update switch classes, cleanup
alexstotsky Jan 8, 2024
cbf1d96
Fix classes
alexstotsky Jan 8, 2024
6408d4b
Improve switch active state representation
alexstotsky Jan 8, 2024
b5f77b4
Update use min balance initial state
alexstotsky Jan 9, 2024
a83722c
Add minimum balance input
alexstotsky Jan 9, 2024
3043bad
Fix input key values types related warnings
alexstotsky Jan 9, 2024
8e1a8dc
Allow optional labels for input keys
alexstotsky Jan 9, 2024
cc2883d
Adjust initial minimum balance
alexstotsky Jan 9, 2024
de89b9b
Implement balance changing flow
alexstotsky Jan 9, 2024
836f5c8
Add customizable disabled state for input key
alexstotsky Jan 9, 2024
e56d6e3
Claenup
alexstotsky Jan 9, 2024
df9b7de
Adjust minimum balance input styling
alexstotsky Jan 9, 2024
2e1b5c6
Implement minimum balance disabled state handling and representation
alexstotsky Jan 9, 2024
1b02cf9
Add input balance currency icon
alexstotsky Jan 9, 2024
474bc6a
Implement currency type styling and positioning
alexstotsky Jan 9, 2024
6dddbb2
Update getMinimumBalance selector
alexstotsky Jan 9, 2024
1ecea78
Improve balance value handling
alexstotsky Jan 9, 2024
df84411
Update summary by asset reducers
alexstotsky Jan 9, 2024
52a7c60
Update balance target value setting
alexstotsky Jan 9, 2024
1697bdd
Actualize prepareSummaryByAssetData handler
alexstotsky Jan 9, 2024
b58dca1
Implement minimum balances handling flow
alexstotsky Jan 9, 2024
d7b7a6e
Improve merged entries filtering flow
alexstotsky Jan 9, 2024
4a033be
Lint fix
alexstotsky Jan 10, 2024
9693da9
Cleanup
alexstotsky Jan 10, 2024
faecf7c
Update getUseMinBalance selector default
alexstotsky Jan 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion public/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,12 @@
"volume": "Volume",
"total": "Total",
"trading_fees": "Trading Fees",
"fund_earnings": "Funding Earnings"
"fund_earnings": "Funding Earnings",
"filter": {
"title": "Filter",
"min_balance_switch": "Minimum Balance",
"min_balance_input": "Set a minimum balance for assets to show up in the table."
}
}
},
"symbols": {
Expand Down
26 changes: 18 additions & 8 deletions src/components/AppSummary/AppSummary.byAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ import { fetchData, refresh } from 'state/summaryByAsset/actions'
import {
getPageLoading,
getDataReceived,
getUseMinBalance,
getMinimumBalance,
getSummaryByAssetTotal,
getSummaryByAssetEntries,
} from 'state/summaryByAsset/selectors'
import { getTimezone } from 'state/base/selectors'
import { getIsSyncRequired } from 'state/sync/selectors'
import { getTimeRange, getTimeFrame } from 'state/timeRange/selectors'

import SummaryFilters from './AppSummary.filters'
import { getAssetColumns } from './AppSummary.columns'
import { prepareSummaryByAssetData } from './AppSummary.helpers'

Expand All @@ -32,6 +35,8 @@ const AppSummaryByAsset = () => {
const entries = useSelector(getSummaryByAssetEntries)
const isSyncRequired = useSelector(getIsSyncRequired)
const { start, end } = useSelector(getTimeFrame)
const minimumBalance = useSelector(getMinimumBalance)
const useMinimumBalance = useSelector(getUseMinBalance)

useEffect(() => {
if (!dataReceived && !pageLoading && !isSyncRequired) {
Expand All @@ -44,8 +49,8 @@ const AppSummaryByAsset = () => {
}, [timeRange])

const preparedData = useMemo(
() => prepareSummaryByAssetData(entries, total, t),
[entries, total, t],
() => prepareSummaryByAssetData(entries, total, t, minimumBalance, useMinimumBalance),
[entries, total, t, minimumBalance, useMinimumBalance],
)

const columns = useMemo(
Expand All @@ -71,12 +76,17 @@ const AppSummaryByAsset = () => {

return (
<div className='app-summary-item full-width-item'>
<div className='app-summary-item-title'>
{t('summary.by_asset.title')}
</div>
<div className='app-summary-item-sub-title'>
{t('summary.by_asset.sub_title')}
{`${formatDate(start, timezone)} - ${formatDate(end, timezone)}`}
<div className='app-summary-item-title--row'>
<div>
<div className='app-summary-item-title'>
{t('summary.by_asset.title')}
</div>
<div className='app-summary-item-sub-title'>
{t('summary.by_asset.sub_title')}
{`${formatDate(start, timezone)} - ${formatDate(end, timezone)}`}
</div>
</div>
<SummaryFilters />
</div>
{showContent}
</div>
Expand Down
95 changes: 95 additions & 0 deletions src/components/AppSummary/AppSummary.filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import classNames from 'classnames'
import {
Switch,
Popover,
Position,
Alignment,
} from '@blueprintjs/core'

import Icon from 'icons'
import InputKey from 'components/Auth/InputKey'
import { getMinimumBalance, getUseMinBalance } from 'state/summaryByAsset/selectors'
import { setMinimumBalance, toggleUseMinimumBalance } from 'state/summaryByAsset/actions'

const SummaryFilters = () => {
const { t } = useTranslation()
const dispatch = useDispatch()
const minimumBalance = useSelector(getMinimumBalance)
const useMinimumBalance = useSelector(getUseMinBalance)
const [isOpen, setIsOpen] = useState(false)
const [balanceValue, setBalanceValue] = useState(minimumBalance)

const togglePopover = (isPopoverOpen) => {
setIsOpen(isPopoverOpen)
}

const onChange = (event) => {
const { value } = event.target
setBalanceValue(value)
dispatch(setMinimumBalance(value))
}

const classes = classNames('summary-filters--menu', {
'summary-filters--menu-open': isOpen,
})

const switchClasses = classNames('switch-btn', {
active: useMinimumBalance,
})

return (
<div className={classes}>
<Popover
minimal
autoFocus={false}
usePortal={false}
position={Position.BOTTOM_RIGHT}
onOpening={() => togglePopover(true)}
onClosing={() => togglePopover(false)}
content={(
<div className='summary-filters--menu-content'>
<div className='switch-row'>
<div className='switch-title'>
{t('summary.by_asset.filter.min_balance_switch')}
</div>
<Switch
large
className={switchClasses}
checked={useMinimumBalance}
alignIndicator={Alignment.RIGHT}
onChange={() => dispatch(toggleUseMinimumBalance())}
/>
</div>
<div className='balance-input-label'>
{t('summary.by_asset.filter.min_balance_input')}
</div>
<div className='balance-input'>
<InputKey
type='number'
name='minimumBalance'
value={balanceValue}
onChange={onChange}
disabled={!useMinimumBalance}
/>
<span className='balance-input-currency'>
USD
</span>
</div>
</div>
)}
targetTagName='div'
popoverClassName='summary-filters--menu-popover'
>
<div className='summary-filters--button'>
<Icon.FILTER_SUMMARY />
<span>{t('summary.by_asset.filter.title')}</span>
</div>
</Popover>
</div>
)
}

export default SummaryFilters
11 changes: 8 additions & 3 deletions src/components/AppSummary/AppSummary.helpers.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react'
import { fixedFloat, formatThousands } from 'ui/utils'

export const prepareSummaryByAssetData = (entries, total, t) => (
[...entries, { currency: t('summary.by_asset.total'), ...total }]
)
export const prepareSummaryByAssetData = (entries, total, t, minimumBalance, useMinimumBalance) => {
const mergedEntries = [...entries, { currency: t('summary.by_asset.total'), ...total }]
if (useMinimumBalance) {
return mergedEntries.filter(entry => fixedFloat(entry?.balanceUsd, 2) >= minimumBalance)
}
return mergedEntries
}


export const prepareNumericValue = (value) => {
let val = +fixedFloat(value, 2)
Expand Down
134 changes: 131 additions & 3 deletions src/components/AppSummary/_AppSummary.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
display: flex;
flex-wrap: wrap;
max-width: 1000px;
min-height: 390px;
min-height: 441px;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 35px;
Expand Down Expand Up @@ -112,7 +112,7 @@
.loading-container {
display: flex;
margin-top: -4px;
min-height: 320px;
min-height: 387px;

.loading {
margin: auto;
Expand All @@ -137,6 +137,134 @@
max-width: 100%;
min-height: 300px;

.app-summary-item-title--row {
display: flex;
max-width: 1000px;
position: relative;
align-items: center;
justify-content: space-between;

.summary-filters {
&--button {
display: flex;
align-items: center;
justify-content: center;
min-width: 84px;
min-height: 34px;
border-radius: 4px;
color: var(--color2);
border: 1px solid var(--borderColor);

&:hover {
cursor: pointer;
}

svg {
margin-top: -2px;
margin-right: 5px;
}

&.bp3-active {
color: var(--thColor);
border-color: var(--thColor);

svg {
path {
stroke: var(--thColor);
}
}
}
}

&--menu-popover {
min-width: 314px;
min-height: 150px;
padding: 26px 24px;
border-radius: 4px;
background-color: var(--bgColor2);
border: 1px solid var(--borderColor);

.bp3-popover-content {
background-color: var(--bgColor2);

.switch {
&-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;

.switch-btn{
margin-bottom: 0;

.bp3-control-indicator {
background: var(--bgColor);
&::before {
background: var(--switchBtnColor);
}
}

&.active {
.bp3-control-indicator {
background: var(--thColor);
&::before {
background: var(--color);
}
}
}
}
}

&-title {
font-size: 14px;
}
}

.balance-input {
display: flex;
max-width: 140px;
position: relative;

&-label {
font-size: 14px;
max-width: 266px;
color: var(--color2);
}

.bp3-form-group {
margin-bottom: 8px;
}

.bp3-input-group {
margin-bottom: 0;

.bp3-input {
height: 31px;
max-width: 140px;
padding: 0 40px 0 10px ;
font-size: 13px;
}
}

.bp3-disabled,
.bp3-input:disabled {
border-radius: 4px;
background: var(--multiBg);
}

&-currency {
right: 8px;
top: 16px;
font-size: 13px;
position: absolute;
color: var(--color2);;
}
}
}
}
}
}

.bp3-table-container {
box-shadow: none;
}
Expand Down Expand Up @@ -261,7 +389,7 @@

.loading-container {
display: flex;
min-height: 320px;
min-height: 387px;

.loading {
margin: auto;
Expand Down
10 changes: 7 additions & 3 deletions src/components/Auth/InputKey/InputKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ export const InputKey = ({
label,
value,
onChange,
disabled,
placeholder,
}) => {
const { t } = useTranslation()
return (
<div className='bitfinex-auth-form-input'>
<FormGroup
label={t(label)}
label={label ? t(label) : ''}
labelFor={name}
/>
<InputGroup
Expand All @@ -27,6 +28,7 @@ export const InputKey = ({
type={type}
value={value}
onChange={onChange}
disabled={disabled}
placeholder={placeholder && t(placeholder)}
/>
</div>
Expand All @@ -35,18 +37,20 @@ export const InputKey = ({

InputKey.propTypes = {
name: PropTypes.string,
type: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
disabled: PropTypes.bool,
onChange: PropTypes.func,
placeholder: PropTypes.string,
type: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}

InputKey.defaultProps = {
name: '',
value: '',
label: '',
placeholder: '',
disabled: false,
type: 'password',
onChange: () => {},
}
Expand Down
Loading