Skip to content

Commit

Permalink
Add USD value banner on tokens page (#5934)
Browse files Browse the repository at this point in the history
# Motivation

Using the banner component from
#5932 on the tokens page.

# Changes

1. Calculate the sum of USD values in
`frontend/src/lib/pages/Tokens.svelte`.
2. Add `UsdValueBanner` if `ENABLE_USD_VALUES` is enabled.

# Tests

1. Unit tests added.
2. Tested manually at
https://qsgjb-riaaa-aaaaa-aaaga-cai.dskloet-ingress.devenv.dfinity.network/

# Todos

- [ ] Add entry to changelog (if necessary).
not yet
  • Loading branch information
dskloetd authored and yhabib committed Dec 9, 2024
1 parent 6457d63 commit 319944a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 4 deletions.
35 changes: 31 additions & 4 deletions frontend/src/lib/pages/Tokens.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
<script lang="ts">
import TestIdWrapper from "$lib/components/common/TestIdWrapper.svelte";
import HideZeroBalancesToggle from "$lib/components/tokens/TokensTable/HideZeroBalancesToggle.svelte";
import TokensTable from "$lib/components/tokens/TokensTable/TokensTable.svelte";
import UsdValueBanner from "$lib/components/ui/UsdValueBanner.svelte";
import { OWN_CANISTER_ID_TEXT } from "$lib/constants/canister-ids.constants";
import { MAX_IMPORTED_TOKENS } from "$lib/constants/imported-tokens.constants";
import ImportTokenModal from "$lib/modals/accounts/ImportTokenModal.svelte";
import { ENABLE_USD_VALUES } from "$lib/stores/feature-flags.store";
import { hideZeroBalancesStore } from "$lib/stores/hide-zero-balances.store";
import { i18n } from "$lib/stores/i18n";
import { importedTokensStore } from "$lib/stores/imported-tokens.store";
import type { ImportedTokenData } from "$lib/types/imported-tokens";
import type { UserToken } from "$lib/types/tokens-page";
import { replacePlaceholders } from "$lib/utils/i18n.utils";
import { isImportedToken } from "$lib/utils/imported-tokens.utils";
import { IconAccountsPage } from "@dfinity/gix-components";
import { IconPlus, IconSettings, Tooltip } from "@dfinity/gix-components";
import { Popover } from "@dfinity/gix-components";
import { TokenAmountV2, nonNullish } from "@dfinity/utils";
import { TokenAmountV2, isNullish, nonNullish } from "@dfinity/utils";
export let userTokensData: UserToken[];
const getUsdBalance = (token: UserToken) => {
if (!("balanceInUsd" in token) || isNullish(token.balanceInUsd)) {
return 0;
}
return token.balanceInUsd;
};
let totalBalanceInUsd: number;
$: totalBalanceInUsd = userTokensData.reduce(
(acc, token) => acc + getUsdBalance(token),
0
);
let settingsButton: HTMLButtonElement | undefined;
let settingsPopupVisible = false;
Expand Down Expand Up @@ -67,7 +82,13 @@
($importedTokensStore.importedTokens?.length ?? 0) >= MAX_IMPORTED_TOKENS;
</script>

<TestIdWrapper testId="tokens-page-component">
<div class="wrapper" data-tid="tokens-page-component">
{#if $ENABLE_USD_VALUES}
<UsdValueBanner usdAmount={totalBalanceInUsd}>
<IconAccountsPage slot="icon" />
</UsdValueBanner>
{/if}

<TokensTable
userTokensData={shownTokensData}
on:nnsAction
Expand Down Expand Up @@ -130,12 +151,18 @@
{#if showImportTokenModal}
<ImportTokenModal on:nnsClose={() => (showImportTokenModal = false)} />
{/if}
</TestIdWrapper>
</div>

<style lang="scss">
@use "@dfinity/gix-components/dist/styles/mixins/effect";
@use "@dfinity/gix-components/dist/styles/mixins/media";
.wrapper {
display: flex;
flex-direction: column;
gap: var(--padding-2x);
}
.settings-button {
--content-color: var(--text-description);
Expand Down
55 changes: 55 additions & 0 deletions frontend/src/tests/lib/pages/Tokens.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MAX_IMPORTED_TOKENS } from "$lib/constants/imported-tokens.constants";
import { NNS_TOKEN_DATA } from "$lib/constants/tokens.constants";
import TokensPage from "$lib/pages/Tokens.svelte";
import { overrideFeatureFlagsStore } from "$lib/stores/feature-flags.store";
import { hideZeroBalancesStore } from "$lib/stores/hide-zero-balances.store";
import { importedTokensStore } from "$lib/stores/imported-tokens.store";
import type { UserTokenData } from "$lib/types/tokens-page";
Expand Down Expand Up @@ -288,4 +289,58 @@ describe("Tokens page", () => {
expect(await po.getImportTokenModalPo().isPresent()).toBe(true);
});
});

it("should not show total USD value banner when feature flag is disabled", async () => {
overrideFeatureFlagsStore.setFlag("ENABLE_USD_VALUES", false);

const po = renderPage(userTokensPageMock);

expect(await po.getUsdValueBannerPo().isPresent()).toBe(false);
});

it("should show total USD value banner when feature flag is enabled", async () => {
overrideFeatureFlagsStore.setFlag("ENABLE_USD_VALUES", true);

const po = renderPage(userTokensPageMock);

expect(await po.getUsdValueBannerPo().isPresent()).toBe(true);
});

it("should show total USD value", async () => {
overrideFeatureFlagsStore.setFlag("ENABLE_USD_VALUES", true);

const token1 = createUserToken({
universeId: principal(1),
balanceInUsd: 2,
});
const token2 = createUserToken({
universeId: principal(2),
balanceInUsd: 3,
});
const po = renderPage([token1, token2]);

expect(await po.getUsdValueBannerPo().isPresent()).toBe(true);
expect(await po.getUsdValueBannerPo().getPrimaryAmount()).toBe("$5.00");
});

it("should ignore tokens with unknown balance in USD when adding up the total", async () => {
overrideFeatureFlagsStore.setFlag("ENABLE_USD_VALUES", true);

const token1 = createUserToken({
universeId: principal(1),
balanceInUsd: 3,
});
const token2 = createUserToken({
universeId: principal(2),
balanceInUsd: undefined,
});
const token3 = createUserToken({
universeId: principal(3),
balanceInUsd: 5,
});
const po = renderPage([token1, token2, token3]);

expect(await po.getUsdValueBannerPo().isPresent()).toBe(true);
expect(await po.getUsdValueBannerPo().getPrimaryAmount()).toBe("$8.00");
});
});
5 changes: 5 additions & 0 deletions frontend/src/tests/page-objects/TokensPage.page-object.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ImportTokenModalPo } from "$tests/page-objects/ImportTokenModal.page-object";
import { UsdValueBannerPo } from "$tests/page-objects/UsdValueBanner.page-object";
import { BasePageObject } from "$tests/page-objects/base.page-object";
import type { PageObjectElement } from "$tests/types/page-object.types";
import { BackdropPo } from "./Backdrop.page-object";
Expand All @@ -14,6 +15,10 @@ export class TokensPagePo extends BasePageObject {
return new TokensPagePo(element.byTestId(TokensPagePo.TID));
}

getUsdValueBannerPo(): UsdValueBannerPo {
return UsdValueBannerPo.under(this.root);
}

getTokensTable(): TokensTablePo {
return TokensTablePo.under(this.root);
}
Expand Down

0 comments on commit 319944a

Please sign in to comment.