Adds tab for realm role details + update/save functionality (#228)

* add file for realm role details

* add details and attributes tabs

* clean up a bit

* get name working

* add reload

* fix route config

* fix prettier

* call with Don

* header and description working

* update route-config.ts

* wrap in FormAccess component

* name input gets value from call

* try to get save working

* feedback from Erik

* more feedback from Erik

* fix formatting

* format

* address PR feedback from Erik

* delete comment

* set name field to read-only

* delete defaultValue prop
This commit is contained in:
Eugenia 2020-11-23 10:20:21 -05:00 committed by GitHub
parent 147be1d6b2
commit dc2ceef27b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 24 deletions

View file

@ -26,6 +26,7 @@
"disabled": "Disabled", "disabled": "Disabled",
"disable": "Disable", "disable": "Disable",
"selectOne": "Select an option", "selectOne": "Select an option",
"reload": "Reload",
"signOut": "Sign out", "signOut": "Sign out",
"manageAccount": "Manage account", "manageAccount": "Manage account",

View file

@ -1,7 +1,8 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { useHistory } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { import {
ActionGroup, ActionGroup,
AlertVariant,
Button, Button,
FormGroup, FormGroup,
PageSection, PageSection,
@ -10,24 +11,60 @@ import {
TabTitleText, TabTitleText,
TextArea, TextArea,
TextInput, TextInput,
ValidatedOptions,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import { ViewHeader } from "../components/view-header/ViewHeader";
import { RoleRepresentation } from "../model/role-model";
import { FormAccess } from "../components/form-access/FormAccess"; import { FormAccess } from "../components/form-access/FormAccess";
export const RolesForm = () => { import { useAlerts } from "../components/alert/Alerts";
const { t } = useTranslation("client-scopes"); import { ViewHeader } from "../components/view-header/ViewHeader";
const { register, errors } = useForm<RoleRepresentation>();
const history = useHistory();
import { useAdminClient } from "../context/auth/AdminClient";
import RoleRepresentation from "keycloak-admin/lib/defs/roleRepresentation";
export const RolesForm = () => {
const { t } = useTranslation("roles");
const { register, handleSubmit, errors, control, setValue } = useForm<
RoleRepresentation
>();
const history = useHistory();
const [name, setName] = useState("");
const [activeTab, setActiveTab] = useState(0); const [activeTab, setActiveTab] = useState(0);
const adminClient = useAdminClient();
const { id } = useParams<{ id: string }>();
const { addAlert } = useAlerts();
useEffect(() => {
(async () => {
const fetchedRole = await adminClient.roles.findOneById({ id });
setName(fetchedRole.name!);
setupForm(fetchedRole);
})();
}, []);
const setupForm = (role: RoleRepresentation) => {
Object.entries(role).map((entry) => {
setValue(entry[0], entry[1]);
});
};
const save = async (role: RoleRepresentation) => {
try {
await adminClient.roles.updateById({ id }, role);
setupForm(role as RoleRepresentation);
addAlert(t("roleSaveSuccess"), AlertVariant.success);
} catch (error) {
addAlert(`${t("roleSaveError")} '${error}'`, AlertVariant.danger);
}
};
return ( return (
<> <>
<ViewHeader titleKey={"Role Name"} subKey="" /> <ViewHeader titleKey={name} subKey="" />
<PageSection variant="light"> <PageSection variant="light">
<Tabs <Tabs
@ -35,28 +72,49 @@ export const RolesForm = () => {
onSelect={(_, key) => setActiveTab(key as number)} onSelect={(_, key) => setActiveTab(key as number)}
isBox isBox
> >
<Tab eventKey={0} title={<TabTitleText>{t("Details")}</TabTitleText>}> <Tab eventKey={0} title={<TabTitleText>{t("details")}</TabTitleText>}>
<FormAccess isHorizontal role="manage-realm" className="pf-u-mt-lg"> <FormAccess
isHorizontal
onSubmit={handleSubmit(save)}
role="manage-realm"
className="pf-u-mt-lg"
>
<FormGroup <FormGroup
label={t("Role name")} label={t("roleName")}
fieldId="kc-name" fieldId="kc-name"
isRequired isRequired
validated={errors.name ? "error" : "default"} validated={errors.name ? "error" : "default"}
helperTextInvalid={t("common:required")} helperTextInvalid={t("common:required")}
> >
<TextInput {name ? (
ref={register({ required: true })} <TextInput
type="text" ref={register({ required: true })}
id="kc-name" type="text"
name="name" id="kc-name"
/> name="name"
isReadOnly
/>
) : undefined}
</FormGroup> </FormGroup>
<FormGroup label={t("description")} fieldId="kc-description"> <FormGroup label={t("description")} fieldId="kc-description">
<TextArea <Controller
ref={register}
type="text"
id="kc-description"
name="description" name="description"
defaultValue=""
control={control}
rules={{ maxLength: 255 }}
render={({ onChange, value }) => (
<TextArea
type="text"
validated={
errors.description
? ValidatedOptions.error
: ValidatedOptions.default
}
id="kc-role-description"
value={value}
onChange={onChange}
/>
)}
/> />
</FormGroup> </FormGroup>
<ActionGroup> <ActionGroup>

View file

@ -8,8 +8,10 @@
"homeURL": "Home URL", "homeURL": "Home URL",
"roleExplain": "Realm-level roles are a global namespace to define your roles.", "roleExplain": "Realm-level roles are a global namespace to define your roles.",
"roleName": "Role name", "roleName": "Role name",
"roleDetails": "Role details",
"composite": "Composite", "composite": "Composite",
"description": "Description", "description": "Description",
"details": "Details",
"roleList": "Role list", "roleList": "Role list",
"generalSettings": "General Settings", "generalSettings": "General Settings",
"capabilityConfig": "Capability config", "capabilityConfig": "Capability config",
@ -21,6 +23,8 @@
"roleDeleteConfirmDialog": "This action will permanently delete the role {{selectedRoleName}} and cannot be undone.", "roleDeleteConfirmDialog": "This action will permanently delete the role {{selectedRoleName}} and cannot be undone.",
"roleDeletedSuccess": "The role has been deleted", "roleDeletedSuccess": "The role has been deleted",
"roleDeleteError": "Could not delete role:", "roleDeleteError": "Could not delete role:",
"roleSaveSuccess": "The role has been saved",
"roleSaveError": "Could not save role:",
"noRolesInThisRealm": "No roles in this realm", "noRolesInThisRealm": "No roles in this realm",
"noRolesInThisRealmInstructions": "You haven't created any roles in this realm. Create a role to get started.", "noRolesInThisRealmInstructions": "You haven't created any roles in this realm. Create a role to get started.",
"roleAuthentication": "Role authentication" "roleAuthentication": "Role authentication"