pending transaction, finally!

This commit is contained in:
Sebastian 2022-03-11 11:14:27 -03:00
parent 9337734a24
commit ab68ecc733
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
11 changed files with 236 additions and 33 deletions

View File

@ -128,7 +128,7 @@ export const decorators = [
<Story />
</div>
}
if (kind.startsWith('mui')) {
if (kind.startsWith('mui') || kind.startsWith('component')) {
return <div style={{ display: 'flex', flexWrap: 'wrap' }}>
<Story />
</div>

View File

@ -0,0 +1,30 @@
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Sebastian Javier Marchano (sebasjm)
*/
/*
* Linaria need pre-process typscript files into javascript before running.
* We choose to use the default preact-cli config.
* This file should be used from @linaria/rollup plugin only
*/
{
"presets": [
"preact-cli/babel",
]
}

View File

@ -71,6 +71,10 @@ const makePlugins = () => [
image(),
linaria({
babelOptions: {
babelrc: false,
configFile: './babel.config-linaria.json',
},
sourceMap: process.env.NODE_ENV !== 'production',
}),

View File

@ -91,7 +91,7 @@ export const PendingOperation = () => (
<Wrapper>
<Banner
title="PENDING TRANSACTIONS"
style={{ backgroundColor: "lightblue", padding: 8 }}
style={{ backgroundColor: "lightcyan", padding: 8 }}
elements={[
{
icon: (

View File

@ -29,16 +29,24 @@ export function Banner({ title, elements, confirm, ...rest }: Props) {
</Grid>
</Grid>
)}
<Grid container wrap="nowrap" spacing={1} alignItems="center">
<Grid container columns={1}>
{elements.map((e, i) => (
<Fragment key={i}>
<Grid
container
item
xs={1}
key={i}
wrap="nowrap"
spacing={1}
alignItems="center"
>
{e.icon && (
<Grid item>
<Grid item xs={"auto"}>
<Avatar>{e.icon}</Avatar>
</Grid>
)}
<Grid item>{e.description}</Grid>
</Fragment>
</Grid>
))}
</Grid>
{confirm && (

View File

@ -0,0 +1,143 @@
/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
*
* @author Sebastian Javier Marchano (sebasjm)
*/
import { PendingTransactionsView as TestedComponent } from "./PendingTransactions";
import { Fragment, h, VNode } from "preact";
import { createExample } from "../test-utils";
import { Transaction, TransactionType } from "@gnu-taler/taler-util";
export default {
title: "component/PendingTransactions",
component: TestedComponent,
};
export const OnePendingTransaction = createExample(TestedComponent, {
transactions: [
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
],
});
export const ThreePendingTransactions = createExample(TestedComponent, {
transactions: [
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
],
});
export const TenPendingTransactions = createExample(TestedComponent, {
transactions: [
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
{
amountEffective: "USD:10",
type: TransactionType.Withdrawal,
timestamp: {
t_ms: 1,
},
} as Transaction,
],
});

View File

@ -1,20 +1,42 @@
import { Amounts, Transaction } from "@gnu-taler/taler-util";
import { Amounts, NotificationType, Transaction } from "@gnu-taler/taler-util";
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { Fragment, h, JSX } from "preact";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
import { Avatar } from "../mui/Avatar";
import { Typography } from "../mui/Typography";
import Banner from "./Banner";
import { Time } from "./Time";
import * as wxApi from "../wxApi";
interface Props {
transactions: Transaction[];
interface Props extends JSX.HTMLAttributes {}
export function PendingTransactions({}: Props) {
const state = useAsyncAsHook(wxApi.getTransactions, [
NotificationType.WithdrawGroupFinished,
]);
const transactions =
!state || state.hasError ? [] : state.response.transactions;
if (!state || state.hasError) {
return <Fragment />;
}
return <PendingTransactionsView transactions={transactions} />;
}
export function PendingTransactions({ transactions }: Props) {
export function PendingTransactionsView({
transactions,
}: {
transactions: Transaction[];
}) {
return (
<Banner
title="PENDING OPERATIONS"
style={{ backgroundColor: "lightblue", padding: 8 }}
style={{
backgroundColor: "lightcyan",
maxHeight: 150,
padding: 8,
overflowY: transactions.length > 3 ? "scroll" : "hidden",
}}
elements={transactions.map((t) => {
const amount = Amounts.parseOrThrow(t.amountEffective);
return {

View File

@ -15,7 +15,7 @@ interface Props {
startIcon?: VNode;
variant?: "contained" | "outlined" | "text";
color?: "primary" | "secondary" | "success" | "error" | "info" | "warning";
onClick: () => void;
onClick?: () => void;
}
const baseStyle = css`

View File

@ -28,7 +28,6 @@ import { JustInDevMode } from "../components/JustInDevMode";
import { Loading } from "../components/Loading";
import { LoadingError } from "../components/LoadingError";
import { MultiActionButton } from "../components/MultiActionButton";
import PendingTransactions from "../components/PendingTransactions";
import { ButtonBoxPrimary, ButtonPrimary } from "../components/styled";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
import { AddNewActionView } from "../wallet/AddNewActionView";
@ -46,19 +45,10 @@ export function BalancePage({
goToWalletHistory,
}: Props): VNode {
const [addingAction, setAddingAction] = useState(false);
const state = useAsyncAsHook(
async () => ({
balance: await wxApi.getBalance(),
pending: await wxApi.getTransactions(),
}),
[NotificationType.WithdrawGroupFinished],
);
const balances =
!state || state.hasError ? [] : state.response.balance.balances;
const pending =
!state || state.hasError
? []
: state.response.pending.transactions.filter((t) => t.pending);
const state = useAsyncAsHook(wxApi.getBalance, [
NotificationType.WithdrawGroupFinished,
]);
const balances = !state || state.hasError ? [] : state.response.balances;
if (!state) {
return <Loading />;
@ -80,7 +70,6 @@ export function BalancePage({
return (
<BalanceView
balances={balances}
pending={pending}
goToWalletManualWithdraw={goToWalletManualWithdraw}
goToWalletDeposit={goToWalletDeposit}
goToWalletHistory={goToWalletHistory}
@ -90,7 +79,6 @@ export function BalancePage({
}
export interface BalanceViewProps {
balances: Balance[];
pending: Transaction[];
goToWalletManualWithdraw: () => void;
goToAddAction: () => void;
goToWalletDeposit: (currency: string) => void;
@ -99,7 +87,6 @@ export interface BalanceViewProps {
export function BalanceView({
balances,
pending,
goToWalletManualWithdraw,
goToWalletDeposit,
goToWalletHistory,
@ -117,9 +104,6 @@ export function BalanceView({
return (
<Fragment>
{/* {pending.length > 0 ? (
<PendingTransactions transactions={pending} />
) : undefined} */}
<section>
<BalanceTable
balances={balances}

View File

@ -26,6 +26,7 @@ import { Fragment, h, render, VNode } from "preact";
import Router, { route, Route } from "preact-router";
import { Match } from "preact-router/match";
import { useEffect } from "preact/hooks";
import PendingTransactions from "./components/PendingTransactions";
import { PopupBox } from "./components/styled";
import { DevContextProvider } from "./context/devContext";
import { IoCProviderForRuntime } from "./context/iocContext";
@ -82,6 +83,7 @@ function Application(): VNode {
<DevContextProvider>
{({ devMode }: { devMode: boolean }) => (
<IoCProviderForRuntime>
<PendingTransactions />
<Match>
{({ path }: { path: string }) => <PopupNavBar path={path} />}
</Match>

View File

@ -27,6 +27,7 @@ import Router, { route, Route } from "preact-router";
import Match from "preact-router/match";
import { useEffect, useState } from "preact/hooks";
import { LogoHeader } from "./components/LogoHeader";
import PendingTransactions from "./components/PendingTransactions";
import {
NavigationHeader,
NavigationHeaderHolder,
@ -112,6 +113,15 @@ function Application(): VNode {
);
}}
</Match>
<div
style={{
backgroundColor: "lightcyan",
display: "flex",
justifyContent: "center",
}}
>
<PendingTransactions />
</div>
<WalletBox>
{globalNotification && (
<SuccessBox onClick={clearNotification}>