Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/ddw-16-table-comparison-…
Browse files Browse the repository at this point in the history
…view-for-stake-pools' into feature/ddw-16-table-comparison-view-for-stake-pools

# Conflicts:
#	source/renderer/app/components/staking/stake-pools/StakePoolsTable.js
  • Loading branch information
DeeJayElly committed Oct 20, 2020
2 parents fd4b23e + 48fd290 commit 98fc020
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 159 deletions.
Expand Up @@ -18,7 +18,6 @@
overflow-x: hidden;
overflow-y: scroll;
position: relative;
scroll-behavior: smooth;
&::-webkit-scrollbar-thumb {
&:vertical {
min-height: 60px !important;
Expand Down
326 changes: 169 additions & 157 deletions source/renderer/app/components/staking/stake-pools/StakePoolsTable.js
Expand Up @@ -10,10 +10,13 @@ import BigNumber from 'bignumber.js';
import styles from './StakePoolsTable.scss';
import StakePool from '../../../domains/StakePool';
import LoadingSpinner from '../../widgets/LoadingSpinner';
import { StakingPageScrollContext } from '../layouts/StakingWithNavigation';
import BorderedBox from '../../widgets/BorderedBox';
import sortIcon from '../../../assets/images/ascending.inline.svg';
import { formattedLovelaceToAmount, formattedWalletAmount, shortNumber } from '../../../utils/formatters';
import {
formattedLovelaceToAmount,
formattedWalletAmount,
shortNumber,
} from '../../../utils/formatters';
import { getColorFromRange, getSaturationColor } from '../../../utils/colors';
import TooltipPool from '../widgets/TooltipPool';
import { getRelativePosition } from '../../../utils/domManipulation';
Expand Down Expand Up @@ -153,6 +156,10 @@ export class StakePoolsTable extends Component<Props, State> {
...initialState,
};

scrollableDomElement: ?HTMLElement = null;

searchInput: ?HTMLElement = null;

_isMounted = false;

scrollableDomElement: ?HTMLElement = null;
Expand All @@ -175,9 +182,9 @@ export class StakePoolsTable extends Component<Props, State> {
}

handleResize = () =>
debounce(this.handleClose, 200, { leading: true, trailing: false });
debounce(this.handleCloseTooltip, 200, { leading: true, trailing: false });

handleOpenThumbnail = (poolId: SyntheticMouseEvent<HTMLElement>) => {
handleOpenTooltip = (poolId: SyntheticMouseEvent<HTMLElement>) => {
const {
isListActive,
setListActive,
Expand Down Expand Up @@ -236,7 +243,7 @@ export class StakePoolsTable extends Component<Props, State> {
return result;
};

handleClose = (item: SyntheticMouseEvent<HTMLElement>) => {
handleCloseTooltip = (item: SyntheticMouseEvent<HTMLElement>) => {
const { isListActive, setListActive } = this.props;
let selectedRow = null;
if (item) {
Expand Down Expand Up @@ -403,165 +410,170 @@ export class StakePoolsTable extends Component<Props, State> {
];

return (
<StakingPageScrollContext.Consumer>
{() => (
<div className={componentClasses}>
<BorderedBox className={styles.boxedContainer}>
{sortedStakePoolList.length > 0 && (
<table>
<thead className={tableHeaderClasses}>
<tr>
{map(availableTableHeaders, (tableHeader) => {
const isSorted =
tableHeader.name === stakePoolsSortBy ||
(tableHeader.name === 'ticker' &&
stakePoolsSortBy === 'ticker');
const sortIconClasses = classNames([
styles.sortIcon,
isSorted ? styles.sorted : null,
isSorted && stakePoolsOrder === 'asc'
? styles.ascending
: null,
]);

return (
<th
key={tableHeader.name}
onClick={() => this.handleSort(tableHeader.name)}
>
{tableHeader.title}
<SVGInline
svg={sortIcon}
className={sortIconClasses}
/>
</th>
);
})}
</tr>
</thead>
<tbody>
{map(sortedStakePoolList, (stakePool, key) => {
const rank = get(stakePool, 'ranking', '');
const ticker = get(stakePool, 'ticker', '');
const saturation = get(stakePool, 'saturation', '');
const cost = new BigNumber(get(stakePool, 'cost', ''));
const margin = get(stakePool, 'profitMargin', '');
const producedBlocks = get(
stakePool,
'producedBlocks',
''
);
const pledge = new BigNumber(
get(stakePool, 'pledge', '')
);
const retiring = get(stakePool, 'retiring', '');
const memberRewards = get(stakePool, 'nonMyopicMemberRewards', '');
const potentialRewards = memberRewards ? `${shortNumber(formattedLovelaceToAmount(memberRewards)) } ${intl.formatMessage(globalMessages.unitAda)}` : '-';
const isOversaturated = saturation / 100 >= 1;
const saturationValue =
isOversaturated || !saturation
? parseInt(saturation, 10)
: parseInt(saturation, 10);
const calculatedDateRange = moment(retiring).diff(
moment(),
'days'
);

const pledgeValue = this.bigNumbersToFormattedNumbers(
pledge,
true
);
const pledgeCalculatedValue = Number(pledgeValue)
? Number(pledgeValue).toFixed(2)
: pledgeValue;
const costValue = this.bigNumbersToFormattedNumbers(cost);

const saturationBarClassnames = classNames([
styles.progress,
styles[getSaturationColor(saturation)],
<div>
<div className={componentClasses}>
<BorderedBox className={styles.boxedContainer}>
{sortedStakePoolList.length > 0 && (
<table>
<thead className={tableHeaderClasses}>
<tr>
{map(availableTableHeaders, (tableHeader) => {
const isSorted =
tableHeader.name === stakePoolsSortBy ||
(tableHeader.name === 'ticker' &&
stakePoolsSortBy === 'ticker');
const sortIconClasses = classNames([
styles.sortIcon,
isSorted ? styles.sorted : null,
isSorted && stakePoolsOrder === 'asc'
? styles.ascending
: null,
]);

const isHighlighted = this.getIsHighlighted(stakePool.id);
const color = getColorFromRange(rank, numberOfRankedStakePools);
const { top, left, selectedRow } = this.state;

return (
<tr
key={key}
className={
selectedRow && selectedRow === key
? styles.selected
: null
}
<th
key={tableHeader.name}
onClick={() => this.handleSort(tableHeader.name)}
>
<td>
{rank}
{isHighlighted && (
<TooltipPool
stakePool={stakePool}
isVisible
onClick={this.handleClose}
currentTheme={currentTheme}
onOpenExternalLink={onOpenExternalLink}
top={top}
left={left}
fromStakePool
color={color}
onSelect={this.handleSelect}
showWithSelectButton={showWithSelectButton}
containerClassName={containerClassName}
numberOfRankedStakePools={numberOfRankedStakePools}
{tableHeader.title}
<SVGInline
svg={sortIcon}
className={sortIconClasses}
/>
</th>
);
})}
</tr>
</thead>
<tbody>
{map(sortedStakePoolList, (stakePool, key) => {
const rank = get(stakePool, 'ranking', '');
const ticker = get(stakePool, 'ticker', '');
const saturation = get(stakePool, 'saturation', '');
const cost = new BigNumber(get(stakePool, 'cost', ''));
const margin = get(stakePool, 'profitMargin', '');
const producedBlocks = get(stakePool, 'producedBlocks', '');
const pledge = new BigNumber(get(stakePool, 'pledge', ''));
const retiring = get(stakePool, 'retiring', '');
const memberRewards = get(
stakePool,
'nonMyopicMemberRewards',
''
);
const potentialRewards = memberRewards
? `${shortNumber(
formattedLovelaceToAmount(memberRewards)
)} ${intl.formatMessage(globalMessages.unitAda)}`
: '-';
const isOversaturated = saturation / 100 >= 1;
const saturationValue =
isOversaturated || !saturation
? parseInt(saturation, 10)
: parseInt(saturation, 10);
const calculatedDateRange = moment(retiring).diff(
moment(),
'days'
);

const pledgeValue = this.bigNumbersToFormattedNumbers(
pledge,
true
);
const pledgeCalculatedValue = Number(pledgeValue)
? Number(pledgeValue).toFixed(2)
: pledgeValue;
const costValue = this.bigNumbersToFormattedNumbers(cost);

const saturationBarClassnames = classNames([
styles.progress,
styles[getSaturationColor(saturation)],
]);

const isHighlighted = this.getIsHighlighted(stakePool.id);
const color = getColorFromRange(
rank,
numberOfRankedStakePools
);
const { top, left, selectedRow } = this.state;

return (
<tr
key={key}
className={
selectedRow && selectedRow === key
? styles.selected
: null
}
>
<td>
{rank}
{isHighlighted && (
<TooltipPool
stakePool={stakePool}
isVisible
onClick={this.handleCloseTooltip}
currentTheme={currentTheme}
onOpenExternalLink={onOpenExternalLink}
top={top}
left={left}
fromStakePool
color={color}
onSelect={this.handleSelect}
showWithSelectButton={showWithSelectButton}
containerClassName={containerClassName}
numberOfRankedStakePools={
numberOfRankedStakePools
}
/>
)}
</td>
<td>
<span
className={styles.ticker}
role="presentation"
onClick={this.handleOpenTooltip}
>
{ticker}
</span>
</td>
<td>
<div className={styles.currentEpochProgressBar}>
<div className={styles.progressBarContainer}>
<div
className={saturationBarClassnames}
style={{ width: `${saturationValue}%` }}
/>
)}
</td>
<td>
<span
className={styles.ticker}
role="presentation"
onClick={this.handleOpenThumbnail}
>
{ticker}
</span>
</td>
<td>
<div className={styles.currentEpochProgressBar}>
<div className={styles.progressBarContainer}>
<div
className={saturationBarClassnames}
style={{ width: `${saturationValue}%` }}
/>
<div className={styles.progressLabel}>
{saturationValue}%
</div>
<div className={styles.progressLabel}>
{saturationValue}%
</div>
</div>
</td>
<td>{Number(costValue).toFixed(2)}</td>
<td>{margin}%</td>
<td>{producedBlocks}</td>
<td>{potentialRewards}</td>
<td>{pledgeCalculatedValue}</td>
<td>
{retiring && calculatedDateRange ? (
<span className={styles.retiring}>
{calculatedDateRange === 1
? `${calculatedDateRange} day`
: `${calculatedDateRange} days`}
</span>
) : (
<span>-</span>
)}
</td>
</tr>
);
})}
</tbody>
</table>
)}
</BorderedBox>
</div>
)}
</StakingPageScrollContext.Consumer>
</div>
</td>
<td>{Number(costValue).toFixed(2)}</td>
<td>{margin}%</td>
<td>{producedBlocks}</td>
<td>{potentialRewards}</td>
<td>{pledgeCalculatedValue}</td>
<td>
{retiring && calculatedDateRange ? (
<span className={styles.retiring}>
{calculatedDateRange === 1
? `${calculatedDateRange} day`
: `${calculatedDateRange} days`}
</span>
) : (
<span>-</span>
)}
</td>
</tr>
);
})}
</tbody>
</table>
)}
</BorderedBox>
</div>
</div>
);
}
}
6 changes: 5 additions & 1 deletion source/renderer/app/components/widgets/BackToTopButton.js
Expand Up @@ -2,6 +2,7 @@
import React, { Component } from 'react';
import classnames from 'classnames';
import { defineMessages, intlShape } from 'react-intl';
import { debounce } from 'lodash';
import styles from './BackToTopButton.scss';

const messages = defineMessages({
Expand Down Expand Up @@ -45,7 +46,10 @@ export default class BackToTopButton extends Component<Props, State> {
if (!this.scrollableDomElement) return false;
return this.scrollableDomElement.addEventListener(
'scroll',
this.getIsBackToTopActive
debounce(this.getIsBackToTopActive, 300, {
leading: false,
trailing: true,
})
);
}

Expand Down

0 comments on commit 98fc020

Please sign in to comment.