summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-04-23 00:16:35 +0200
committerFlorian Dold <florian@dold.me>2024-04-23 00:16:35 +0200
commit920a384e90bc35f262361920aa8ddd1046abac34 (patch)
tree11cbf47f5321b23c778191828028b02ec4caab4a /packages
parentdfb1716769068859a49b1a2187f187b99a5fe88b (diff)
downloadwallet-core-920a384e90bc35f262361920aa8ddd1046abac34.tar.gz
wallet-core-920a384e90bc35f262361920aa8ddd1046abac34.tar.bz2
wallet-core-920a384e90bc35f262361920aa8ddd1046abac34.zip
wallet-core: avoid use of plain 'id' field, misc. fixes
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-util/src/wallet-types.ts20
-rw-r--r--packages/taler-wallet-core/src/wallet-api-types.ts16
-rw-r--r--packages/taler-wallet-core/src/wallet.ts4
-rw-r--r--packages/taler-wallet-webextension/src/components/WalletActivity.tsx1318
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts5
5 files changed, 812 insertions, 551 deletions
diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts
index d39eb3ce9..0564c45f7 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -2621,30 +2621,30 @@ export const codecForWithdrawFakebankRequest =
.build("WithdrawFakebankRequest");
export interface ActiveTask {
- id: string;
+ taskId: string;
transaction: TransactionIdStr | undefined;
firstTry: AbsoluteTime | undefined;
nextTry: AbsoluteTime | undefined;
- counter: number | undefined;
+ retryCounter: number | undefined;
lastError: TalerErrorDetail | undefined;
}
-export interface GetActiveTasks {
+export interface GetActiveTasksResponse {
tasks: ActiveTask[];
}
export const codecForActiveTask = (): Codec<ActiveTask> =>
buildCodecForObject<ActiveTask>()
- .property("id", codecForString())
+ .property("taskId", codecForString())
.property("transaction", codecOptional(codecForTransactionIdStr()))
- .property("counter", codecForNumber())
- .property("firstTry", codecForAbsoluteTime)
- .property("nextTry", codecForAbsoluteTime)
- .property("lastError", codecForTalerErrorDetail())
+ .property("retryCounter", codecOptional(codecForNumber()))
+ .property("firstTry", codecOptional(codecForAbsoluteTime))
+ .property("nextTry", codecOptional(codecForAbsoluteTime))
+ .property("lastError", codecOptional(codecForTalerErrorDetail()))
.build("ActiveTask");
-export const codecForGetActiveTasks = (): Codec<GetActiveTasks> =>
- buildCodecForObject<GetActiveTasks>()
+export const codecForGetActiveTasks = (): Codec<GetActiveTasksResponse> =>
+ buildCodecForObject<GetActiveTasksResponse>()
.property("tasks", codecForList(codecForActiveTask()))
.build("GetActiveTasks");
diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts
index f493a6b8b..ba28c009a 100644
--- a/packages/taler-wallet-core/src/wallet-api-types.ts
+++ b/packages/taler-wallet-core/src/wallet-api-types.ts
@@ -60,7 +60,7 @@ import {
FailTransactionRequest,
ForceRefreshRequest,
ForgetKnownBankAccountsRequest,
- GetActiveTasks,
+ GetActiveTasksResponse,
GetAmountRequest,
GetBalanceDetailRequest,
GetContractTermsDetailsRequest,
@@ -235,11 +235,6 @@ export enum WalletApiOperation {
Recycle = "recycle",
ApplyDevExperiment = "applyDevExperiment",
ValidateIban = "validateIban",
- TestingWaitTransactionsFinal = "testingWaitTransactionsFinal",
- TestingWaitRefreshesFinal = "testingWaitRefreshesFinal",
- TestingWaitTransactionState = "testingWaitTransactionState",
- TestingWaitTasksDone = "testingWaitTasksDone",
- TestingSetTimetravel = "testingSetTimetravel",
GetCurrencySpecification = "getCurrencySpecification",
ListStoredBackups = "listStoredBackups",
CreateStoredBackup = "createStoredBackup",
@@ -248,7 +243,6 @@ export enum WalletApiOperation {
UpdateExchangeEntry = "updateExchangeEntry",
ListExchangesForScopedCurrency = "listExchangesForScopedCurrency",
PrepareWithdrawExchange = "prepareWithdrawExchange",
- TestingInfiniteTransactionLoop = "testingInfiniteTransactionLoop",
GetExchangeResources = "getExchangeResources",
DeleteExchange = "deleteExchange",
ListGlobalCurrencyExchanges = "listGlobalCurrencyExchanges",
@@ -258,6 +252,12 @@ export enum WalletApiOperation {
AddGlobalCurrencyAuditor = "addGlobalCurrencyAuditor",
RemoveGlobalCurrencyAuditor = "removeGlobalCurrencyAuditor",
ListAssociatedRefreshes = "listAssociatedRefreshes",
+ TestingWaitTransactionsFinal = "testingWaitTransactionsFinal",
+ TestingWaitRefreshesFinal = "testingWaitRefreshesFinal",
+ TestingWaitTransactionState = "testingWaitTransactionState",
+ TestingWaitTasksDone = "testingWaitTasksDone",
+ TestingSetTimetravel = "testingSetTimetravel",
+ TestingInfiniteTransactionLoop = "testingInfiniteTransactionLoop",
TestingListTaskForTransaction = "testingListTasksForTransaction",
TestingGetDenomStats = "testingGetDenomStats",
TestingPing = "testingPing",
@@ -1074,7 +1074,7 @@ export type GetPendingTasksOp = {
export type GetActiveTasksOp = {
op: WalletApiOperation.GetActiveTasks;
request: EmptyObject;
- response: GetActiveTasks;
+ response: GetActiveTasksResponse;
};
/**
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 45f9e6078..f743e82b1 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -1043,8 +1043,8 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
const lastError = d?.lastError;
return {
- id: taskId,
- counter,
+ taskId: taskId,
+ retryCounter: counter,
firstTry,
nextTry,
lastError,
diff --git a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
index 1c566c3e4..69a2c0675 100644
--- a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
+++ b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
@@ -22,7 +22,7 @@ import {
TalerErrorDetail,
TaskProgressNotification,
WalletNotification,
- assertUnreachable
+ assertUnreachable,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -37,61 +37,80 @@ import { WxApiType } from "../wxApi.js";
import { Modal } from "./Modal.js";
import { Time } from "./Time.js";
-interface Props extends JSX.HTMLAttributes {
-}
+interface Props extends JSX.HTMLAttributes {}
-export function WalletActivity({ }: Props): VNode {
- const { i18n } = useTranslationContext()
- const [settings, updateSettings] = useSettings()
+export function WalletActivity({}: Props): VNode {
+ const { i18n } = useTranslationContext();
+ const [settings, updateSettings] = useSettings();
const api = useBackendContext();
useEffect(() => {
- document.body.style.marginBottom = "250px"
+ document.body.style.marginBottom = "250px";
return () => {
- document.body.style.marginBottom = "0px"
- }
- })
- const [table, setTable] = useState<"tasks" | "events">("tasks")
+ document.body.style.marginBottom = "0px";
+ };
+ });
+ const [table, setTable] = useState<"tasks" | "events">("tasks");
return (
- <div style={{ position: "fixed", bottom: 0, background: "white", zIndex: 1, height: 250, overflowY: "scroll", width: "100%" }}>
- <div style={{ display: "flex", justifyContent: "space-between", float: "right" }}>
+ <div
+ style={{
+ position: "fixed",
+ bottom: 0,
+ background: "white",
+ zIndex: 1,
+ height: 250,
+ overflowY: "scroll",
+ width: "100%",
+ }}
+ >
+ <div
+ style={{
+ display: "flex",
+ justifyContent: "space-between",
+ float: "right",
+ }}
+ >
<div />
<div>
- <div style={{ padding: 4, margin: 2, border: "solid 1px black" }} onClick={() => {
- updateSettings("showWalletActivity", false)
- }}>
+ <div
+ style={{ padding: 4, margin: 2, border: "solid 1px black" }}
+ onClick={() => {
+ updateSettings("showWalletActivity", false);
+ }}
+ >
close
</div>
</div>
</div>
<div style={{ display: "flex", justifyContent: "space-around" }}>
- <Button variant={table === "tasks" ? "contained" : "outlined"}
+ <Button
+ variant={table === "tasks" ? "contained" : "outlined"}
style={{ margin: 4 }}
onClick={async () => {
- setTable("tasks")
+ setTable("tasks");
}}
>
<i18n.Translate>Tasks</i18n.Translate>
</Button>
- <Button variant={table === "events" ? "contained" : "outlined"}
+ <Button
+ variant={table === "events" ? "contained" : "outlined"}
style={{ margin: 4 }}
onClick={async () => {
- setTable("events")
+ setTable("events");
}}
>
<i18n.Translate>Events</i18n.Translate>
</Button>
-
</div>
{(function (): VNode {
switch (table) {
case "events": {
- return <ObservabilityEventsTable />
+ return <ObservabilityEventsTable />;
}
case "tasks": {
- return <ActiveTasksTable />
+ return <ActiveTasksTable />;
}
default: {
- assertUnreachable(table)
+ assertUnreachable(table);
}
}
})()}
@@ -99,398 +118,554 @@ export function WalletActivity({ }: Props): VNode {
);
}
-interface MoreInfoPRops { events: (WalletNotification & { when: AbsoluteTime })[], onClick: (content: VNode) => void }
+interface MoreInfoPRops {
+ events: (WalletNotification & { when: AbsoluteTime })[];
+ onClick: (content: VNode) => void;
+}
type Notif = {
id: string;
events: (WalletNotification & { when: AbsoluteTime })[];
description: string;
start: AbsoluteTime;
end: AbsoluteTime;
- reference: {
- eventType: NotificationType,
- referenceType: "task" | "transaction" | "operation" | "exchange",
- id: string;
- } | undefined,
+ reference:
+ | {
+ eventType: NotificationType;
+ referenceType: "task" | "transaction" | "operation" | "exchange";
+ id: string;
+ }
+ | undefined;
MoreInfo: (p: MoreInfoPRops) => VNode;
-}
+};
function ShowBalanceChange({ events }: MoreInfoPRops): VNode {
if (!events.length) return <Fragment />;
const not = events[0];
if (not.type !== NotificationType.BalanceChange) return <Fragment />;
- return <Fragment>
- <dt>Transaction</dt>
- <dd>
- <a title={not.hintTransactionId} href={Pages.balanceTransaction({ tid: not.hintTransactionId })}>{not.hintTransactionId.substring(0, 10)}</a>
- </dd>
- </Fragment>
+ return (
+ <Fragment>
+ <dt>Transaction</dt>
+ <dd>
+ <a
+ title={not.hintTransactionId}
+ href={Pages.balanceTransaction({ tid: not.hintTransactionId })}
+ >
+ {not.hintTransactionId.substring(0, 10)}
+ </a>
+ </dd>
+ </Fragment>
+ );
}
function ShowBackupOperationError({ events, onClick }: MoreInfoPRops): VNode {
if (!events.length) return <Fragment />;
const not = events[0];
if (not.type !== NotificationType.BackupOperationError) return <Fragment />;
- return <Fragment>
- <dt>Error</dt>
- <dd>
- <a href="#" onClick={(e) => {
- e.preventDefault();
- const error = not.error
- onClick(<Fragment>
- <dl>
- <dt>Code</dt>
- <dd>{TalerErrorCode[error.code]} ({error.code})</dd>
- <dt>Hint</dt>
- <dd>{error.hint ?? "--"}</dd>
- <dt>Time</dt>
- <dd><Time
- timestamp={error.when}
- format="yyyy/MM/dd HH:mm:ss"
- /></dd>
- </dl>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
- {JSON.stringify(error, undefined, 2)}
- </pre>
- </Fragment>)
- }}>{TalerErrorCode[not.error.code]}</a>
- </dd>
- </Fragment>
-}
-
-function ShowTransactionStateTransition({ events, onClick }: MoreInfoPRops): VNode {
- if (!events.length) return <Fragment />;
- const not = events[0];
- if (not.type !== NotificationType.TransactionStateTransition) return <Fragment />;
- return <Fragment>
- <dt>Old state</dt>
- <dd>
- {not.oldTxState.major} - {not.oldTxState.minor ?? ""}
- </dd>
- <dt>New state</dt>
- <dd>
- {not.newTxState.major} - {not.newTxState.minor ?? ""}
- </dd>
- <dt>Transaction</dt>
- <dd>
- <a title={not.transactionId} href={Pages.balanceTransaction({ tid: not.transactionId })}>{not.transactionId.substring(0, 10)}</a>
- </dd>
- {not.errorInfo ? <Fragment>
+ return (
+ <Fragment>
<dt>Error</dt>
<dd>
- <a href="#" onClick={(e) => {
- if (!not.errorInfo) return;
- e.preventDefault();
- const error = not.errorInfo;
- onClick(<Fragment>
- <dl>
- <dt>Code</dt>
- <dd>{TalerErrorCode[error.code]} ({error.code})</dd>
- <dt>Hint</dt>
- <dd>{error.hint ?? "--"}</dd>
- <dt>Message</dt>
- <dd>{error.message ?? "--"}</dd>
- </dl>
- </Fragment>)
-
- }}>{TalerErrorCode[not.errorInfo.code]}</a>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ const error = not.error;
+ onClick(
+ <Fragment>
+ <dl>
+ <dt>Code</dt>
+ <dd>
+ {TalerErrorCode[error.code]} ({error.code})
+ </dd>
+ <dt>Hint</dt>
+ <dd>{error.hint ?? "--"}</dd>
+ <dt>Time</dt>
+ <dd>
+ <Time timestamp={error.when} format="yyyy/MM/dd HH:mm:ss" />
+ </dd>
+ </dl>
+ <pre
+ style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ >
+ {JSON.stringify(error, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
+ >
+ {TalerErrorCode[not.error.code]}
+ </a>
</dd>
- </Fragment> : undefined}
- <dt>Experimental</dt>
- <dd>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
- {JSON.stringify(not.experimentalUserData, undefined, 2)}
- </pre>
- </dd>
-
-
- </Fragment>
+ </Fragment>
+ );
}
-function ShowExchangeStateTransition({ events, onClick }: MoreInfoPRops): VNode {
+
+function ShowTransactionStateTransition({
+ events,
+ onClick,
+}: MoreInfoPRops): VNode {
if (!events.length) return <Fragment />;
const not = events[0];
- if (not.type !== NotificationType.ExchangeStateTransition) return <Fragment />;
- return <Fragment>
- <dt>Exchange</dt>
- <dd>
- {not.exchangeBaseUrl}
- </dd>
- {not.oldExchangeState && not.newExchangeState.exchangeEntryStatus !== not.oldExchangeState?.exchangeEntryStatus && <Fragment>
- <dt>Entry status</dt>
+ if (not.type !== NotificationType.TransactionStateTransition)
+ return <Fragment />;
+ return (
+ <Fragment>
+ <dt>Old state</dt>
<dd>
- from {not.oldExchangeState.exchangeEntryStatus} to {not.newExchangeState.exchangeEntryStatus}
+ {not.oldTxState.major} - {not.oldTxState.minor ?? ""}
</dd>
- </Fragment>}
- {not.oldExchangeState && not.newExchangeState.exchangeUpdateStatus !== not.oldExchangeState?.exchangeUpdateStatus && <Fragment>
- <dt>Update status</dt>
+ <dt>New state</dt>
<dd>
- from {not.oldExchangeState.exchangeUpdateStatus} to {not.newExchangeState.exchangeUpdateStatus}
+ {not.newTxState.major} - {not.newTxState.minor ?? ""}
</dd>
- </Fragment>}
- {not.oldExchangeState && not.newExchangeState.tosStatus !== not.oldExchangeState?.tosStatus && <Fragment>
- <dt>Tos status</dt>
+ <dt>Transaction</dt>
<dd>
- from {not.oldExchangeState.tosStatus} to {not.newExchangeState.tosStatus}
+ <a
+ title={not.transactionId}
+ href={Pages.balanceTransaction({ tid: not.transactionId })}
+ >
+ {not.transactionId.substring(0, 10)}
+ </a>
</dd>
- </Fragment>}
- </Fragment>
+ {not.errorInfo ? (
+ <Fragment>
+ <dt>Error</dt>
+ <dd>
+ <a
+ href="#"
+ onClick={(e) => {
+ if (!not.errorInfo) return;
+ e.preventDefault();
+ const error = not.errorInfo;
+ onClick(
+ <Fragment>
+ <dl>
+ <dt>Code</dt>
+ <dd>
+ {TalerErrorCode[error.code]} ({error.code})
+ </dd>
+ <dt>Hint</dt>
+ <dd>{error.hint ?? "--"}</dd>
+ <dt>Message</dt>
+ <dd>{error.message ?? "--"}</dd>
+ </dl>
+ </Fragment>,
+ );
+ }}
+ >
+ {TalerErrorCode[not.errorInfo.code]}
+ </a>
+ </dd>
+ </Fragment>
+ ) : undefined}
+ <dt>Experimental</dt>
+ <dd>
+ <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
+ {JSON.stringify(not.experimentalUserData, undefined, 2)}
+ </pre>
+ </dd>
+ </Fragment>
+ );
+}
+function ShowExchangeStateTransition({
+ events,
+ onClick,
+}: MoreInfoPRops): VNode {
+ if (!events.length) return <Fragment />;
+ const not = events[0];
+ if (not.type !== NotificationType.ExchangeStateTransition)
+ return <Fragment />;
+ return (
+ <Fragment>
+ <dt>Exchange</dt>
+ <dd>{not.exchangeBaseUrl}</dd>
+ {not.oldExchangeState &&
+ not.newExchangeState.exchangeEntryStatus !==
+ not.oldExchangeState?.exchangeEntryStatus && (
+ <Fragment>
+ <dt>Entry status</dt>
+ <dd>
+ from {not.oldExchangeState.exchangeEntryStatus} to{" "}
+ {not.newExchangeState.exchangeEntryStatus}
+ </dd>
+ </Fragment>
+ )}
+ {not.oldExchangeState &&
+ not.newExchangeState.exchangeUpdateStatus !==
+ not.oldExchangeState?.exchangeUpdateStatus && (
+ <Fragment>
+ <dt>Update status</dt>
+ <dd>
+ from {not.oldExchangeState.exchangeUpdateStatus} to{" "}
+ {not.newExchangeState.exchangeUpdateStatus}
+ </dd>
+ </Fragment>
+ )}
+ {not.oldExchangeState &&
+ not.newExchangeState.tosStatus !== not.oldExchangeState?.tosStatus && (
+ <Fragment>
+ <dt>Tos status</dt>
+ <dd>
+ from {not.oldExchangeState.tosStatus} to{" "}
+ {not.newExchangeState.tosStatus}
+ </dd>
+ </Fragment>
+ )}
+ </Fragment>
+ );
}
-type ObservaNotifWithTime = ((TaskProgressNotification | RequestProgressNotification) & {
+type ObservaNotifWithTime = (
+ | TaskProgressNotification
+ | RequestProgressNotification
+) & {
when: AbsoluteTime;
-})
+};
function ShowObservabilityEvent({ events, onClick }: MoreInfoPRops): VNode {
// let prev: ObservaNotifWithTime;
- const asd = events.map(not => {
- if (not.type !== NotificationType.RequestObservabilityEvent && not.type !== NotificationType.TaskObservabilityEvent) return <Fragment />;
+ const asd = events.map((not) => {
+ if (
+ not.type !== NotificationType.RequestObservabilityEvent &&
+ not.type !== NotificationType.TaskObservabilityEvent
+ )
+ return <Fragment />;
const title = (function () {
switch (not.event.type) {
case ObservabilityEventType.HttpFetchFinishError:
case ObservabilityEventType.HttpFetchFinishSuccess:
- case ObservabilityEventType.HttpFetchStart: return "HTTP Request"
+ case ObservabilityEventType.HttpFetchStart:
+ return "HTTP Request";
case ObservabilityEventType.DbQueryFinishSuccess:
case ObservabilityEventType.DbQueryFinishError:
- case ObservabilityEventType.DbQueryStart: return "Database"
+ case ObservabilityEventType.DbQueryStart:
+ return "Database";
case ObservabilityEventType.RequestFinishSuccess:
case ObservabilityEventType.RequestFinishError:
- case ObservabilityEventType.RequestStart: return "Wallet"
+ case ObservabilityEventType.RequestStart:
+ return "Wallet";
case ObservabilityEventType.CryptoFinishSuccess:
case ObservabilityEventType.CryptoFinishError:
- case ObservabilityEventType.CryptoStart: return "Crypto"
- case ObservabilityEventType.TaskStart: return "Task start"
- case ObservabilityEventType.TaskStop: return "Task stop"
- case ObservabilityEventType.TaskReset: return "Task reset"
- case ObservabilityEventType.ShepherdTaskResult: return "Schedule"
- case ObservabilityEventType.DeclareTaskDependency: return "Task dependency"
- case ObservabilityEventType.Message: return "Message"
+ case ObservabilityEventType.CryptoStart:
+ return "Crypto";
+ case ObservabilityEventType.TaskStart:
+ return "Task start";
+ case ObservabilityEventType.TaskStop:
+ return "Task stop";
+ case ObservabilityEventType.TaskReset:
+ return "Task reset";
+ case ObservabilityEventType.ShepherdTaskResult:
+ return "Schedule";
+ case ObservabilityEventType.DeclareTaskDependency:
+ return "Task dependency";
+ case ObservabilityEventType.Message:
+ return "Message";
}
})();
- return <ShowObervavilityDetails title={title} notif={not} onClick={onClick} />
-
- })
- return <table>
- <thead>
- <td>Event</td>
- <td>Info</td>
- <td>Start</td>
- <td>End</td>
- </thead>
- <tbody>
- {asd}
- </tbody>
- </table>
+ return (
+ <ShowObervavilityDetails title={title} notif={not} onClick={onClick} />
+ );
+ });
+ return (
+ <table>
+ <thead>
+ <td>Event</td>
+ <td>Info</td>
+ <td>Start</td>
+ <td>End</td>
+ </thead>
+ <tbody>{asd}</tbody>
+ </table>
+ );
}
-function ShowObervavilityDetails({ title, notif, onClick, prev }: { title: string, notif: ObservaNotifWithTime, prev?: ObservaNotifWithTime, onClick: (content: VNode) => void }): VNode {
+function ShowObervavilityDetails({
+ title,
+ notif,
+ onClick,
+ prev,
+}: {
+ title: string;
+ notif: ObservaNotifWithTime;
+ prev?: ObservaNotifWithTime;
+ onClick: (content: VNode) => void;
+}): VNode {
switch (notif.event.type) {
case ObservabilityEventType.HttpFetchStart:
case ObservabilityEventType.HttpFetchFinishError:
case ObservabilityEventType.HttpFetchFinishSuccess: {
- return <tr>
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
- >
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.url} {
- prev?.event.type === ObservabilityEventType.HttpFetchFinishSuccess ? `(${prev.event.status})`
- : prev?.event.type === ObservabilityEventType.HttpFetchFinishError ? <a href="#" onClick={(e) => {
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
e.preventDefault();
- if (prev.event.type !== ObservabilityEventType.HttpFetchFinishError) return;
- const error = prev.event.error
- onClick(<Fragment>
- <dl>
- <dt>Code</dt>
- <dd>{TalerErrorCode[error.code]} ({error.code})</dd>
- <dt>Hint</dt>
- <dd>{error.hint ?? "--"}</dd>
- <dt>Time</dt>
- <dd><Time
- timestamp={error.when}
- format="yyyy/MM/dd HH:mm:ss"
- /></dd>
- </dl>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
- {JSON.stringify(error, undefined, 2)}
- </pre>
-
- </Fragment>)
- }}>fail</a> : undefined
- }
- </td>
- <td> <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- /></td>
- <td> <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- /></td>
- </tr>
-
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
+ >
+ {title}
+ </a>
+ </td>
+ <td>
+ {notif.event.url}{" "}
+ {prev?.event.type ===
+ ObservabilityEventType.HttpFetchFinishSuccess ? (
+ `(${prev.event.status})`
+ ) : prev?.event.type ===
+ ObservabilityEventType.HttpFetchFinishError ? (
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ if (
+ prev.event.type !==
+ ObservabilityEventType.HttpFetchFinishError
+ )
+ return;
+ const error = prev.event.error;
+ onClick(
+ <Fragment>
+ <dl>
+ <dt>Code</dt>
+ <dd>
+ {TalerErrorCode[error.code]} ({error.code})
+ </dd>
+ <dt>Hint</dt>
+ <dd>{error.hint ?? "--"}</dd>
+ <dt>Time</dt>
+ <dd>
+ <Time
+ timestamp={error.when}
+ format="yyyy/MM/dd HH:mm:ss"
+ />
+ </dd>
+ </dl>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify(error, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
+ >
+ fail
+ </a>
+ ) : undefined}
+ </td>
+ <td>
+ {" "}
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ {" "}
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.DbQueryStart:
case ObservabilityEventType.DbQueryFinishSuccess:
case ObservabilityEventType.DbQueryFinishError: {
- return <tr>
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
>
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.location} {notif.event.name}
- </td>
- <td>
- <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- </tr>
+ {title}
+ </a>
+ </td>
+ <td>
+ {notif.event.location} {notif.event.name}
+ </td>
+ <td>
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.TaskStart:
case ObservabilityEventType.TaskStop:
case ObservabilityEventType.DeclareTaskDependency:
case ObservabilityEventType.TaskReset: {
- return <tr>
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
>
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.taskId}
- </td>
- <td>
- <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- </tr>
+ {title}
+ </a>
+ </td>
+ <td>{notif.event.taskId}</td>
+ <td>
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.ShepherdTaskResult: {
- return <tr>
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
>
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.resultType}
- </td>
- <td>
- <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- </tr>
-
+ {title}
+ </a>
+ </td>
+ <td>{notif.event.resultType}</td>
+ <td>
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.CryptoStart:
case ObservabilityEventType.CryptoFinishSuccess:
case ObservabilityEventType.CryptoFinishError: {
- return <tr>
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
>
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.operation}
- </td>
- <td>
- <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- </tr>
+ {title}
+ </a>
+ </td>
+ <td>{notif.event.operation}</td>
+ <td>
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.RequestStart:
case ObservabilityEventType.RequestFinishSuccess:
case ObservabilityEventType.RequestFinishError: {
- return <tr >
- <td><a href="#" onClick={(e) => {
- e.preventDefault();
- onClick(<Fragment>
- <pre
- style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
+ return (
+ <tr>
+ <td>
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ onClick(
+ <Fragment>
+ <pre
+ style={{
+ whiteSpace: "pre-wrap",
+ wordBreak: "break-word",
+ }}
+ >
+ {JSON.stringify({ event: notif, prev }, undefined, 2)}
+ </pre>
+ </Fragment>,
+ );
+ }}
>
- {JSON.stringify({ event: notif, prev }, undefined, 2)}
- </pre>
- </Fragment>);
- }}>{title}</a></td>
- <td>
- {notif.event.type}
- </td>
- <td>
- <Time
- timestamp={notif.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={prev?.when}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- </tr>
+ {title}
+ </a>
+ </td>
+ <td>{notif.event.type}</td>
+ <td>
+ <Time timestamp={notif.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ <Time timestamp={prev?.when} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ </tr>
+ );
}
case ObservabilityEventType.Message:
// FIXME
@@ -498,11 +673,16 @@ function ShowObervavilityDetails({ title, notif, onClick, prev }: { title: strin
}
}
-function getNotificationFor(id: string, event: WalletNotification, start: AbsoluteTime, list: Notif[]): Notif | undefined {
- const eventWithTime = { ...event, when: start }
+function getNotificationFor(
+ id: string,
+ event: WalletNotification,
+ start: AbsoluteTime,
+ list: Notif[],
+): Notif | undefined {
+ const eventWithTime = { ...event, when: start };
switch (event.type) {
case NotificationType.BalanceChange: {
- return ({
+ return {
id,
events: [eventWithTime],
reference: {
@@ -513,28 +693,32 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
description: "Balance change",
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowBalanceChange
- })
+ MoreInfo: ShowBalanceChange,
+ };
}
case NotificationType.BackupOperationError: {
- return ({
+ return {
id,
events: [eventWithTime],
reference: undefined,
description: "Backup error",
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowBackupOperationError
- })
+ MoreInfo: ShowBackupOperationError,
+ };
}
case NotificationType.TransactionStateTransition: {
- const found = list.find(a => a.reference?.eventType === event.type && a.reference.id === event.transactionId)
+ const found = list.find(
+ (a) =>
+ a.reference?.eventType === event.type &&
+ a.reference.id === event.transactionId,
+ );
if (found) {
found.end = start;
- found.events.unshift(eventWithTime)
- return undefined
+ found.events.unshift(eventWithTime);
+ return undefined;
}
- return ({
+ return {
id,
events: [eventWithTime],
reference: {
@@ -545,17 +729,21 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
description: event.type,
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowTransactionStateTransition
- })
+ MoreInfo: ShowTransactionStateTransition,
+ };
}
case NotificationType.ExchangeStateTransition: {
- const found = list.find(a => a.reference?.eventType === event.type && a.reference.id === event.exchangeBaseUrl)
+ const found = list.find(
+ (a) =>
+ a.reference?.eventType === event.type &&
+ a.reference.id === event.exchangeBaseUrl,
+ );
if (found) {
found.end = start;
- found.events.unshift(eventWithTime)
- return undefined
+ found.events.unshift(eventWithTime);
+ return undefined;
}
- return ({
+ return {
id,
events: [eventWithTime],
description: "Exchange update",
@@ -566,17 +754,21 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
},
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowExchangeStateTransition
- })
+ MoreInfo: ShowExchangeStateTransition,
+ };
}
case NotificationType.TaskObservabilityEvent: {
- const found = list.find(a => a.reference?.eventType === event.type && a.reference.id === event.taskId)
+ const found = list.find(
+ (a) =>
+ a.reference?.eventType === event.type &&
+ a.reference.id === event.taskId,
+ );
if (found) {
found.end = start;
- found.events.unshift(eventWithTime)
- return undefined
+ found.events.unshift(eventWithTime);
+ return undefined;
}
- return ({
+ return {
id,
events: [eventWithTime],
reference: {
@@ -587,17 +779,20 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
description: `Task update ${event.taskId}`,
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent
- })
+ MoreInfo: ShowObservabilityEvent,
+ };
}
case NotificationType.WithdrawalOperationTransition: {
- const found = list.find(a => a.reference?.eventType === event.type && a.reference.id === event.uri)
+ const found = list.find(
+ (a) =>
+ a.reference?.eventType === event.type && a.reference.id === event.uri,
+ );
if (found) {
found.end = start;
- found.events.unshift(eventWithTime)
- return undefined
+ found.events.unshift(eventWithTime);
+ return undefined;
}
- return ({
+ return {
id,
events: [eventWithTime],
reference: {
@@ -608,17 +803,21 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
description: `Withdrawal operation updated`,
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent
- })
+ MoreInfo: ShowObservabilityEvent,
+ };
}
case NotificationType.RequestObservabilityEvent: {
- const found = list.find(a => a.reference?.eventType === event.type && a.reference.id === event.requestId)
+ const found = list.find(
+ (a) =>
+ a.reference?.eventType === event.type &&
+ a.reference.id === event.requestId,
+ );
if (found) {
found.end = start;
- found.events.unshift(eventWithTime)
- return undefined
+ found.events.unshift(eventWithTime);
+ return undefined;
}
- return ({
+ return {
id,
events: [eventWithTime],
reference: {
@@ -629,145 +828,183 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu
description: `wallet.${event.operation}(${event.requestId})`,
start,
end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent
- })
+ MoreInfo: ShowObservabilityEvent,
+ };
}
+ case NotificationType.Idle:
+ return undefined;
default: {
- assertUnreachable(event)
+ assertUnreachable(event);
}
}
}
-
function refresh(api: WxApiType, onUpdate: (list: Notif[]) => void) {
- api.background.call("getNotifications", undefined).then(notif => {
-
- const list: Notif[] = []
- for (const n of notif) {
- if (n.notification.type === NotificationType.RequestObservabilityEvent &&
- n.notification.operation === "getActiveTasks") {
- //ignore monitor request
- continue;
- }
- const event = getNotificationFor(String(list.length), n.notification, n.when, list)
- // pepe.
- if (event) {
- list.unshift(event)
+ api.background
+ .call("getNotifications", undefined)
+ .then((notif) => {
+ const list: Notif[] = [];
+ for (const n of notif) {
+ if (
+ n.notification.type === NotificationType.RequestObservabilityEvent &&
+ n.notification.operation === "getActiveTasks"
+ ) {
+ //ignore monitor request
+ continue;
+ }
+ const event = getNotificationFor(
+ String(list.length),
+ n.notification,
+ n.when,
+ list,
+ );
+ // pepe.
+ if (event) {
+ list.unshift(event);
+ }
}
- }
- onUpdate(list);
- }).catch(error => {
- console.log(error)
- })
+ onUpdate(list);
+ })
+ .catch((error) => {
+ console.log(error);
+ });
}
-export function ObservabilityEventsTable({ }: {}): VNode {
- const { i18n } = useTranslationContext()
+export function ObservabilityEventsTable({}: {}): VNode {
+ const { i18n } = useTranslationContext();
const api = useBackendContext();
- const [notifications, setNotifications] = useState<Notif[]>([])
- const [showDetails, setShowDetails] = useState<VNode>()
+ const [notifications, setNotifications] = useState<Notif[]>([]);
+ const [showDetails, setShowDetails] = useState<VNode>();
useEffect(() => {
let lastTimeout: ReturnType<typeof setTimeout>;
function periodicRefresh() {
-
- refresh(api, setNotifications)
+ refresh(api, setNotifications);
lastTimeout = setTimeout(() => {
periodicRefresh();
- }, 1000)
+ }, 1000);
- //clear on unload
- return () => { clearTimeout(lastTimeout) }
+ //clear on unload
+ return () => {
+ clearTimeout(lastTimeout);
+ };
}
- return periodicRefresh()
+ return periodicRefresh();
}, [1]);
- return <div>
- <div style={{ display: "flex", justifyContent: "space-between" }}>
-
- <div style={{ padding: 4, margin: 2, border: "solid 1px black" }} onClick={() => {
- api.background.call("clearNotifications", undefined).then(d => {
- refresh(api, setNotifications)
- })
- }}>
- clear
+ return (
+ <div>
+ <div style={{ display: "flex", justifyContent: "space-between" }}>
+ <div
+ style={{ padding: 4, margin: 2, border: "solid 1px black" }}
+ onClick={() => {
+ api.background.call("clearNotifications", undefined).then((d) => {
+ refresh(api, setNotifications);
+ });
+ }}
+ >
+ clear
+ </div>
</div>
-
-
- </div>
- {showDetails && <Modal title="event details" onClose={{ onClick: (async () => { setShowDetails(undefined) }) as any }} >
- {showDetails}
- </Modal>}
- {notifications.map((not) => {
- return (
- <details key={not.id}>
- <summary>
- <div style={{ width: "90%", display: "inline-flex", justifyContent: "space-between", padding: 4 }}>
- <div style={{ padding: 4 }}>
- {not.description}
- </div>
- <div style={{ padding: 4 }}>
- <Time
- timestamp={not.start}
- format="yyyy/MM/dd HH:mm:ss"
- />
+ {showDetails && (
+ <Modal
+ title="event details"
+ onClose={{
+ onClick: (async () => {
+ setShowDetails(undefined);
+ }) as any,
+ }}
+ >
+ {showDetails}
+ </Modal>
+ )}
+ {notifications.map((not) => {
+ return (
+ <details key={not.id}>
+ <summary>
+ <div
+ style={{
+ width: "90%",
+ display: "inline-flex",
+ justifyContent: "space-between",
+ padding: 4,
+ }}
+ >
+ <div style={{ padding: 4 }}>{not.description}</div>
+ <div style={{ padding: 4 }}>
+ <Time timestamp={not.start} format="yyyy/MM/dd HH:mm:ss" />
+ </div>
+ <div style={{ padding: 4 }}>
+ <Time timestamp={not.end} format="yyyy/MM/dd HH:mm:ss" />
+ </div>
</div>
- <div style={{ padding: 4 }}><Time
- timestamp={not.end}
- format="yyyy/MM/dd HH:mm:ss"
- /></div>
- </div>
- </summary>
- <not.MoreInfo events={not.events} onClick={(details) => {
- setShowDetails(details)
- }} />
- </details>
- );
- })}
- </div >
+ </summary>
+ <not.MoreInfo
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ </details>
+ );
+ })}
+ </div>
+ );
}
-function ErroDetailModal({ error, onClose }: { error: TalerErrorDetail, onClose: () => void }): VNode {
- return <Modal title="Full detail" onClose={{
- onClick: onClose as any
- }}>
- <dl>
- <dt>Code</dt>
- <dd>{TalerErrorCode[error.code]} ({error.code})</dd>
- <dt>Hint</dt>
- <dd>{error.hint ?? "--"}</dd>
- <dt>Time</dt>
- <dd><Time
- timestamp={error.when}
- format="yyyy/MM/dd HH:mm:ss"
- /></dd>
- </dl>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
- {JSON.stringify(error, undefined, 2)}
- </pre>
- </Modal>
+function ErroDetailModal({
+ error,
+ onClose,
+}: {
+ error: TalerErrorDetail;
+ onClose: () => void;
+}): VNode {
+ return (
+ <Modal
+ title="Full detail"
+ onClose={{
+ onClick: onClose as any,
+ }}
+ >
+ <dl>
+ <dt>Code</dt>
+ <dd>
+ {TalerErrorCode[error.code]} ({error.code})
+ </dd>
+ <dt>Hint</dt>
+ <dd>{error.hint ?? "--"}</dd>
+ <dt>Time</dt>
+ <dd>
+ <Time timestamp={error.when} format="yyyy/MM/dd HH:mm:ss" />
+ </dd>
+ </dl>
+ <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
+ {JSON.stringify(error, undefined, 2)}
+ </pre>
+ </Modal>
+ );
}
-export function ActiveTasksTable({ }: {}): VNode {
- const { i18n } = useTranslationContext()
+export function ActiveTasksTable({}: {}): VNode {
+ const { i18n } = useTranslationContext();
const api = useBackendContext();
const state = useAsyncAsHook(() => {
return api.wallet.call(WalletApiOperation.GetActiveTasks, {});
});
- const [showError, setShowError] = useState<TalerErrorDetail>()
+ const [showError, setShowError] = useState<TalerErrorDetail>();
const tasks = state && !state.hasError ? state.response.tasks : [];
useEffect(() => {
- if (!state || state.hasError) return
+ if (!state || state.hasError) return;
const lastTimeout = setTimeout(() => {
state.retry();
- }, 1000)
+ }, 1000);
return () => {
- clearTimeout(lastTimeout)
- }
- }, [tasks])
+ clearTimeout(lastTimeout);
+ };
+ }, [tasks]);
// const listenAllEvents = Array.from<NotificationType>({ length: 1 });
// listenAllEvents.includes = () => true
@@ -776,59 +1013,88 @@ export function ActiveTasksTable({ }: {}): VNode {
// state?.retry()
// });
// });
- return <Fragment>
- {showError && <ErroDetailModal error={showError} onClose={(async () => { setShowError(undefined) })} />}
+ return (
+ <Fragment>
+ {showError && (
+ <ErroDetailModal
+ error={showError}
+ onClose={async () => {
+ setShowError(undefined);
+ }}
+ />
+ )}
- <table style={{ width: "100%" }}>
- <thead>
- <tr>
- <th>
- <i18n.Translate>Type</i18n.Translate>
- </th>
- <th>
- <i18n.Translate>Id</i18n.Translate>
- </th>
- <th>
- <i18n.Translate>Since</i18n.Translate>
- </th>
- <th>
- <i18n.Translate>Next try</i18n.Translate>
- </th>
- <th>
- <i18n.Translate>Error</i18n.Translate>
- </th>
- <th>
- <i18n.Translate>Transaction</i18n.Translate>
- </th>
- </tr>
- </thead>
- <tbody>
- {tasks.map((task) => {
- const [type, id] = task.id.split(":")
- return (
- <tr>
- <td>{type}</td>
- <td title={id}>{id.substring(0, 10)}</td>
- <td>
- <Time
- timestamp={task.firstTry}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>
- <Time
- timestamp={task.nextTry}
- format="yyyy/MM/dd HH:mm:ss"
- />
- </td>
- <td>{!task.lastError?.code ? "" : <a href="#" onClick={(e) => { e.preventDefault(); setShowError(task.lastError) }}>{TalerErrorCode[task.lastError.code]}</a>}</td>
- <td>
- {task.transaction ? <a title={task.transaction} href={Pages.balanceTransaction({ tid: task.transaction })}>{task.transaction.substring(0, 10)}</a> : "--"}
- </td>
- </tr>
- );
- })}
- </tbody>
- </table>
- </Fragment>
-} \ No newline at end of file
+ <table style={{ width: "100%" }}>
+ <thead>
+ <tr>
+ <th>
+ <i18n.Translate>Type</i18n.Translate>
+ </th>
+ <th>
+ <i18n.Translate>Id</i18n.Translate>
+ </th>
+ <th>
+ <i18n.Translate>Since</i18n.Translate>
+ </th>
+ <th>
+ <i18n.Translate>Next try</i18n.Translate>
+ </th>
+ <th>
+ <i18n.Translate>Error</i18n.Translate>
+ </th>
+ <th>
+ <i18n.Translate>Transaction</i18n.Translate>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {tasks.map((task) => {
+ const [type, id] = task.taskId.split(":");
+ return (
+ <tr>
+ <td>{type}</td>
+ <td title={id}>{id.substring(0, 10)}</td>
+ <td>
+ <Time
+ timestamp={task.firstTry}
+ format="yyyy/MM/dd HH:mm:ss"
+ />
+ </td>
+ <td>
+ <Time timestamp={task.nextTry} format="yyyy/MM/dd HH:mm:ss" />
+ </td>
+ <td>
+ {!task.lastError?.code ? (
+ ""
+ ) : (
+ <a
+ href="#"
+ onClick={(e) => {
+ e.preventDefault();
+ setShowError(task.lastError);
+ }}
+ >
+ {TalerErrorCode[task.lastError.code]}
+ </a>
+ )}
+ </td>
+ <td>
+ {task.transaction ? (
+ <a
+ title={task.transaction}
+ href={Pages.balanceTransaction({ tid: task.transaction })}
+ >
+ {task.transaction.substring(0, 10)}
+ </a>
+ ) : (
+ "--"
+ )}
+ </td>
+ </tr>
+ );
+ })}
+ </tbody>
+ </table>
+ </Fragment>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index 315ab5332..bf70f68df 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -341,11 +341,6 @@ async function reinitWallet(): Promise<void> {
});
});
- platform.keepAlive(() => {
- return wallet.runTaskLoop().catch((e) => {
- logger.error("error during wallet task loop", e);
- });
- });
// Useful for debugging in the background page.
if (typeof window !== "undefined") {
(window as any).talerWallet = wallet;