diff --git a/src/pageUtils.ts b/src/pageUtils.ts index 4190924..fe4bfff 100644 --- a/src/pageUtils.ts +++ b/src/pageUtils.ts @@ -60,23 +60,3 @@ export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000 ); }); } - -export function setErrorText(text: string): void { - const errorTextElement = document.querySelector("#errorText"); - if (errorTextElement) { - /* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ - const p = document.querySelector("#errorText") as HTMLParagraphElement; - p.innerText = `Error: ${text}`; - /* eslint-enable @typescript-eslint/no-unnecessary-type-assertion */ - } - UIkit.notification({ - message: `Error: ${text}`, - status: "danger", - pos: "top-center", - timeout: 2000, - }); -} - -export function notImplemented(): void { - setErrorText(i18next.t("not_implemented")); -} diff --git a/src/ui/elements/ErrorMessage.tsx b/src/ui/elements/ErrorMessage.tsx new file mode 100644 index 0000000..9dc293a --- /dev/null +++ b/src/ui/elements/ErrorMessage.tsx @@ -0,0 +1,63 @@ +import { Component, createRef } from "preact"; +import UIkit from "uikit"; +import i18next from "i18next"; + +type ErrorMessageState = { + errorMessage: string; +}; + +// Use only when a error text element can't be used +// e.g inside componentDidMount +export function sendErrorNotification(errorMessage: string) { + UIkit.notification({ + message: `Error: ${errorMessage}`, + status: "danger", + pos: "top-center", + timeout: 2000, + }); +} + +export function notImplementedNotification(): void { + sendErrorNotification(i18next.t("not_implemented")); +} + +export class ErrorMessage extends Component { + public setErrorMessage(errorMessage: string) { + this.setState({ + errorMessage: `Error: ${errorMessage}`, + }); + + sendErrorNotification(errorMessage); + + // make browser focus on the change. + this.errorMessageRef.current.focus(); + } + + public clear() { + this.setState({ errorMessage: "" }); + } + + errorMessageRef = createRef(); + + render() { + return ( +

+ {this.state.errorMessage || ""} +

+ ); + } +} diff --git a/src/ui/pages/Access/AccessHome.tsx b/src/ui/pages/Access/AccessHome.tsx index 8a8c5b3..c055e27 100644 --- a/src/ui/pages/Access/AccessHome.tsx +++ b/src/ui/pages/Access/AccessHome.tsx @@ -3,7 +3,7 @@ import { DefaultPageProps } from "../../../types/DefaultPageProps"; import { Grid, GridSizes } from "../../elements/Grid"; import { PageTitle } from "../../elements/PageTitle"; import { Tile } from "../../elements/Tile"; -import { notImplemented } from "../../../pageUtils"; +import { notImplementedNotification } from "../../elements/ErrorMessage"; import { route } from "preact-router"; import i18next from "i18next"; @@ -23,19 +23,19 @@ export class AccessHomePage extends Component { title={i18next.t("access_entities_title")} description={i18next.t("access_entities_description")} icon="user" - onclick={async () => notImplemented()} + onclick={async () => notImplementedNotification()} /> notImplemented()} + onclick={async () => notImplementedNotification()} /> notImplemented()} + onclick={async () => notImplementedNotification()} /> diff --git a/src/ui/pages/Access/Auth/AuthHome.tsx b/src/ui/pages/Access/Auth/AuthHome.tsx index bcb3954..e3b2453 100644 --- a/src/ui/pages/Access/Auth/AuthHome.tsx +++ b/src/ui/pages/Access/Auth/AuthHome.tsx @@ -4,7 +4,7 @@ import { Component, JSX } from "preact"; import { DefaultPageProps } from "../../../../types/DefaultPageProps"; import { PageTitle } from "../../../elements/PageTitle"; import { authViewConfigURL, userPassUserListURL } from "../../pageLinks"; -import { notImplemented } from "../../../../pageUtils"; +import { notImplementedNotification, sendErrorNotification } from "../../../elements/ErrorMessage"; import { objectToMap } from "../../../../utils"; import { route } from "preact-router"; import i18next from "i18next"; @@ -46,7 +46,7 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {