Skip to content

Commit

Permalink
Merge pull request #3645 from LiskHQ/3643-new-block-and-tx-buttons
Browse files Browse the repository at this point in the history
Fix new block and new transaction buttons - Closes #3643
  • Loading branch information
reyraa authored Jun 24, 2021
2 parents 3ca85d8 + c70328c commit bb0ecc2
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 108 deletions.
3 changes: 3 additions & 0 deletions src/assets/images/icons/refresh.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/screens/monitor/blocks/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const Blocks = ({
<BlockFilterDropdown filters={filters} applyFilters={applyFilters} />
</BoxHeader>
<LoadLatestButton
event="update.block"
entity="block"
onClick={loadLastBlocks}
>
{t('New blocks')}
Expand Down
37 changes: 6 additions & 31 deletions src/components/shared/loadLatestButton/index.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
import React, { useEffect, useState } from 'react';
import { PrimaryButton } from '@toolbox/buttons';
import Icon from '@toolbox/icon';
import useServiceSocketUpdates from '../../../hooks/useServiceSocketUpdates';
import styles from './loadLatestButton.css';
import { connect } from 'react-redux';
import LoadLatestButton from './loadLatestButton';

const LoadLatestButton = ({ children, onClick, event }) => {
const [isUpdateAvailable, hideUpdateButton] = useServiceSocketUpdates(event);
const [hasUpdatedRecently, didUpdateRecently] = useState(false);
const mapStateToProps = state => ({
latestBlocks: state.blocks.latestBlocks,
});

const handleClick = () => {
hideUpdateButton();
const timer = setTimeout(() => {
didUpdateRecently(false);
}, 10000);
didUpdateRecently(timer);
onClick();
};

// willUnmount
useEffect(() => () => clearTimeout(hasUpdatedRecently), []);

return (isUpdateAvailable && hasUpdatedRecently === false
? (
<PrimaryButton onClick={handleClick} className={styles.button}>
<Icon name="arrowUpCircle" className={styles.icon} />
{children}
</PrimaryButton>
)
: null);
};

export default LoadLatestButton;
export default connect(mapStateToProps)(LoadLatestButton);
16 changes: 14 additions & 2 deletions src/components/shared/loadLatestButton/loadLatestButton.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
}

100% {
transform: translateX(-50%) translateY(100px);
transform: translateX(-50%) translateY(30px);
}
}

Expand All @@ -13,12 +13,24 @@
animation-fill-mode: forwards;
position: absolute;
z-index: 2;
width: 200px;
transform: translateX(-50%);
left: 50%;
background: var(--color-white);
color: var(--color-ultramarine-blue);
border-radius: 30px;
box-shadow: var(--box-shadow-standard), 0 0 0 10px var(--color-body-bg);

& .icon {
vertical-align: bottom;
padding-right: 12px;
}

& .icon,
& span {
vertical-align: middle;
}

&:hover {
box-shadow: var(--box-shadow-standard), 0 0 0 10px var(--color-body-bg);
}
}
55 changes: 55 additions & 0 deletions src/components/shared/loadLatestButton/loadLatestButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';

import { PrimaryButton } from '@toolbox/buttons';
import Icon from '@toolbox/icon';
import styles from './loadLatestButton.css';

const shouldShow = {
block: (updateHeight, latestBlocks) => (
latestBlocks.length > 0
&& updateHeight > 0
&& latestBlocks[0].height > (updateHeight + 2)
),
transaction: (updateHeight, latestBlocks) => (
latestBlocks.length > 0
&& updateHeight > 0
&& latestBlocks[0].height > updateHeight
&& latestBlocks[0].numberOfTransactions > 0
),
};

const LoadLatestButton = ({
children, onClick, entity, latestBlocks,
}) => {
const [updateHeight, setUpdateHeight] = useState(
latestBlocks.length ? latestBlocks[0].height : 0,
);

const handleClick = () => {
setUpdateHeight(latestBlocks[0].height);
onClick();
};

useEffect(() => {
if (latestBlocks.length > 0 && updateHeight === 0) {
setUpdateHeight(latestBlocks[0].height);
}
}, [latestBlocks.length]);

return shouldShow[entity] && shouldShow[entity](updateHeight, latestBlocks)
? (
<PrimaryButton onClick={handleClick} className={styles.button}>
<Icon name="refresh" className={styles.icon} />
<span>{children}</span>
</PrimaryButton>
)
: null;
};

LoadLatestButton.propTypes = {
entity: PropTypes.oneOf(['block', 'transaction']),
onClick: PropTypes.func.isRequired,
};

export default LoadLatestButton;
63 changes: 22 additions & 41 deletions src/components/shared/loadLatestButton/loadLatestButton.test.js
Original file line number Diff line number Diff line change
@@ -1,66 +1,47 @@
import { act } from 'react-dom/test-utils';
import React from 'react';
import { mount } from 'enzyme';
import io from 'socket.io-client';
import { subscribeConnections } from '@api/ws';
import LoadLatestButton from '.';

jest.mock('socket.io-client');

const on = (ev, callback) => {
setTimeout(() => {
callback(ev);
}, 1);
};
const close = jest.fn();
io.mockImplementation(() => ({ on, close }));
import LoadLatestButton from './loadLatestButton';

describe('LoadLatestButton', () => {
const props = {
onClick: jest.fn(),
event: 'test.event',
entity: 'block',
children: 'Test load button',
};
const render = () => {
const wrapper = mount(<LoadLatestButton {...props} />);
return wrapper;
latestBlocks: [
{ height: 11111111 },
],
};

it('renders empty by default', () => {
const wrapper = render();
it('renders accept transaction and block for entity and render empty by default', () => {
const blockProps = { ...props, entity: 'block' };
let wrapper = mount(<LoadLatestButton {...blockProps} />);
expect(wrapper).toBeEmptyRender();
});

it('shows button on websocket event and hides the button on click', () => {
jest.useFakeTimers();
const transactionProps = { ...props, entity: 'transaction' };
wrapper = mount(<LoadLatestButton {...transactionProps} />);
expect(wrapper).toBeEmptyRender();
});

const wrapper = render();
it('shows button when there is a new block', () => {
const wrapper = mount(<LoadLatestButton {...props} />);
expect(wrapper).toBeEmptyRender();
wrapper.setProps({
latestBlocks: [
{ height: 11111114 },
],
});
act(() => {
jest.runOnlyPendingTimers();
wrapper.update();
});
wrapper.update();
expect(wrapper).toContainExactlyOneMatchingElement('button');
expect(wrapper).toHaveText(props.children);

wrapper.find('button').simulate('click');
wrapper.find('button').at(0).simulate('click');
expect(props.onClick).toHaveBeenCalledWith();
act(() => {
jest.runOnlyPendingTimers();
wrapper.update();
});
expect(wrapper).toBeEmptyRender();
expect(subscribeConnections[props.event]).toBeDefined();
});

it('clears the timeout before unmounting', () => {
jest.useFakeTimers();
const wrapper = render();
expect(subscribeConnections[props.event]).toBeDefined();
expect(close).toHaveBeenCalledTimes(0);

wrapper.unmount();
expect(clearTimeout).toHaveBeenCalledTimes(1);
expect(close).toHaveBeenCalledTimes(1);
expect(subscribeConnections[props.event]).not.toBeDefined();
});
});
2 changes: 1 addition & 1 deletion src/components/shared/transactionsTable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const TransactionsTable = ({
{isLoadMoreEnabled
&& (
<LoadLatestButton
event="update.transactions.confirmed"
entity="transaction"
onClick={transactions.loadData}
>
{t('New transactions')}
Expand Down
2 changes: 2 additions & 0 deletions src/components/toolbox/icon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ import initialiseIcon from '../../../assets/images/icons/initialise-icon.svg';
import initialiseRegistration from '../../../assets/images/icons/initialise-registration.svg';
import warningYellow from '../../../assets/images/icons/warning-yellow.svg';
import linkIcon from '../../../assets/images/icons/link-icon.svg';
import refresh from '../../../assets/images/icons/refresh.svg';

export const icons = {
academy,
Expand Down Expand Up @@ -316,6 +317,7 @@ export const icons = {
arrowRightWithStroke,
arrowRightWithStrokeDark,
multisignatureTransaction,
refresh,
};

const Icon = ({ name, noTheme, ...props }) => {
Expand Down
32 changes: 0 additions & 32 deletions src/hooks/useServiceSocketUpdates.js

This file was deleted.

0 comments on commit bb0ecc2

Please sign in to comment.