diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx')
-rw-r--r-- | packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx | 155 |
1 files changed, 86 insertions, 69 deletions
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx index 6abe55be0..ad3cb0e32 100644 --- a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx +++ b/packages/merchant-backoffice-ui/src/components/form/InputDuration.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 @@ -18,18 +18,21 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { intervalToDuration, formatDuration } from "date-fns"; -import { h, VNode } from "preact"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { formatDuration, intervalToDuration } from "date-fns"; +import { ComponentChildren, h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { Translate, useTranslator } from "../../i18n/index.js"; import { SimpleModal } from "../modal/index.js"; import { DurationPicker } from "../picker/DurationPicker.js"; import { InputProps, useField } from "./useField.js"; +import { Duration } from "@gnu-taler/taler-util"; export interface Props<T> extends InputProps<T> { expand?: boolean; readonly?: boolean; withForever?: boolean; + side?: ComponentChildren; + withoutClear?: boolean; } export function InputDuration<T>({ @@ -41,35 +44,41 @@ export function InputDuration<T>({ help, readonly, withForever, + withoutClear, + side, }: Props<keyof T>): VNode { const [opened, setOpened] = useState(false); - const i18n = useTranslator(); + const { i18n } = useTranslationContext(); - const { error, required, value, onChange } = useField<T>(name); + const { error, required, value: anyValue, onChange } = useField<T>(name); let strValue = ""; + const value: Duration = anyValue if (!value) { strValue = ""; - } else if (value.d_us === "forever") { - strValue = i18n`forever`; + } else if (value.d_ms === "forever") { + strValue = i18n.str`forever`; } else { + if (value.d_ms === undefined) { + throw Error(`assertion error: duration should have a d_ms but got '${JSON.stringify(value)}'`) + } strValue = formatDuration( - intervalToDuration({ start: 0, end: value.d_us / 1000 }), + intervalToDuration({ start: 0, end: value.d_ms }), { locale: { formatDistance: (name, value) => { switch (name) { case "xMonths": - return i18n`${value}M`; + return i18n.str`${value}M`; case "xYears": - return i18n`${value}Y`; + return i18n.str`${value}Y`; case "xDays": - return i18n`${value}d`; + return i18n.str`${value}d`; case "xHours": - return i18n`${value}h`; + return i18n.str`${value}h`; case "xMinutes": - return i18n`${value}min`; + return i18n.str`${value}min`; case "xSeconds": - return i18n`${value}sec`; + return i18n.str`${value}sec`; } }, localize: { @@ -81,13 +90,13 @@ export function InputDuration<T>({ era: () => "e", }, }, - } + }, ); } return ( <div class="field is-horizontal"> - <div class="field-label is-normal"> + <div class="field-label is-normal is-flex-grow-3"> <label class="label"> {label} {tooltip && ( @@ -97,72 +106,80 @@ export function InputDuration<T>({ )} </label> </div> - <div class="field-body is-flex-grow-3"> - <div class="field"> - <div class="field has-addons"> - <p class={expand ? "control is-expanded " : "control "}> - <input - class="input" - type="text" - readonly - value={strValue} - placeholder={placeholder} + + <div class="is-flex-grow-3"> + <div class="field-body "> + <div class="field"> + <div class="field has-addons"> + <p class={expand ? "control is-expanded " : "control "}> + <input + class="input" + type="text" + readonly + value={strValue} + placeholder={placeholder} + onClick={() => { + if (!readonly) setOpened(true); + }} + /> + {required && ( + <span class="icon has-text-danger is-right"> + <i class="mdi mdi-alert" /> + </span> + )} + </p> + <div + class="control" onClick={() => { if (!readonly) setOpened(true); }} - /> - {required && ( - <span class="icon has-text-danger is-right"> - <i class="mdi mdi-alert" /> - </span> - )} - {help} - </p> - <div - class="control" - onClick={() => { - if (!readonly) setOpened(true); - }} - > - <a class="button is-static"> - <span class="icon"> - <i class="mdi mdi-clock" /> - </span> - </a> + > + <a class="button is-static"> + <span class="icon"> + <i class="mdi mdi-clock" /> + </span> + </a> + </div> </div> + {error && <p class="help is-danger">{error}</p>} </div> - {error && <p class="help is-danger">{error}</p>} + {withForever && ( + <span data-tooltip={i18n.str`change value to never`}> + <button + class="button is-info mr-3" + onClick={() => onChange({ d_ms: "forever" } as any)} + > + <i18n.Translate>forever</i18n.Translate> + </button> + </span> + )} + {!readonly && !withoutClear && ( + <span data-tooltip={i18n.str`change value to empty`}> + <button + class="button is-info " + onClick={() => onChange(undefined as any)} + > + <i18n.Translate>clear</i18n.Translate> + </button> + </span> + )} + {side} </div> - {withForever && ( - <span data-tooltip={i18n`change value to never`}> - <button - class="button is-info mr-3" - onClick={() => onChange({ d_us: "forever" } as any)} - > - <Translate>forever</Translate> - </button> - </span> - )} - {!readonly && ( - <span data-tooltip={i18n`change value to empty`}> - <button - class="button is-info " - onClick={() => onChange(undefined as any)} - > - <Translate>clear</Translate> - </button> - </span> - )} + <span> + {help} + </span> </div> + + {opened && ( <SimpleModal onCancel={() => setOpened(false)}> <DurationPicker days hours minutes - value={!value || value.d_us === "forever" ? 0 : value.d_us} + value={!value || value.d_ms === "forever" ? 0 : value.d_ms} onChange={(v) => { - onChange({ d_us: v } as any); + onChange({ d_ms: v } as any); }} /> </SimpleModal> |