merchant-backoffice

ZZZ: Inactive/Deprecated
Log | Files | Refs | Submodules | README

commit 36095f3ffcfbc872b95438aeea6d7b8c00c884ad
parent b38595a7114174038a195cbf70449123a07b9cda
Author: Sebastian <sebasjm@gmail.com>
Date:   Tue, 16 Mar 2021 15:00:36 -0300

routing pages without changing path url

Diffstat:
Mpackages/frontend/package.json | 2++
Mpackages/frontend/src/ApplicationReadyRoutes.tsx | 1-
Mpackages/frontend/src/InstanceRoutes.tsx | 37+++++++++++++++++++------------------
Mpackages/frontend/src/components/menu/SideBar.tsx | 2+-
Mpackages/frontend/src/hooks/index.ts | 13+++++++++++--
Mpackages/frontend/src/paths/admin/list/Table.tsx | 4+++-
Mpnpm-lock.yaml | 37+++++++++++++++++++++++++++++++++++--
7 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/packages/frontend/package.json b/packages/frontend/package.json @@ -44,6 +44,7 @@ "dependencies": { "axios": "^0.21.1", "date-fns": "^2.19.0", + "history": "4.10.1", "messageformat": "^2.3.0", "preact": "^10.5.13", "preact-messages": "workspace:*", @@ -64,6 +65,7 @@ "@testing-library/preact": "^2.0.1", "@testing-library/preact-hooks": "^1.1.0", "@types/enzyme": "^3.10.8", + "@types/history": "^4.7.8", "@types/jest": "^26.0.20", "@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/parser": "^4.18.0", diff --git a/packages/frontend/src/ApplicationReadyRoutes.tsx b/packages/frontend/src/ApplicationReadyRoutes.tsx @@ -27,7 +27,6 @@ import { InstanceRoutes } from "./InstanceRoutes"; import LoginPage from './paths/login'; import { INSTANCE_ID_LOOKUP } from './utils/constants'; import { NotYetReadyAppMenu, Menu } from './components/menu'; -import { AdminRoutes } from './AdminRoutes'; import { useMessageTemplate } from 'preact-messages'; interface Props { pushNotification: (n: Notification) => void; diff --git a/packages/frontend/src/InstanceRoutes.tsx b/packages/frontend/src/InstanceRoutes.tsx @@ -23,6 +23,7 @@ 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'; +import { createHashHistory } from 'history'; import { useBackendInstanceToken } from './hooks'; import { InstanceContextProvider, useBackendContext } from './context/backend'; import { SwrError } from "./hooks/backend"; @@ -47,7 +48,7 @@ import TipUpdatePage from './paths/instance/tips/update' import TransferListPage from './paths/instance/transfers/list' import TransferCreatePage from './paths/instance/transfers/create' -// import { AdminRoutes } from './AdminRoutes'; + import InstanceListPage from './paths/admin/list'; import InstanceCreatePage from "./paths/admin/create"; @@ -83,7 +84,7 @@ export interface Props { admin?: boolean; } -const rootPath = typeof window !== 'undefined' ? window.location.pathname : '/' +// const rootPath = typeof window !== 'undefined' ? window.location.pathname : '/' export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { const [token, updateToken] = useBackendInstanceToken(id); @@ -104,9 +105,9 @@ export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { const value = useMemo(() => ({ id, token, admin }), [id, token]) return <InstanceContextProvider value={value}> - <Router> + <Router history={createHashHistory()}> {admin && - <Route path={rootPath + AdminPaths.list_instances} component={InstanceListPage} + <Route path={AdminPaths.list_instances} component={InstanceListPage} onCreate={() => { route(AdminPaths.new_instance); @@ -128,7 +129,7 @@ export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { } {admin && - <Route path={rootPath + AdminPaths.new_instance} component={InstanceCreatePage} + <Route path={AdminPaths.new_instance} component={InstanceCreatePage} onBack={() => route(AdminPaths.list_instances)} @@ -144,7 +145,7 @@ export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { /> } - <Route path={rootPath + InstancePaths.details} + <Route path={InstancePaths.details} component={DetailPage} onUnauthorized={() => <LoginPage @@ -156,7 +157,7 @@ export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { onConfirm={updateLoginStatus} />} /> - <Route path={rootPath + InstancePaths.update} + <Route path={InstancePaths.update} component={InstanceUpdatePage} onUnauthorized={() => <LoginPage @@ -181,7 +182,7 @@ export function InstanceRoutes({ id, pushNotification, admin }: Props): VNode { }} /> - <Route path={rootPath + InstancePaths.product_list} + <Route path={InstancePaths.product_list} component={ProductListPage} onUnauthorized={() => <LoginPage withMessage={{ message: i18n`Access denied`, description: i18n`Check your token is valid`, type: 'ERROR', }} @@ -191,14 +192,14 @@ export function InstanceRoutes({ id, pushNotification, admin }: 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={rootPath + InstancePaths.product_update} + <Route path={InstancePaths.product_update} component={ProductUpdatePage} /> - <Route path={rootPath + InstancePaths.product_new} + <Route path={InstancePaths.product_new} component={ProductCreatePage} /> - <Route path={rootPath + InstancePaths.order_list} + <Route path={InstancePaths.order_list} component={OrderListPage} onUnauthorized={() => <LoginPage withMessage={{ message: i18n`Access denied`, description: i18n`Check your token is valid`, type: 'ERROR', }} @@ -208,14 +209,14 @@ export function InstanceRoutes({ id, pushNotification, admin }: 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={rootPath + InstancePaths.order_update} + <Route path={InstancePaths.order_update} component={OrderUpdatePage} /> - <Route path={rootPath + InstancePaths.order_new} + <Route path={InstancePaths.order_new} component={OrderCreatePage} /> - <Route path={rootPath + InstancePaths.tips_list} + <Route path={InstancePaths.tips_list} component={TipListPage} onUnauthorized={() => <LoginPage withMessage={{ message: i18n`Access denied`, description: i18n`Check your token is valid`, type: 'ERROR', }} @@ -225,14 +226,14 @@ export function InstanceRoutes({ id, pushNotification, admin }: 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={rootPath + InstancePaths.tips_update} + <Route path={InstancePaths.tips_update} component={TipUpdatePage} /> - <Route path={rootPath + InstancePaths.tips_new} + <Route path={InstancePaths.tips_new} component={TipCreatePage} /> - <Route path={rootPath + InstancePaths.transfers_list} + <Route path={InstancePaths.transfers_list} component={TransferListPage} onUnauthorized={() => <LoginPage withMessage={{ message: i18n`Access denied`, description: i18n`Check your token is valid`, type: 'ERROR', }} @@ -242,7 +243,7 @@ export function InstanceRoutes({ id, pushNotification, admin }: 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={rootPath + InstancePaths.transfers_new} + <Route path={InstancePaths.transfers_new} component={TransferCreatePage} /> diff --git a/packages/frontend/src/components/menu/SideBar.tsx b/packages/frontend/src/components/menu/SideBar.tsx @@ -64,7 +64,7 @@ export function Sidebar({ mobile, instance, onLogout, admin }: Props): VNode { </li> <li> <a href="/products" class="has-icon"> - <span class="icon"><i class="mdi mdi-mdi-shopping" /></span> + <span class="icon"><i class="mdi mdi-shopping" /></span> <span class="menu-item-label">Products</span> </a> </li> diff --git a/packages/frontend/src/hooks/index.ts b/packages/frontend/src/hooks/index.ts @@ -48,7 +48,7 @@ export function useBackendURL(): [string, boolean, StateUpdater<string>, () => v setTriedToLog('yes') return setter(p => (v instanceof Function ? v(p) : v).replace(/\/$/, '')) } - + const resetBackend = () => { setTriedToLog(undefined) } @@ -77,6 +77,13 @@ export function useBackendInstanceToken(id: string): [string | undefined, StateU }) }, [id, setIds]) + const [defaultToken, defaultSetToken] = useBackendDefaultToken() + + // instance named 'default' use the default token + if (id === 'default') { + return [defaultToken, defaultSetToken, clearAllTokens] + } + return [token, setToken, clearAllTokens] } @@ -96,7 +103,9 @@ export function useBackendInstanceToken(id: string): [string | undefined, StateU // } export function useLang(): [string, StateUpdater<string>] { - return useNotNullLocalStorage('lang-preference', typeof window !== "undefined" ? navigator.language || (navigator as any).userLanguage : 'en') + const browserLang = typeof window !== "undefined" ? navigator.language || (navigator as any).userLanguage : undefined; + const defaultLang = (browserLang || 'en').substring(0,2) + return useNotNullLocalStorage('lang-preference', defaultLang) } export function useLocalStorage(key: string, initialValue?: string): [string | undefined, StateUpdater<string | undefined>] { diff --git a/packages/frontend/src/paths/admin/list/Table.tsx b/packages/frontend/src/paths/admin/list/Table.tsx @@ -22,6 +22,7 @@ import { h, VNode } from "preact" import { Message } from "preact-messages" import { StateUpdater, useEffect, useState } from "preact/hooks" +import { useBackendContext } from "../../../context/backend"; import { MerchantBackend } from "../../../declaration" interface Props { @@ -94,6 +95,7 @@ function toggleSelected<T>(id: T): (prev: T[]) => T[] { } function Table({ rowSelection, rowSelectionHandler, instances, onUpdate, onDelete }: TableProps): VNode { + const { changeBackend, url } = useBackendContext() return ( <table class="table is-fullwidth is-striped is-hoverable is-fullwidth"> <thead> @@ -118,7 +120,7 @@ function Table({ rowSelection, rowSelectionHandler, instances, onUpdate, onDelet <span class="check" /> </label> </td> - <td><a onClick={(): void => onUpdate(i.id)} style={{ cursor: 'pointer' }} >{i.id}</a></td> + <td><a href={`/instances/${i.id}`} {...{ native: true }} onClick={() => changeBackend(`${url}/instances/${i.id}`)} >{i.id}</a></td> <td >{i.name}</td> <td class="is-actions-cell"> <div class="buttons is-right"> diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml @@ -5,6 +5,7 @@ importers: dependencies: axios: 0.21.1 date-fns: 2.19.0 + history: 4.10.1 messageformat: 2.3.0 preact: 10.5.13 preact-messages: link:../preact-messages @@ -24,6 +25,7 @@ importers: '@testing-library/preact': 2.0.1_preact@10.5.13 '@testing-library/preact-hooks': 1.1.0_8a3b8354086a0a31d950b2aa8b26d524 '@types/enzyme': 3.10.8 + '@types/history': 4.7.8 '@types/jest': 26.0.20 '@typescript-eslint/eslint-plugin': 4.18.0_ef0f217f6395606fd8bbe7b0291eff7e '@typescript-eslint/parser': 4.18.0_eslint@7.22.0+typescript@4.2.3 @@ -71,6 +73,7 @@ importers: '@testing-library/preact': ^2.0.1 '@testing-library/preact-hooks': ^1.1.0 '@types/enzyme': ^3.10.8 + '@types/history': ^4.7.8 '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.18.0 '@typescript-eslint/parser': ^4.18.0 @@ -91,6 +94,7 @@ importers: eslint: ^7.22.0 eslint-config-preact: ^1.1.3 eslint-plugin-header: ^3.1.1 + history: 4.10.1 html-webpack-inline-chunk-plugin: ^1.1.1 html-webpack-inline-source-plugin: 0.0.10 html-webpack-skip-assets-plugin: ^1.0.1 @@ -3077,6 +3081,10 @@ packages: dev: true resolution: integrity: sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q== + /@types/history/4.7.8: + dev: true + resolution: + integrity: sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== /@types/html-minifier-terser/5.1.1: dev: true resolution: @@ -8640,6 +8648,17 @@ packages: dev: true resolution: integrity: sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ== + /history/4.10.1: + dependencies: + '@babel/runtime': 7.13.10 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + dev: false + resolution: + integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== /hmac-drbg/1.0.1: dependencies: hash.js: 1.1.7 @@ -10340,7 +10359,6 @@ packages: resolution: integrity: sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= /js-tokens/4.0.0: - dev: true resolution: integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== /js-yaml/3.14.1: @@ -10817,7 +10835,6 @@ packages: /loose-envify/1.4.0: dependencies: js-tokens: 4.0.0 - dev: true hasBin: true resolution: integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -14079,6 +14096,10 @@ packages: node: '>=8' resolution: integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + /resolve-pathname/3.0.0: + dev: false + resolution: + integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== /resolve-url/0.2.1: deprecated: https://github.com/lydell/resolve-url#deprecated dev: true @@ -15555,6 +15576,14 @@ packages: optional: true resolution: integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + /tiny-invariant/1.1.0: + dev: false + resolution: + integrity: sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + /tiny-warning/1.0.3: + dev: false + resolution: + integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== /tinycolor2/1.4.2: dev: true resolution: @@ -16358,6 +16387,10 @@ packages: dev: true resolution: integrity: sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + /value-equal/1.0.1: + dev: false + resolution: + integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== /vary/1.1.2: dev: true engines: