[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] 01/02: change token using modal
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] 01/02: change token using modal |
Date: |
Mon, 24 May 2021 16:22:57 +0200 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
commit 9316f178fa73bb9b42a62eaf5d499a1d3de86346
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon May 24 11:20:45 2021 -0300
change token using modal
---
CHANGELOG.md | 19 +++++-
packages/frontend/src/components/form/Input.tsx | 2 +-
.../frontend/src/components/form/InputSecured.tsx | 74 +++++-----------------
packages/frontend/src/components/modal/index.tsx | 62 +++++++++++-------
.../instance/reserves/list/AutorizeTipModal.tsx | 4 +-
.../src/paths/instance/update/UpdatePage.tsx | 1 -
packages/frontend/src/scss/main.scss | 11 +++-
7 files changed, 85 insertions(+), 88 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6aa6b3..45bfb40 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,9 +31,26 @@ and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0
- react routing refactor to use query parameters from history
- create taler ui
- contract terms in the wallet
- - when backoffice get a response of the merchant that have info about the
reponse of the exchange, the error is not readed correctly... see wire transfer
+ - when backoffice get a response of the merchant that have info about the
reponsse of the exchange, the error is not readed correctly... see wire transfer
- when creating the first default instance, the page keeps reloading
preventing for filling the form
-
+ - payto auto remove (add if is missing)
+ - back cancel in all dialog (order)
+ - transfer use the tabs instead of three state
+ - spining while working,
+ - disabled button grey out
+ - add timeout to the request
+ - hash
+
+ - delete button, without
+ - delete transaction if verified is missing
+
+ - update instance
+ - auth token: status => external/managed
+
+
+ - price not required: product page has required field that should not be
required
+ - animation on load
## [Unreleased]
- fixed bug when updating token and not admin
diff --git a/packages/frontend/src/components/form/Input.tsx
b/packages/frontend/src/components/form/Input.tsx
index f257d59..200bf54 100644
--- a/packages/frontend/src/components/form/Input.tsx
+++ b/packages/frontend/src/components/form/Input.tsx
@@ -22,7 +22,7 @@ import { ComponentChildren, h, VNode } from "preact";
import { useField, InputProps } from "./useField";
interface Props<T> extends InputProps<T> {
- inputType?: 'text' | 'number' | 'multiline';
+ inputType?: 'text' | 'number' | 'multiline' | 'password';
expand?: boolean;
toStr?: (v?: any) => string;
fromStr?: (s: string) => any;
diff --git a/packages/frontend/src/components/form/InputSecured.tsx
b/packages/frontend/src/components/form/InputSecured.tsx
index 64737e3..6e3059b 100644
--- a/packages/frontend/src/components/form/InputSecured.tsx
+++ b/packages/frontend/src/components/form/InputSecured.tsx
@@ -21,6 +21,7 @@
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Translate } from "../../i18n";
+import { UpdateTokenModal } from "../modal";
import { InputProps, useField } from "./useField";
export type Props<T> = InputProps<T>;
@@ -39,7 +40,7 @@ export function InputSecured<T>({ name, readonly,
placeholder, tooltip, label, h
const { error, value, initial, onChange, toStr, fromStr } =
useField<T>(name);
const [active, setActive] = useState(false);
- const [newValue, setNuewValue] = useState("")
+ const [newValue, setNuewValue] = useState("");
return <Fragment>
<div class="field is-horizontal">
@@ -52,65 +53,22 @@ export function InputSecured<T>({ name, readonly,
placeholder, tooltip, label, h
</label>
</div>
<div class="field-body is-flex-grow-3">
- {!active ?
- <Fragment>
- <div class="field has-addons">
- <button class="button" onClick={(): void => {
setActive(!active); }} >
- <div class="icon is-left"><i class="mdi mdi-lock-reset"
/></div>
- <span><Translate>Manage token</Translate></span>
- </button>
- <TokenStatus prev={initial} post={value} />
- </div>
- </Fragment> :
- <Fragment>
- <div class="field has-addons">
- <div class="control">
- <a class="button is-static">secret-token:</a>
- </div>
- <div class="control is-expanded">
- <input class="input" type="text"
- placeholder={placeholder} readonly={readonly || !active}
- disabled={readonly || !active}
- name={String(name)} value={newValue}
- onInput={(e): void => {
- setNuewValue(e.currentTarget.value)
- }} />
- {help}
- </div>
- <div class="control">
- <button class="button is-info" disabled={fromStr(newValue) ===
value} onClick={(): void => { onChange(fromStr(newValue)); setActive(!active);
setNuewValue(""); }} >
- <div class="icon is-left"><i class="mdi mdi-lock-outline"
/></div>
- <span><Translate>Update</Translate></span>
- </button>
- </div>
- </div>
- </Fragment>
- }
+ <div class="field has-addons">
+ <button class="button" onClick={(): void => { setActive(!active); }}
>
+ <div class="icon is-left"><i class="mdi mdi-lock-reset" /></div>
+ <span><Translate>Manage token</Translate></span>
+ </button>
+ <TokenStatus prev={initial} post={value} />
+ </div>
{error ? <p class="help is-danger">{error}</p> : null}
</div>
</div>
- {active &&
- <div class="field is-horizontal">
- <div class="field-body is-flex-grow-3">
- <div class="level" style={{ width: '100%' }}>
- <div class="level-right is-flex-grow-1">
- <div class="level-item">
- <button class="button is-danger" disabled={null === value ||
undefined === value} onClick={(): void => { onChange(null!);
setActive(!active); setNuewValue(""); }} >
- <div class="icon is-left"><i class="mdi
mdi-lock-open-variant" /></div>
- <span><Translate>Remove</Translate></span>
- </button>
- </div>
- <div class="level-item">
- <button class="button " onClick={(): void => {
onChange(initial!); setActive(!active); setNuewValue(""); }} >
- <div class="icon is-left"><i class="mdi
mdi-lock-open-variant" /></div>
- <span><Translate>Cancel</Translate></span>
- </button>
- </div>
- </div>
-
- </div>
- </div>
- </div>
- }
+ {active && <UpdateTokenModal oldToken={initial}
+ onCancel={() => { onChange(initial!); setActive(false); }}
+ onClear={() => { onChange(null!); setActive(false); }}
+ onConfirm={(newToken) => {
+ onChange(newToken as any); setActive(false)
+ }}
+ />}
</Fragment >;
}
diff --git a/packages/frontend/src/components/modal/index.tsx
b/packages/frontend/src/components/modal/index.tsx
index 44b103c..baf8bb5 100644
--- a/packages/frontend/src/components/modal/index.tsx
+++ b/packages/frontend/src/components/modal/index.tsx
@@ -22,6 +22,7 @@
import { ComponentChildren, h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { useInstanceContext } from "../../context/instance";
import { Translate, useTranslator } from "../../i18n";
import { DEFAULT_REQUEST_TIMEOUT } from "../../utils/constants";
import { FormProvider } from "../form/FormProvider";
@@ -80,7 +81,7 @@ export function ContinueModal({ active, description,
onCancel, onConfirm, childr
</div>
}
-export function ClearConfirmModal({ description, onCancel, onClear, onConfirm,
children, disabled }: Props & { onClear?: () => void }): VNode {
+export function ClearConfirmModal({ description, onCancel, onClear, onConfirm,
children }: Props & { onClear?: () => void }): VNode {
return <div class="modal is-active">
<div class="modal-background " onClick={onCancel} />
<div class="modal-card">
@@ -88,13 +89,15 @@ export function ClearConfirmModal({ description, onCancel,
onClear, onConfirm, c
{!description ? null : <p class="modal-card-title">{description}</p>}
<button class="delete " aria-label="close" onClick={onCancel} />
</header>
- <section class="modal-card-body">
+ <section class="modal-card-body is-main-section">
{children}
</section>
<footer class="modal-card-foot">
- <button class="button " onClick={onCancel}
><Translate>Cancel</Translate></button>
- <button class="button is-danger" onClick={onClear} disabled={disabled}
><Translate>Clear</Translate></button>
- <button class="button is-info" onClick={onConfirm} disabled={disabled}
><Translate>Confirm</Translate></button>
+ {onClear && <button class="button is-danger" onClick={onClear}
disabled={onClear === undefined} ><Translate>Clear</Translate></button> }
+ <div class="buttons is-right" style={{ width: '100%' }}>
+ <button class="button " onClick={onCancel}
><Translate>Cancel</Translate></button>
+ <button class="button is-info" onClick={onConfirm}
disabled={onConfirm === undefined} ><Translate>Confirm</Translate></button>
+ </div>
</footer>
</div>
<button class="modal-close is-large " aria-label="close"
onClick={onCancel} />
@@ -115,43 +118,54 @@ export function DeleteModal({ element, onCancel,
onConfirm }: DeleteModalProps):
}
interface UpdateTokenModalProps {
- element: { id: string, name: string };
oldToken?: string;
onCancel: () => void;
onConfirm: (value: string) => void;
onClear: () => void;
}
-export function UpdateTokenModal({ element, onCancel, onClear, onConfirm,
oldToken }: UpdateTokenModalProps): VNode {
- type State = { old_token: string, new_token: string }
+export function UpdateTokenModal({ onCancel, onClear, onConfirm, oldToken }:
UpdateTokenModalProps): VNode {
+ type State = { old_token: string, new_token: string, repeat_token: string }
const [form, setValue] = useState<Partial<State>>({
- old_token: '', new_token: ''
+ old_token: '', new_token: '', repeat_token: '',
})
const i18n = useTranslator()
+
+ const hasInputTheCorrectOldToken = oldToken && oldToken !== form.old_token
const errors = {
- old_token: oldToken && oldToken !== form.old_token ? i18n`should be the
same` : undefined,
- new_token: !form.new_token ? i18n`should be the same` : (form.new_token
=== form.old_token ? i18n`cannot be the same as before` : undefined),
+ old_token: hasInputTheCorrectOldToken ? i18n`is not the same as the
current token` : undefined,
+ new_token: !form.new_token ? i18n`cannot be empty` : (form.new_token ===
form.old_token ? i18n`cannot be the same as the old token` : undefined),
+ repeat_token: form.new_token !== form.repeat_token ? i18n`is not the same`
: undefined
}
- const text = i18n`You are updating the authorization token from instance
${element.name} with id ${element.id}`
+ const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !==
undefined)
+
+ const instance = useInstanceContext()
- return <ClearConfirmModal description="update_token"
+ const text = i18n`You are updating the authorization token from instance
with id ${instance.id}`
+
+ return <ClearConfirmModal description={text}
onCancel={onCancel}
- onConfirm={() => onConfirm(form.new_token!)}
- onClear={onClear}
- disabled={!!errors.new_token || !!errors.old_token}
+ onConfirm={!hasErrors ? () => onConfirm(form.new_token!) : undefined}
+ onClear={!hasInputTheCorrectOldToken && oldToken ? onClear : undefined}
>
- <p>{text}</p>
- <FormProvider errors={errors} object={form} valueHandler={setValue}>
- <Input name="old_token" label={i18n`Old token`} tooltip={i18n`token
currently in use`} />
- <Input name="new_token" label={i18n`New token`} tooltip={i18n`next token
to be used`} />
- </FormProvider>
- <p><Translate>Clearing the auth token will mean public access to the
instance</Translate></p>
+ <div class="columns">
+ <div class="column" />
+ <div class="column is-four-fifths" >
+ <FormProvider errors={errors} object={form} valueHandler={setValue}>
+ { oldToken && <Input<State> name="old_token" label={i18n`Old token`}
tooltip={i18n`token currently in use`} inputType="password"/> }
+ <Input<State> name="new_token" label={i18n`New token`}
tooltip={i18n`next token to be used`} inputType="password"/>
+ <Input<State> name="repeat_token" label={i18n`Repeat token`}
tooltip={i18n`confirm the same token`} inputType="password"/>
+ </FormProvider>
+ <p><Translate>Clearing the auth token will mean public access to the
instance</Translate></p>
+ </div>
+ <div class="column" />
+ </div>
</ClearConfirmModal>
}
-export function LoadingModal({ onCancel }: { onCancel: () => void}): VNode {
+export function LoadingModal({ onCancel }: { onCancel: () => void }): VNode {
const i18n = useTranslator()
return <div class={"modal is-active"}>
<div class="modal-background " onClick={onCancel} />
@@ -160,7 +174,7 @@ export function LoadingModal({ onCancel }: { onCancel: ()
=> void}): VNode {
<p class="modal-card-title"><Translate>Operation is taking to much
time</Translate></p>
</header>
<section class="modal-card-body">
- <p><Translate>You can wait a little longer or abort the request to the
backend. If the problem persist
+ <p><Translate>You can wait a little longer or abort the request to the
backend. If the problem persist
contact the administrator.</Translate></p>
<p>{i18n`The operation will be automatically canceled after
${DEFAULT_REQUEST_TIMEOUT} seconds`}</p>
</section>
diff --git
a/packages/frontend/src/paths/instance/reserves/list/AutorizeTipModal.tsx
b/packages/frontend/src/paths/instance/reserves/list/AutorizeTipModal.tsx
index 72215fb..6879695 100644
--- a/packages/frontend/src/paths/instance/reserves/list/AutorizeTipModal.tsx
+++ b/packages/frontend/src/paths/instance/reserves/list/AutorizeTipModal.tsx
@@ -30,7 +30,7 @@ import { useTranslator } from "../../../../i18n";
import { AuthorizeTipSchema } from "../../../../schemas";
import { CreatedSuccessfully } from "./CreatedSuccessfully";
-interface AutorizaTipModalProps {
+interface AuthorizeTipModalProps {
onCancel: () => void;
onConfirm: (value: MerchantBackend.Tips.TipCreateRequest) => void;
tipAuthorized?: {
@@ -39,7 +39,7 @@ interface AutorizaTipModalProps {
};
}
-export function AuthorizeTipModal({ onCancel, onConfirm, tipAuthorized }:
AutorizaTipModalProps): VNode {
+export function AuthorizeTipModal({ onCancel, onConfirm, tipAuthorized }:
AuthorizeTipModalProps): VNode {
// const result = useOrderDetails(id)
type State = MerchantBackend.Tips.TipCreateRequest
const [form, setValue] = useState<Partial<State>>({})
diff --git a/packages/frontend/src/paths/instance/update/UpdatePage.tsx
b/packages/frontend/src/paths/instance/update/UpdatePage.tsx
index d1a1d7c..975cb7c 100644
--- a/packages/frontend/src/paths/instance/update/UpdatePage.tsx
+++ b/packages/frontend/src/paths/instance/update/UpdatePage.tsx
@@ -77,7 +77,6 @@ export function UpdatePage({ onUpdate, selected, onBack }:
Props): VNode {
errors = yupErrors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev,
[cur.path]: cur.message }), {})
}
const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !==
undefined)
-
const submit = async (): Promise<void> => {
// use conversion instead of this
const newToken = value.auth_token;
diff --git a/packages/frontend/src/scss/main.scss
b/packages/frontend/src/scss/main.scss
index e9b8cb6..08e2f79 100644
--- a/packages/frontend/src/scss/main.scss
+++ b/packages/frontend/src/scss/main.scss
@@ -47,6 +47,8 @@
@import "fonts/nunito.css";
@import "icons/materialdesignicons-4.9.95.min.css";
+$tooltip-color: red;
+
@import
"../../node_modules/@creativebulma/bulma-tooltip/dist/bulma-tooltip.min.css";
@import "../../node_modules/bulma-timeline/dist/css/bulma-timeline.min.css";
@@ -154,4 +156,11 @@ tr:hover .right-sticky {
input:read-only {
cursor: initial;
-}
\ No newline at end of file
+}
+
+span.icon[data-tooltip]:before {
+ z-index: 1000;
+ max-width: 250px;
+ transform: inherit;
+ // white-space: normal;
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.