diff options
-rw-r--r-- | packages/bank-ui/src/hooks/regional.ts | 11 | ||||
-rw-r--r-- | packages/bank-ui/src/pages/admin/AdminHome.tsx | 109 | ||||
-rw-r--r-- | packages/bank-ui/src/pages/admin/DownloadStats.tsx | 4 | ||||
-rw-r--r-- | packages/taler-util/src/http-client/bank-core.ts | 10 |
4 files changed, 95 insertions, 39 deletions
diff --git a/packages/bank-ui/src/hooks/regional.ts b/packages/bank-ui/src/hooks/regional.ts index 3e832a944..e9aa9a6be 100644 --- a/packages/bank-ui/src/hooks/regional.ts +++ b/packages/bank-ui/src/hooks/regional.ts @@ -18,6 +18,7 @@ import { PAGE_SIZE } from "../utils.js"; import { useSessionState } from "./session.js"; import { + AbsoluteTime, AccessToken, AmountJson, Amounts, @@ -31,9 +32,9 @@ import { TalerHttpError, opFixedSuccess, } from "@gnu-taler/taler-util"; +import { useBankCoreApiContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; import _useSWR, { SWRHook, mutate } from "swr"; -import { useBankCoreApiContext } from "@gnu-taler/web-util/browser"; import { buildPaginatedResult } from "./account.js"; // FIX default import https://github.com/microsoft/TypeScript/issues/49189 @@ -438,8 +439,8 @@ export function revalidateLastMonitorInfo() { ); } export function useLastMonitorInfo( - currentMoment: number, - previousMoment: number, + currentMoment: AbsoluteTime, + previousMoment: AbsoluteTime, timeframe: TalerCorebankApi.MonitorTimeframeParam, ) { const { lib: { bank: api } } = useBankCoreApiContext(); @@ -452,8 +453,8 @@ export function useLastMonitorInfo( TalerCorebankApi.MonitorTimeframeParam, ]) { const [current, previous] = await Promise.all([ - api.getMonitor(token, { timeframe, which: currentMoment }), - api.getMonitor(token, { timeframe, which: previousMoment }), + api.getMonitor(token, { timeframe, date: currentMoment }), + api.getMonitor(token, { timeframe, date: previousMoment }), ]); return { current, diff --git a/packages/bank-ui/src/pages/admin/AdminHome.tsx b/packages/bank-ui/src/pages/admin/AdminHome.tsx index 4784fc73a..636563243 100644 --- a/packages/bank-ui/src/pages/admin/AdminHome.tsx +++ b/packages/bank-ui/src/pages/admin/AdminHome.tsx @@ -14,6 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { + AbsoluteTime, AmountString, Amounts, CurrencySpecification, @@ -22,10 +23,14 @@ import { TalerError, assertUnreachable, } from "@gnu-taler/taler-util"; -import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { + Attention, + RouteDefinition, + useBankCoreApiContext, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; import { format, - getDate, getDaysInMonth, getHours, getMonth, @@ -40,9 +45,7 @@ import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js"; import { Transactions } from "../../components/Transactions/index.js"; -import { useBankCoreApiContext } from "@gnu-taler/web-util/browser"; import { useConversionInfo, useLastMonitorInfo } from "../../hooks/regional.js"; -import { RouteDefinition } from "@gnu-taler/web-util/browser"; import { RenderAmount } from "../PaytoWireTransferForm.js"; import { WireTransfer } from "../WireTransfer.js"; import { AccountList } from "./AccountList.js"; @@ -96,22 +99,22 @@ export function AdminHome({ } function getDateForTimeframe( - which: number, + date: AbsoluteTime, timeframe: TalerCorebankApi.MonitorTimeframeParam, locale: Locale, ): string { - const time = Date.now(); + if (date.t_ms === "never") return "--"; switch (timeframe) { case TalerCorebankApi.MonitorTimeframeParam.hour: - return `${format(setHours(time, which), "HH", { locale })}hs`; + return `${format(date.t_ms, "HH", { locale })}hs`; case TalerCorebankApi.MonitorTimeframeParam.day: - return format(setDate(time, which), "EEEE", { locale }); + return format(date.t_ms, "EEEE", { locale }); case TalerCorebankApi.MonitorTimeframeParam.month: - return format(setMonth(time, which), "MMMM", { locale }); + return format(date.t_ms, "MMMM", { locale }); case TalerCorebankApi.MonitorTimeframeParam.year: - return format(setYear(time, which), "yyyy", { locale }); + return format(date.t_ms, "yyyy", { locale }); case TalerCorebankApi.MonitorTimeframeParam.decade: - return format(setYear(time, which), "yyyy", { locale }); + return format(date.t_ms, "yyyy", { locale }); } assertUnreachable(timeframe); } @@ -119,32 +122,32 @@ function getDateForTimeframe( export function getTimeframesForDate( time: Date, timeframe: TalerCorebankApi.MonitorTimeframeParam, -): { current: number; previous: number } { +): { current: AbsoluteTime; previous: AbsoluteTime } { switch (timeframe) { case TalerCorebankApi.MonitorTimeframeParam.hour: return { - current: getHours(sub(time, { hours: 1 })), - previous: getHours(sub(time, { hours: 2 })), + current: AbsoluteTime.fromMilliseconds(sub(time, { hours: 1 }).getTime()), + previous: AbsoluteTime.fromMilliseconds(sub(time, { hours: 2 }).getTime()), }; case TalerCorebankApi.MonitorTimeframeParam.day: return { - current: getDaysInMonth(sub(time, { days: 1 })), - previous: getDaysInMonth(sub(time, { days: 2 })), + current: AbsoluteTime.fromMilliseconds(sub(time, { days: 1 }).getTime()), + previous: AbsoluteTime.fromMilliseconds(sub(time, { days: 4 }).getTime()), }; case TalerCorebankApi.MonitorTimeframeParam.month: return { - current: getMonth(sub(time, { months: 1 })), - previous: getMonth(sub(time, { months: 2 })), + current: AbsoluteTime.fromMilliseconds(sub(time, { months: 1 }).getTime()), + previous: AbsoluteTime.fromMilliseconds(sub(time, { months: 2 }).getTime()), }; case TalerCorebankApi.MonitorTimeframeParam.year: return { - current: getYear(sub(time, { years: 1 })), - previous: getYear(sub(time, { years: 2 })), + current: AbsoluteTime.fromMilliseconds(sub(time, { years: 1 }).getTime()), + previous: AbsoluteTime.fromMilliseconds(sub(time, { years: 2 }).getTime()), }; case TalerCorebankApi.MonitorTimeframeParam.decade: return { - current: getYear(sub(time, { years: 10 })), - previous: getYear(sub(time, { years: 20 })), + current: AbsoluteTime.fromMilliseconds(sub(time, { years: 10 }).getTime()), + previous: AbsoluteTime.fromMilliseconds(sub(time, { years: 20 }).getTime()), }; default: assertUnreachable(timeframe); @@ -186,13 +189,61 @@ function Metrics({ </Attention> ); } - default: + default: { assertUnreachable(respInfo.case); + } } } - if (resp.current.type !== "ok" || resp.previous.type !== "ok") { - return <Fragment />; + if (resp.current.type !== "ok") { + switch (resp.current.case) { + case HttpStatusCode.BadRequest: + return ( + <Attention + type="warning" + title={i18n.str`Querying for the current stats failed`} + > + <i18n.Translate>The request parameters are wrong</i18n.Translate> + </Attention> + ); + case HttpStatusCode.Unauthorized: + return ( + <Attention + type="warning" + title={i18n.str`Querying for the current stats failed`} + > + <i18n.Translate>The user is unauthorized</i18n.Translate> + </Attention> + ); + default: { + assertUnreachable(resp.current); + } + } + } + if (resp.previous.type !== "ok") { + switch (resp.previous.case) { + case HttpStatusCode.BadRequest: + return ( + <Attention + type="warning" + title={i18n.str`Querying for the previous stats failed`} + > + <i18n.Translate>The request parameters are wrong</i18n.Translate> + </Attention> + ); + case HttpStatusCode.Unauthorized: + return ( + <Attention + type="warning" + title={i18n.str`Querying for the previous stats failed`} + > + <i18n.Translate>The user is unauthorized</i18n.Translate> + </Attention> + ); + default: { + assertUnreachable(resp.previous); + } + } } return ( <div class="px-4 mt-4"> @@ -364,7 +415,7 @@ function Metrics({ </div> <dl class="mt-5 grid grid-cols-1 md:grid-cols-2 divide-y divide-gray-200 overflow-hidden rounded-lg bg-white shadow-lg md:divide-x md:divide-y-0"> {resp.current.body.type !== "with-conversions" || - resp.previous.body.type !== "with-conversions" ? undefined : ( + resp.previous.body.type !== "with-conversions" ? undefined : ( <Fragment> <div class="px-4 py-5 sm:p-6"> <dt class="text-base font-normal text-gray-900"> @@ -463,9 +514,9 @@ function MetricValue({ const rate = !currAmount || - Number.isNaN(currAmount) || - !prevAmount || - Number.isNaN(prevAmount) + Number.isNaN(currAmount) || + !prevAmount || + Number.isNaN(prevAmount) ? 0 : cmp === -1 ? 1 - Math.round(currAmount) / Math.round(prevAmount) diff --git a/packages/bank-ui/src/pages/admin/DownloadStats.tsx b/packages/bank-ui/src/pages/admin/DownloadStats.tsx index b9ae401e7..49798c2c6 100644 --- a/packages/bank-ui/src/pages/admin/DownloadStats.tsx +++ b/packages/bank-ui/src/pages/admin/DownloadStats.tsx @@ -461,7 +461,7 @@ async function fetchAllStatus( const previous = options.compareWithPrevious ? await api.getMonitor(token, { timeframe: frame.timeframe, - which: frame.moment.previous, + date: frame.moment.previous, }) : undefined; @@ -471,7 +471,7 @@ async function fetchAllStatus( const current = await api.getMonitor(token, { timeframe: frame.timeframe, - which: frame.moment.current, + date: frame.moment.current, }); if (current.type === "fail" && options.endOnFirstFail) { diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts index 3ef58b2f4..b89ac8af6 100644 --- a/packages/taler-util/src/http-client/bank-core.ts +++ b/packages/taler-util/src/http-client/bank-core.ts @@ -15,6 +15,7 @@ */ import { + AbsoluteTime, HttpStatusCode, LibtoolVersion, LongPollParams, @@ -924,7 +925,7 @@ export class TalerCoreBankHttpClient { auth: AccessToken, params: { timeframe?: TalerCorebankApi.MonitorTimeframeParam; - which?: number; + date?: AbsoluteTime; } = {}, ) { const url = new URL(`monitor`, this.baseUrl); @@ -934,8 +935,11 @@ export class TalerCoreBankHttpClient { TalerCorebankApi.MonitorTimeframeParam[params.timeframe], ); } - if (params.which) { - url.searchParams.set("which", String(params.which)); + if (params.date) { + const {t_s: seconds} = AbsoluteTime.toProtocolTimestamp(params.date) + if (seconds !== "never") { + url.searchParams.set("date_s", String(seconds)); + } } const resp = await this.httpLib.fetch(url.href, { method: "GET", |