aboutsummaryrefslogtreecommitdiff
path: root/packages/bank-ui/src/pages/BankFrame.tsx
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-03-11 14:56:25 -0300
committerSebastian <sebasjm@gmail.com>2024-03-11 14:57:48 -0300
commit37f46f4d6b821d163c3e4db5c374b1120212ac74 (patch)
tree641c5bccd6d1b77fa440e67b80543eec9378ef4a /packages/bank-ui/src/pages/BankFrame.tsx
parent4cbe754aca72b6edee922e3a84f251030293f088 (diff)
downloadwallet-core-37f46f4d6b821d163c3e4db5c374b1120212ac74.tar.xz
obs and cancel request, plus lint
Diffstat (limited to 'packages/bank-ui/src/pages/BankFrame.tsx')
-rw-r--r--packages/bank-ui/src/pages/BankFrame.tsx166
1 files changed, 148 insertions, 18 deletions
diff --git a/packages/bank-ui/src/pages/BankFrame.tsx b/packages/bank-ui/src/pages/BankFrame.tsx
index 427e9a156..39f042455 100644
--- a/packages/bank-ui/src/pages/BankFrame.tsx
+++ b/packages/bank-ui/src/pages/BankFrame.tsx
@@ -14,7 +14,14 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { Amounts, TalerError, TranslatedString } from "@gnu-taler/taler-util";
+import {
+ AbsoluteTime,
+ Amounts,
+ ObservabilityEventType,
+ TalerError,
+ TranslatedString,
+ assertUnreachable,
+} from "@gnu-taler/taler-util";
import {
Footer,
Header,
@@ -22,22 +29,23 @@ import {
ToastBanner,
notifyError,
notifyException,
- useTranslationContext
+ useTranslationContext,
} from "@gnu-taler/web-util/browser";
-import { ComponentChildren, VNode, h } from "preact";
-import { useEffect, useErrorBoundary } from "preact/hooks";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
+import { useEffect, useErrorBoundary, useState } from "preact/hooks";
import { useBankCoreApiContext } from "../context/config.js";
import { useSettingsContext } from "../context/settings.js";
import { useAccountDetails } from "../hooks/account.js";
-import { useSessionState } from "../hooks/session.js";
import { useBankState } from "../hooks/bank-state.js";
import {
getAllBooleanPreferences,
getLabelForPreferences,
usePreferences,
} from "../hooks/preferences.js";
+import { useSessionState } from "../hooks/session.js";
import { RouteDefinition } from "../route.js";
import { RenderAmount } from "./PaytoWireTransferForm.js";
+import { privatePages } from "../Routing.js";
const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined;
const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
@@ -85,13 +93,18 @@ export function BankFrame({
title="Bank"
iconLinkURL={settings.iconLinkURL ?? "#"}
profileURL={routeAccountDetails?.url({})}
+ notificationURL={
+ preferences.showDebugInfo
+ ? privatePages.notifications.url({})
+ : undefined
+ }
onLogout={
session.state.status !== "loggedIn"
? undefined
: () => {
- session.logOut();
- resetBankState();
- }
+ session.logOut();
+ resetBankState();
+ }
}
sites={
!settings.topNavSites ? [] : Object.entries(settings.topNavSites)
@@ -102,11 +115,11 @@ export function BankFrame({
<div class="text-xs font-semibold leading-6 text-gray-400">
<i18n.Translate>Preferences</i18n.Translate>
</div>
- <ul role="list" class="space-y-1">
+ <ul role="list" class="space-y-4">
{getAllBooleanPreferences().map((set) => {
const isOn: boolean = !!preferences[set];
return (
- <li key={set} class="mt-2 pl-2">
+ <li key={set} class="pl-2">
<div class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<span
@@ -144,19 +157,23 @@ export function BankFrame({
</Header>
</div>
- <div class="fixed z-20 w-full">
+ <div class="fixed z-20 top-14 w-full">
<div class="mx-auto w-4/5">
<ToastBanner />
+ {/* <Attention type="success" title={"hola" as TranslatedString} onClose={() => { }} /> */}
</div>
</div>
<main class="-mt-32 flex-1">
{account && routeAccountDetails && (
- <header class="py-5 bg-indigo-600 ">
+ <header class="py-6 bg-indigo-600">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<h1 class=" flex flex-wrap items-center justify-between sm:flex-nowrap">
<span class="text-2xl font-bold tracking-tight text-white">
- <WelcomeAccount account={account} routeAccountDetails={routeAccountDetails} />
+ <WelcomeAccount
+ account={account}
+ routeAccountDetails={routeAccountDetails}
+ />
</span>
<span class="text-2xl font-bold tracking-tight text-white">
<AccountBalance account={account} />
@@ -166,13 +183,15 @@ export function BankFrame({
</header>
)}
- <div class="mx-auto max-w-7xl px-4 pb-12 sm:px-6 lg:px-8">
+ <div class="mx-auto max-w-7xl px-4 pb-4 sm:px-6 lg:px-8">
<div class="rounded-lg bg-white px-5 py-6 shadow sm:px-6">
{children}
</div>
</div>
</main>
+ <AppActivity />
+
<Footer
testingUrlKey="corebank-api-base-url"
GIT_HASH={GIT_HASH}
@@ -182,8 +201,117 @@ export function BankFrame({
);
}
-function WelcomeAccount({ account, routeAccountDetails }: {
- account: string,
+function Wait({ class: clazz }: { class?: string }): VNode {
+ return (
+ <Fragment>
+ <style>{`
+ .animated-loader {
+ display: inline-block;
+ --b: 5px;
+ border-radius: 50%;
+ aspect-ratio: 1;
+ padding: 1px;
+ background: conic-gradient(#0000 10%,#4f46e5) content-box;
+ -webkit-mask:
+ repeating-conic-gradient(#0000 0deg,#000 1deg 20deg,#0000 21deg 36deg),
+ radial-gradient(farthest-side,#0000 calc(100% - var(--b) - 1px),#000 calc(100% - var(--b)));
+ -webkit-mask-composite: destination-in;
+ mask-composite: intersect;
+ animation:spinning-loader 1s infinite steps(10);
+ }
+ @keyframes spinning-loader {to{transform: rotate(1turn)}}
+ `}</style>
+ <div class={`animated-loader ${clazz}`} />
+ </Fragment>
+ );
+}
+
+function AppActivity(): VNode {
+ const [lastEvent, setLastEvent] = useState<{
+ url: string;
+ id: string;
+ when: AbsoluteTime;
+ }>();
+ const [status, setStatus] = useState<"ok" | "fail">();
+ const d = useBankCoreApiContext();
+ const onBackendActivity = !d ? undefined : d.onBackendActivity;
+ const cancelRequest = !d ? undefined : d.cancelRequest;
+ const [pref] = usePreferences();
+ useEffect(() => {
+ // console.log("ASDASDS", onBackendActivity)
+ if (!pref.showDebugInfo) return;
+ if (!onBackendActivity) return;
+ return onBackendActivity((ev) => {
+ switch (ev.type) {
+ case ObservabilityEventType.HttpFetchStart: {
+ setLastEvent(ev);
+ setStatus(undefined);
+ return;
+ }
+ case ObservabilityEventType.HttpFetchFinishError: {
+ setStatus("fail");
+ return;
+ }
+ case ObservabilityEventType.HttpFetchFinishSuccess: {
+ setStatus("ok");
+ return;
+ }
+ /**
+ * all of this are ignored
+ */
+ case ObservabilityEventType.DbQueryStart:
+ case ObservabilityEventType.DbQueryFinishSuccess:
+ case ObservabilityEventType.DbQueryFinishError:
+ case ObservabilityEventType.RequestStart:
+ case ObservabilityEventType.RequestFinishSuccess:
+ case ObservabilityEventType.RequestFinishError:
+ case ObservabilityEventType.TaskStart:
+ case ObservabilityEventType.TaskStop:
+ case ObservabilityEventType.TaskReset:
+ case ObservabilityEventType.ShepherdTaskResult:
+ case ObservabilityEventType.DeclareTaskDependency:
+ case ObservabilityEventType.CryptoStart:
+ case ObservabilityEventType.CryptoFinishSuccess:
+ case ObservabilityEventType.CryptoFinishError:
+ return;
+ default: {
+ assertUnreachable(ev);
+ }
+ }
+ });
+ });
+ if (!pref.showDebugInfo || !lastEvent) return <Fragment />;
+ return (
+ <div
+ data-status={status}
+ class="fixed z-20 bottom-0 w-full ease-in-out delay-1000 transition-transform data-[status=ok]:scale-y-0"
+ >
+ <div
+ data-status={status}
+ class="mx-auto w-4/5 center flex p-1 bg-gray-300 m-1 data-[status=fail]:bg-red-200 data-[status=ok]:bg-green-200 "
+ >
+ {!status ? <Wait class="w-6 h-6" /> : <div class="w-6 h-6" />}
+
+ <p class="ml-2 my-auto text-sm text-gray-500">{lastEvent.url}</p>
+ {!status ? (
+ <button
+ onClick={() => {
+ if (cancelRequest) cancelRequest(lastEvent.id);
+ }}
+ >
+ cancel
+ </button>
+ ) : undefined}
+ </div>
+ </div>
+ );
+}
+
+function WelcomeAccount({
+ account,
+ routeAccountDetails,
+}: {
+ account: string;
routeAccountDetails: RouteDefinition;
}): VNode {
const { i18n } = useTranslationContext();
@@ -196,7 +324,8 @@ function WelcomeAccount({ account, routeAccountDetails }: {
}
if (result.type === "fail") {
return (
- <a name="account details"
+ <a
+ name="account details"
href={routeAccountDetails.url({})}
class="underline underline-offset-2"
>
@@ -205,7 +334,8 @@ function WelcomeAccount({ account, routeAccountDetails }: {
);
}
return (
- <a name="account details"
+ <a
+ name="account details"
href={routeAccountDetails.url({})}
class="underline underline-offset-2"
>