aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-18 09:55:23 -0300
committerSebastian <sebasjm@gmail.com>2023-11-18 09:55:23 -0300
commit7ed3e78f790837479fc2bb2eb6ddc40c78ce59b5 (patch)
treed914627537315e15240034fed441239448dfff07 /packages/aml-backoffice-ui/src
parentc797d551d9716924120d6ce6f270793c7bb5a4f9 (diff)
sync page with history
Diffstat (limited to 'packages/aml-backoffice-ui/src')
-rw-r--r--packages/aml-backoffice-ui/src/Dashboard.tsx83
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useOfficer.ts47
-rw-r--r--packages/aml-backoffice-ui/src/hooks/useSettings.ts10
-rw-r--r--packages/aml-backoffice-ui/src/route.ts77
4 files changed, 93 insertions, 124 deletions
diff --git a/packages/aml-backoffice-ui/src/Dashboard.tsx b/packages/aml-backoffice-ui/src/Dashboard.tsx
index d111ae145..b813f83d5 100644
--- a/packages/aml-backoffice-ui/src/Dashboard.tsx
+++ b/packages/aml-backoffice-ui/src/Dashboard.tsx
@@ -77,75 +77,6 @@ const versionText = VERSION
* writing text with the correct format
*/
-const pageList = Object.values(Pages);
-function LeftMenu() {
- const currentLocation = useCurrentLocation(pageList);
-
- return (
- <nav class="flex flex-1 flex-col">
- <ul role="list" class="flex flex-1 flex-col gap-y-7">
- <li>
- <ul role="list" class="-mx-2 space-y-1">
- <li>
- <a
- href={Pages.cases.url}
- class={classNames(
- Pages.cases.url === currentLocation?.path
- ? "bg-indigo-700 text-white"
- : "text-indigo-200 hover:text-white hover:bg-indigo-700",
- "group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold",
- )}
- >
- {/* <InformationCircleIcon
- class={classNames(
- Pages.cases.url === currentLocation?.path
- ? "text-white"
- : "text-indigo-200 group-hover:text-white",
- "h-6 w-6 shrink-0",
- )}
- aria-hidden="true"
- /> */}
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
- <path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
- </svg>
-
- Cases
- </a>
- </li>
- <li>
- <a
- href={Pages.officer.url}
- class={classNames(
- Pages.officer.url === currentLocation?.path
- ? "bg-indigo-700 text-white"
- : "text-indigo-200 hover:text-white hover:bg-indigo-700",
- "group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold",
- )}
- >
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
- <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" />
- </svg>
-
- {/* <UserIcon
- class={classNames(
- Pages.officer.url === currentLocation?.path
- ? "text-white"
- : "text-indigo-200 group-hover:text-white",
- "h-6 w-6 shrink-0",
- )}
- aria-hidden="true"
- /> */}
- Account
- </a>
- </li>
- </ul>
- </li>
- </ul>
- </nav>
- );
-}
-
-
export function ExchangeAmlFrame({
children,
}: {
@@ -238,21 +169,21 @@ function Navigation(): VNode {
]
const location = useChangeLocation();
return (
- <div class="flex gap-y-5 w-48 bg-indigo-600 divide-y rounded-r-lg divide-cyan-800 overflow-y-auto overflow-x-clip">
+ <div class="hidden sm:block w-48 min-w-min bg-indigo-600 divide-y rounded-r-lg divide-cyan-800 overflow-y-auto overflow-x-clip">
<nav class="flex flex-1 flex-col mx-4 mt-4 mb-2">
<ul role="list" class="flex flex-1 flex-col gap-y-7">
<li>
<ul role="list" class="-mx-2 space-y-1">
{pageList.map(p => {
-
+
return <li>
- {/* <!-- Current: "bg-indigo-700 text-white",
- Default: "text-indigo-200 hover:text-white hover:bg-indigo-700" --> */}
- <a href={p.url} data-selected={location == p.url}
+ <a href={p.url} data-selected={location == p.url}
class="data-[selected=true]:bg-indigo-700 data-[selected=true]:text-white text-indigo-200 hover:text-white hover:bg-indigo-700 group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold">
- { p.Icon && <p.Icon />}
- {p.name}
+ {p.Icon && <p.Icon />}
+ <span class="hidden md:inline">
+ {p.name}
+ </span>
</a>
</li>
diff --git a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
index 0747170e8..64cf79cc9 100644
--- a/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useOfficer.ts
@@ -3,10 +3,15 @@ import {
Codec,
LockedAccount,
OfficerAccount,
+ OfficerId,
+ SigningKey,
buildCodecForObject,
codecForAbsoluteTime,
codecForString,
+ codecOptional,
createNewOfficerAccount,
+ decodeCrock,
+ encodeCrock,
unlockOfficerAccount,
} from "@gnu-taler/taler-util";
import {
@@ -14,6 +19,7 @@ import {
useLocalStorage,
useMemoryStorage,
} from "@gnu-taler/web-util/browser";
+import { useMemo } from "preact/hooks";
export interface Officer {
account: LockedAccount;
@@ -22,6 +28,17 @@ export interface Officer {
const codecForLockedAccount = codecForString() as Codec<LockedAccount>;
+type OfficerAccountString = {
+ id: string,
+ strKey: string;
+}
+
+export const codecForOfficerAccount = (): Codec<OfficerAccountString> =>
+ buildCodecForObject<OfficerAccountString>()
+ .property("id", codecForString()) // FIXME
+ .property("strKey", codecForString()) // FIXME
+ .build("OfficerAccount");
+
export const codecForOfficer = (): Codec<Officer> =>
buildCodecForObject<Officer>()
.property("account", codecForLockedAccount) // FIXME
@@ -47,26 +64,41 @@ interface OfficerReady {
}
const OFFICER_KEY = buildStorageKey("officer", codecForOfficer());
+const DEV_ACCOUNT_KEY = buildStorageKey("account-dev", codecForOfficerAccount());
const ACCOUNT_KEY = "account";
export function useOfficer(): OfficerState {
- const accountStorage = useMemoryStorage<OfficerAccount>(ACCOUNT_KEY);
- const officerStorage = useLocalStorage(OFFICER_KEY);
+ // dev account, is save when reloaded.
+ const accountStorage = useLocalStorage(DEV_ACCOUNT_KEY);
+ const account = useMemo(() => {
+ if (!accountStorage.value) return undefined
+ return {
+ id: accountStorage.value.id as OfficerId,
+ signingKey: decodeCrock(accountStorage.value.strKey) as SigningKey
+ }
+ }, [accountStorage.value])
+
+
+ // const accountStorage = useMemoryStorage<OfficerAccount>(ACCOUNT_KEY);
+ // const account = accountStorage.value;
+ const officerStorage = useLocalStorage(OFFICER_KEY);
const officer = officerStorage.value;
- const account = accountStorage.value;
+
if (officer === undefined) {
return {
state: "not-found",
create: async (pwd: string) => {
- const { id, safe, signingKey } = await createNewOfficerAccount(pwd);
+ const { id, safe, signingKey } = await createNewOfficerAccount(pwd);
officerStorage.update({
account: safe,
when: AbsoluteTime.now(),
});
- accountStorage.update({ id, signingKey });
+ // accountStorage.update({ id, signingKey });
+ const strKey = encodeCrock(signingKey)
+ accountStorage.update({id, strKey })
},
};
}
@@ -79,14 +111,15 @@ export function useOfficer(): OfficerState {
},
tryUnlock: async (pwd: string) => {
const ac = await unlockOfficerAccount(officer.account, pwd);
- accountStorage.update(ac);
+ // accountStorage.update(ac);
+ accountStorage.update({id: ac.id, strKey: encodeCrock(ac.signingKey)})
},
};
}
return {
state: "ready",
- account: account,
+ account,
lock: () => {
accountStorage.reset();
},
diff --git a/packages/aml-backoffice-ui/src/hooks/useSettings.ts b/packages/aml-backoffice-ui/src/hooks/useSettings.ts
index 52f6f1614..f1610576e 100644
--- a/packages/aml-backoffice-ui/src/hooks/useSettings.ts
+++ b/packages/aml-backoffice-ui/src/hooks/useSettings.ts
@@ -27,25 +27,29 @@ import { buildStorageKey, useLocalStorage, useTranslationContext } from "@gnu-ta
interface Settings {
allowInsecurePassword: boolean;
+ keepSessionAfterReload: boolean;
}
export function getAllBooleanSettings(): Array<keyof Settings> {
- return ["allowInsecurePassword"]
+ return ["allowInsecurePassword", "keepSessionAfterReload"]
}
export function getLabelForSetting(k: keyof Settings, i18n: ReturnType<typeof useTranslationContext>["i18n"]): TranslatedString {
switch (k) {
case "allowInsecurePassword": return i18n.str`Allow Insecure password`
+ case "keepSessionAfterReload": return i18n.str`Keep session after reload`
}
}
export const codecForSettings = (): Codec<Settings> =>
buildCodecForObject<Settings>()
- .property("allowInsecurePassword", (codecForBoolean()))
- .build("Settings");
+ .property("allowInsecurePassword", (codecForBoolean()))
+ .property("keepSessionAfterReload", (codecForBoolean()))
+ .build("Settings");
const defaultSettings: Settings = {
allowInsecurePassword: false,
+ keepSessionAfterReload: false,
};
const EXCHANGE_SETTINGS_KEY = buildStorageKey(
diff --git a/packages/aml-backoffice-ui/src/route.ts b/packages/aml-backoffice-ui/src/route.ts
index 9176ab5e4..091b92d5c 100644
--- a/packages/aml-backoffice-ui/src/route.ts
+++ b/packages/aml-backoffice-ui/src/route.ts
@@ -79,48 +79,17 @@ type Location = {
path: string;
values: Record<string, string>;
};
-export function useCurrentLocation(pageList: Array<PageEntry<any>>) {
- const [currentLocation, setCurrentLocation] = useState<Location>();
- /**
- * Search path in the pageList
- * get the values from the path found
- * add params from searchParams
- *
- * @param path
- * @param params
- */
- function doSync(path: string, params: URLSearchParams) {
- let result: typeof currentLocation;
- for (let idx = 0; idx < pageList.length; idx++) {
- const page = pageList[idx];
- if (typeof page.url === "string") {
- if (page.url === path) {
- const values: Record<string, string> = {};
- params.forEach((v, k) => {
- values[k] = v;
- });
- result = { page, values, path };
- break;
- }
- } else {
- const values = doestUrlMatchToRoute(path, page.url.pattern);
- if (values !== undefined) {
- params.forEach((v, k) => {
- values[k] = v;
- });
- result = { page, values, path };
- break;
- }
- }
- }
- setCurrentLocation(result);
- }
+export function useCurrentLocation(pageList: Array<PageEntry<any>>): Location | undefined {
+ const [currentLocation, setCurrentLocation] = useState<Location | null | undefined>(null);
useEffect(() => {
- doSync(window.location.hash, new URLSearchParams(window.location.search));
return history.listen(() => {
- doSync(window.location.hash, new URLSearchParams(window.location.search));
+ const result = doSync(window.location.hash, new URLSearchParams(window.location.search), pageList);
+ setCurrentLocation(result);
});
}, []);
+ if (currentLocation === null) {
+ return doSync(window.location.hash, new URLSearchParams(window.location.search), pageList);
+ }
return currentLocation;
}
@@ -134,6 +103,38 @@ export function useChangeLocation() {
return location;
}
+/**
+ * Search path in the pageList
+ * get the values from the path found
+ * add params from searchParams
+ *
+ * @param path
+ * @param params
+ */
+export function doSync(path: string, params: URLSearchParams, pageList: Array<PageEntry<any>>): Location | undefined {
+ for (let idx = 0; idx < pageList.length; idx++) {
+ const page = pageList[idx];
+ if (typeof page.url === "string") {
+ if (page.url === path) {
+ const values: Record<string, string> = {};
+ params.forEach((v, k) => {
+ values[k] = v;
+ });
+ return { page, values, path };
+ }
+ } else {
+ const values = doestUrlMatchToRoute(path, page.url.pattern);
+ if (values !== undefined) {
+ params.forEach((v, k) => {
+ values[k] = v;
+ });
+ return { page, values, path };
+ }
+ }
+ }
+ return undefined;
+}
+
function doestUrlMatchToRoute(
url: string,
route: string,