158 lines
7.1 KiB
TypeScript
158 lines
7.1 KiB
TypeScript
import { useEffect } from "react";
|
|
import { assert } from "keycloakify/tools/assert";
|
|
import { clsx } from "keycloakify/tools/clsx";
|
|
import { useGetClassName } from "keycloakify/account/lib/useGetClassName";
|
|
import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags";
|
|
import { useSetClassName } from "keycloakify/tools/useSetClassName";
|
|
import type { TemplateProps } from "keycloakify/account/TemplateProps";
|
|
import type { KcContext } from "./KcContext";
|
|
import { useI18n } from "./i18n";
|
|
|
|
export default function Template(props: TemplateProps<KcContext>) {
|
|
const { kcContext, doUseDefaultCss, active, classes, children } = props;
|
|
|
|
const { getClassName } = useGetClassName({ doUseDefaultCss, classes });
|
|
|
|
const { msg, msgStr, getChangeLocalUrl, labelBySupportedLanguageTag, currentLanguageTag } = useI18n({ kcContext });
|
|
|
|
const { locale, url, features, realm, message, referrer } = kcContext;
|
|
|
|
useEffect(() => {
|
|
document.title = msgStr("accountManagementTitle");
|
|
}, []);
|
|
|
|
useSetClassName({
|
|
qualifiedName: "html",
|
|
className: getClassName("kcHtmlClass")
|
|
});
|
|
|
|
useSetClassName({
|
|
qualifiedName: "body",
|
|
className: clsx("admin-console", "user", getClassName("kcBodyClass"))
|
|
});
|
|
|
|
useEffect(() => {
|
|
const { currentLanguageTag } = locale ?? {};
|
|
|
|
if (currentLanguageTag === undefined) {
|
|
return;
|
|
}
|
|
|
|
const html = document.querySelector("html");
|
|
assert(html !== null);
|
|
html.lang = currentLanguageTag;
|
|
}, []);
|
|
|
|
const { areAllStyleSheetsLoaded } = useInsertLinkTags({
|
|
componentOrHookName: "Template",
|
|
hrefs: !doUseDefaultCss
|
|
? []
|
|
: [
|
|
`${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`,
|
|
`${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`,
|
|
`${url.resourcesPath}/css/account.css`
|
|
]
|
|
});
|
|
|
|
if (!areAllStyleSheetsLoaded) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<header className="navbar navbar-default navbar-pf navbar-main header">
|
|
<nav className="navbar" role="navigation">
|
|
<div className="navbar-header">
|
|
<div className="container">
|
|
<h1 className="navbar-title">Keycloak</h1>
|
|
</div>
|
|
</div>
|
|
<div className="navbar-collapse navbar-collapse-1">
|
|
<div className="container">
|
|
<ul className="nav navbar-nav navbar-utility">
|
|
{realm.internationalizationEnabled && (assert(locale !== undefined), true) && locale.supported.length > 1 && (
|
|
<li>
|
|
<div className="kc-dropdown" id="kc-locale-dropdown">
|
|
<a href="#" id="kc-current-locale-link">
|
|
{labelBySupportedLanguageTag[currentLanguageTag]}
|
|
</a>
|
|
<ul>
|
|
{locale.supported.map(({ languageTag }) => (
|
|
<li key={languageTag} className="kc-dropdown-item">
|
|
<a href={getChangeLocalUrl(languageTag)}>{labelBySupportedLanguageTag[languageTag]}</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</li>
|
|
)}
|
|
{referrer?.url && (
|
|
<li>
|
|
<a href={referrer.url} id="referrer">
|
|
{msg("backTo", referrer.name)}
|
|
</a>
|
|
</li>
|
|
)}
|
|
<li>
|
|
<a href={url.getLogoutUrl()}>{msg("doSignOut")}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
|
|
<div className="container">
|
|
<div className="bs-sidebar col-sm-3">
|
|
<ul>
|
|
<li className={clsx(active === "account" && "active")}>
|
|
<a href={url.accountUrl}>{msg("account")}</a>
|
|
</li>
|
|
{features.passwordUpdateSupported && (
|
|
<li className={clsx(active === "password" && "active")}>
|
|
<a href={url.passwordUrl}>{msg("password")}</a>
|
|
</li>
|
|
)}
|
|
<li className={clsx(active === "totp" && "active")}>
|
|
<a href={url.totpUrl}>{msg("authenticator")}</a>
|
|
</li>
|
|
{features.identityFederation && (
|
|
<li className={clsx(active === "social" && "active")}>
|
|
<a href={url.socialUrl}>{msg("federatedIdentity")}</a>
|
|
</li>
|
|
)}
|
|
<li className={clsx(active === "sessions" && "active")}>
|
|
<a href={url.sessionsUrl}>{msg("sessions")}</a>
|
|
</li>
|
|
<li className={clsx(active === "applications" && "active")}>
|
|
<a href={url.applicationsUrl}>{msg("applications")}</a>
|
|
</li>
|
|
{features.log && (
|
|
<li className={clsx(active === "log" && "active")}>
|
|
<a href={url.logUrl}>{msg("log")}</a>
|
|
</li>
|
|
)}
|
|
{realm.userManagedAccessAllowed && features.authorization && (
|
|
<li className={clsx(active === "authorization" && "active")}>
|
|
<a href={url.resourceUrl}>{msg("myResources")}</a>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
</div>
|
|
|
|
<div className="col-sm-9 content-area">
|
|
{message !== undefined && (
|
|
<div className={clsx("alert", `alert-${message.type}`)}>
|
|
{message.type === "success" && <span className="pficon pficon-ok"></span>}
|
|
{message.type === "error" && <span className="pficon pficon-error-circle-o"></span>}
|
|
<span className="kc-feedback-text">{message.summary}</span>
|
|
</div>
|
|
)}
|
|
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|