Initial version without filter (#2518)

This commit is contained in:
Erik Jan de Wit 2022-04-28 15:36:43 +02:00 committed by GitHub
parent ebf56dacc0
commit 60a81c8e86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 176 additions and 87 deletions

View file

@ -12,5 +12,9 @@
"infoEnabledFeatures": "Something about what enabled features are.", "infoEnabledFeatures": "Something about what enabled features are.",
"infoDisabledFeatures": "Something about what disabled features are.", "infoDisabledFeatures": "Something about what disabled features are.",
"disabledFeatures": "Disabled features", "disabledFeatures": "Disabled features",
"adminUiVersion": "<0 className=\"pf-u-mr-md\">Admin UI version</0>{{version}}" "adminUiVersion": "<0 className=\"pf-u-mr-md\">Admin UI version</0>{{version}}",
"providerInfo": "Provider info",
"providers": "Providers",
"realmInfo": "Realm info",
"spi": "SPI"
} }

View file

@ -1,3 +1,7 @@
import React from "react";
import { useHistory } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
import { xor } from "lodash-es";
import { import {
Brand, Brand,
Card, Card,
@ -16,22 +20,34 @@ import {
ListItem, ListItem,
ListVariant, ListVariant,
PageSection, PageSection,
Tab,
TabTitleText,
Text, Text,
TextContent, TextContent,
Title, Title,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import React from "react"; import {
import { Trans, useTranslation } from "react-i18next"; TableComposable,
import { xor } from "lodash-es"; Tbody,
Td,
Th,
Thead,
Tr,
} from "@patternfly/react-table";
import { useRealm } from "../context/realm-context/RealmContext"; import { useRealm } from "../context/realm-context/RealmContext";
import { useServerInfo } from "../context/server-info/ServerInfoProvider"; import { useServerInfo } from "../context/server-info/ServerInfoProvider";
import { toUpperCase } from "../util"; import { toUpperCase } from "../util";
import { HelpItem } from "../components/help-enabler/HelpItem"; import { HelpItem } from "../components/help-enabler/HelpItem";
import environment from "../environment"; import environment from "../environment";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
import {
routableTab,
RoutableTabs,
} from "../components/routable-tabs/RoutableTabs";
import { DashboardTab, toDashboard } from "./routes/Dashboard";
import "./dashboard.css"; import "./dashboard.css";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
const EmptyDashboard = () => { const EmptyDashboard = () => {
const { t } = useTranslation("dashboard"); const { t } = useTranslation("dashboard");
@ -60,6 +76,7 @@ const Dashboard = () => {
const { t } = useTranslation("dashboard"); const { t } = useTranslation("dashboard");
const { realm } = useRealm(); const { realm } = useRealm();
const serverInfo = useServerInfo(); const serverInfo = useServerInfo();
const history = useHistory();
const enabledFeatures = xor( const enabledFeatures = xor(
serverInfo.profileInfo?.disabledFeatures, serverInfo.profileInfo?.disabledFeatures,
@ -67,18 +84,25 @@ const Dashboard = () => {
serverInfo.profileInfo?.previewFeatures serverInfo.profileInfo?.previewFeatures
); );
const isExperimentalFeature = (feature: string) => { const isExperimentalFeature = (feature: string) =>
return serverInfo.profileInfo?.experimentalFeatures?.includes(feature); serverInfo.profileInfo?.experimentalFeatures?.includes(feature);
};
const isPreviewFeature = (feature: string) => { const isPreviewFeature = (feature: string) =>
return serverInfo.profileInfo?.previewFeatures?.includes(feature); serverInfo.profileInfo?.previewFeatures?.includes(feature);
};
if (Object.keys(serverInfo).length === 0) { if (Object.keys(serverInfo).length === 0) {
return <KeycloakSpinner />; return <KeycloakSpinner />;
} }
const route = (tab: DashboardTab) =>
routableTab({
to: toDashboard({
realm,
tab,
}),
history,
});
return ( return (
<> <>
<PageSection variant="light"> <PageSection variant="light">
@ -94,79 +118,138 @@ const Dashboard = () => {
</Text> </Text>
</TextContent> </TextContent>
</PageSection> </PageSection>
<PageSection> <PageSection variant="light" className="pf-u-p-0">
<Grid hasGutter> <RoutableTabs
<GridItem lg={2} sm={12}> data-testid="dashboard-tabs"
<Card className="keycloak__dashboard_card"> defaultLocation={toDashboard({
<CardTitle>{t("serverInfo")}</CardTitle> realm,
<CardBody> tab: "info",
<DescriptionList> })}
<DescriptionListGroup> isBox
<DescriptionListTerm>{t("version")}</DescriptionListTerm> mountOnEnter
<DescriptionListDescription> >
{serverInfo.systemInfo?.version} <Tab
</DescriptionListDescription> id="info"
<DescriptionListTerm>{t("product")}</DescriptionListTerm> data-testid="infoTab"
<DescriptionListDescription> title={<TabTitleText>{t("realmInfo")}</TabTitleText>}
{toUpperCase(serverInfo.profileInfo?.name!)} {...route("info")}
</DescriptionListDescription> >
</DescriptionListGroup> <PageSection variant="light">
</DescriptionList> <Grid hasGutter>
</CardBody> <GridItem lg={2} sm={12}>
</Card> <Card className="keycloak__dashboard_card">
</GridItem> <CardTitle>{t("serverInfo")}</CardTitle>
<GridItem lg={10} sm={12}> <CardBody>
<Card className="keycloak__dashboard_card"> <DescriptionList>
<CardTitle>{t("profile")}</CardTitle> <DescriptionListGroup>
<CardBody> <DescriptionListTerm>
<DescriptionList> {t("version")}
<DescriptionListGroup> </DescriptionListTerm>
<DescriptionListTerm> <DescriptionListDescription>
{t("enabledFeatures")}{" "} {serverInfo.systemInfo?.version}
<HelpItem </DescriptionListDescription>
fieldLabelId="dashboard:enabledFeatures" <DescriptionListTerm>
helpText="dashboard:infoEnabledFeatures" {t("product")}
/> </DescriptionListTerm>
</DescriptionListTerm> <DescriptionListDescription>
<DescriptionListDescription> {toUpperCase(serverInfo.profileInfo?.name!)}
<List variant={ListVariant.inline}> </DescriptionListDescription>
{enabledFeatures.map((feature) => ( </DescriptionListGroup>
<ListItem key={feature}> </DescriptionList>
{feature}{" "} </CardBody>
{isExperimentalFeature(feature) ? ( </Card>
<Label color="orange">{t("experimental")}</Label> </GridItem>
) : null} <GridItem lg={10} sm={12}>
{isPreviewFeature(feature) ? ( <Card className="keycloak__dashboard_card">
<Label color="blue">{t("preview")}</Label> <CardTitle>{t("profile")}</CardTitle>
) : null} <CardBody>
</ListItem> <DescriptionList>
))} <DescriptionListGroup>
</List> <DescriptionListTerm>
</DescriptionListDescription> {t("enabledFeatures")}{" "}
</DescriptionListGroup> <HelpItem
<DescriptionListGroup> fieldLabelId="dashboard:enabledFeatures"
<DescriptionListTerm> helpText="dashboard:infoEnabledFeatures"
{t("disabledFeatures")}{" "} />
<HelpItem </DescriptionListTerm>
fieldLabelId="dashboard:disabledFeatures" <DescriptionListDescription>
helpText="dashboard:infoDisabledFeatures" <List variant={ListVariant.inline}>
/> {enabledFeatures.map((feature) => (
</DescriptionListTerm> <ListItem key={feature}>
<DescriptionListDescription> {feature}{" "}
<List variant={ListVariant.inline}> {isExperimentalFeature(feature) ? (
{serverInfo.profileInfo?.disabledFeatures?.map( <Label color="orange">
(feature) => ( {t("experimental")}
<ListItem key={feature}>{feature}</ListItem> </Label>
) ) : null}
)} {isPreviewFeature(feature) ? (
</List> <Label color="blue">{t("preview")}</Label>
</DescriptionListDescription> ) : null}
</DescriptionListGroup> </ListItem>
</DescriptionList> ))}
</CardBody> </List>
</Card> </DescriptionListDescription>
</GridItem> </DescriptionListGroup>
</Grid> <DescriptionListGroup>
<DescriptionListTerm>
{t("disabledFeatures")}{" "}
<HelpItem
fieldLabelId="dashboard:disabledFeatures"
helpText="dashboard:infoDisabledFeatures"
/>
</DescriptionListTerm>
<DescriptionListDescription>
<List variant={ListVariant.inline}>
{serverInfo.profileInfo?.disabledFeatures?.map(
(feature) => (
<ListItem key={feature}>{feature}</ListItem>
)
)}
</List>
</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionList>
</CardBody>
</Card>
</GridItem>
</Grid>
</PageSection>
</Tab>
<Tab
id="providers"
data-testid="providersTab"
title={<TabTitleText>{t("providerInfo")}</TabTitleText>}
{...route("providers")}
>
<PageSection variant="light">
<TableComposable variant="compact">
<Thead>
<Tr>
<Th width={20}>{t("spi")}</Th>
<Th>{t("providers")}</Th>
</Tr>
</Thead>
<Tbody>
{Object.keys(serverInfo.providers || []).map((name) => (
<Tr key={name}>
<Td>{name}</Td>
<Td>
<ul>
{Object.keys(
serverInfo.providers?.[name].providers || []
).map((value) => (
<li key={value}>{value}</li>
))}
</ul>
</Td>
</Tr>
))}
</Tbody>
</TableComposable>
<ul></ul>
</PageSection>
</Tab>
</RoutableTabs>
</PageSection> </PageSection>
</> </>
); );

View file

@ -3,10 +3,12 @@ import { lazy } from "react";
import { generatePath } from "react-router-dom"; import { generatePath } from "react-router-dom";
import type { RouteDef } from "../../route-config"; import type { RouteDef } from "../../route-config";
export type DashboardParams = { realm?: string }; export type DashboardTab = "info" | "providers";
export type DashboardParams = { realm?: string; tab?: DashboardTab };
export const DashboardRoute: RouteDef = { export const DashboardRoute: RouteDef = {
path: "/:realm?", path: "/:realm?/:tab?",
component: lazy(() => import("../Dashboard")), component: lazy(() => import("../Dashboard")),
breadcrumb: (t) => t("common:home"), breadcrumb: (t) => t("common:home"),
access: "anyone", access: "anyone",

View file

@ -43,7 +43,7 @@ export const routes: RouteDef[] = [
...sessionRoutes, ...sessionRoutes,
...userFederationRoutes, ...userFederationRoutes,
...userRoutes, ...userRoutes,
...dashboardRoutes,
...groupsRoutes, ...groupsRoutes,
...dashboardRoutes,
NotFoundRoute, NotFoundRoute,
]; ];