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