diff --git a/frontend/src/lib/components/portfolio/HeldTokensCard.svelte b/frontend/src/lib/components/portfolio/HeldTokensCard.svelte
index f86a925be89..65f28c65de2 100644
--- a/frontend/src/lib/components/portfolio/HeldTokensCard.svelte
+++ b/frontend/src/lib/components/portfolio/HeldTokensCard.svelte
@@ -7,6 +7,7 @@
import { AppPath } from "$lib/constants/routes.constants";
import { authSignedInStore } from "$lib/derived/auth.derived";
import { i18n } from "$lib/stores/i18n";
+ import { icpSwapTickersStore } from "$lib/stores/icp-swap.store";
import type { UserTokenData } from "$lib/types/tokens-page";
import { formatNumber } from "$lib/utils/format.utils";
import { shouldShowInfoRow } from "$lib/utils/portfolio.utils";
@@ -107,10 +108,15 @@
role="cell"
aria-label={`${heldToken.title} USD: ${heldToken?.balanceInUsd ?? 0}`}
>
- $
+ $
+ {#if $icpSwapTickersStore !== "error"}
+
+ {:else}
+ {PRICE_NOT_AVAILABLE_PLACEHOLDER}
+ {/if}
{/each}
diff --git a/frontend/src/lib/components/portfolio/StakedTokensCard.svelte b/frontend/src/lib/components/portfolio/StakedTokensCard.svelte
index bbc6269dc0f..950753dd7a8 100644
--- a/frontend/src/lib/components/portfolio/StakedTokensCard.svelte
+++ b/frontend/src/lib/components/portfolio/StakedTokensCard.svelte
@@ -8,6 +8,7 @@
import { AppPath } from "$lib/constants/routes.constants";
import { authSignedInStore } from "$lib/derived/auth.derived";
import { i18n } from "$lib/stores/i18n";
+ import { icpSwapTickersStore } from "$lib/stores/icp-swap.store";
import type { TableProject } from "$lib/types/staking";
import { formatNumber } from "$lib/utils/format.utils";
import { shouldShowInfoRow } from "$lib/utils/portfolio.utils";
@@ -106,10 +107,15 @@
role="cell"
aria-label={`${stakedToken.title} USD: ${stakedToken?.stakeInUsd ?? 0}`}
>
- $
+ $
+ {#if $icpSwapTickersStore !== "error"}
+
+ {:else}
+ {PRICE_NOT_AVAILABLE_PLACEHOLDER}
+ {/if}
token.balance === "loading")
);
const heldTokensCard: TokensCardType = $derived(
- !$authSignedInStore
+ !$authSignedInStore || isExchangeProviderDown
? "full"
: areHeldTokensLoading
? "skeleton"
@@ -95,7 +98,7 @@
tableProjects.some((project) => project.isStakeLoading)
);
const stakedTokensCard: TokensCardType = $derived(
- !$authSignedInStore
+ !$authSignedInStore || isExchangeProviderDown
? "full"
: areStakedTokensLoading
? "skeleton"
@@ -121,6 +124,7 @@
getTopHeldTokens({
userTokens: userTokens,
isSignedIn: $authSignedInStore,
+ areExchangePairsAvailable: !isExchangeProviderDown,
})
);
@@ -128,6 +132,7 @@
getTopStakedTokens({
projects: tableProjects,
isSignedIn: $authSignedInStore,
+ areExchangePairsAvailable: !isExchangeProviderDown,
})
);
diff --git a/frontend/src/lib/utils/portfolio.utils.ts b/frontend/src/lib/utils/portfolio.utils.ts
index 4ce5de16ba2..990e9de9f36 100644
--- a/frontend/src/lib/utils/portfolio.utils.ts
+++ b/frontend/src/lib/utils/portfolio.utils.ts
@@ -10,6 +10,7 @@ import {
mergeComparators,
} from "$lib/utils/sort.utils";
import {
+ compareByNeuronCount,
compareByProjectTitle,
compareIcpFirst,
} from "$lib/utils/staking.utils";
@@ -34,12 +35,22 @@ const compareTokensByUsdBalance = createDescendingComparator(
(token: UserTokenData) => token?.balanceInUsd ?? 0 > 0
);
+const compareTokensByBalance = createDescendingComparator(
+ (token: UserTokenData) => token?.balance ?? 0 > 0
+);
+
const compareTokens = mergeComparators([
compareTokensIcpFirst,
compareTokensByUsdBalance,
compareTokensByImportance,
]);
+const compareTokensWhenExchangeProviderIsDown = mergeComparators([
+ compareTokensIcpFirst,
+ compareTokensByBalance,
+ compareTokensByImportance,
+]);
+
/**
* Filters and sorts user tokens based on specific criteria:
* - Always prioritizes ICP token first
@@ -51,21 +62,30 @@ const compareTokens = mergeComparators([
export const getTopHeldTokens = ({
userTokens,
isSignedIn = false,
+ areExchangePairsAvailable = true,
}: {
userTokens: UserToken[];
isSignedIn?: boolean;
+ areExchangePairsAvailable?: boolean;
}): UserTokenData[] => {
const topTokens = userTokens
.filter(isUserTokenData)
.filter(({ universeId }) =>
filterCyclesTransferStation({ universeId: universeId.toText() })
)
- .sort(compareTokens)
+ .sort(
+ areExchangePairsAvailable
+ ? compareTokensWhenExchangeProviderIsDown
+ : compareTokens
+ )
.slice(0, MAX_NUMBER_OF_ITEMS);
if (!isSignedIn) return topTokens;
- return topTokens.filter((token) => token?.balanceInUsd ?? 0 > 0);
+ const propertyToFilterBy = areExchangePairsAvailable
+ ? "balanceInUsd"
+ : "balance";
+ return topTokens.filter((token) => token?.[propertyToFilterBy] ?? 0 > 0);
};
const compareProjectsByUsdBalance = createDescendingComparator(
@@ -78,6 +98,12 @@ const compareProjects = mergeComparators([
compareByProjectTitle,
]);
+const compareProjectsWhenExchangeProviderIsDown = mergeComparators([
+ compareIcpFirst,
+ compareByNeuronCount,
+ compareByProjectTitle,
+]);
+
/**
* Filters and sorts projects based on specific criteria:
* - Always prioritizes ICP project first
@@ -89,18 +115,27 @@ const compareProjects = mergeComparators([
export const getTopStakedTokens = ({
projects,
isSignedIn = false,
+ areExchangePairsAvailable = true,
}: {
projects: TableProject[];
isSignedIn?: boolean;
+ areExchangePairsAvailable?: boolean;
}): TableProject[] => {
const topProjects = [...projects]
.filter(filterCyclesTransferStation)
- .sort(compareProjects)
+ .sort(
+ areExchangePairsAvailable
+ ? compareProjects
+ : compareProjectsWhenExchangeProviderIsDown
+ )
.slice(0, MAX_NUMBER_OF_ITEMS);
if (!isSignedIn) return topProjects;
- return topProjects.filter((project) => project?.stakeInUsd ?? 0 > 0);
+ const propertyToFilterBy = areExchangePairsAvailable ? "stakeInUsd" : "stake";
+ return topProjects.filter(
+ (project) => project?.[propertyToFilterBy] ?? 0 > 0
+ );
};
/**