gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-backoffice] 02/03: login with message and instanceContex


From: gnunet
Subject: [taler-merchant-backoffice] 02/03: login with message and instanceContext
Date: Mon, 22 Feb 2021 23:09:14 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository merchant-backoffice.

commit a4a3aa5eaa355c43f66e250c02829c33974407e0
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Feb 22 10:28:37 2021 -0300

    login with message and instanceContext
---
 packages/frontend/src/components/auth/index.tsx    |  17 ++-
 .../src/components/notifications/index.tsx         |   4 +-
 packages/frontend/src/context/backend.ts           |  19 ++-
 packages/frontend/src/hooks/backend.ts             |  42 ++++--
 packages/frontend/src/hooks/notifications.ts       |   4 +-
 packages/frontend/src/i18n/index.ts                |   8 +-
 packages/frontend/src/index.tsx                    | 160 ++++++++++++---------
 .../src/routes/instances/details/DetailPage.tsx    |   1 -
 .../src/routes/instances/details/index.tsx         |  19 +--
 .../frontend/src/routes/instances/list/index.tsx   |  45 +-----
 .../src/routes/instances/update/UpdatePage.tsx     |   7 +-
 .../frontend/src/routes/instances/update/index.tsx |  15 +-
 packages/frontend/src/routes/login/index.tsx       |   6 +-
 packages/frontend/tests/hooks/notification.test.ts |   2 +-
 14 files changed, 190 insertions(+), 159 deletions(-)

diff --git a/packages/frontend/src/components/auth/index.tsx 
b/packages/frontend/src/components/auth/index.tsx
index 8c0a20b..8fdccbf 100644
--- a/packages/frontend/src/components/auth/index.tsx
+++ b/packages/frontend/src/components/auth/index.tsx
@@ -20,14 +20,17 @@
 */
 
 import { h, VNode } from "preact";
+import { Text } from "preact-i18n";
 import { useContext, useState } from "preact/hooks";
 import { BackendContext } from "../../context/backend";
+import { Notification } from "../../declaration";
 
 interface Props {
+  withMessage?: Notification;
   onConfirm: (backend: string, token?: string) => void;
 }
 
-export function LoginModal({ onConfirm }: Props): VNode {
+export function LoginModal({ onConfirm, withMessage }: Props): VNode {
   const backend = useContext(BackendContext)
   const [updatingToken, setUpdatingToken] = useState(false)
   const [token, setToken] = useState(backend.token || '')
@@ -37,6 +40,16 @@ export function LoginModal({ onConfirm }: Props): VNode {
   return <div class="modal is-active is-clipped">
     <div class="modal-background" />
     <div class="modal-card">
+      {withMessage && <div class={withMessage.type === 'ERROR' ? "notification 
is-danger" : "notification is-info"}>
+        <div class="columns is-vcentered">
+          <div class="column is-12">
+              <div>
+                <p><Text id={`notification.${withMessage.messageId}.title`} /> 
</p>
+                <Text id={`notification.${withMessage.messageId}.description`} 
fields={withMessage.params} />
+              </div>
+            </div>
+        </div>
+      </div>}
       <header class="modal-card-head">
         <p class="modal-card-title">Login required</p>
       </header>
@@ -72,7 +85,7 @@ export function LoginModal({ onConfirm }: Props): VNode {
           </div>
         </div>
       </section>
-      <footer class="modal-card-foot " style={{justifyContent: 'flex-end'}}>
+      <footer class="modal-card-foot " style={{ justifyContent: 'flex-end' }}>
         <button class="button is-info" onClick={(): void => {
           onConfirm(url, updatingToken && token ? token : undefined);
         }} >Confirm</button>
diff --git a/packages/frontend/src/components/notifications/index.tsx 
b/packages/frontend/src/components/notifications/index.tsx
index a581823..a5450fd 100644
--- a/packages/frontend/src/components/notifications/index.tsx
+++ b/packages/frontend/src/components/notifications/index.tsx
@@ -25,7 +25,7 @@ import { MessageType, Notification } from "../../declaration";
 
 interface Props {
   notifications: Notification[];
-  removeNotification: (n: Notification) => void;
+  removeNotification?: (n: Notification) => void;
 }
 
 function messageStyle(type: MessageType): string {
@@ -43,7 +43,7 @@ export function Notifications({ notifications, 
removeNotification }: Props): VNo
     {notifications.map(n => <article class={messageStyle(n.type)}>
       <div class="message-header">
         <p><Text id={`notification.${n.messageId}.title`} /> </p>
-        <button class="delete" onClick={()=> removeNotification(n)} />
+        <button class="delete" onClick={()=> removeNotification && 
removeNotification(n)} />
       </div>
       <div class="message-body">
         <Text id={`notification.${n.messageId}.description`} fields={n.params} 
/>
diff --git a/packages/frontend/src/context/backend.ts 
b/packages/frontend/src/context/backend.ts
index 64e4dd2..f48b2e3 100644
--- a/packages/frontend/src/context/backend.ts
+++ b/packages/frontend/src/context/backend.ts
@@ -1,11 +1,13 @@
 import { createContext } from 'preact'
+import { StateUpdater } from 'preact/hooks'
 
 export interface BackendContextType {
   url: string;
   token?: string;
   changeBackend: (url: string) => void;
-  clearToken: () => void;
-  updateToken: (token:string) => void;
+  // clearTokens: () => void;
+  // addTokenCleaner: (c: StateUpdater<string | undefined>) => void;
+  updateToken: (token?:string) => void;
   lang: string;
   setLang: (lang: string) => void;
 }
@@ -14,12 +16,18 @@ export interface ConfigContextType {
   currency?: string;
 }
 
+export interface InstanceContextType {
+  id: string;
+  token?: string;
+}
+
 export const BackendContext = createContext<BackendContextType>({
   url: '',
   lang: 'en',
   token: undefined,
   changeBackend: () => null,
-  clearToken: () => null,
+  // clearTokens: () => null,
+  // addTokenCleaner: () => null,
   updateToken: () => null,
   setLang: () => null,
 })
@@ -27,3 +35,8 @@ export const BackendContext = 
createContext<BackendContextType>({
 export const ConfigContext = createContext<ConfigContextType>({
   currency: undefined,
 })
+
+export const InstanceContext = createContext<InstanceContextType>({
+  id: '',
+  token: undefined,
+})
\ No newline at end of file
diff --git a/packages/frontend/src/hooks/backend.ts 
b/packages/frontend/src/hooks/backend.ts
index c1118f9..75246c8 100644
--- a/packages/frontend/src/hooks/backend.ts
+++ b/packages/frontend/src/hooks/backend.ts
@@ -23,7 +23,8 @@ import useSWR, { mutate } from 'swr';
 import axios from 'axios'
 import { MerchantBackend } from '../declaration';
 import { useContext } from 'preact/hooks';
-import { BackendContext } from '../context/backend';
+import { BackendContext, InstanceContext } from '../context/backend';
+import { useBackendInstanceToken } from '.';
 
 type HttpResponse<T> = HttpResponseOk<T> | HttpResponseError<T>;
 
@@ -71,8 +72,10 @@ function fetcher(url: string, token: string, backend: 
string) {
 
 interface BackendMutateAPI {
   createInstance: (data: 
MerchantBackend.Instances.InstanceConfigurationMessage) => Promise<void>;
-  updateInstance: (id: string, data: 
MerchantBackend.Instances.InstanceReconfigurationMessage) => Promise<void>;
-  deleteInstance: (id: string) => Promise<void>;
+}
+interface BackendInstaceMutateAPI {
+  updateInstance: (data: 
MerchantBackend.Instances.InstanceReconfigurationMessage) => Promise<void>;
+  deleteInstance: () => Promise<void>;
 }
 
 export function useBackendMutateAPI(): BackendMutateAPI {
@@ -87,27 +90,35 @@ export function useBackendMutateAPI(): BackendMutateAPI {
 
     mutate('/private/instances')
   }
-  const updateInstance = async (updateId: string, instance: 
MerchantBackend.Instances.InstanceReconfigurationMessage): Promise<void> => {
-    await request(`${url}/private/instances/${updateId}`, {
+  return { createInstance }
+}
+
+export function useBackendInstanceMutateAPI(): BackendInstaceMutateAPI {
+  const { url } = useContext(BackendContext)
+  const { id, token } = useContext(InstanceContext)
+
+  const updateInstance = async (instance: 
MerchantBackend.Instances.InstanceReconfigurationMessage): Promise<void> => {
+    await request(`${url}/private/instances/${id}`, {
       method: 'patch',
       token,
       data: instance
     })
 
     mutate('/private/instances', null)
-    mutate(`/private/instances/${updateId}`, null)
+    mutate(`/private/instances/${id}`, null)
   };
-  const deleteInstance = async (deleteId: string): Promise<void> => {
-    await request(`${url}/private/instances/${deleteId}`, {
+  
+  const deleteInstance = async (): Promise<void> => {
+    await request(`${url}/private/instances/${id}`, {
       method: 'delete',
       token,
     })
 
     mutate('/private/instances', null)
-    mutate(`/private/instances/${deleteId}`, null)
+    mutate(`/private/instances/${id}`, null)
   }
 
-  return { createInstance, updateInstance, deleteInstance }
+  return { updateInstance, deleteInstance }
 }
 
 export function useBackendInstances(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
@@ -117,16 +128,19 @@ export function useBackendInstances(): 
HttpResponse<MerchantBackend.Instances.In
   return { data, unauthorized: error?.status === 401, error }
 }
 
-export function useBackendInstance(id: string | null): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
-  const { url, token } = useContext(BackendContext)
-  const { data, error } = 
useSWR<MerchantBackend.Instances.QueryInstancesResponse>(id ? 
[`/private/instances/${id}`, token, url] : null, fetcher)
+export function useBackendInstance(): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+  const { url } = useContext(BackendContext);
+  const { id, token } = useContext(InstanceContext);
+  const { data, error } = 
useSWR<MerchantBackend.Instances.QueryInstancesResponse>([`/private/instances/${id}`,
 token, url], fetcher)
 
   return { data, unauthorized: error?.status === 401, error }
 }
 
 export function useBackendConfig(): 
HttpResponse<MerchantBackend.VersionResponse> {
   const { url, token } = useContext(BackendContext)
-  const { data, error } = useSWR<MerchantBackend.VersionResponse>(['/config', 
token, url], fetcher)
+  const { data, error } = useSWR<MerchantBackend.VersionResponse>(['/config', 
token, url], fetcher, {
+    shouldRetryOnError: false
+  })
 
   return { data, unauthorized: error?.status === 401, error }
 }
diff --git a/packages/frontend/src/hooks/notifications.ts 
b/packages/frontend/src/hooks/notifications.ts
index 2a3cb3f..c66594c 100644
--- a/packages/frontend/src/hooks/notifications.ts
+++ b/packages/frontend/src/hooks/notifications.ts
@@ -30,8 +30,8 @@ interface Result {
 
 type NotificationWithDate = Notification & { since: Date }
 
-export function useNotifications(timeout = 3000): Result {
-  const [notifications, setNotifications] = 
useState<(NotificationWithDate)[]>([])
+export function useNotifications(initial: Notification[] = [], timeout = 
3000): Result {
+  const [notifications, setNotifications] = 
useState<(NotificationWithDate)[]>(initial.map(i => ({...i, since: new Date() 
})))
 
   const pushNotification = (n: Notification): void => {
     const entry = { ...n, since: new Date() }
diff --git a/packages/frontend/src/i18n/index.ts 
b/packages/frontend/src/i18n/index.ts
index cdc6984..f497f81 100644
--- a/packages/frontend/src/i18n/index.ts
+++ b/packages/frontend/src/i18n/index.ts
@@ -118,13 +118,17 @@ export const translations = {
     },
     notification: {
       unauthorized: {
-        title: 'unauthorized access',
-        description: 'backend has denied access'
+        title: 'Could not access the backend',
+        description: 'backend has denied access, try using another token'
       },
       error: {
         title: 'Error query the backend',
         description: 'Got message: "{{error.message}}" from: {{backend}} 
(hasToken: {{hasToken}})'
       },
+      no_server: {
+        title: 'Could not access the backend',
+        description: `There was a problem trying to reach the backend. \n Got 
message: "{{error.message}}" from: {{backend}} (hasToken: {{hasToken}})`
+      },
       create_error: {
         title: 'create error',
         description: 'the create process went wrong, server says: 
{{info.hint}}'
diff --git a/packages/frontend/src/index.tsx b/packages/frontend/src/index.tsx
index 07d34ac..0b0b48c 100644
--- a/packages/frontend/src/index.tsx
+++ b/packages/frontend/src/index.tsx
@@ -22,7 +22,7 @@
 import "./scss/main.scss"
 
 import { h, VNode } from 'preact';
-import { useContext, useEffect } from "preact/hooks";
+import { StateUpdater, useCallback, useContext, useEffect, useState } from 
"preact/hooks";
 import { Route, Router, route } from 'preact-router';
 import { IntlProvider } from 'preact-i18n';
 
@@ -33,7 +33,7 @@ import { Notifications } from './components/notifications';
 import { translations } from './i18n';
 import { useBackendURL, useBackendDefaultToken, useLang, 
useBackendInstanceToken } from './hooks';
 import { useNotifications } from "./hooks/notifications";
-import { BackendContext } from './context/backend';
+import { BackendContext, ConfigContext, InstanceContext } from 
'./context/backend';
 import { useBackendConfig } from "./hooks/backend";
 
 import NotFoundPage from './routes/notfound';
@@ -66,38 +66,42 @@ function Redirect({ to }: { to: string }): null {
 
 function AppRouting(): VNode {
   const { notifications, pushNotification, removeNotification } = 
useNotifications()
-  const { lang, setLang, clearToken, changeBackend, updateToken } = 
useContext(BackendContext)
+  const { lang, setLang, changeBackend, updateToken } = 
useContext(BackendContext)
   const backendConfig = useBackendConfig();
 
-  const error = backendConfig.data || backendConfig.error
-
-  useEffect(() =>{
-    pushNotification({
-      messageId: 'error',
+  const LoginWithError = () => <Login
+    withMessage={{
+      messageId: 'no_server',
       type: 'ERROR',
-      params: error
-    })
-  }, [error, pushNotification])
+      params: !backendConfig.data ? backendConfig.error : {}
+    }}
+    onConfirm={(url: string, token?: string) => {
+      changeBackend(url)
+      if (token) updateToken(token)
+      route(RootPages.instances)
+    }}
+  />
+
+  const cleaner = useCallback(() =>{updateToken(undefined)},[])
+
+  const [cleaners, setCleaners] = useState([cleaner])
+  const addTokenCleaner = (c:() => void) => setCleaners(cs => [...cs,c])
+  const addTokenCleanerNemo = useCallback((c:() => void) 
=>{addTokenCleaner(c)},[cleaner])
 
   return <div id="app">
-    <NavigationBar lang={lang} setLang={setLang} onLogout={clearToken} />
-    <Sidebar />
-    <Notifications notifications={notifications} 
removeNotification={removeNotification} />
-    {!backendConfig.data ?
-      <Route default 
-        component={Login}
-
-        onConfirm={(url: string, token?: string) => {
-          changeBackend(url)
-          if (token) updateToken(token)
-          route(RootPages.instances)
-        }} /> :
-      <Route default component={AppReady} pushNotification={pushNotification} 
/>
-    }
+    <ConfigContext.Provider value={backendConfig.data || {}}>
+      <NavigationBar lang={lang} setLang={setLang} onLogout={() => { 
cleaners.forEach( c => c() ) }} />
+      <Sidebar />
+      <Notifications notifications={notifications} 
removeNotification={removeNotification} />
+      {!backendConfig.data ?
+        <Route default component={LoginWithError} /> :
+        <Route default component={AppReady} 
pushNotification={pushNotification} addTokenCleaner={addTokenCleanerNemo} />
+      }
+    </ConfigContext.Provider>
   </div>
 }
 
-function AppReady({ pushNotification }: { pushNotification: (n: Notification) 
=> void }): VNode {
+function AppReady({ pushNotification,addTokenCleaner }: { pushNotification: 
(n: Notification) => void, addTokenCleaner: any }): VNode {
   const { changeBackend, updateToken } = useContext(BackendContext)
 
   const updateLoginStatus = (url: string, token?: string) => {
@@ -119,7 +123,10 @@ function AppReady({ pushNotification }: { 
pushNotification: (n: Notification) =>
         route(`/instance/${id}/update`)
       }}
 
-      onUnauthorized={() => <Login onConfirm={updateLoginStatus} />}
+      onUnauthorized={() => <Login
+        withMessage={{ messageId: 'unauthorized', type: 'ERROR', }}
+        onConfirm={updateLoginStatus}
+      />}
 
       onError={(error: Error) => {
         pushNotification({ messageId: 'error', params: error, type: 'ERROR' })
@@ -141,7 +148,7 @@ function AppReady({ pushNotification }: { pushNotification: 
(n: Notification) =>
       }}
     />
 
-    <Route path={RootPages.instance_id_route} component={SubPages} 
pushNotification={pushNotification} />
+    <Route path={RootPages.instance_id_route} component={SubPages} 
pushNotification={pushNotification} addTokenCleaner={addTokenCleaner} />
 
     <Route default component={NotFoundPage} />
 
@@ -152,9 +159,8 @@ function useBackendContextState() {
   const [lang, setLang] = useLang()
   const [url, changeBackend] = useBackendURL();
   const [token, updateToken] = useBackendDefaultToken();
-  const clearToken = () => updateToken(undefined)
 
-  return { url, token, changeBackend, clearToken, updateToken, lang, setLang }
+  return { url, token, changeBackend, updateToken, lang, setLang }
 }
 
 export default function Application(): VNode {
@@ -170,52 +176,70 @@ export default function Application(): VNode {
 interface SubPagesProps {
   id: string;
   pushNotification: (n: Notification) => void;
+  addTokenCleaner: any;
 }
 
-function SubPages({ id, pushNotification }: SubPagesProps): VNode {
-  const [, updateToken] = useBackendInstanceToken(id);
+function SubPages({ id, pushNotification, addTokenCleaner }: SubPagesProps): 
VNode {
+  const [token, updateToken] = useBackendInstanceToken(id);
   const { changeBackend } = useContext(BackendContext)
 
+  const cleaner = useCallback(() =>{updateToken(undefined)},[id])
+
+  useEffect(() => {
+    addTokenCleaner(cleaner)
+  }, [addTokenCleaner, cleaner])
+
   const updateLoginStatus = (url: string, token?: string) => {
     changeBackend(url)
     if (token) updateToken(token)
   }
 
-  return <Router>
-    <Route path={InstancePages.details}
-      component={Details}
-      onUnauthorized={() => <Login onConfirm={updateLoginStatus} />}
-      onUpdate={() => {
-        route(`/instance/${id}/update`)
-      }}
-      onLoadError={(e: Error) => {
-        pushNotification({ messageId: 'update_load_error', type: 'ERROR', 
params: e })
-        route(`/instance/${id}/`)
-        return <div />
-      }}
-
-    />
-
-    <Route path={InstancePages.update}
-      component={Update}
-      onUnauthorized={() => <Login onConfirm={updateLoginStatus} />}
-      onLoadError={(e: Error) => {
-        pushNotification({ messageId: 'update_load_error', type: 'ERROR', 
params: e })
-        route(`/instance/${id}/`)
-        return <div />
-      }}
-      onBack={() => {
-        route(`/instance/${id}/`)
-      }}
-      onConfirm={() => {
-        pushNotification({ messageId: 'create_success', type: 'SUCCESS' })
-        route(`/instance/${id}/`)
-      }}
-      onUpdateError={(e: Error) => {
-        pushNotification({ messageId: 'update_error', type: 'ERROR', params: e 
})
-      }}
-    />
+  return <InstanceContext.Provider value={{id, token}}>
+    <Router>
+      <Route path={InstancePages.details}
+        component={Details}
+
+        onUnauthorized={() => <Login
+          withMessage={{ messageId: 'unauthorized', type: 'ERROR', }}
+          onConfirm={updateLoginStatus}
+        />}
+
+        onUpdate={() => {
+          route(`/instance/${id}/update`)
+        }}
+
+        onLoadError={(e: Error) => {
+          pushNotification({ messageId: 'update_load_error', type: 'ERROR', 
params: e })
+          route(`/instance/${id}/`)
+          return <div />
+        }}
+      />
+
+      <Route path={InstancePages.update}
+        component={Update}
+        onUnauthorized={() => <Login
+          withMessage={{ messageId: 'unauthorized', type: 'ERROR', }}
+          onConfirm={updateLoginStatus}
+        />}
+        onLoadError={(e: Error) => {
+          pushNotification({ messageId: 'update_load_error', type: 'ERROR', 
params: e })
+          route(`/instance/${id}/`)
+          return <div />
+        }}
+        onBack={() => {
+          route(`/instance/${id}/`)
+        }}
+        onConfirm={() => {
+          pushNotification({ messageId: 'create_success', type: 'SUCCESS' })
+          route(`/instance/${id}/`)
+        }}
+        onUpdateError={(e: Error) => {
+          pushNotification({ messageId: 'update_error', type: 'ERROR', params: 
e })
+        }}
+      />
+
+      <Route default component={NotFoundPage} />
+    </Router>
+  </InstanceContext.Provider>
 
-    <Route default component={NotFoundPage} />
-  </Router>
 }
\ No newline at end of file
diff --git a/packages/frontend/src/routes/instances/details/DetailPage.tsx 
b/packages/frontend/src/routes/instances/details/DetailPage.tsx
index f4ab4a7..38c89d2 100644
--- a/packages/frontend/src/routes/instances/details/DetailPage.tsx
+++ b/packages/frontend/src/routes/instances/details/DetailPage.tsx
@@ -30,7 +30,6 @@ interface Props {
   onUpdate: () => void;
   onDelete: () => void;
   selected: MerchantBackend.Instances.QueryInstancesResponse;
-  id: string,
   isLoading: boolean;
 }
 
diff --git a/packages/frontend/src/routes/instances/details/index.tsx 
b/packages/frontend/src/routes/instances/details/index.tsx
index 177278d..ab19342 100644
--- a/packages/frontend/src/routes/instances/details/index.tsx
+++ b/packages/frontend/src/routes/instances/details/index.tsx
@@ -1,7 +1,8 @@
 import { Fragment, h, VNode } from "preact";
-import { useState } from "preact/hooks";
+import { useContext, useState } from "preact/hooks";
+import { InstanceContext } from "../../../context/backend";
 import { Notification } from "../../../declaration";
-import { useBackendInstance, useBackendMutateAPI } from 
"../../../hooks/backend";
+import { useBackendInstance, useBackendInstanceMutateAPI } from 
"../../../hooks/backend";
 import { DeleteModal } from "../list/DeleteModal";
 import { DetailPage } from "./DetailPage";
 
@@ -9,15 +10,15 @@ interface Props {
   onUnauthorized: () => VNode;
   onLoadError: (e: Error) => VNode;
   onUpdate: () => void;
-  id: string;
   pushNotification: (n: Notification) => void;
 }
 
-export default function Detail({ onUpdate, onLoadError, onUnauthorized, id, 
pushNotification }: Props): VNode {
-  const details = useBackendInstance(id)
+export default function Detail({ onUpdate, onLoadError, onUnauthorized, 
pushNotification }: Props): VNode {
+  const { id } = useContext(InstanceContext)
+  const details = useBackendInstance()
   const [deleting, setDeleting] = useState<boolean>(false)
 
-  const { deleteInstance } = useBackendMutateAPI()
+  const { deleteInstance } = useBackendInstanceMutateAPI()
 
   if (!details.data) {
     if (details.unauthorized) return onUnauthorized()
@@ -30,16 +31,16 @@ export default function Detail({ onUpdate, onLoadError, 
onUnauthorized, id, push
   return <Fragment>
     <DetailPage
       isLoading={false}
-      selected={details.data} id={id}
+      selected={details.data} 
       onUpdate={onUpdate}
       onDelete={() => setDeleting(true) }
     />
     {deleting && <DeleteModal 
       element={{name: details.data.name, id }} 
       onCancel={() => setDeleting(false) } 
-      onConfirm={async (id: string): Promise<void> => {
+      onConfirm={async (): Promise<void> => {
         try {
-          await deleteInstance(id)
+          await deleteInstance()
           pushNotification({ messageId: 'delete_success', type: 'SUCCESS' })
         } catch (error) {
           pushNotification({ messageId: 'delete_error', type: 'ERROR', params: 
error })
diff --git a/packages/frontend/src/routes/instances/list/index.tsx 
b/packages/frontend/src/routes/instances/list/index.tsx
index b9eedc9..f63e05e 100644
--- a/packages/frontend/src/routes/instances/list/index.tsx
+++ b/packages/frontend/src/routes/instances/list/index.tsx
@@ -21,7 +21,7 @@
 
 import { Fragment, h, VNode } from 'preact';
 import { View } from './View';
-import { useBackendInstances, useBackendMutateAPI } from 
'../../../hooks/backend';
+import { useBackendInstances, useBackendInstanceMutateAPI } from 
'../../../hooks/backend';
 import { useState } from 'preact/hooks';
 import { MerchantBackend, Notification } from '../../../declaration';
 import { DeleteModal } from './DeleteModal';
@@ -36,53 +36,16 @@ interface Props {
 export default function Instances({ pushNotification, onUnauthorized, onError, 
onCreate, onUpdate }: Props): VNode {
   const list = useBackendInstances()
   const [deleting, setDeleting] = useState<MerchantBackend.Instances.Instance 
| null>(null)
-  // const details = useBackendInstance(selectedId)
-  // const [create, setCreate] = useState<boolean>(false)
-  // const [update, setUpdate] = useState<boolean>(false)
-  const { deleteInstance } = useBackendMutateAPI()
+  const { deleteInstance } = useBackendInstanceMutateAPI()
 
-  // || (selectedId != null && !details.data && details.unauthorized)
   const isLoadingTheList = (!list.data && !list.error)
-  // const isLoadingTheDetails = (!details.data && !details.error)
   const error = !list.data && list.error
-  // || !details.data && details.error
 
   if (!list.data) {
     if (list.unauthorized) return onUnauthorized()
     if (list.error) return onError(list.error)    
   }
 
-  // if (create) {
-  //   return <CreatePage
-  //     goBack={() => setCreate(false)}
-  //     isLoading={false}
-
-  //     onCreate={(d): Promise<void> => list.create(d)
-  //       .then((): void => pushNotification({ messageId: 'create_success', 
type: 'SUCCESS' }))
-  //       .catch((error): void => pushNotification({ messageId: 
'create_error', type: 'ERROR', params: error }))
-  //     }
-  //   />
-  // }
-
-  // if (update && details.data && selectedId) {
-  //   return <UpdatePage
-  //     goBack={() => setUpdate(false)}
-  //     isLoading={false}
-  //     selected={{ ...details.data, id: selectedId }}
-  //     onUpdate={(id, d): Promise<void> => details.update(id, d)
-  //       .then((): void => pushNotification({ messageId: 'update_success', 
type: 'SUCCESS' }))
-  //       .catch((error): void => pushNotification({ messageId: 
'update_error', type: 'ERROR', params: error }))
-  //     }
-  //   />
-  // }
-  // {selected && action === 'DELETE' ?
-
-  // : null}
-
-  // (id): Promise<void> => deleteInstance(id)
-  // .then((): void => pushNotification({ messageId: 'delete_success', type: 
'SUCCESS' }))
-  // .catch((error): void => pushNotification({ messageId: 'delete_error', 
type: 'ERROR', params: error }))
-
   return <Fragment>
     <View instances={list.data?.instances || []}
       isLoading={isLoadingTheList}
@@ -94,9 +57,9 @@ export default function Instances({ pushNotification, 
onUnauthorized, onError, o
     {deleting && <DeleteModal 
       element={deleting} 
       onCancel={() => setDeleting(null) } 
-      onConfirm={async (id: string): Promise<void> => {
+      onConfirm={async (): Promise<void> => {
         try {
-          await deleteInstance(id)
+          await deleteInstance()
           pushNotification({ messageId: 'delete_success', type: 'SUCCESS' })
         } catch (e) {
           pushNotification({ messageId: 'delete_error', type: 'ERROR', params: 
error })
diff --git a/packages/frontend/src/routes/instances/update/UpdatePage.tsx 
b/packages/frontend/src/routes/instances/update/UpdatePage.tsx
index f99f797..54c157f 100644
--- a/packages/frontend/src/routes/instances/update/UpdatePage.tsx
+++ b/packages/frontend/src/routes/instances/update/UpdatePage.tsx
@@ -28,9 +28,8 @@ import { InstanceUpdateSchema as schema } from 
'../../../schemas'
 import { Text } from "preact-i18n";
 
 interface Props {
-  onUpdate: (id: string, d: 
MerchantBackend.Instances.InstanceReconfigurationMessage) => void;
+  onUpdate: (d: MerchantBackend.Instances.InstanceReconfigurationMessage) => 
void;
   selected: MerchantBackend.Instances.QueryInstancesResponse;
-  id: string,
   isLoading: boolean;
   onBack: () => void;
 }
@@ -50,14 +49,14 @@ function convert(from: 
MerchantBackend.Instances.QueryInstancesResponse): Mercha
   return { ...defaults, ...rest, payto_uris };
 }
 
-export function UpdatePage({ onUpdate, isLoading, selected, id, onBack }: 
Props): VNode {
+export function UpdatePage({ onUpdate, isLoading, selected, onBack }: Props): 
VNode {
   const [value, valueHandler] = useState(convert(selected))
   const [errors, setErrors] = useState<KeyValue>({})
 
   const submit = (): void => {
     try {
       schema.validateSync(value, { abortEarly: false })
-      onUpdate(id, schema.cast(value));
+      onUpdate(schema.cast(value));
       onBack()
     } catch (err) {
       const errors = err.inner as yup.ValidationError[]
diff --git a/packages/frontend/src/routes/instances/update/index.tsx 
b/packages/frontend/src/routes/instances/update/index.tsx
index 8147ff8..3afe7c5 100644
--- a/packages/frontend/src/routes/instances/update/index.tsx
+++ b/packages/frontend/src/routes/instances/update/index.tsx
@@ -1,6 +1,6 @@
 import { h, VNode } from "preact";
 import { MerchantBackend } from "../../../declaration";
-import { useBackendInstance, useBackendMutateAPI } from 
"../../../hooks/backend";
+import { useBackendInstance, useBackendInstanceMutateAPI } from 
"../../../hooks/backend";
 import { UpdatePage } from "./UpdatePage";
 
 interface Props {
@@ -12,12 +12,11 @@ interface Props {
   onLoadError: (e: Error) => VNode;
   onUpdateError: (e: Error) => void;
 
-  id: string;
 }
 
-export default function Update({ onBack, onConfirm, onLoadError, 
onUpdateError, onUnauthorized, id }: Props): VNode {
-  const { updateInstance } = useBackendMutateAPI();
-  const details = useBackendInstance(id)
+export default function Update({ onBack, onConfirm, onLoadError, 
onUpdateError, onUnauthorized }: Props): VNode {
+  const { updateInstance } = useBackendInstanceMutateAPI();
+  const details = useBackendInstance()
 
   if (!details.data) {
     if (details.unauthorized) return onUnauthorized()
@@ -30,8 +29,8 @@ export default function Update({ onBack, onConfirm, 
onLoadError, onUpdateError,
   return <UpdatePage 
     onBack={onBack}
     isLoading={false}
-    selected={details.data} id={id}
-    onUpdate={(id: string, d: 
MerchantBackend.Instances.InstanceReconfigurationMessage): Promise<void> => {
-      return updateInstance(id, d).then(onConfirm).catch(onUpdateError)
+    selected={details.data}
+    onUpdate={(d: MerchantBackend.Instances.InstanceReconfigurationMessage): 
Promise<void> => {
+      return updateInstance(d).then(onConfirm).catch(onUpdateError)
   }} />
 }
\ No newline at end of file
diff --git a/packages/frontend/src/routes/login/index.tsx 
b/packages/frontend/src/routes/login/index.tsx
index 1651bf7..b7aa67a 100644
--- a/packages/frontend/src/routes/login/index.tsx
+++ b/packages/frontend/src/routes/login/index.tsx
@@ -1,9 +1,11 @@
 import { h, VNode } from "preact";
 import { LoginModal } from '../../components/auth';
+import { Notification } from "../../declaration";
 
 interface Props {
+  withMessage?: Notification;
   onConfirm: (url: string, token?: string) => void;
 }
-export default function LoginPage({onConfirm}: Props):VNode {
-  return <LoginModal onConfirm={onConfirm} />
+export default function LoginPage({ onConfirm, withMessage }: Props): VNode {
+  return <LoginModal onConfirm={onConfirm} withMessage={withMessage} />
 } 
\ No newline at end of file
diff --git a/packages/frontend/tests/hooks/notification.test.ts 
b/packages/frontend/tests/hooks/notification.test.ts
index 1fd248f..e70cdd2 100644
--- a/packages/frontend/tests/hooks/notification.test.ts
+++ b/packages/frontend/tests/hooks/notification.test.ts
@@ -28,7 +28,7 @@ test('notification should disapear after timeout', () => {
   jest.spyOn(global, 'setTimeout');
 
   const timeout = 1000
-  const { result, rerender } = renderHook(() => useNotifications(timeout));
+  const { result, rerender } = renderHook(() => useNotifications(undefined, 
timeout));
 
   expect(result.current?.notifications.length).toBe(0);
 

-- 
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]