[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] branch master updated: more i18n
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] branch master updated: more i18n |
Date: |
Thu, 11 Feb 2021 22:11:51 +0100 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
The following commit(s) were added to refs/heads/master by this push:
new 8a0fbe7 more i18n
8a0fbe7 is described below
commit 8a0fbe79ef3c16cd256c4ebc35f4e8b0bc38dba3
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Feb 11 18:11:39 2021 -0300
more i18n
---
README.md | 2 +
.../modal/index.tsx} | 7 +-
src/components/yup/YupInput.tsx | 32 +++++++
src/i18n/index.ts | 101 +++++++++++++++++++++
src/routes/instances/CardTable.tsx | 3 +-
src/routes/instances/CreateModal.stories.tsx | 16 ++++
src/routes/instances/CreateModal.tsx | 27 +-----
src/routes/instances/DeleteModal.tsx | 4 +-
src/routes/instances/EmptyTable.tsx | 3 +-
src/routes/instances/Table.tsx | 9 +-
src/routes/instances/UpdateModal.stories.tsx | 6 +-
src/routes/instances/UpdateModal.tsx | 22 ++---
src/routes/instances/View.stories.tsx | 34 +++++--
src/routes/instances/View.tsx | 7 +-
14 files changed, 214 insertions(+), 59 deletions(-)
diff --git a/README.md b/README.md
index c756821..24987d7 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,8 @@ Use the browser to navigate into `http://localhost:8080`
* preact-router: URL component router for Preact
+* preact-i18n: Simple localization for Preact
+
* SWR: React Hooks library for data fetching. (stale-while-revalidate)
* Yup: schema builder for value parsing and validation
diff --git a/src/routes/instances/ConfirmModal.tsx
b/src/components/modal/index.tsx
similarity index 76%
rename from src/routes/instances/ConfirmModal.tsx
rename to src/components/modal/index.tsx
index a074a60..b95eea7 100644
--- a/src/routes/instances/ConfirmModal.tsx
+++ b/src/components/modal/index.tsx
@@ -1,4 +1,5 @@
import { h, VNode } from "preact";
+import { Text } from "preact-i18n";
interface Props {
active?: boolean;
@@ -14,15 +15,15 @@ export default function ConfirmModal({ active, description,
onCancel, onConfirm,
<div class="modal-background jb-modal-close" onClick={onCancel} />
<div class="modal-card">
<header class="modal-card-head">
- <p class="modal-card-title">Confirm action: {description}</p>
+ <p class="modal-card-title"> <Text id="confirm_modal.title" /> {
!description ? null : <Text id={`confirm_modal.${description}`} /> }</p>
<button class="delete jb-modal-close" aria-label="close"
onClick={onCancel} />
</header>
<section class="modal-card-body">
{children}
</section>
<footer class="modal-card-foot">
- <button class="button jb-modal-close" onClick={onCancel}
>Cancel</button>
- <button class={danger ? "button is-danger jb-modal-close" : "button
is-info jb-modal-close"} onClick={onConfirm} >Confirm</button>
+ <button class="button jb-modal-close" onClick={onCancel} ><Text
id="cancel" /></button>
+ <button class={danger ? "button is-danger jb-modal-close" : "button
is-info jb-modal-close"} onClick={onConfirm} ><Text id="confirm" /></button>
</footer>
</div>
<button class="modal-close is-large jb-modal-close" aria-label="close"
onClick={onCancel} />
diff --git a/src/components/yup/YupInput.tsx b/src/components/yup/YupInput.tsx
new file mode 100644
index 0000000..b10ff22
--- /dev/null
+++ b/src/components/yup/YupInput.tsx
@@ -0,0 +1,32 @@
+import { h, VNode } from "preact";
+import { Text, useText } from "preact-i18n";
+
+interface Props {
+ name: string;
+ value: any;
+ info: any;
+ errors: any;
+ valueHandler: any;
+}
+
+export default function YupInput({ name, info, value, errors, valueHandler }:
Props): VNode {
+ const dict = useText({placeholder: `fields.instance.${name}.placeholder`})
+
+ return <div class="field is-horizontal">
+ <div class="field-label is-normal">
+ <label class="label"><Text id={`fields.instance.${name}.label`} /></label>
+ </div>
+ <div class="field-body">
+ <div class="field">
+ <p class="control is-expanded has-icons-left">
+ <input class="input" type="text"
+ placeholder={dict['placeholder']} readonly={info?.meta?.readonly}
+ name={name} value={value[name]}
+ onChange={(e): void => valueHandler((prev: any) => ({ ...prev,
[name]: e.currentTarget.value }))} />
+ <Text id={`fields.instance.${name}.help`} />
+ </p>
+ {errors[name] ? <p class="help is-danger"><Text
id={`validation.${errors[name].type}`}
fields={errors[name].params}>{errors[name].message}</Text></p> : null}
+ </div>
+ </div>
+</div>
+}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
index 0a47692..73467ca 100644
--- a/src/i18n/index.ts
+++ b/src/i18n/index.ts
@@ -1,18 +1,119 @@
export default {
es: {
+ confirm_modal: {
+ title: 'confirmar accion',
+ create_instance: 'crear instancia',
+ delete_instance: 'borrar instancia',
+ update_instance: 'actualizar instancia',
+ },
notification: {
unauthorized: {
title: 'acceso no autorizado',
description: 'el servidor a denegado el acceso'
},
},
+ cancel: 'cancelar',
+ confirm: 'confirmar',
+ fields: {
+ instance: {
+ id: {
+ label: 'Id',
+ },
+ merchant_pub: {
+ label: 'Clave pública'
+ },
+ payment_targets: {
+ label: 'Dirección de pago',
+ },
+ name: {
+ label: 'Nombre',
+ },
+ payto_uris: {
+ label: 'PaytTO URI',
+ placeholder: 'comma separated values',
+ help: 'payto://x-taler-bank/bank.taler:5882/blogger',
+ },
+ default_max_deposit_fee: {
+ label: 'Máximo pago por depósito',
+ },
+ default_max_wire_fee: {
+ label: 'Máximo pago por transferencia bancaria',
+ },
+ default_wire_fee_amortization: {
+ label: 'Amortización de pago',
+ },
+ },
+ },
+ validation: {
+ required: '{{label}} es obligatorio',
+ typeError: '{{label}} '
+ },
+ text: {
+ instances: 'Instancias',
+ merchant: 'Merchant',
+ list_of_configured_instances: 'Lista de instancias configuradas',
+ instance: {
+ empty_list: 'No instance configured yet, setup one pressing the +
button',
+ }
+ }
},
en: {
+ confirm_modal: {
+ title: 'confirm action',
+ create_instance: 'create instance',
+ delete_instance: 'delete instance',
+ update_instance: 'update instance',
+ },
notification: {
unauthorized: {
title: 'unauthorized access',
description: 'backend has denied access'
},
},
+ cancel: 'cancel',
+ confirm: 'confirm',
+ fields: {
+ instance: {
+ id: {
+ label: 'Id',
+ },
+ merchant_pub: {
+ label: 'Public Key'
+ },
+ payment_targets: {
+ label: 'Payment targets',
+ },
+ name: {
+ label: 'Name',
+ },
+ payto_uris: {
+ label: 'PaytTO URI',
+ placeholder: 'comma separated values',
+ help: 'payto://x-taler-bank/bank.taler:5882/blogger',
+ },
+ default_max_deposit_fee: {
+ label: 'Max deposit fee',
+ },
+ default_max_wire_fee: {
+ label: 'Max wire fee',
+ },
+ default_wire_fee_amortization: {
+ label: 'Max fee amortization',
+ },
+ }
+ },
+ validation: {
+ required: '{{label}} is required',
+ typeError: '{{label}} '
+ },
+ text: {
+ instances: 'Instances',
+ merchant: 'Merchant',
+ list_of_configured_instances: 'List of configured instances',
+
+ instance: {
+ empty_list: 'No instance configured yet, setup one pressing the +
button',
+ }
+ },
},
}
\ No newline at end of file
diff --git a/src/routes/instances/CardTable.tsx
b/src/routes/instances/CardTable.tsx
index 551a543..44c0402 100644
--- a/src/routes/instances/CardTable.tsx
+++ b/src/routes/instances/CardTable.tsx
@@ -1,4 +1,5 @@
import { h, VNode } from "preact";
+import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks";
import { MerchantBackend, WidthId as WithId } from "../../declaration";
import EmptyTable from "./EmptyTable";
@@ -47,7 +48,7 @@ export default function CardTable({ instances, onCreate,
onSelect, selected }: P
return <div class="card has-table">
<header class="card-header">
- <p class="card-header-title"><span class="icon"><i class="mdi
mdi-account-multiple" /></span>Instances</p>
+ <p class="card-header-title"><span class="icon"><i class="mdi
mdi-account-multiple" /></span><Text id="text.instances" /></p>
<button class={rowSelection.length > 0 ? "card-header-icon" :
"card-header-icon is-hidden"}
type="button" onClick={(): void =>
actionQueueHandler(buildActions(instances, rowSelection, 'DELETE'))} >
diff --git a/src/routes/instances/CreateModal.stories.tsx
b/src/routes/instances/CreateModal.stories.tsx
new file mode 100644
index 0000000..1906f0c
--- /dev/null
+++ b/src/routes/instances/CreateModal.stories.tsx
@@ -0,0 +1,16 @@
+/* eslint-disable @typescript-eslint/camelcase */
+import { h, VNode } from 'preact';
+import CreateModal from './CreateModal'
+
+
+export default {
+ title: 'Instances/CreateModal',
+ component: CreateModal,
+ argTypes: {
+ element: { control: 'object' },
+ onCancel: { action: 'onCancel' },
+ onConfirm: { action: 'onConfirm' },
+ }
+};
+
+export const Example = (a: any): VNode => <CreateModal {...a} />;
diff --git a/src/routes/instances/CreateModal.tsx
b/src/routes/instances/CreateModal.tsx
index 2c99b60..b66b483 100644
--- a/src/routes/instances/CreateModal.tsx
+++ b/src/routes/instances/CreateModal.tsx
@@ -2,7 +2,8 @@ import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Duration, MerchantBackend } from "../../declaration";
import * as yup from 'yup';
-import ConfirmModal from "./ConfirmModal";
+import ConfirmModal from "../../components/modal";
+import YupInput from "../../components/yup/YupInput"
function stringToArray(this: yup.AnySchema, current: any, original: string):
string[] {
if (this.isType(current)) return current;
@@ -25,7 +26,6 @@ const schema = yup.object().shape({
name: yup.string().required().label("Name"),
payto_uris: yup.array().of(yup.string())
.min(1).label("Payment Method")
- .meta({ placeholder: 'comma separated values', help:
'payto://x-taler-bank/bank.taler:5882/blogger' })
.transform(stringToArray),
default_max_deposit_fee: yup.string().required().label("Max Deposit Fee"),
default_max_wire_fee: yup.string().required().label("Max Wire"),
@@ -53,32 +53,15 @@ export default function CreateModal({ onCancel, onConfirm
}: Props): VNode {
onConfirm({ ...schema.cast(value), address: {}, jurisdiction: {},
default_wire_transfer_delay: { d_ms: 6000 }, default_pay_delay: { d_ms: 3000 }
} as MerchantBackend.Instances.InstanceConfigurationMessage);
} catch (err) {
const errors = err.inner as yup.ValidationError[]
- const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({
...prev, [cur.path]: cur.message }), {})
+ const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({
...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message
} }), {})
setErrors(pathMessages)
}
}
- return <ConfirmModal description="create instance" active onConfirm={submit}
onCancel={onCancel}>
+ return <ConfirmModal description="create_instance" active onConfirm={submit}
onCancel={onCancel}>
{Object.keys(schema.fields).map(f => {
-
const info = schema.fields[f].describe()
-
- // Just text field for now
- return <div class="field is-horizontal">
- <div class="field-label is-normal">
- <label class="label">{info.label}</label>
- </div>
- <div class="field-body">
- <div class="field">
- <p class="control is-expanded has-icons-left">
- <input class="input" type="text"
placeholder={info?.meta?.placeholder} readonly={info?.meta?.readonly} name={f}
value={value[f]} onChange={(e): void => valueHandler((prev: any) => ({ ...prev,
[f]: e.currentTarget.value }))} />
- {info?.meta?.help}
- </p>
- {errors[f] ? <p class="help is-danger">{errors[f]}</p> : null}
- </div>
- </div>
- </div>
-
+ return <YupInput name={f} info={info} errors={errors} value={value}
valueHandler={valueHandler} />
})}
</ConfirmModal>
diff --git a/src/routes/instances/DeleteModal.tsx
b/src/routes/instances/DeleteModal.tsx
index 276dab4..d7788d1 100644
--- a/src/routes/instances/DeleteModal.tsx
+++ b/src/routes/instances/DeleteModal.tsx
@@ -1,6 +1,6 @@
import { h, VNode } from "preact";
import { MerchantBackend, WidthId } from "../../declaration";
-import ConfirmModal from "./ConfirmModal";
+import ConfirmModal from "../../components/modal";
interface Props {
element: MerchantBackend.Instances.QueryInstancesResponse & WidthId;
@@ -9,7 +9,7 @@ interface Props {
}
export default function DeleteModal({ element, onCancel, onConfirm }: Props):
VNode {
- return <ConfirmModal description="delete instance" danger active
onCancel={onCancel} onConfirm={() => onConfirm(element)}>
+ return <ConfirmModal description="delete_instance" danger active
onCancel={onCancel} onConfirm={() => onConfirm(element)}>
<p>This will permanently delete instance "{element.name}" with id
<b>{element.id}</b></p>
<p>Please confirm this action</p>
</ConfirmModal>
diff --git a/src/routes/instances/EmptyTable.tsx
b/src/routes/instances/EmptyTable.tsx
index 5aff8ef..f7faf92 100644
--- a/src/routes/instances/EmptyTable.tsx
+++ b/src/routes/instances/EmptyTable.tsx
@@ -1,10 +1,11 @@
import { h, VNode } from "preact";
+import { Text } from "preact-i18n";
export default function EmptyTable(): VNode {
return <div class="content has-text-grey has-text-centered">
<p>
<span class="icon is-large"><i class="mdi mdi-emoticon-sad mdi-48px"
/></span>
</p>
- <p>No instance configured yet, setup one pressing the + button </p>
+ <p><Text id="text.intance.empty_list" /></p>
</div>
}
diff --git a/src/routes/instances/Table.tsx b/src/routes/instances/Table.tsx
index 761b068..67ce90d 100644
--- a/src/routes/instances/Table.tsx
+++ b/src/routes/instances/Table.tsx
@@ -1,4 +1,5 @@
import { h, VNode } from "preact"
+import { Text } from "preact-i18n"
import { StateUpdater } from "preact/hooks"
import { MerchantBackend } from "../../declaration"
@@ -24,10 +25,10 @@ export default function Table({ rowSelection,
rowSelectionHandler, instances, on
<span class="check" />
</label>
</th>
- <th>id</th>
- <th>name</th>
- <th>public key</th>
- <th>payments</th>
+ <th><Text id="fields.instance.id.label" /></th>
+ <th><Text id="fields.instance.name.label" /></th>
+ <th><Text id="fields.instance.merchant_pub.label" /></th>
+ <th><Text id="fields.instance.payment_targets.label" /></th>
<th />
</tr>
</thead>
diff --git a/src/routes/instances/UpdateModal.stories.tsx
b/src/routes/instances/UpdateModal.stories.tsx
index 1ae5bca..4d8cb0f 100644
--- a/src/routes/instances/UpdateModal.stories.tsx
+++ b/src/routes/instances/UpdateModal.stories.tsx
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/camelcase */
-import { h } from 'preact';
+import { h, VNode } from 'preact';
import UpdateModal from './UpdateModal'
@@ -13,11 +13,11 @@ export default {
}
};
-export const WithDefaultInstance = (a: any) => <UpdateModal {...a} />;
+export const WithDefaultInstance = (a: any): VNode => <UpdateModal {...a} />;
WithDefaultInstance.args = {
element: {
id: 'default',
- name: 'the default instance',
+ name: 'update',
merchant_pub: 'abcdef',
payment_targets: ['qwe','asd']
}
diff --git a/src/routes/instances/UpdateModal.tsx
b/src/routes/instances/UpdateModal.tsx
index d729729..9906b0f 100644
--- a/src/routes/instances/UpdateModal.tsx
+++ b/src/routes/instances/UpdateModal.tsx
@@ -2,7 +2,8 @@ import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { MerchantBackend } from "../../declaration";
import * as yup from 'yup';
-import ConfirmModal from "./ConfirmModal";
+import ConfirmModal from '../../components/modal'
+import { Text } from "preact-i18n";
function stringToArray(this: yup.AnySchema, current: any, original: string):
string[] {
if (this.isType(current)) return current;
@@ -10,14 +11,11 @@ function stringToArray(this: yup.AnySchema, current: any,
original: string): str
}
const schema = yup.object().shape({
- name: yup.string().required().label("Name"),
- payto_uris: yup.array().of(yup.string())
- .min(1).label("Payment Method")
- .meta({ placeholder: 'comma separated values', help:
'payto://x-taler-bank/bank.taler:5882/blogger' })
- .transform(stringToArray),
- default_max_deposit_fee: yup.string().required().label("Max Deposit Fee"),
- default_max_wire_fee: yup.string().required().label("Max Wire"),
- default_wire_fee_amortization: yup.number().required().label("WireFee
Amortization"),
+ name: yup.string().required(),
+ payto_uris: yup.array().of(yup.string()).min(1).transform(stringToArray),
+ default_max_deposit_fee: yup.string().required(),
+ default_max_wire_fee: yup.string().required(),
+ default_wire_fee_amortization: yup.number().required(),
// default_pay_delay: yup.number().required().label("Pay
delay").transform(numberToDuration),
// default_wire_transfer_delay: yup.number().required().label("Wire transfer
Delay").transform(numberToDuration),
});
@@ -45,12 +43,12 @@ export default function UpdateModal({ element, onCancel,
onConfirm }: Props): VN
onConfirm({...schema.cast(value), address: {}, jurisdiction: {},
default_wire_transfer_delay: { d_ms: 6000 }, default_pay_delay: { d_ms: 3000 }}
as MerchantBackend.Instances.InstanceReconfigurationMessage);
} catch (err) {
const errors = err.inner as yup.ValidationError[]
- const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({
...prev, [cur.path]: cur.message }), {})
+ const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({
...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message
} }), {})
setErrors(pathMessages)
}
}
- return <ConfirmModal description="update instance" active={element != null}
onConfirm={submit} onCancel={onCancel}>
+ return <ConfirmModal description="update_instance" active={element != null}
onConfirm={submit} onCancel={onCancel}>
{Object.keys(schema.fields).map(f => {
const info = schema.fields[f].describe()
@@ -58,7 +56,7 @@ export default function UpdateModal({ element, onCancel,
onConfirm }: Props): VN
// Just text field for now
return <div class="field is-horizontal">
<div class="field-label is-normal">
- <label class="label">{info.label}</label>
+ <label class="label"><Text id={`fields.instance.${f}.label`}
/></label>
</div>
<div class="field-body">
<div class="field">
diff --git a/src/routes/instances/View.stories.tsx
b/src/routes/instances/View.stories.tsx
index 5804152..292c073 100644
--- a/src/routes/instances/View.stories.tsx
+++ b/src/routes/instances/View.stories.tsx
@@ -7,9 +7,7 @@ export default {
title: 'Instances/View',
component: View,
argTypes: {
- onLogin: { action: 'onLogin' },
- onLogout: { action: 'onLogout' },
- onCreateAccount: { action: 'onCreateAccount' },
+ onSelect: { action: 'onSelect' },
},
};
@@ -28,17 +26,37 @@ WithDefaultInstance.args = {
}]
}
-export const WithTwoInstance = (a: any) => <View {...a} />;
-WithTwoInstance.args = {
+export const WithFiveInstance = (a: any) => <View {...a} />;
+WithFiveInstance.args = {
instances: [{
id: 'first',
name: 'the first instance',
merchant_pub: 'abcdefgh',
- payment_targets: []
+ payment_targets: ['asd']
},{
id: 'second',
- name: 'other instance',
+ name: 'the second instance',
+ merchant_pub: 'zxczxcz',
+ payment_targets: ['asd']
+ },{
+ id: 'third',
+ name: 'the third instance',
+ merchant_pub: 'QWEQWEWQE',
+ payment_targets: ['asd']
+ },{
+ id: 'other',
+ name: 'the other instance',
+ merchant_pub: 'FHJHGJGHJ',
+ payment_targets: ['asd']
+ },{
+ id: 'another',
+ name: 'the another instance',
+ merchant_pub: 'abcd3423423efgh',
+ payment_targets: ['asd']
+ },{
+ id: 'last',
+ name: 'last instance',
merchant_pub: 'zxcvvbnm',
- payment_targets: ['pay-to']
+ payment_targets: ['pay-to','asd']
}]
}
diff --git a/src/routes/instances/View.tsx b/src/routes/instances/View.tsx
index 4305564..61435cd 100644
--- a/src/routes/instances/View.tsx
+++ b/src/routes/instances/View.tsx
@@ -5,6 +5,7 @@ import Table from './CardTable';
import DeleteModal from './DeleteModal'
import UpdateModal from './UpdateModal'
import CreateModal from './CreateModal'
+import { Text } from "preact-i18n";
interface Props {
instances: MerchantBackend.Instances.Instance[];
@@ -32,8 +33,8 @@ export default function View({ instances, isLoading,
onCreate, onDelete, onSelec
<div class="level-left">
<div class="level-item">
<ul>
- <li>Merchant</li>
- <li>Instances</li>
+ <li><Text id="text.merchant" /></li>
+ <li><Text id="text.instances" /></li>
</ul>
</div>
</div>
@@ -45,7 +46,7 @@ export default function View({ instances, isLoading,
onCreate, onDelete, onSelec
<div class="level">
<div class="level-left">
<div class="level-item">
- <h1 class="title">List of configured instances</h1>
+ <h1 class="title"><Text id="text.list_of_configured_instances"
/></h1>
</div>
</div>
<div class="level-right" style="display: none;">
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant-backoffice] branch master updated: more i18n,
gnunet <=