import { TranslatedString } from "@gnu-taler/taler-util"; import { Footer, GlobalNotificationsBanner, Header, notifyError, notifyException, useTranslationContext } from "@gnu-taler/web-util/browser"; import { ComponentChildren, Fragment, VNode, h } from "preact"; import { useEffect, useErrorBoundary } from "preact/hooks"; import { useOfficer } from "./hooks/useOfficer.js"; import { getAllBooleanSettings, getLabelForSetting, useSettings } from "./hooks/useSettings.js"; import { Pages } from "./pages.js"; import { PageEntry, useChangeLocation, useCurrentLocation } from "./route.js"; import { uiSettings } from "./settings.js"; function classNames(...classes: string[]) { return classes.filter(Boolean).join(" "); } /** * mapping route to view * not found (error page) * nested, index element, relative routes * link interception * form POST interception, call action * fromData => Object.fromEntries * segments in the URL * navigationState: idle, submitting, loading * form GET interception: does a navigateTo * form GET Sync: * 1.- back after submit: useEffect to sync URL to form * 2.- refresh after submit: input default value * useSubmit for form submission onChange, history replace * * post form without redirect * * * @param param0 * @returns */ const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined; const versionText = VERSION ? GIT_HASH ? `v${VERSION} (${GIT_HASH.substring(0, 8)})` : VERSION : ""; /** * TO BE FIXED: * * 1.- when the form change to other form and both form share the same structure * the same input component may be rendered in the same place, * since input are uncontrolled the are not re-rendered and since they are * uncontrolled it will keep the value of the previous form. * One solutions could be to remove the form when unloading and when the new * form load it will start without previous vdom, preventing the cache * to create this behavior. * Other solutions could be using IDs in the fields that are constructed * with the ID of the form, so two fields of different form will need to re-render * cleaning up the state of the previous form. * * 2.- currently the design prop and the behavior prop of the flexible form * are two side of the same coin. From the design point of view, it is important * to design the form in a list-of-field manner and there may be additional * content that is not directly mapped to the form structure (object) * So maybe we want to change the current shape so the computation of the state * of the form is in a field level, but this computation required the field value and * the whole form values and state (since one field may be disabled/hidden) because * of the value of other field. * * 3.- given the previous requirement, maybe the name of the field of the form could be * a function (P: F -> V) where F is the form (or parent object) and V is the type of the * property. That will help with the typing of the forms props * * 4.- tooltip are not placed correctly: the arrow should point the question mark * and the text area should be bigger * * 5.- date field should have the calendar icon clickable so the user can select date without * writing text with the correct format */ const pageList = Object.values(Pages); function LeftMenu() { const currentLocation = useCurrentLocation(pageList); return ( ); } export function ExchangeAmlFrame({ children, }: { children?: ComponentChildren; }): VNode { const { i18n } = useTranslationContext(); const [error, resetError] = useErrorBoundary(); useEffect(() => { if (error) { if (error instanceof Error) { notifyException(i18n.str`Internal error, please report.`, error) } else { notifyError(i18n.str`Internal error, please report.`, String(error) as TranslatedString) } resetError() } }, [error]) const officer = useOfficer(); const [settings, updateSettings] = useSettings(); return (
{ officer.lock() }} sites={[]} supportedLangs={["en", "es", "de"]} >
  • Preferences
      {getAllBooleanSettings().map(set => { const isOn: boolean = !!settings[set] return
    • {getLabelForSetting(set, i18n)}
    • })}
  • {officer.state !== "ready" ? undefined : }
    {children}
    ); } function Navigation(): VNode { const { i18n } = useTranslationContext() const pageList: Array = [ Pages.officer, Pages.cases ] const location = useChangeLocation(); return (
    ) }