summaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
diff options
context:
space:
mode:
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.tsx178
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>