Skip to content

Commit

Permalink
[DTRA] Maryia/DTRA-1360/fix: is_loading state in portfolio-store.js (d…
Browse files Browse the repository at this point in the history
…eriv-com#15675)

* fix: is_loading state in portfolio-store

* fix: ensure DTrader V2 Positions page shows loading when the app is offline

* fix: initial is_loading state in portfolio-store

* revert: necessary change of setting is_loading to true inside initializePortfolio
  • Loading branch information
maryia-deriv authored Jun 21, 2024
1 parent 25de538 commit f58ca5f
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 49 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/Stores/portfolio-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class PortfolioStore extends BaseStore {
positions = [];
all_positions = [];
positions_map = {};
is_loading = false;
is_loading = true;
error = '';

//accumulators
Expand Down Expand Up @@ -472,7 +472,7 @@ export default class PortfolioStore extends BaseStore {
}

networkStatusChangeListener(is_online) {
this.is_loading = !is_online;
this.is_loading = this.is_loading || !is_online;
}

onMount() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,63 +1,35 @@
import React from 'react';
import { act, render, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import EmptyPositions from '../empty-positions';

describe('EmptyPositions', () => {
const iconId = 'dt_empty_state_icon';

it('should render Loader before timer ends', () => {
render(<EmptyPositions />);

expect(screen.getByTestId('dt_initial_loader')).toBeInTheDocument();
});

it('should render "No open trades" content when isClosedTab prop is false', () => {
jest.useFakeTimers();
render(<EmptyPositions />);

act(() => {
jest.advanceTimersByTime(700);
});

expect(screen.getByText('No open trades')).toBeInTheDocument();
expect(screen.getByText('Your open trades will appear here.')).toBeInTheDocument();
});

it('should render "No closed trades" content when isClosedTab prop is true', () => {
jest.useFakeTimers();
render(<EmptyPositions isClosedTab />);

act(() => {
jest.advanceTimersByTime(700);
});

expect(screen.getByText('No closed trades')).toBeInTheDocument();
expect(screen.getByText('Your closed trades will be shown here.')).toBeInTheDocument();
});

it('should render "No matches found" content when noMatchesFound prop is true', () => {
jest.useFakeTimers();
render(<EmptyPositions noMatchesFound />);

act(() => {
jest.advanceTimersByTime(700);
});

expect(screen.getByText('No matches found')).toBeInTheDocument();
expect(screen.getByText(/Try changing or removing filters/i)).toBeInTheDocument();
});

it('should render an empty state icon regardless of props', () => {
jest.useFakeTimers();
const { rerender } = render(<EmptyPositions />);

act(() => {
jest.advanceTimersByTime(700);
});

expect(screen.getByTestId(iconId)).toBeInTheDocument();

rerender(<EmptyPositions isClosedTab />);
expect(screen.getByTestId(iconId)).toBeInTheDocument();

rerender(<EmptyPositions noMatchesFound />);
expect(screen.getByTestId(iconId)).toBeInTheDocument();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { Text } from '@deriv-com/quill-ui';
import { Loading } from '@deriv/components';
import { StandaloneBriefcaseFillIcon, StandaloneSearchFillIcon } from '@deriv/quill-icons';
import { Localize } from '@deriv/translations';

Expand All @@ -10,26 +9,14 @@ export type TEmptyPositionsProps = {
};

const EmptyPositions = ({ isClosedTab, noMatchesFound }: TEmptyPositionsProps) => {
const [showLoader, setShowLoader] = React.useState(true);

React.useEffect(() => {
const timeout = setTimeout(() => setShowLoader(false), 700);
return () => {
clearTimeout(timeout);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const Icon = noMatchesFound ? StandaloneSearchFillIcon : StandaloneBriefcaseFillIcon;

if (showLoader) return <Loading />;
return (
<div className={`empty-positions__${isClosedTab ? 'closed' : 'open'}`}>
<div className='icon' data-testid='dt_empty_state_icon'>
<Icon iconSize='2xl' />
</div>
<div className='message'>
{/* There is an issue with tokens: the 'lg' size should give 18px but it's giving 20px, it's being discussed. */}
<Text bold size='lg' color='quill-typography__color--subtle'>
{noMatchesFound && <Localize i18n_default_text='No matches found' />}
{!noMatchesFound &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TPortfolioPosition } from '@deriv/stores/types';
const contractTypeFilter = 'Filter by trade types';
const contractCardList = 'ContractCardList';
const emptyPositions = 'EmptyPositions';
const loaderTestId = 'dt_initial_loader';
const totalProfitLoss = 'Total profit/loss:';

const mediaQueryList = {
Expand Down Expand Up @@ -292,7 +293,14 @@ describe('PositionsContent', () => {
defaultMockStore = mockStore({});
render(mockPositionsContent());

expect(screen.getByTestId('dt_initial_loader')).toBeInTheDocument();
expect(screen.getByTestId(loaderTestId)).toBeInTheDocument();
});

it('should render loader if is_loading is true in portfolio-store', () => {
defaultMockStore = mockStore({ portfolio: { ...defaultMockStore.portfolio, is_loading: true } });
render(mockPositionsContent());

expect(screen.getByTestId(loaderTestId)).toBeInTheDocument();
});

it('should render EmptyPositions if data has loaded but user has no open positions', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD
const { common, client, portfolio } = useStore();
const { server_time = undefined } = isClosedTab ? {} : common; // Server time is required only to update cards timers in Open positions
const { currency } = client;
const { active_positions, is_active_empty, onClickCancel, onClickSell, onMount: onOpenTabMount } = portfolio;
const {
active_positions,
is_active_empty,
is_loading,
onClickCancel,
onClickSell,
onMount: onOpenTabMount,
} = portfolio;
const {
clearTable,
data,
Expand All @@ -54,6 +61,7 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD
const shouldShowEmptyMessage = hasNoPositions || noMatchesFound;
const shouldShowContractCards =
!!filteredPositions.length && (isClosedTab || (filteredPositions[0]?.contract_info as TContractInfo)?.status);
const shouldShowLoading = isClosedTab ? isFetchingClosedPositions : is_loading;
const shouldShowTakeProfit = !isClosedTab || !!(timeFilter || customTimeRangeFilter);

const onScroll = React.useCallback(
Expand Down Expand Up @@ -115,7 +123,7 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

if (!shouldShowContractCards && !shouldShowEmptyMessage) return <Loading />;
if (shouldShowLoading || (!shouldShowContractCards && !shouldShowEmptyMessage)) return <Loading />;
return (
<div
className={`positions-page__${isClosedTab ? 'closed' : 'open'}`}
Expand Down

0 comments on commit f58ca5f

Please sign in to comment.