gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]