diff --git a/clients/banking/src/components/CardsArea.tsx b/clients/banking/src/components/CardsArea.tsx
index 83b7899d0..b9d2d8d7a 100644
--- a/clients/banking/src/components/CardsArea.tsx
+++ b/clients/banking/src/components/CardsArea.tsx
@@ -1,4 +1,4 @@
-import { Option } from "@swan-io/boxed";
+import { AsyncData, Option, Result } from "@swan-io/boxed";
import { Breadcrumbs, BreadcrumbsRoot } from "@swan-io/lake/src/components/Breadcrumbs";
import { FullViewportLayer } from "@swan-io/lake/src/components/FullViewportLayer";
import { LakeButton } from "@swan-io/lake/src/components/LakeButton";
@@ -7,11 +7,11 @@ import { ResponsiveContainer } from "@swan-io/lake/src/components/ResponsiveCont
import { Space } from "@swan-io/lake/src/components/Space";
import { commonStyles } from "@swan-io/lake/src/constants/commonStyles";
import { breakpoints, colors, spacings } from "@swan-io/lake/src/constants/design";
+import { useDeferredUrqlQuery } from "@swan-io/lake/src/hooks/useUrqlQuery";
import { isNotNullish, isNullish } from "@swan-io/lake/src/utils/nullish";
-import { Suspense, useMemo } from "react";
+import { Suspense, useEffect, useMemo } from "react";
import { StyleSheet, View } from "react-native";
import { P, match } from "ts-pattern";
-import { useQuery } from "urql";
import {
AccountAreaQuery,
CardCountWithAccountDocument,
@@ -23,6 +23,7 @@ import { t } from "../utils/i18n";
import { Router } from "../utils/routes";
import { CardItemArea } from "./CardItemArea";
import { CardWizard } from "./CardWizard";
+import { ErrorView } from "./ErrorView";
import { Redirect } from "./Redirect";
const styles = StyleSheet.create({
@@ -91,43 +92,45 @@ const useDisplayableCardsInformation = ({
} as const;
}, [accountId]);
- const [withAccountQuery] = useQuery({
- query: CardCountWithAccountDocument,
- pause: !hasAccountId,
- variables: {
- first: 1,
- filters: filtersWithAccount,
- },
- });
+ const { data: withAccountQuery, query: queryWithAccount } = useDeferredUrqlQuery(
+ CardCountWithAccountDocument,
+ );
- const [withoutAccountQuery] = useQuery({
- query: CardCountWithoutAccountDocument,
- pause: hasAccountId,
- variables: {
- accountMembershipId,
- first: 1,
- filters: relevantCardsFilter,
- },
- });
+ const { data: withoutAccountQuery, query: queryWithoutAccount } = useDeferredUrqlQuery(
+ CardCountWithoutAccountDocument,
+ );
+
+ useEffect(() => {
+ if (hasAccountId) {
+ queryWithAccount({
+ first: 1,
+ filters: filtersWithAccount,
+ });
+ } else {
+ queryWithoutAccount({
+ accountMembershipId,
+ first: 1,
+ filters: relevantCardsFilter,
+ });
+ }
+ }, [accountMembershipId, accountId, filtersWithAccount]);
if (hasAccountId) {
- return {
+ return withAccountQuery.mapOk(data => ({
onlyCardId:
- withAccountQuery.data?.cards.totalCount === 1
- ? Option.fromNullable(withAccountQuery.data?.cards.edges[0]?.node.id)
+ data?.cards.totalCount === 1
+ ? Option.fromNullable(data?.cards.edges[0]?.node.id)
: Option.None(),
- totalDisplayableCardCount: withAccountQuery.data?.cards.totalCount ?? 0,
- };
+ totalDisplayableCardCount: data?.cards.totalCount ?? 0,
+ }));
} else {
- return {
+ return withoutAccountQuery.mapOk(data => ({
onlyCardId:
- withoutAccountQuery.data?.accountMembership?.cards.totalCount === 1
- ? Option.fromNullable(
- withoutAccountQuery.data?.accountMembership?.cards.edges[0]?.node.id,
- )
+ data?.accountMembership?.cards.totalCount === 1
+ ? Option.fromNullable(data?.accountMembership?.cards.edges[0]?.node.id)
: Option.None(),
- totalDisplayableCardCount: withoutAccountQuery.data?.accountMembership?.cards.totalCount ?? 0,
- };
+ totalDisplayableCardCount: data?.accountMembership?.cards.totalCount ?? 0,
+ }));
}
};
@@ -145,7 +148,7 @@ export const CardsArea = ({
}: Props) => {
const route = Router.useRoute(["AccountCardsList", "AccountCardsItemArea"]);
- const { onlyCardId, totalDisplayableCardCount } = useDisplayableCardsInformation({
+ const data = useDisplayableCardsInformation({
accountMembershipId,
accountId,
});
@@ -160,111 +163,123 @@ export const CardsArea = ({
[accountMembershipId],
);
- if (onlyCardId.isSome() && route?.name !== "AccountCardsItemArea") {
- return (
-
- );
- }
-
if (isNullish(route?.name)) {
return ;
}
- return (
-
- {({ large }) => (
-
-
- {totalDisplayableCardCount > 1 ? (
-
-
-
- ) : null}
+ return match(data)
+ .with(AsyncData.P.NotAsked, AsyncData.P.Loading, () => )
+ .with(AsyncData.P.Done(Result.P.Error(P.select())), error => )
+ .with(
+ AsyncData.P.Done(Result.P.Ok(P.select())),
+ ({ onlyCardId, totalDisplayableCardCount }) => {
+ if (onlyCardId.isSome() && route?.name !== "AccountCardsItemArea") {
+ return (
+
+ );
+ }
- {onlyCardId.isSome() ? : null}
+ return (
+
+ {({ large }) => (
+
+
+ {totalDisplayableCardCount > 1 ? (
+
+
+
+ ) : null}
- }>
-
- {match(route)
- .with(
- { name: "AccountCardsList" },
- ({ params: { accountMembershipId, new: _, ...params } }) => (
-
- ),
- )
- .with({ name: "AccountCardsItemArea" }, ({ params: { cardId } }) => (
- <>
- {canAddCard && cardOrderVisible && onlyCardId.isSome() ? (
-
-
- Router.push("AccountCardsItem", {
- cardId,
- accountMembershipId,
- new: "",
- })
- }
- >
- {t("common.new")}
-
-
- ) : null}
+ {onlyCardId.isSome() ? : null}
-
- >
- ))
- .with(P.nullish, () => null)
- .exhaustive()}
-
-
+ }>
+
+ {match(route)
+ .with(
+ { name: "AccountCardsList" },
+ ({ params: { accountMembershipId, new: _, ...params } }) => (
+
+ ),
+ )
+ .with({ name: "AccountCardsItemArea" }, ({ params: { cardId } }) => (
+ <>
+ {canAddCard && cardOrderVisible && onlyCardId.isSome() ? (
+
+
+ Router.push("AccountCardsItem", {
+ cardId,
+ accountMembershipId,
+ new: "",
+ })
+ }
+ >
+ {t("common.new")}
+
+
+ ) : null}
-
- {
- match(route)
- .with({ name: P.string }, ({ name, params }) => {
- Router.push(name === "AccountCardsItemArea" ? "AccountCardsItem" : name, {
- ...params,
- new: undefined,
- });
- })
- .otherwise(() => {});
- }}
- />
-
-
-
- )}
-
- );
+
+ >
+ ))
+ .with(P.nullish, () => null)
+ .exhaustive()}
+
+
+
+
+ {
+ match(route)
+ .with({ name: P.string }, ({ name, params }) => {
+ Router.push(
+ name === "AccountCardsItemArea" ? "AccountCardsItem" : name,
+ {
+ ...params,
+ new: undefined,
+ },
+ );
+ })
+ .otherwise(() => {});
+ }}
+ />
+
+
+
+ )}
+
+ );
+ },
+ )
+ .exhaustive();
};
diff --git a/clients/banking/src/components/MembershipDetailArea.tsx b/clients/banking/src/components/MembershipDetailArea.tsx
index 1b99edd3a..66a2e17ff 100644
--- a/clients/banking/src/components/MembershipDetailArea.tsx
+++ b/clients/banking/src/components/MembershipDetailArea.tsx
@@ -1,21 +1,23 @@
+import { AsyncData, Result } from "@swan-io/boxed";
import { Box } from "@swan-io/lake/src/components/Box";
import { LakeAlert } from "@swan-io/lake/src/components/LakeAlert";
import { LakeHeading } from "@swan-io/lake/src/components/LakeHeading";
import { LakeText } from "@swan-io/lake/src/components/LakeText";
import { ListRightPanelContent } from "@swan-io/lake/src/components/ListRightPanel";
+import { LoadingView } from "@swan-io/lake/src/components/LoadingView";
import { Space } from "@swan-io/lake/src/components/Space";
import { TabView } from "@swan-io/lake/src/components/TabView";
import { Tag } from "@swan-io/lake/src/components/Tag";
import { Tile } from "@swan-io/lake/src/components/Tile";
import { commonStyles } from "@swan-io/lake/src/constants/commonStyles";
import { colors, negativeSpacings, spacings } from "@swan-io/lake/src/constants/design";
+import { useUrqlQuery } from "@swan-io/lake/src/hooks/useUrqlQuery";
import { isNotNullishOrEmpty } from "@swan-io/lake/src/utils/nullish";
import { CountryCCA3 } from "@swan-io/shared-business/src/constants/countries";
import dayjs from "dayjs";
import { useMemo } from "react";
import { ScrollView, StyleSheet, View } from "react-native";
import { P, match } from "ts-pattern";
-import { useQuery } from "urql";
import { AccountMembershipFragment, MembershipDetailDocument } from "../graphql/partner";
import { getMemberName } from "../utils/accountMembership";
import { t } from "../utils/i18n";
@@ -90,290 +92,297 @@ export const MembershipDetailArea = ({
}: Props) => {
const route = Router.useRoute(membershipsDetailRoutes);
- const [{ data }, reload] = useQuery({
+ const { data, reload } = useUrqlQuery({
query: MembershipDetailDocument,
variables: { accountMembershipId: editingAccountMembershipId },
});
const accountMembership = useMemo(() => {
- return match(data)
- .returnType()
- .with(
- {
- accountMembership: {
- canManageAccountMembership: false,
- canInitiatePayments: false,
- canManageBeneficiaries: false,
- canViewAccount: false,
- canManageCards: false,
- statusInfo: {
- __typename: "AccountMembershipBindingUserErrorStatusInfo",
- idVerifiedMatchError: true,
+ return data.mapOk(data =>
+ match(data)
+ .returnType()
+ .with(
+ {
+ accountMembership: {
+ canManageAccountMembership: false,
+ canInitiatePayments: false,
+ canManageBeneficiaries: false,
+ canViewAccount: false,
+ canManageCards: false,
+ statusInfo: {
+ __typename: "AccountMembershipBindingUserErrorStatusInfo",
+ idVerifiedMatchError: true,
+ },
},
+ projectInfo: { B2BMembershipIDVerification: false },
},
- projectInfo: { B2BMembershipIDVerification: false },
- },
- ({ accountMembership }) => ({
- ...accountMembership,
- statusInfo: {
- ...accountMembership.statusInfo,
- idVerifiedMatchError: false,
- },
- }),
- )
- .otherwise(() => data?.accountMembership ?? undefined);
+ ({ accountMembership }) => ({
+ ...accountMembership,
+ statusInfo: {
+ ...accountMembership.statusInfo,
+ idVerifiedMatchError: false,
+ },
+ }),
+ )
+ .otherwise(() => data?.accountMembership ?? undefined),
+ );
}, [data]);
- if (accountMembership == null) {
- return null;
- }
-
- const requiresIdentityVerification =
- shouldDisplayIdVerification && accountMembership.hasRequiredIdentificationLevel === false;
+ return match(data)
+ .with(AsyncData.P.NotAsked, AsyncData.P.Loading, () => (
+
+ ))
+ .with(AsyncData.P.Done(Result.P.Error(P.select())), error => )
+ .with(AsyncData.P.Done(Result.P.Ok(P.select())), ({ accountMembership }) => {
+ if (accountMembership == null) {
+ return null;
+ }
- return (
-
-
-
- (
-
- ),
- )
- .with({ __typename: "AccountMembershipBindingUserErrorStatusInfo" }, () => (
-
- ))
- .otherwise(() => null)}
- >
-
- {match(accountMembership.statusInfo)
- .with({ __typename: "AccountMembershipEnabledStatusInfo" }, () => (
- {t("memberships.status.active")}
- ))
+ const requiresIdentityVerification =
+ shouldDisplayIdVerification && accountMembership.hasRequiredIdentificationLevel === false;
+
+
+
+ {t("memberships.status.limitedAccess")},
+ () => (
+
+ ),
)
.with({ __typename: "AccountMembershipBindingUserErrorStatusInfo" }, () => (
- {t("memberships.status.conflict")}
- ))
- .with({ __typename: "AccountMembershipInvitationSentStatusInfo" }, () => (
- {t("memberships.status.invitationSent")}
- ))
- .with({ __typename: "AccountMembershipSuspendedStatusInfo" }, () => (
- {t("memberships.status.temporarilyBlocked")}
- ))
- .with({ __typename: "AccountMembershipDisabledStatusInfo" }, () => (
- {t("memberships.status.permanentlyBlocked")}
+
))
- .with({ __typename: "AccountMembershipConsentPendingStatusInfo" }, () => null)
- .exhaustive()}
+ .otherwise(() => null)}
+ >
+
+ {match(accountMembership.statusInfo)
+ .with({ __typename: "AccountMembershipEnabledStatusInfo" }, () => (
+ {t("memberships.status.active")}
+ ))
+ .with(
+ {
+ __typename: "AccountMembershipBindingUserErrorStatusInfo",
+ idVerifiedMatchError: true,
+ },
+ () => {t("memberships.status.limitedAccess")},
+ )
+ .with({ __typename: "AccountMembershipBindingUserErrorStatusInfo" }, () => (
+ {t("memberships.status.conflict")}
+ ))
+ .with({ __typename: "AccountMembershipInvitationSentStatusInfo" }, () => (
+ {t("memberships.status.invitationSent")}
+ ))
+ .with({ __typename: "AccountMembershipSuspendedStatusInfo" }, () => (
+ {t("memberships.status.temporarilyBlocked")}
+ ))
+ .with({ __typename: "AccountMembershipDisabledStatusInfo" }, () => (
+ {t("memberships.status.permanentlyBlocked")}
+ ))
+ .with({ __typename: "AccountMembershipConsentPendingStatusInfo" }, () => null)
+ .exhaustive()}
-
+
-
- {getMemberName({ accountMembership })}
-
+
+ {getMemberName({ accountMembership })}
+
-
+
-
- {t("membershipDetail.addedAt", {
- date: dayjs(accountMembership.createdAt).format("LL"),
- })}
-
-
-
-
+
+ {t("membershipDetail.addedAt", {
+ date: dayjs(accountMembership.createdAt).format("LL"),
+ })}
+
+
+
+
-
+
- {match(accountMembership)
- .with(
- {
- statusInfo: {
- __typename: "AccountMembershipBindingUserErrorStatusInfo",
- idVerifiedMatchError: P.not(true),
+ {match(accountMembership)
+ .with(
+ {
+ statusInfo: {
+ __typename: "AccountMembershipBindingUserErrorStatusInfo",
+ idVerifiedMatchError: P.not(true),
+ },
+ user: P.nonNullable,
},
- user: P.nonNullable,
- },
- accountMembership => (
-
- {
- onAccountMembershipUpdate();
- reload();
- }}
- />
-
- ),
- )
- .with(
- {
- statusInfo: {
- __typename: P.union(
- "AccountMembershipDisabledStatusInfo",
- "AccountMembershipEnabledStatusInfo",
- "AccountMembershipBindingUserErrorStatusInfo",
- "AccountMembershipInvitationSentStatusInfo",
- "AccountMembershipSuspendedStatusInfo",
- ),
+ accountMembership => (
+
+ {
+ onAccountMembershipUpdate();
+ reload();
+ }}
+ />
+
+ ),
+ )
+ .with(
+ {
+ statusInfo: {
+ __typename: P.union(
+ "AccountMembershipDisabledStatusInfo",
+ "AccountMembershipEnabledStatusInfo",
+ "AccountMembershipBindingUserErrorStatusInfo",
+ "AccountMembershipInvitationSentStatusInfo",
+ "AccountMembershipSuspendedStatusInfo",
+ ),
+ },
},
- },
- accountMembership => (
- <>
- (
+ <>
+ [
+ {
+ label: t("membershipDetail.cards"),
+ url: Router.AccountMembersDetailsCardList({
+ ...params,
+ accountMembershipId: currentUserAccountMembershipId,
+ editingAccountMembershipId,
+ }),
+ },
+ ],
+ )
+ .otherwise(() => []),
+ ]}
+ otherLabel={t("common.tabs.other")}
+ />
+
+
+ {match({ route, currentUserAccountMembership, accountMembership })
.with(
- P.union(
- {
- currentUserAccountMembership: { canManageCards: true },
- },
- {
- accountMembership: { id: currentUserAccountMembershipId },
+ { route: { name: "AccountMembersDetailsRoot" } },
+ ({
+ route: {
+ params: { showInvitationLink },
},
+ }) => (
+ {
+ reload();
+ onRefreshRequest();
+ }}
+ large={large}
+ showInvitationLink={isNotNullishOrEmpty(showInvitationLink)}
+ />
),
- () => [
- {
- label: t("membershipDetail.cards"),
- url: Router.AccountMembersDetailsCardList({
- ...params,
- accountMembershipId: currentUserAccountMembershipId,
- editingAccountMembershipId,
- }),
- },
- ],
)
- .otherwise(() => []),
- ]}
- otherLabel={t("common.tabs.other")}
- />
-
-
- {match({ route, currentUserAccountMembership, accountMembership })
- .with(
- { route: { name: "AccountMembersDetailsRoot" } },
- ({
- route: {
- params: { showInvitationLink },
- },
- }) => (
- (
+ {
reload();
onRefreshRequest();
}}
large={large}
- showInvitationLink={isNotNullishOrEmpty(showInvitationLink)}
/>
- ),
- )
- .with({ route: { name: "AccountMembersDetailsRights" } }, () => (
- {
- reload();
- onRefreshRequest();
- }}
- large={large}
- />
- ))
- .with(
- P.union(
- {
- route: { name: "AccountMembersDetailsCardList" },
- currentUserAccountMembership: { canManageCards: true },
- },
- {
- route: { name: "AccountMembersDetailsCardList" },
- accountMembership: { id: currentUserAccountMembershipId },
- },
- ),
- ({
- route: {
- params: {
- accountMembershipId,
- editingAccountMembershipId,
- newCard: isCardWizardOpen,
- ...params
+ ))
+ .with(
+ P.union(
+ {
+ route: { name: "AccountMembersDetailsCardList" },
+ currentUserAccountMembership: { canManageCards: true },
},
- },
- }) => (
-
-
-
- ),
- )
- .otherwise(() => null)}
-
- >
- ),
- )
- .otherwise(() => (
-
- ))}
-
-
- );
+ {
+ route: { name: "AccountMembersDetailsCardList" },
+ accountMembership: { id: currentUserAccountMembershipId },
+ },
+ ),
+ ({
+ route: {
+ params: {
+ accountMembershipId,
+ editingAccountMembershipId,
+ newCard: isCardWizardOpen,
+ ...params
+ },
+ },
+ }) => (
+
+
+
+ ),
+ )
+ .otherwise(() => null)}
+
+ >
+ ),
+ )
+ .otherwise(() => (
+
+ ))}
+
+ ;
+ })
+ .exhaustive();
};
diff --git a/clients/banking/src/components/MembershipInvitationLinkModal.tsx b/clients/banking/src/components/MembershipInvitationLinkModal.tsx
index c3012dcc1..00ee99420 100644
--- a/clients/banking/src/components/MembershipInvitationLinkModal.tsx
+++ b/clients/banking/src/components/MembershipInvitationLinkModal.tsx
@@ -3,9 +3,10 @@ import { Box } from "@swan-io/lake/src/components/Box";
import { LakeLabel } from "@swan-io/lake/src/components/LakeLabel";
import { LakeTextInput } from "@swan-io/lake/src/components/LakeTextInput";
import { Space } from "@swan-io/lake/src/components/Space";
+import { useDeferredUrqlQuery } from "@swan-io/lake/src/hooks/useUrqlQuery";
import { LakeModal } from "@swan-io/shared-business/src/components/LakeModal";
+import { useEffect } from "react";
import { P, match } from "ts-pattern";
-import { useQuery } from "urql";
import { MembershipDetailDocument } from "../graphql/partner";
import { getMemberName } from "../utils/accountMembership";
import { t } from "../utils/i18n";
@@ -17,11 +18,14 @@ type Props = {
onPressClose: () => void;
};
export const MembershipInvitationLinkModal = ({ accountMembershipId, onPressClose }: Props) => {
- const [{ data }] = useQuery({
- query: MembershipDetailDocument,
- variables: { accountMembershipId: accountMembershipId as string },
- pause: accountMembershipId == null,
- });
+ const { data, query } = useDeferredUrqlQuery(MembershipDetailDocument);
+
+ useEffect(() => {
+ if (accountMembershipId != null) {
+ const request = query({ accountMembershipId });
+ return () => request.cancel();
+ }
+ }, [accountMembershipId]);
const value = match(projectConfiguration)
.with(
@@ -31,20 +35,21 @@ export const MembershipInvitationLinkModal = ({ accountMembershipId, onPressClos
)
.otherwise(() => `${__env.BANKING_URL}/api/invitation/${accountMembershipId ?? ""}`);
- const accountMembership = data?.accountMembership;
-
return (
result.toOption())
+ .flatMap(data => Option.fromNullable(data.accountMembership))
+ .map(accountMembership =>
+ t("members.invitationTitle.name", {
+ fullName: getMemberName({ accountMembership }),
+ }),
+ )
+ .getWithDefault(t("members.invitationTitle"))}
>
{
const accountCountry = account.country ?? "FRA";
- const [, updateAccount] = useMutation(UpdateAccountDocument);
+ const [, updateAccount] = useUrqlMutation(UpdateAccountDocument);
const holderInfo = account.holder.info;
const isCompany = holderInfo?.__typename === "AccountHolderCompanyInfo";
@@ -344,16 +344,16 @@ const UpdateAccountForm = ({
taxIdentificationNumber,
},
})
- .then(parseOperationResult)
- .then(({ updateAccount, updateAccountHolder }) =>
- Promise.all([
- filterRejectionsToPromise(updateAccount),
- filterRejectionsToPromise(updateAccountHolder),
+ .mapOkToResult(({ updateAccount, updateAccountHolder }) =>
+ Result.all([
+ filterRejectionsToResult(updateAccount),
+ filterRejectionsToResult(updateAccountHolder),
]),
)
- .catch((error: unknown) => {
+ .tapError((error: unknown) => {
showToast({ variant: "error", error, title: translateError(error) });
- });
+ })
+ .toPromise();
}
});
}}
diff --git a/clients/banking/src/pages/AccountDetailsVirtualIbansPage.tsx b/clients/banking/src/pages/AccountDetailsVirtualIbansPage.tsx
index 4a38e2a23..f531a9a78 100644
--- a/clients/banking/src/pages/AccountDetailsVirtualIbansPage.tsx
+++ b/clients/banking/src/pages/AccountDetailsVirtualIbansPage.tsx
@@ -1,3 +1,4 @@
+import { Option } from "@swan-io/boxed";
import {
FixedListViewEmpty,
PlainListViewPlaceholder,
@@ -17,17 +18,17 @@ import { commonStyles } from "@swan-io/lake/src/constants/commonStyles";
import { breakpoints, spacings } from "@swan-io/lake/src/constants/design";
import { useBoolean } from "@swan-io/lake/src/hooks/useBoolean";
import { useResponsive } from "@swan-io/lake/src/hooks/useResponsive";
+import { useUrqlMutation } from "@swan-io/lake/src/hooks/useUrqlMutation";
import { useUrqlPaginatedQuery } from "@swan-io/lake/src/hooks/useUrqlQuery";
import { showToast } from "@swan-io/lake/src/state/toasts";
import { GetEdge } from "@swan-io/lake/src/utils/types";
-import { filterRejectionsToPromise, parseOperationResult } from "@swan-io/lake/src/utils/urql";
+import { filterRejectionsToResult } from "@swan-io/lake/src/utils/urql";
import { LakeModal } from "@swan-io/shared-business/src/components/LakeModal";
import { translateError } from "@swan-io/shared-business/src/utils/i18n";
import { printIbanFormat } from "@swan-io/shared-business/src/utils/validation";
import { useMemo } from "react";
import { StyleSheet, View } from "react-native";
import { match } from "ts-pattern";
-import { useMutation } from "urql";
import { ErrorView } from "../components/ErrorView";
import {
AccountDetailsVirtualIbansPageDocument,
@@ -176,18 +177,17 @@ const smallColumns: ColumnConfig[] = [
const Actions = ({ onCancel, virtualIbanId }: { onCancel: () => void; virtualIbanId: string }) => {
const [modalVisible, setModalVisible] = useBoolean(false);
- const [{ fetching }, cancelVirtualIban] = useMutation(CancelVirtualIbanDocument);
+ const [virtualIbanCancelation, cancelVirtualIban] = useUrqlMutation(CancelVirtualIbanDocument);
const onPressCancel = () => {
cancelVirtualIban({ virtualIbanId })
- .then(parseOperationResult)
- .then(data => data.cancelVirtualIbanEntry)
- .then(filterRejectionsToPromise)
- .then(onCancel)
- .catch((error: unknown) =>
+ .mapOkToResult(data => Option.fromNullable(data.cancelVirtualIbanEntry).toResult(undefined))
+ .mapOkToResult(filterRejectionsToResult)
+ .tapOk(onCancel)
+ .tapError((error: unknown) =>
showToast({ variant: "error", error, title: translateError(error) }),
)
- .finally(setModalVisible.off);
+ .tap(setModalVisible.off);
};
return (
@@ -211,7 +211,12 @@ const Actions = ({ onCancel, virtualIbanId }: { onCancel: () => void; virtualIba
-
+
{t("accountDetails.virtualIbans.cancelVirtualIban")}
@@ -225,7 +230,7 @@ const keyExtractor = ({ node: { id } }: Edge) => id;
export const AccountDetailsVirtualIbansPage = ({ accountId }: Props) => {
// use useResponsive to fit with scroll behavior set in AccountArea
const { desktop } = useResponsive();
- const [{ fetching: adding }, addVirtualIban] = useMutation(AddVirtualIbanDocument);
+ const [virtualIbanAddition, addVirtualIban] = useUrqlMutation(AddVirtualIbanDocument);
const { data, nextData, reload, setAfter } = useUrqlPaginatedQuery(
{
@@ -237,12 +242,10 @@ export const AccountDetailsVirtualIbansPage = ({ accountId }: Props) => {
const onPressNew = () => {
addVirtualIban({ accountId })
- .then(parseOperationResult)
- .then(data => data.addVirtualIbanEntry)
- .then(data => data ?? Promise.reject())
- .then(filterRejectionsToPromise)
- .then(reload)
- .catch((error: unknown) => {
+ .mapOkToResult(data => Option.fromNullable(data.addVirtualIbanEntry).toResult(undefined))
+ .mapOkToResult(filterRejectionsToResult)
+ .tapOk(reload)
+ .tapError((error: unknown) => {
showToast({ variant: "error", error, title: translateError(error) });
});
};
@@ -273,7 +276,7 @@ export const AccountDetailsVirtualIbansPage = ({ accountId }: Props) => {
{edges.length > 0 && unlimited && (
{
{unlimited && (