first backup list prototype
This commit is contained in:
parent
05e89a3cf7
commit
23dab91ee9
@ -0,0 +1,88 @@
|
|||||||
|
import { Amounts } from "@gnu-taler/taler-util";
|
||||||
|
// import { ProviderInfo } from "@gnu-taler/taler-wallet-core/src/operations/backup/index.js";
|
||||||
|
|
||||||
|
|
||||||
|
export interface ProvidersByCurrency {
|
||||||
|
[s:string] : any | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = {
|
||||||
|
"trustedAuditors": [],
|
||||||
|
"trustedExchanges": [
|
||||||
|
{
|
||||||
|
"currency": "ARS",
|
||||||
|
"exchangeBaseUrl": "http://exchange.taler:8081/",
|
||||||
|
"exchangeMasterPub": "WHA6G542TW8B10N3E857M3P252HV7B896TSP1HP6NREG96ADA4MG"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"currency": "KUDOS",
|
||||||
|
"exchangeBaseUrl": "https://exchange.demo.taler.net/",
|
||||||
|
"exchangeMasterPub": "FH1Y8ZMHCTPQ0YFSZECDH8C9407JR3YN0MF1706PTG24Q4NEWGV0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"currency": "USD",
|
||||||
|
"exchangeBaseUrl": "https://exchange.demo.taler.net/",
|
||||||
|
"exchangeMasterPub": "FH1Y8ZMHCTPQ0YFSZECDH8C9407JR3YN0MF1706PTG24Q4NEWGV0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"currency": "EUR",
|
||||||
|
"exchangeBaseUrl": "https://exchange.demo.taler.net/",
|
||||||
|
"exchangeMasterPub": "FH1Y8ZMHCTPQ0YFSZECDH8C9407JR3YN0MF1706PTG24Q4NEWGV0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = {
|
||||||
|
"deviceId": "thenameofthisdevice",
|
||||||
|
"walletRootPub": "83DYRKK262TG72H1SD09CTWXQFC151P2DXF9WYH30J8EQ7EAZMCG",
|
||||||
|
"providers": [
|
||||||
|
{
|
||||||
|
"active": false,
|
||||||
|
"syncProviderBaseUrl": "http://sync.demo.taler.net/",
|
||||||
|
"paymentProposalIds": [],
|
||||||
|
"paymentStatus": {
|
||||||
|
"type": "unpaid"
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"annualFee": "KUDOS:0.1",
|
||||||
|
"storageLimitInMegabytes": 16,
|
||||||
|
"supportedProtocolVersion": "0.0"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"active": true,
|
||||||
|
"syncProviderBaseUrl": "http://sync.taler:9967/",
|
||||||
|
"lastSuccessfulBackupTimestamp": {
|
||||||
|
"t_ms": 1625063925078
|
||||||
|
},
|
||||||
|
"paymentProposalIds": [
|
||||||
|
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
|
||||||
|
],
|
||||||
|
"paymentStatus": {
|
||||||
|
"type": "paid",
|
||||||
|
"paidUntil": {
|
||||||
|
"t_ms": 1656599921000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"annualFee": "ARS:1",
|
||||||
|
"storageLimitInMegabytes": 16,
|
||||||
|
"supportedProtocolVersion": "0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useProvidersByCurrency(): ProvidersByCurrency {
|
||||||
|
const currencies = list.trustedExchanges.map(e => e.currency)
|
||||||
|
const providerByCurrency = status.providers.reduce((p, c) => {
|
||||||
|
if (c.terms) {
|
||||||
|
p[Amounts.parseOrThrow(c.terms.annualFee).currency] = c
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}, {} as Record<string, any | undefined>)
|
||||||
|
|
||||||
|
|
||||||
|
return providerByCurrency
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
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 { FunctionalComponent } from 'preact';
|
||||||
|
import { BackupView as TestedComponent } from './BackupPage';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'popup/backup/list',
|
||||||
|
component: TestedComponent,
|
||||||
|
argTypes: {
|
||||||
|
onRetry: { action: 'onRetry' },
|
||||||
|
onDelete: { action: 'onDelete' },
|
||||||
|
onBack: { action: 'onBack' },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) {
|
||||||
|
const r = (args: any) => <Component {...args} />
|
||||||
|
r.args = props
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Example = createExample(TestedComponent, {
|
||||||
|
deviceName: "somedevicename",
|
||||||
|
providers: {
|
||||||
|
ARS: {
|
||||||
|
"active": true,
|
||||||
|
"syncProviderBaseUrl": "http://sync.taler:9967/",
|
||||||
|
"lastSuccessfulBackupTimestamp": {
|
||||||
|
"t_ms": 1625063925078
|
||||||
|
},
|
||||||
|
"paymentProposalIds": [
|
||||||
|
"43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG"
|
||||||
|
],
|
||||||
|
"paymentStatus": {
|
||||||
|
"type": 'paid',
|
||||||
|
"paidUntil": {
|
||||||
|
"t_ms": 1656599921000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"annualFee": "ARS:1",
|
||||||
|
"storageLimitInMegabytes": 16,
|
||||||
|
"supportedProtocolVersion": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KUDOS: {
|
||||||
|
"active": false,
|
||||||
|
"syncProviderBaseUrl": "http://sync.demo.taler.net/",
|
||||||
|
"paymentProposalIds": [],
|
||||||
|
"paymentStatus": {
|
||||||
|
"type": 'unpaid',
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"annualFee": "KUDOS:0.1",
|
||||||
|
"storageLimitInMegabytes": 16,
|
||||||
|
"supportedProtocolVersion": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
USD: undefined,
|
||||||
|
EUR: undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -15,21 +15,126 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { VNode } from "preact";
|
import { Timestamp } from "@gnu-taler/taler-util";
|
||||||
import { useDevContext } from "../context/useDevContext";
|
// import { ProviderPaymentStatus } from "@gnu-taler/taler-wallet-core/src/operations/backup";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { formatDuration, intervalToDuration } from "date-fns";
|
||||||
|
import { JSX, VNode } from "preact";
|
||||||
|
import { ProvidersByCurrency, useProvidersByCurrency } from "../hooks/useProvidersByCurrency";
|
||||||
|
|
||||||
export function BackupPage(): VNode {
|
export function BackupPage(): VNode {
|
||||||
return <BackupView />;
|
const providers = useProvidersByCurrency()
|
||||||
|
return <BackupView deviceName={"thisdevicename"} providers={providers}/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
|
deviceName: string;
|
||||||
|
providers: ProvidersByCurrency
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BackupView({}: ViewProps): VNode {
|
export function BackupView({ deviceName, providers }: ViewProps): VNode {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div style={{ height: 'calc(320px - 34px - 16px)', overflow: 'auto' }}>
|
||||||
Backup page
|
<div style={{ display: 'flex', flexDirection: 'row', width: '100%', justifyContent: 'space-between' }}>
|
||||||
|
<h2 style={{ width: 240, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', marginTop: 10, marginBottom:10 }}>
|
||||||
|
{deviceName}
|
||||||
|
</h2>
|
||||||
|
<div style={{ flexDirection: 'row', marginTop: 'auto', marginBottom: 'auto' }}>
|
||||||
|
<button class="pure-button button-secondary">rename</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{Object.keys(providers).map((currency) => {
|
||||||
|
const provider = providers[currency]
|
||||||
|
if (!provider) {
|
||||||
|
return <BackupLayout
|
||||||
|
id={currency}
|
||||||
|
title={currency}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
return <BackupLayout
|
||||||
|
status={provider.paymentStatus}
|
||||||
|
timestamp={provider.lastSuccessfulBackupTimestamp}
|
||||||
|
id={currency}
|
||||||
|
active={provider.active}
|
||||||
|
subtitle={provider.syncProviderBaseUrl}
|
||||||
|
title={currency}
|
||||||
|
/>
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TransactionLayoutProps {
|
||||||
|
status?: any;
|
||||||
|
timestamp?: Timestamp;
|
||||||
|
title: string;
|
||||||
|
id: string;
|
||||||
|
subtitle?: string;
|
||||||
|
active?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function BackupLayout(props: TransactionLayoutProps): JSX.Element {
|
||||||
|
const date = !props.timestamp ? undefined : new Date(props.timestamp.t_ms);
|
||||||
|
const dateStr = date?.toLocaleString([], {
|
||||||
|
dateStyle: "medium",
|
||||||
|
timeStyle: "short",
|
||||||
|
} as any);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
border: "1px solid gray",
|
||||||
|
borderRadius: "0.5em",
|
||||||
|
margin: "0.5em 0",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
padding: "0.5em",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ display: "flex", flexDirection: "column", color: !props.active ? "gray" : undefined }}
|
||||||
|
>
|
||||||
|
{dateStr && <div style={{ fontSize: "small", color: "gray" }}>{dateStr}</div>}
|
||||||
|
{!dateStr && <div style={{ fontSize: "small", color: "red" }}>never synced</div>}
|
||||||
|
<div style={{ fontVariant: "small-caps", fontSize: "x-large" }}>
|
||||||
|
<a href=""><span>{props.title}</span></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>{props.subtitle}</div>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
marginLeft: "auto",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
alignSelf: "center"
|
||||||
|
}}>
|
||||||
|
<div style={{}}>
|
||||||
|
{!props.status ? "missing" : (
|
||||||
|
props.status?.type === 'paid' ? daysUntil(props.status.paidUntil) : 'unpaid'
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function daysUntil(d: Timestamp) {
|
||||||
|
if (d.t_ms === 'never') return undefined
|
||||||
|
const duration = intervalToDuration({
|
||||||
|
start: d.t_ms,
|
||||||
|
end: new Date(),
|
||||||
|
})
|
||||||
|
const str = formatDuration(duration, {
|
||||||
|
delimiter: ', ',
|
||||||
|
format: [
|
||||||
|
duration?.years ? 'years' : (
|
||||||
|
duration?.months ? 'months' : (
|
||||||
|
duration?.days ? 'days' : (
|
||||||
|
duration.hours ? 'hours' : 'minutes'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
})
|
||||||
|
return `${str} left`
|
||||||
}
|
}
|
@ -24,9 +24,7 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
import { i18n } from "@gnu-taler/taler-util";
|
||||||
classifyTalerUri, i18n, TalerUriType
|
|
||||||
} from "@gnu-taler/taler-util";
|
|
||||||
import { ComponentChildren, JSX } from "preact";
|
import { ComponentChildren, JSX } from "preact";
|
||||||
import Match from "preact-router/match";
|
import Match from "preact-router/match";
|
||||||
import { useDevContext } from "../context/useDevContext";
|
import { useDevContext } from "../context/useDevContext";
|
||||||
|
@ -126,12 +126,18 @@ export function getBalance(): Promise<BalancesResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get balances for all currencies/exchanges.
|
* Retrieve the full event history for this wallet.
|
||||||
*/
|
*/
|
||||||
export function getTransactions(): Promise<TransactionsResponse> {
|
export function getTransactions(): Promise<TransactionsResponse> {
|
||||||
return callBackend("getTransactions", {});
|
return callBackend("getTransactions", {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get currency from known auditors and exchanges
|
||||||
|
*/
|
||||||
|
export function listCurrencies(): Promise<TransactionsResponse> {
|
||||||
|
return callBackend("listCurrencies", {});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Retry a transaction
|
* Retry a transaction
|
||||||
* @param transactionId
|
* @param transactionId
|
||||||
|
Loading…
Reference in New Issue
Block a user