diff --git a/src/App.tsx b/src/App.tsx
index a46a18ec98..afdeb3375a 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -29,66 +29,52 @@ export const App = () => {
} isManagedSidebar sidebar={}>
-
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
diff --git a/src/client-scopes/ClientScopesSection.tsx b/src/client-scopes/ClientScopesSection.tsx
index ef8cc2d287..e8210c6c64 100644
--- a/src/client-scopes/ClientScopesSection.tsx
+++ b/src/client-scopes/ClientScopesSection.tsx
@@ -1,5 +1,10 @@
+import { PageSection } from "@patternfly/react-core";
import React from "react";
export const ClientScopesSection = () => {
- return <>The Client Scopes Page>;
+ return (
+ <>
+ The Client Scopes Page
+ >
+ );
};
diff --git a/src/clients/ClientsSection.tsx b/src/clients/ClientsSection.tsx
index 07c4b2c1a2..598b9a23dc 100644
--- a/src/clients/ClientsSection.tsx
+++ b/src/clients/ClientsSection.tsx
@@ -1,7 +1,7 @@
import React, { useState, useContext } from "react";
import { useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
-import { Button } from "@patternfly/react-core";
+import { Button, PageSection } from "@patternfly/react-core";
import { DataLoader } from "../components/data-loader/DataLoader";
import { TableToolbar } from "../components/table-toolbar/TableToolbar";
@@ -28,35 +28,40 @@ export const ClientsSection = () => {
};
return (
-
- {(clients) => (
- {
- setFirst(f);
- setMax(m);
- }}
- toolbarItem={
- <>
-
-
- >
- }
- >
-
-
- )}
-
+
+
+ {(clients) => (
+ {
+ setFirst(f);
+ setMax(m);
+ }}
+ toolbarItem={
+ <>
+
+
+ >
+ }
+ >
+
+
+ )}
+
+
);
};
diff --git a/src/events/EventsSection.tsx b/src/events/EventsSection.tsx
index fad54953ba..27e937679d 100644
--- a/src/events/EventsSection.tsx
+++ b/src/events/EventsSection.tsx
@@ -1,5 +1,10 @@
+import { PageSection } from "@patternfly/react-core";
import React from "react";
export const EventsSection = () => {
- return <>The Events Page>;
+ return (
+ <>
+ The Events Page
+ >
+ );
};
diff --git a/src/groups/GroupsSection.tsx b/src/groups/GroupsSection.tsx
index 1f9f895419..c49c029de1 100644
--- a/src/groups/GroupsSection.tsx
+++ b/src/groups/GroupsSection.tsx
@@ -1,7 +1,7 @@
import React, { useContext, useState } from "react";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
-import { Button } from "@patternfly/react-core";
+import { Button, PageSection } from "@patternfly/react-core";
import { HttpClientContext } from "../http-service/HttpClientContext";
import { GroupsList } from "./GroupsList";
@@ -24,30 +24,32 @@ export const GroupsSection = () => {
return (
<>
-
- {(groups) => (
- {
- setFirst(f);
- setMax(m);
- }}
- toolbarItem={
- <>
-
- >
- }
- >
-
-
- )}
-
+
+
+ {(groups) => (
+ {
+ setFirst(f);
+ setMax(m);
+ }}
+ toolbarItem={
+ <>
+
+ >
+ }
+ >
+
+
+ )}
+
+
>
);
};
diff --git a/src/i18n.ts b/src/i18n.ts
index d58c7ed28a..1453e643af 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -5,13 +5,14 @@ import { initReactI18next } from "react-i18next";
import common from "./common-messages.json";
import clients from "./clients/messages.json";
import realm from "./realm/messages.json";
+import roles from "./realm-roles/messages.json";
import help from "./help.json";
const initOptions = {
- ns: ["common", "help", "clients", "realm"],
+ ns: ["common", "help", "clients", "realm", "roles"],
defaultNS: "common",
resources: {
- en: { ...common, ...help, ...clients, ...realm },
+ en: { ...common, ...help, ...clients, ...realm, ...roles },
},
lng: "en",
fallbackLng: "en",
diff --git a/src/model/role-model.ts b/src/model/role-model.ts
new file mode 100644
index 0000000000..377aaa7b8e
--- /dev/null
+++ b/src/model/role-model.ts
@@ -0,0 +1,19 @@
+// Generated using typescript-generator version 2.0.400 on 2020-09-11 12:02:07.
+
+export interface RoleRepresentation {
+ id?: string;
+ name?: string;
+ description?: string;
+ scopeParamRequired?: boolean;
+ composite?: boolean;
+ composites?: Composites;
+ clientRole?: boolean;
+ containerId?: string;
+ attributes?: { [index: string]: string[] };
+}
+
+export interface Composites {
+ realm?: string[];
+ client?: { [index: string]: string[] };
+ application?: { [index: string]: string[] };
+}
diff --git a/src/realm-roles/NoRealmRoles.tsx b/src/realm-roles/NoRealmRoles.tsx
new file mode 100644
index 0000000000..1e28359f33
--- /dev/null
+++ b/src/realm-roles/NoRealmRoles.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import {
+ Button,
+ PageSection,
+ EmptyState,
+ EmptyStateVariant,
+ EmptyStateIcon,
+ Title,
+ EmptyStateBody,
+} from "@patternfly/react-core";
+import { useHistory } from "react-router-dom";
+
+import { PlusCircleIcon } from "@patternfly/react-icons";
+import { useTranslation } from "react-i18next";
+
+export const NoRealmRolesPage = () => {
+ const { t } = useTranslation("realm");
+ const history = useHistory();
+ return (
+ <>
+
+
+
+
+ {t("noRealmRoles")}
+
+ {t("emptyStateText")}
+
+
+
+ >
+ );
+};
diff --git a/src/realm-roles/RealmRolesSection.tsx b/src/realm-roles/RealmRolesSection.tsx
index 62b150db95..e7e2460d92 100644
--- a/src/realm-roles/RealmRolesSection.tsx
+++ b/src/realm-roles/RealmRolesSection.tsx
@@ -1,5 +1,78 @@
-import React from "react";
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import React, { useState, useContext, useEffect } from "react";
+import { useHistory } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+import {
+ Button,
+ Divider,
+ Page,
+ PageSection,
+ PageSectionVariants,
+ Text,
+ TextContent,
+} from "@patternfly/react-core";
+
+import { DataLoader } from "../components/data-loader/DataLoader";
+import { TableToolbar } from "../components/table-toolbar/TableToolbar";
+import { HttpClientContext } from "../http-service/HttpClientContext";
+import { RoleRepresentation } from "../model/role-model";
+import { RolesList } from "./RoleList";
+import { RealmContext } from "../components/realm-context/RealmContext";
export const RealmRolesSection = () => {
- return <>The Realm Roles Page>;
+ const { t } = useTranslation("roles");
+ const history = useHistory();
+ const [max, setMax] = useState(10);
+ const [, setRoles] = useState([] as RoleRepresentation[]);
+ const [first, setFirst] = useState(0);
+ const httpClient = useContext(HttpClientContext)!;
+ const { realm } = useContext(RealmContext);
+
+ const loader = async () => {
+ return await httpClient
+ .doGet(`/admin/realms/${realm}/roles`)
+ .then((r) => r.data as RoleRepresentation[]);
+ };
+
+ useEffect(() => {
+ loader().then((result) => setRoles(result || []));
+ }, []);
+
+ return (
+
+ {(roles) => (
+ <>
+
+
+ Realm roles
+ {t("roleExplain")}
+
+
+
+
+ {
+ setFirst(f);
+ setMax(m);
+ }}
+ toolbarItem={
+ <>
+
+ >
+ }
+ >
+
+
+
+ >
+ )}
+
+ );
};
diff --git a/src/realm-roles/RoleList.tsx b/src/realm-roles/RoleList.tsx
new file mode 100644
index 0000000000..7e9b233c4a
--- /dev/null
+++ b/src/realm-roles/RoleList.tsx
@@ -0,0 +1,79 @@
+import React from "react";
+import { useTranslation } from "react-i18next";
+
+import {
+ Table,
+ TableBody,
+ TableHeader,
+ TableVariant,
+ IFormatter,
+ IFormatterValueType,
+} from "@patternfly/react-table";
+
+import { ExternalLink } from "../components/external-link/ExternalLink";
+import { RoleRepresentation } from "../model/role-model";
+
+type RolesListProps = {
+ roles?: RoleRepresentation[];
+};
+
+const columns: (keyof RoleRepresentation)[] = [
+ "name",
+ "composite",
+ "description",
+];
+
+export const RolesList = ({ roles }: RolesListProps) => {
+ const { t } = useTranslation("roles");
+
+ const emptyFormatter = (): IFormatter => (data?: IFormatterValueType) => {
+ return data ? data : "—";
+ };
+
+ const externalLink = (): IFormatter => (data?: IFormatterValueType) => {
+ return (data ? (
+
+ ) : undefined) as object;
+ };
+
+ const boolFormatter = (): IFormatter => (data?: IFormatterValueType) => {
+ const boolVal = data?.toString();
+
+ return (boolVal
+ ? boolVal.charAt(0).toUpperCase() + boolVal.slice(1)
+ : undefined) as string;
+ };
+
+ const data = roles!.map((c) => {
+ return { cells: columns.map((col) => c[col]) };
+ });
+ return (
+
+ );
+};
diff --git a/src/realm-roles/__tests__/mock-roles.json b/src/realm-roles/__tests__/mock-roles.json
new file mode 100644
index 0000000000..e98cefd363
--- /dev/null
+++ b/src/realm-roles/__tests__/mock-roles.json
@@ -0,0 +1,77 @@
+[
+ {
+ "name":"Admin",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Author",
+ "composite":false,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Billing",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit"
+ },
+ {
+ "name":"Contributor",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit, consecte"
+ },
+ {
+ "name":"Editor",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Engineer",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Member",
+ "composite":false,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Moderator",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Owner",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Reader",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ },
+ {
+ "name":"Subscriber",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit "
+ },
+ {
+ "name":"Teenager",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet, consecte occaecat"
+ },
+ {
+ "name":"User",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet, consecte"
+ },
+ {
+ "name":"Writer",
+ "composite":true,
+ "description": "Lorem ipsum dolor"
+ },
+ {
+ "name":"Zara",
+ "composite":true,
+ "description": "Lorem ipsum dolor sit amet"
+ }
+ ]
\ No newline at end of file
diff --git a/src/realm-roles/messages.json b/src/realm-roles/messages.json
new file mode 100644
index 0000000000..8e434d5d15
--- /dev/null
+++ b/src/realm-roles/messages.json
@@ -0,0 +1,22 @@
+{
+ "roles": {
+ "createRole": "Create role",
+ "importRole": "Import role",
+ "roleID": "Role ID",
+ "type": "Type",
+ "homeURL": "Home URL",
+ "roleExplain": "Realm-level roles are a global namespace to define your roles.",
+ "roleName": "Role name",
+ "composite": "Composite",
+ "description": "Description",
+ "roleList": "Role list",
+ "generalSettings": "General Settings",
+ "capabilityConfig": "Capability config",
+ "roleImportError": "Could not import role",
+ "roleImportSuccess": "Role imported succeful",
+ "roleDeletedSucess": "The role has been deleted",
+ "roleDeleteError": "Could not delete role:",
+ "roleAuthentication": "Role authentication"
+ }
+ }
+
\ No newline at end of file
diff --git a/src/realm/messages.json b/src/realm/messages.json
index a14b6d5a93..061d91f158 100644
--- a/src/realm/messages.json
+++ b/src/realm/messages.json
@@ -3,6 +3,9 @@
"uploadFile":"Upload JSON file",
"realmName":"Realm name",
"enabled":"Enabled",
- "create":"Create"
+ "create":"Create",
+ "createRealm": "Create realm",
+ "noRealmRoles": "No realm roles",
+ "emptyStateText": "There aren't any realm roles in this realm. Create a realm role to get started."
}
}
diff --git a/src/sessions/SessionsSection.tsx b/src/sessions/SessionsSection.tsx
index c4cb3de3dd..5224ccc534 100644
--- a/src/sessions/SessionsSection.tsx
+++ b/src/sessions/SessionsSection.tsx
@@ -1,5 +1,13 @@
+import { PageSection } from "@patternfly/react-core";
import React from "react";
export const SessionsSection = () => {
- return <>The Sessions Page>;
+ return (
+ <>
+ <>
+ The Sessions Page
+ >
+ ;
+ >
+ );
};
diff --git a/src/stories/RealmForm.stories.tsx b/src/stories/RealmForm.stories.tsx
index 34960d6e2b..f8a1afd24d 100644
--- a/src/stories/RealmForm.stories.tsx
+++ b/src/stories/RealmForm.stories.tsx
@@ -4,7 +4,7 @@ import { Page } from "@patternfly/react-core";
import { NewRealmForm } from "../realm/add/NewRealmForm";
export default {
- title: "New reaml form",
+ title: "New realm form",
component: NewRealmForm,
} as Meta;
diff --git a/src/stories/RealmRoles.stories.tsx b/src/stories/RealmRoles.stories.tsx
new file mode 100644
index 0000000000..6b15dd2137
--- /dev/null
+++ b/src/stories/RealmRoles.stories.tsx
@@ -0,0 +1,11 @@
+import React from "react";
+import { Meta } from "@storybook/react";
+import { RolesList } from "../realm-roles/RoleList";
+import rolesMock from "../realm-roles/__tests__/mock-roles.json";
+
+export default {
+ title: "Roles List",
+ component: RolesList,
+} as Meta;
+
+export const RolesListExample = () => ;
diff --git a/src/user/UsersSection.tsx b/src/user/UsersSection.tsx
index e0f7176e30..7502e7fa6b 100644
--- a/src/user/UsersSection.tsx
+++ b/src/user/UsersSection.tsx
@@ -1,5 +1,10 @@
+import { PageSection } from "@patternfly/react-core";
import React from "react";
export const UsersSection = () => {
- return <>The Users Page>;
+ return (
+ <>
+ The Users Page
+ >
+ );
};