diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx')
-rw-r--r-- | packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx | 178 |
1 files changed, 50 insertions, 128 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx index b5328249a..cde58967f 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx @@ -1,6 +1,6 @@ /* This file is part of GNU Taler - (C) 2021 Taler Systems S.A. + (C) 2021-2024 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 @@ -19,137 +19,101 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { h, VNode } from "preact"; +import { Duration, TalerMerchantApi } from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { VNode, h } from "preact"; import { useState } from "preact/hooks"; -import * as yup from "yup"; import { AsyncButton } from "../../../components/exception/AsyncButton.js"; import { - FormProvider, FormErrors, + FormProvider, } from "../../../components/form/FormProvider.js"; -import { UpdateTokenModal } from "../../../components/modal/index.js"; -import { useInstanceContext } from "../../../context/instance.js"; -import { MerchantBackend } from "../../../declaration.js"; -import { Translate, useTranslator } from "../../../i18n/index.js"; import { DefaultInstanceFormFields } from "../../../components/instance/DefaultInstanceFormFields.js"; -import { PAYTO_REGEX } from "../../../utils/constants.js"; -import { Amounts } from "@gnu-taler/taler-util"; +import { useSessionContext } from "../../../context/session.js"; import { undefinedIfEmpty } from "../../../utils/table.js"; -type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & { - auth_token?: string; +export type Entity = Omit<Omit<TalerMerchantApi.InstanceReconfigurationMessage, "default_pay_delay">, "default_wire_transfer_delay"> & { + default_pay_delay: Duration, + default_wire_transfer_delay: Duration, }; -//MerchantBackend.Instances.InstanceAuthConfigurationMessage +//TalerMerchantApi.InstanceAuthConfigurationMessage interface Props { - onUpdate: (d: Entity) => void; - onChangeAuth: ( - d: MerchantBackend.Instances.InstanceAuthConfigurationMessage - ) => Promise<void>; - selected: MerchantBackend.Instances.QueryInstancesResponse; + onUpdate: (d: TalerMerchantApi.InstanceReconfigurationMessage) => void; + selected: TalerMerchantApi.QueryInstancesResponse; isLoading: boolean; onBack: () => void; } function convert( - from: MerchantBackend.Instances.QueryInstancesResponse + from: TalerMerchantApi.QueryInstancesResponse, ): Entity { - const { accounts, ...rest } = from; - const payto_uris = accounts.filter((a) => a.active).map((a) => a.payto_uri); + const { default_pay_delay, default_wire_transfer_delay, ...rest } = from; + const defaults = { - default_wire_fee_amortization: 1, - default_pay_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 }, //two hours - default_wire_transfer_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 * 2 }, //two hours + use_stefan: false, + default_pay_delay: Duration.fromTalerProtocolDuration(default_pay_delay), + default_wire_transfer_delay: Duration.fromTalerProtocolDuration(default_wire_transfer_delay), }; - return { ...defaults, ...rest, payto_uris }; -} - -function getTokenValuePart(t?: string): string | undefined { - if (!t) return t; - const match = /secret-token:(.*)/.exec(t); - if (!match || !match[1]) return undefined; - return match[1]; + return { ...defaults, ...rest }; } export function UpdatePage({ onUpdate, - onChangeAuth, selected, onBack, }: Props): VNode { - const { id, token } = useInstanceContext(); - const currentTokenValue = getTokenValuePart(token); - - function updateToken(token: string | undefined | null) { - const value = - token && token.startsWith("secret-token:") - ? token.substring("secret-token:".length) - : token; - - if (!token) { - onChangeAuth({ method: "external" }); - } else { - onChangeAuth({ method: "token", token: `secret-token:${value}` }); - } - } + const { state } = useSessionContext(); const [value, valueHandler] = useState<Partial<Entity>>(convert(selected)); - const i18n = useTranslator(); + const { i18n } = useTranslationContext(); const errors: FormErrors<Entity> = { - name: !value.name ? i18n`required` : undefined, - payto_uris: - !value.payto_uris || !value.payto_uris.length - ? i18n`required` - : undefinedIfEmpty( - value.payto_uris.map((p) => { - return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined; - }) - ), - default_max_deposit_fee: !value.default_max_deposit_fee - ? i18n`required` - : !Amounts.parse(value.default_max_deposit_fee) - ? i18n`invalid format` - : undefined, - default_max_wire_fee: !value.default_max_wire_fee - ? i18n`required` - : !Amounts.parse(value.default_max_wire_fee) - ? i18n`invalid format` - : undefined, - default_wire_fee_amortization: - value.default_wire_fee_amortization === undefined - ? i18n`required` - : isNaN(value.default_wire_fee_amortization) - ? i18n`is not a number` - : value.default_wire_fee_amortization < 1 - ? i18n`must be 1 or greater` + name: !value.name ? i18n.str`required` : undefined, + user_type: !value.user_type + ? i18n.str`required` + : value.user_type !== "business" && value.user_type !== "individual" + ? i18n.str`should be business or individual` : undefined, - default_pay_delay: !value.default_pay_delay ? i18n`required` : undefined, + default_pay_delay: !value.default_pay_delay + ? i18n.str`required` + : !!value.default_wire_transfer_delay && + value.default_wire_transfer_delay.d_ms !== "forever" && + value.default_pay_delay.d_ms !== "forever" && + value.default_pay_delay.d_ms > value.default_wire_transfer_delay.d_ms ? + i18n.str`pay delay can't be greater than wire transfer delay` : undefined, default_wire_transfer_delay: !value.default_wire_transfer_delay - ? i18n`required` + ? i18n.str`required` : undefined, address: undefinedIfEmpty({ address_lines: value.address?.address_lines && value.address?.address_lines.length > 7 - ? i18n`max 7 lines` + ? i18n.str`max 7 lines` : undefined, }), jurisdiction: undefinedIfEmpty({ address_lines: value.address?.address_lines && value.address?.address_lines.length > 7 - ? i18n`max 7 lines` + ? i18n.str`max 7 lines` : undefined, }), }; const hasErrors = Object.keys(errors).some( - (k) => (errors as any)[k] !== undefined + (k) => (errors as any)[k] !== undefined, ); + const submit = async (): Promise<void> => { - await onUpdate(value as Entity); + const { default_pay_delay, default_wire_transfer_delay, ...rest } = value as Required<Entity>; + const result: TalerMerchantApi.InstanceReconfigurationMessage = { + default_pay_delay: Duration.toTalerProtocolDuration(default_pay_delay), + default_wire_transfer_delay: Duration.toTalerProtocolDuration(default_wire_transfer_delay), + ...rest, + } + await onUpdate(result); }; - const [active, setActive] = useState(false); + // const [active, setActive] = useState(false); return ( <div> @@ -160,56 +124,14 @@ export function UpdatePage({ <div class="level-left"> <div class="level-item"> <span class="is-size-4"> - <Translate>Instance id</Translate>: <b>{id}</b> + <i18n.Translate>Instance id</i18n.Translate>: <b>{state.instance}</b> </span> </div> </div> - <div class="level-right"> - <div class="level-item"> - <h1 class="title"> - <button - class="button is-danger" - data-tooltip={i18n`Change the authorization method use for this instance.`} - onClick={(): void => { - setActive(!active); - }} - > - <div class="icon is-left"> - <i class="mdi mdi-lock-reset" /> - </div> - <span> - <Translate>Manage access token</Translate> - </span> - </button> - </h1> - </div> - </div> </div> </div> </section> - <div class="columns"> - <div class="column" /> - <div class="column is-four-fifths"> - {active && ( - <UpdateTokenModal - oldToken={currentTokenValue} - onCancel={() => { - setActive(false); - }} - onClear={() => { - updateToken(null); - setActive(false); - }} - onConfirm={(newToken) => { - updateToken(newToken); - setActive(false); - }} - /> - )} - </div> - <div class="column" /> - </div> <hr /> <div class="columns"> @@ -229,19 +151,19 @@ export function UpdatePage({ onClick={onBack} data-tooltip="cancel operation" > - <Translate>Cancel</Translate> + <i18n.Translate>Cancel</i18n.Translate> </button> <AsyncButton onClick={submit} data-tooltip={ hasErrors - ? i18n`Need to complete marked fields` + ? i18n.str`Need to complete marked fields` : "confirm operation" } disabled={hasErrors} > - <Translate>Confirm</Translate> + <i18n.Translate>Confirm</i18n.Translate> </AsyncButton> </div> </div> |