[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] 01/02: refactor navigator, part 3
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] 01/02: refactor navigator, part 3 |
Date: |
Tue, 16 Mar 2021 14:40:33 +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 b63efaaed60b46d911ec64df31485b913af0a7d1
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Mar 15 10:42:58 2021 -0300
refactor navigator, part 3
---
CHANGELOG.md | 6 +-
packages/frontend/src/AdminRoutes.tsx | 105 +--------------------
packages/frontend/src/ApplicationReadyRoutes.tsx | 24 ++---
packages/frontend/src/InstanceRoutes.tsx | 102 +++++++++++++++-----
packages/frontend/src/components/menu/SideBar.tsx | 48 +++++-----
packages/frontend/src/components/menu/index.tsx | 2 +-
packages/frontend/src/index.tsx | 8 +-
packages/frontend/src/routes/admin/list/index.tsx | 19 +++-
.../src/routes/instance/orders/list/Table.tsx | 2 +-
packages/frontend/tests/header.test.tsx | 2 +-
10 files changed, 139 insertions(+), 179 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a67e119..f4422d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,10 @@ The format is based on [Keep a
Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html).
## [Future work]
+ - change the admin title to "instances" if we are listing the instances and
"settings: $ID" on updating instances (#6790)
+ - update title with: Taler Backoffice: $PAGE_TITLE (#6790)
- notifications should tale place between title and content, and not disapear
(#6788)
+ - if there is enough space for tables in mobile, make the scrollables (#6789)
- complete product list information (#6792)
- complete order list information (#6793)
- gettext templates should be generated from the source code (#6791)
@@ -33,8 +36,9 @@ and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0
- create default instance if it is not already
- - confirmation page when creating instances
+ - /o => /orders
+ /orders/$ORDER_ID
main action => refund
exchange errors
diff --git a/packages/frontend/src/AdminRoutes.tsx
b/packages/frontend/src/AdminRoutes.tsx
index b8da7cf..7eca0e6 100644
--- a/packages/frontend/src/AdminRoutes.tsx
+++ b/packages/frontend/src/AdminRoutes.tsx
@@ -15,51 +15,27 @@
*/
import { h, VNode } from "preact";
import Router, { route, Route } from "preact-router";
-import { Redirect } from "./index";
-import { MerchantBackend } from "./declaration";
import { useMessageTemplate } from "preact-messages";
import { Notification } from "./utils/types";
-import { InstancePaths, InstanceRoutes } from "./InstanceRoutes";
import InstanceListPage from './routes/admin/list';
import InstanceCreatePage from "./routes/admin/create";
import NotFoundPage from './routes/notfound';
-import ProductListPage from './routes/instance/products/list'
-import ProductCreatePage from './routes/instance/products/create'
-import ProductUpdatePage from './routes/instance/products/update'
-
-import OrderListPage from './routes/instance/orders/list'
-import OrderCreatePage from './routes/instance/orders/create'
-import OrderUpdatePage from './routes/instance/orders/update'
-
-import TipListPage from './routes/instance/tips/list'
-import TipCreatePage from './routes/instance/tips/create'
-import TipUpdatePage from './routes/instance/tips/update'
-
-import TransferListPage from './routes/instance/transfers/list'
-import TransferCreatePage from './routes/instance/transfers/create'
-import LoginPage from "./routes/login";
-import { SwrError } from "./hooks/backend";
-
export enum AdminPaths {
- root = '/',
list_instances = '/instances',
- new_instance = '/new',
+ new_instance = '/instance/new',
instance_id_route = '/instance/:id/:rest*',
}
interface Props {
pushNotification: (n: Notification) => void;
- instances: MerchantBackend.Instances.Instance[]
+ // instances: MerchantBackend.Instances.Instance[]
}
-export function AdminRoutes({ instances, pushNotification }: Props): VNode {
+export function AdminRoutes({ pushNotification }: Props): VNode {
const i18n = useMessageTemplate();
- const updateLoginStatus = () => null;
-
return <Router>
- <Route path={AdminPaths.root} component={Redirect}
to={AdminPaths.list_instances} />
<Route path={AdminPaths.list_instances} component={InstanceListPage}
@@ -67,8 +43,6 @@ export function AdminRoutes({ instances, pushNotification }:
Props): VNode {
route(AdminPaths.new_instance);
}}
- instances={instances}
-
onUpdate={(id: string): void => {
route(`/instance/${id}/update`);
}}
@@ -90,78 +64,7 @@ export function AdminRoutes({ instances, pushNotification }:
Props): VNode {
/>
- <Route path={AdminPaths.instance_id_route} component={InstanceRoutes}
- pushNotification={pushNotification}
- parent="/instance/:id"
- />
-
- <Route path={InstancePaths.product_list}
- component={ProductListPage}
- onUnauthorized={() => <LoginPage
- withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
-
- onLoadError={(error: SwrError) => <LoginPage
- withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
- />
- <Route path={InstancePaths.product_update}
- component={ProductUpdatePage}
- />
- <Route path={InstancePaths.product_new}
- component={ProductCreatePage}
- />
-
- <Route path={InstancePaths.order_list}
- component={OrderListPage}
- onUnauthorized={() => <LoginPage
- withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
-
- onLoadError={(error: SwrError) => <LoginPage
- withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
- />
- <Route path={InstancePaths.order_update}
- component={OrderUpdatePage}
- />
- <Route path={InstancePaths.order_new}
- component={OrderCreatePage}
- />
-
- <Route path={InstancePaths.tips_list}
- component={TipListPage}
- onUnauthorized={() => <LoginPage
- withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
-
- onLoadError={(error: SwrError) => <LoginPage
- withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
- />
- <Route path={InstancePaths.tips_update}
- component={TipUpdatePage}
- />
- <Route path={InstancePaths.tips_new}
- component={TipCreatePage}
- />
-
- <Route path={InstancePaths.transfers_list}
- component={TransferListPage}
- onUnauthorized={() => <LoginPage
- withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
-
- onLoadError={(error: SwrError) => <LoginPage
- withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
- onConfirm={updateLoginStatus} />}
- />
- <Route path={InstancePaths.transfers_new}
- component={TransferCreatePage}
- />
-
-
- <Route default component={NotFoundPage} />
+ {/* <Route default component={undefined} /> */}
</Router>
}
\ No newline at end of file
diff --git a/packages/frontend/src/ApplicationReadyRoutes.tsx
b/packages/frontend/src/ApplicationReadyRoutes.tsx
index 6aff0fb..5f85a21 100644
--- a/packages/frontend/src/ApplicationReadyRoutes.tsx
+++ b/packages/frontend/src/ApplicationReadyRoutes.tsx
@@ -26,7 +26,7 @@ import { useBackendInstances } from "./hooks/backend";
import { InstanceRoutes } from "./InstanceRoutes";
import LoginPage from './routes/login';
import { INSTANCE_ID_LOOKUP } from './utils/constants';
-import { Menu } from './components/menu';
+import { NotYetReadyAppMenu, Menu } from './components/menu';
import { AdminRoutes } from './AdminRoutes';
import { useMessageTemplate } from 'preact-messages';
interface Props {
@@ -45,7 +45,7 @@ export function ApplicationReadyRoutes({ pushNotification }:
Props): VNode {
if (!list.data) {
if (list.unauthorized) {
return <Fragment>
- <Menu title="Login" onLogout={() => {
+ <NotYetReadyAppMenu title="Login" onLogout={() => {
clearAllTokens();
route('/')
}} />
@@ -63,7 +63,7 @@ export function ApplicationReadyRoutes({ pushNotification }:
Props): VNode {
// query to /config is ok but the URL
// doest not match with our pattern
return <Fragment>
- <Menu title="Error" onLogout={() => {
+ <NotYetReadyAppMenu title="Error" onLogout={() => {
clearAllTokens();
route('/')
}} />
@@ -73,21 +73,19 @@ export function ApplicationReadyRoutes({ pushNotification
}: Props): VNode {
/>
</Fragment>
}
+
return <Fragment>
<Menu instance={match[1]} onLogout={() => {
clearAllTokens();
route('/')
}} />
- <InstanceRoutes
- id={match[1]}
- pushNotification={pushNotification}
- />
+ <InstanceRoutes id={match[1]} pushNotification={pushNotification} />
</Fragment>
}
-
+
if (list.error) {
return <Fragment>
- <Menu title="Error" />
+ <NotYetReadyAppMenu title="Error" />
<LoginPage
withMessage={{ message: i18n`Couldnt access the server`, description:
list.error.message, type: 'ERROR', }}
onConfirm={updateLoginStatus}
@@ -96,16 +94,14 @@ export function ApplicationReadyRoutes({ pushNotification
}: Props): VNode {
}
// is loading
- return <Menu />
+ return <NotYetReadyAppMenu title="Loading..." />
}
return <Fragment>
- <Menu onLogout={() => {
+ <Menu instance="default" admin onLogout={() => {
clearAllTokens();
route('/')
}} />
- <AdminRoutes instances={list.data.instances}
- pushNotification={pushNotification}
- />
+ <InstanceRoutes admin id="default" pushNotification={pushNotification} />
</Fragment>
}
diff --git a/packages/frontend/src/InstanceRoutes.tsx
b/packages/frontend/src/InstanceRoutes.tsx
index a0db055..9a8f3f0 100644
--- a/packages/frontend/src/InstanceRoutes.tsx
+++ b/packages/frontend/src/InstanceRoutes.tsx
@@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { h, VNode } from 'preact';
+import { Fragment, h, VNode } from 'preact';
import { useCallback, useEffect, useMemo } from "preact/hooks";
import { Route, Router, route } from 'preact-router';
import { useMessageTemplate } from 'preact-messages';
@@ -47,34 +47,45 @@ import TipUpdatePage from './routes/instance/tips/update'
import TransferListPage from './routes/instance/transfers/list'
import TransferCreatePage from './routes/instance/transfers/create'
+// import { AdminRoutes } from './AdminRoutes';
+import InstanceListPage from './routes/admin/list';
+import InstanceCreatePage from "./routes/admin/create";
export enum InstancePaths {
details = '/',
update = '/update',
- product_list = '/p',
- product_update = '/p/:pid/update',
- product_new = '/p/new',
+ product_list = '/products',
+ product_update = '/product/:pid/update',
+ product_new = '/product/new',
- order_list = '/o',
+ order_list = '/orders',
order_update = '/p/:oid/update',
order_new = '/o/new',
- tips_list = '/r',
- tips_update = '/r/:rid/update',
- tips_new = '/r/new',
+ tips_list = '/tips',
+ tips_update = '/tip/:rid/update',
+ tips_new = '/tip/new',
- transfers_list = '/t',
- transfers_new = '/t/new',
+ transfers_list = '/transfers',
+ transfers_new = '/transfer/new',
+}
+
+export enum AdminPaths {
+ list_instances = '/instances',
+ new_instance = '/instance/new',
+ instance_id_route = '/instance/:id/:rest*',
}
export interface Props {
id: string;
pushNotification: (n: Notification) => void;
- parent?: string;
+ admin?: boolean;
}
-export function InstanceRoutes({ id, pushNotification, parent }: Props): VNode
{
+const rootPath = typeof window !== 'undefined' ? window.location.pathname : '/'
+
+export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode {
const [token, updateToken] = useBackendInstanceToken(id);
const { changeBackend, addTokenCleaner } = useBackendContext();
const cleaner = useCallback(() => { updateToken(undefined); }, [id]);
@@ -90,11 +101,50 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
updateToken(token);
};
- const value = useMemo(() => ({ id, token, admin: !!parent }), [id, token])
+ const value = useMemo(() => ({ id, token, admin }), [id, token])
return <InstanceContextProvider value={value}>
<Router>
- <Route path={(!parent ? "" : parent) + InstancePaths.details}
+ {admin &&
+ <Route path={rootPath + AdminPaths.list_instances}
component={InstanceListPage}
+
+ onCreate={() => {
+ route(AdminPaths.new_instance);
+ }}
+
+ onUpdate={(id: string): void => {
+ route(`/instance/${id}/update`);
+ }}
+
+ onUnauthorized={() => <LoginPage
+ withMessage={{ message: i18n`Access denied`, description:
i18n`Check your token is valid`, type: 'ERROR', }}
+ onConfirm={updateLoginStatus} />}
+
+ onLoadError={(error: SwrError) => <LoginPage
+ withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
+ onConfirm={updateLoginStatus} />}
+
+ />
+ }
+
+ {admin &&
+ <Route path={rootPath + AdminPaths.new_instance}
component={InstanceCreatePage}
+
+ onBack={() => route(AdminPaths.list_instances)}
+
+ onConfirm={() => {
+ pushNotification({ message: i18n`create_success`, type: 'SUCCESS'
});
+ route(AdminPaths.list_instances);
+ }}
+
+ onError={(error: any) => {
+ pushNotification({ message: i18n`create_error`, type: 'ERROR' });
+ }}
+
+ />
+ }
+
+ <Route path={rootPath + InstancePaths.details}
component={DetailPage}
onUnauthorized={() => <LoginPage
@@ -106,7 +156,7 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
onConfirm={updateLoginStatus} />}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.update}
+ <Route path={rootPath + InstancePaths.update}
component={InstanceUpdatePage}
onUnauthorized={() => <LoginPage
@@ -131,7 +181,7 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
}}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.product_list}
+ <Route path={rootPath + InstancePaths.product_list}
component={ProductListPage}
onUnauthorized={() => <LoginPage
withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
@@ -141,14 +191,14 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
onConfirm={updateLoginStatus} />}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.product_update}
+ <Route path={rootPath + InstancePaths.product_update}
component={ProductUpdatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.product_new}
+ <Route path={rootPath + InstancePaths.product_new}
component={ProductCreatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.order_list}
+ <Route path={rootPath + InstancePaths.order_list}
component={OrderListPage}
onUnauthorized={() => <LoginPage
withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
@@ -158,14 +208,14 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
onConfirm={updateLoginStatus} />}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.order_update}
+ <Route path={rootPath + InstancePaths.order_update}
component={OrderUpdatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.order_new}
+ <Route path={rootPath + InstancePaths.order_new}
component={OrderCreatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.tips_list}
+ <Route path={rootPath + InstancePaths.tips_list}
component={TipListPage}
onUnauthorized={() => <LoginPage
withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
@@ -175,14 +225,14 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
onConfirm={updateLoginStatus} />}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.tips_update}
+ <Route path={rootPath + InstancePaths.tips_update}
component={TipUpdatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.tips_new}
+ <Route path={rootPath + InstancePaths.tips_new}
component={TipCreatePage}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.transfers_list}
+ <Route path={rootPath + InstancePaths.transfers_list}
component={TransferListPage}
onUnauthorized={() => <LoginPage
withMessage={{ message: i18n`Access denied`, description: i18n`Check
your token is valid`, type: 'ERROR', }}
@@ -192,7 +242,7 @@ export function InstanceRoutes({ id, pushNotification,
parent }: Props): VNode {
withMessage={{ message: i18n`Problem reaching the server`,
description: i18n`Got message: ${error.message} from: ${error.backend}
(hasToken: ${error.hasToken})`, type: 'ERROR', }}
onConfirm={updateLoginStatus} />}
/>
- <Route path={(!parent ? "" : parent) + InstancePaths.transfers_new}
+ <Route path={rootPath + InstancePaths.transfers_new}
component={TransferCreatePage}
/>
diff --git a/packages/frontend/src/components/menu/SideBar.tsx
b/packages/frontend/src/components/menu/SideBar.tsx
index 919d547..f4000c1 100644
--- a/packages/frontend/src/components/menu/SideBar.tsx
+++ b/packages/frontend/src/components/menu/SideBar.tsx
@@ -28,10 +28,11 @@ import { LangSelector } from './LangSelector';
interface Props {
onLogout: () => void;
mobile?: boolean;
- instance?: string;
+ instance: string;
+ admin?: boolean;
}
-export function Sidebar({ mobile, instance, onLogout }: Props): VNode {
+export function Sidebar({ mobile, instance, onLogout, admin }: Props): VNode {
const config = useConfigContext();
const backend = useBackendContext();
@@ -47,47 +48,34 @@ export function Sidebar({ mobile, instance, onLogout }:
Props): VNode {
</div>
</div>
<div class="menu is-menu-main">
- {!instance && <Fragment>
- <p class="menu-label">General</p>
- <ul class="menu-list">
- <li>
- <a href="/" class="is-active router-link-active has-icon">
- <span class="icon"><i class="mdi mdi-desktop-mac" /></span>
- <span class="menu-item-label">Instances</span>
- </a>
- </li>
- </ul>
- </Fragment>}
<p class="menu-label">Instance</p>
<ul class="menu-list">
- {instance && <Fragment>
- <li>
- <a href="/update" class="has-icon">
- <span class="icon"><i class="mdi mdi-square-edit-outline"
/></span>
- <span class="menu-item-label">Settings</span>
- </a>
- </li>
- </Fragment>}
<li>
- <a href="/o" class="has-icon">
+ <a href="/update" class="has-icon">
+ <span class="icon"><i class="mdi mdi-square-edit-outline"
/></span>
+ <span class="menu-item-label">Settings</span>
+ </a>
+ </li>
+ <li>
+ <a href="/orders" class="has-icon">
<span class="icon"><i class="mdi mdi-cash-register" /></span>
<span class="menu-item-label">Orders</span>
</a>
</li>
<li>
- <a href="/p" class="has-icon">
- <span class="icon"><i class="mdi mdi-shopping" /></span>
+ <a href="/products" class="has-icon">
+ <span class="icon"><i class="mdi mdi-mdi-shopping" /></span>
<span class="menu-item-label">Products</span>
</a>
</li>
<li>
- <a href="/t" class="has-icon">
+ <a href="/transfers" class="has-icon">
<span class="icon"><i class="mdi mdi-bank" /></span>
<span class="menu-item-label">Transfers</span>
</a>
</li>
<li>
- <a href="/r" class="has-icon">
+ <a href="/tips" class="has-icon">
<span class="icon"><i class="mdi mdi-cash" /></span>
<span class="menu-item-label">Tips</span>
</a>
@@ -117,6 +105,14 @@ export function Sidebar({ mobile, instance, onLogout }:
Props): VNode {
</span>
</div>
</li>
+ {admin &&
+ <li>
+ <a href="/instance/new" class="has-icon">
+ <span class="icon"><i class="mdi mdi-plus" /></span>
+ <span class="menu-item-label">New Instance</span>
+ </a>
+ </li>
+ }
<li>
<a class="has-icon is-state-info is-hoverable" onClick={(): void
=> onLogout()}>
<span class="icon"><i class="mdi mdi-logout default" /></span>
diff --git a/packages/frontend/src/components/menu/index.tsx
b/packages/frontend/src/components/menu/index.tsx
index f3fe639..8396967 100644
--- a/packages/frontend/src/components/menu/index.tsx
+++ b/packages/frontend/src/components/menu/index.tsx
@@ -98,4 +98,4 @@
</div>
}
-
\ No newline at end of file
+
diff --git a/packages/frontend/src/index.tsx b/packages/frontend/src/index.tsx
index dd6916d..c21c7c2 100644
--- a/packages/frontend/src/index.tsx
+++ b/packages/frontend/src/index.tsx
@@ -36,7 +36,7 @@ import { hasKey, onTranslationError } from
"./utils/functions";
import LoginPage from './routes/login';
import { ApplicationReadyRoutes } from "./ApplicationReadyRoutes";
-import { Menu } from "./components/menu";
+import { NotYetReadyAppMenu } from "./components/menu";
export function Redirect({ to }: { to: string }): null {
useEffect(() => {
@@ -68,7 +68,7 @@ function ApplicationStatusRoutes(): VNode {
if (!triedToLog) {
return <div id="app">
- <Menu title="Welcome!" />
+ <NotYetReadyAppMenu title="Welcome!" />
<LoginPage
onConfirm={(url: string, token?: string) => {
changeBackend(url)
@@ -85,7 +85,7 @@ function ApplicationStatusRoutes(): VNode {
if (backendConfig.unauthorized) {
return <div id="app">
- <Menu title="Login" />
+ <NotYetReadyAppMenu title="Login" />
<LoginPage
onConfirm={(url: string, token?: string) => {
changeBackend(url)
@@ -97,7 +97,7 @@ function ApplicationStatusRoutes(): VNode {
}
return <div id="app">
- <Menu title="Error" />
+ <NotYetReadyAppMenu title="Error" />
<LoginPage
withMessage={{
message: i18n`Couldnt access the server`,
diff --git a/packages/frontend/src/routes/admin/list/index.tsx
b/packages/frontend/src/routes/admin/list/index.tsx
index 19e3696..0fe63ab 100644
--- a/packages/frontend/src/routes/admin/list/index.tsx
+++ b/packages/frontend/src/routes/admin/list/index.tsx
@@ -21,7 +21,7 @@
import { Fragment, h, VNode } from 'preact';
import { View } from './View';
-import { useAdminMutateAPI } from '../../../hooks/backend';
+import { SwrError, useAdminMutateAPI, useBackendInstances } from
'../../../hooks/backend';
import { useState } from 'preact/hooks';
import { MerchantBackend } from '../../../declaration';
import { Notification } from '../../../utils/types';
@@ -31,15 +31,26 @@ interface Props {
pushNotification: (n: Notification) => void;
onCreate: () => void;
onUpdate: (id: string) => void;
- instances: MerchantBackend.Instances.Instance[]
+ instances: MerchantBackend.Instances.Instance[];
+ onUnauthorized: () => VNode;
+ onLoadError: (e: SwrError) => VNode;
}
-export default function Instances({ pushNotification, instances, onCreate,
onUpdate }: Props): VNode {
+export default function Instances({ pushNotification, onUnauthorized,
onLoadError, onCreate, onUpdate }: Props): VNode {
+ const result = useBackendInstances()
const [deleting, setDeleting] = useState<MerchantBackend.Instances.Instance
| null>(null)
const { deleteInstance } = useAdminMutateAPI()
+ if (!result.data) {
+ if (result.unauthorized) return onUnauthorized()
+ if (result.error) return onLoadError(result.error)
+ return <div>
+ loading ....
+ </div>
+ }
+
return <Fragment>
- <View instances={instances}
+ <View instances={result.data.instances}
isLoading={false}
onDelete={setDeleting}
onCreate={onCreate}
diff --git a/packages/frontend/src/routes/instance/orders/list/Table.tsx
b/packages/frontend/src/routes/instance/orders/list/Table.tsx
index f96f683..f2d9915 100644
--- a/packages/frontend/src/routes/instance/orders/list/Table.tsx
+++ b/packages/frontend/src/routes/instance/orders/list/Table.tsx
@@ -26,7 +26,7 @@ import { MerchantBackend, WidthId } from
"../../../../declaration"
import { Actions, buildActions } from "../../../../utils/table";
type Entity = MerchantBackend.Orders.OrderHistoryEntry & { id: string }
- interface Props {
+interface Props {
instances: Entity[];
onUpdate: (id: string) => void;
onDelete: (id: Entity) => void;
diff --git a/packages/frontend/tests/header.test.tsx
b/packages/frontend/tests/header.test.tsx
index f163960..e510571 100644
--- a/packages/frontend/tests/header.test.tsx
+++ b/packages/frontend/tests/header.test.tsx
@@ -31,7 +31,7 @@ describe('Initial Test of the Sidebar', () => {
})
test('Sidbar renders anchors with text', () => {
- const context = shallow(<Sidebar onLogout={() => {}} />);
+ const context = shallow(<Sidebar instance="default" onLogout={() =>
{}} />);
expect(context.find('a').map( a => a.text())).toEqual(["Instances",
"Details", "Orders", "Inventory", "Tipping", "Log out"]);
});
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.