From bf4cae6735ffd07ec188ab878aa236eb5a2c1df1 Mon Sep 17 00:00:00 2001 From: Eugenia <32821331+jenny-s51@users.noreply.github.com> Date: Mon, 22 Mar 2021 04:14:24 -0400 Subject: [PATCH] Changes from Realm Roles UX Review [List] (#433) * realm roles UX review progress wip * filter realm roles on Enter key press, add filter functionality * remove chip group filters * clean up * format * filterChips logic now in table toolbar * fix lint and format * save with erik * remove filter chips functionality * fix check-types * fix realm roles cypress test * format * revert changes to group attributes * cypress test * use filter * remove log * remove unused prop --- cypress/integration/realm_roles_test.spec.ts | 2 - .../manage/realm_roles/AssociatedRolesPage.ts | 4 +- .../manage/realm_roles/CreateRealmRolePage.ts | 4 +- .../attribute-form/AttributeForm.tsx | 4 +- .../table-toolbar/KeycloakDataTable.tsx | 18 +- .../table-toolbar/PaginatingTableToolbar.tsx | 19 +-- src/components/table-toolbar/TableToolbar.tsx | 42 +++-- src/realm-roles/AssociatedRolesTab.tsx | 4 +- src/realm-roles/RealmRoleForm.tsx | 30 ++-- src/realm-roles/RealmRoleTabs.tsx | 15 +- src/realm-roles/RealmRolesSection.css | 5 + src/realm-roles/RealmRolesSection.tsx | 35 +++- src/realm-roles/RoleAttributes.tsx | 160 ++++++++++++++++++ src/realm-roles/RolesList.tsx | 1 + src/realm-roles/messages.json | 3 +- src/user/UsersSection.tsx | 18 +- 16 files changed, 294 insertions(+), 70 deletions(-) create mode 100644 src/realm-roles/RoleAttributes.tsx diff --git a/cypress/integration/realm_roles_test.spec.ts b/cypress/integration/realm_roles_test.spec.ts index aecc44eb5f..8547da7ec4 100644 --- a/cypress/integration/realm_roles_test.spec.ts +++ b/cypress/integration/realm_roles_test.spec.ts @@ -73,8 +73,6 @@ describe("Realm roles test", function () { masthead.checkNotificationMessage("Role created"); - cy.wait(100); - // Add associated realm role associatedRolesPage.addAssociatedRealmRole(); diff --git a/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts b/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts index 1d8fe1dbd2..6be736ea4b 100644 --- a/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts +++ b/cypress/support/pages/admin_console/manage/realm_roles/AssociatedRolesPage.ts @@ -29,7 +29,7 @@ export default class AssociatedRolesPage { cy.wait(100); - cy.get(this.checkbox).eq(1).check(); + cy.get(this.checkbox).eq(2).check(); cy.get(this.addAssociatedRolesModalButton).contains("Add").click(); @@ -53,7 +53,7 @@ export default class AssociatedRolesPage { cy.wait(2500); - cy.get(this.checkbox).eq(40).check({ force: true }); + cy.get(this.checkbox).eq(12).check({ force: true }); cy.get(this.addAssociatedRolesModalButton).contains("Add").click(); diff --git a/cypress/support/pages/admin_console/manage/realm_roles/CreateRealmRolePage.ts b/cypress/support/pages/admin_console/manage/realm_roles/CreateRealmRolePage.ts index 86636dd1a8..7b4260db90 100644 --- a/cypress/support/pages/admin_console/manage/realm_roles/CreateRealmRolePage.ts +++ b/cypress/support/pages/admin_console/manage/realm_roles/CreateRealmRolePage.ts @@ -10,7 +10,7 @@ export default class CreateRealmRolePage { this.realmRoleNameError = "#kc-name-helper"; this.realmRoleDescriptionInput = "#kc-role-description"; - this.saveBtn = '[type="submit"]'; + this.saveBtn = 'realm-roles-save-button'; this.cancelBtn = '[type="button"]'; } @@ -37,7 +37,7 @@ export default class CreateRealmRolePage { //#endregion save() { - cy.get(this.saveBtn).click(); + cy.getId(this.saveBtn).click(); return this; } diff --git a/src/components/attribute-form/AttributeForm.tsx b/src/components/attribute-form/AttributeForm.tsx index af828c3611..8e2cd7aec1 100644 --- a/src/components/attribute-form/AttributeForm.tsx +++ b/src/components/attribute-form/AttributeForm.tsx @@ -58,9 +58,9 @@ export const attributesToArray = (attributes?: { export const AttributesForm = ({ form: { handleSubmit, register, formState, errors, watch }, - save, array: { fields, append, remove }, reset, + save, }: AttributesFormProps) => { const { t } = useTranslation("roles"); @@ -96,7 +96,7 @@ export const AttributesForm = ({ > ({ const [max, setMax] = useState(10); const [first, setFirst] = useState(0); - const [search, setSearch] = useState(""); + const [search, setSearch] = useState(""); const [key, setKey] = useState(0); const refresh = () => setKey(new Date().getTime()); @@ -172,7 +172,7 @@ export function KeycloakDataTable({ }, handleError ); - }, [key, first, max]); + }, [key, first, max, search]); const getNodeText = (node: keyof T | JSX.Element): string => { if (["string", "number"].includes(typeof node)) { @@ -197,6 +197,7 @@ export function KeycloakDataTable({ ) ) ); + setSearch; }; const convertAction = () => @@ -214,13 +215,6 @@ export function KeycloakDataTable({ return action; }); - const searchOnChange = (value: string) => { - if (value === "") { - refresh(); - } - setSearch(value); - }; - const Loading = () => (
@@ -258,8 +252,7 @@ export function KeycloakDataTable({ inputGroupName={ searchPlaceholderKey ? `${ariaLabelKey}input` : undefined } - inputGroupOnChange={searchOnChange} - inputGroupOnClick={refresh} + inputGroupOnEnter={setSearch} inputGroupPlaceholder={t(searchPlaceholderKey || "")} searchTypeComponent={searchTypeComponent} toolbarItem={toolbarItem} @@ -291,8 +284,7 @@ export function KeycloakDataTable({ inputGroupName={ searchPlaceholderKey ? `${ariaLabelKey}input` : undefined } - inputGroupOnChange={searchOnChange} - inputGroupOnClick={() => filter(search)} + inputGroupOnEnter={(search) => filter(search)} inputGroupPlaceholder={t(searchPlaceholderKey || "")} toolbarItem={toolbarItem} searchTypeComponent={searchTypeComponent} diff --git a/src/components/table-toolbar/PaginatingTableToolbar.tsx b/src/components/table-toolbar/PaginatingTableToolbar.tsx index 2366064712..3dba84b6f4 100644 --- a/src/components/table-toolbar/PaginatingTableToolbar.tsx +++ b/src/components/table-toolbar/PaginatingTableToolbar.tsx @@ -1,4 +1,4 @@ -import React, { MouseEventHandler } from "react"; +import React from "react"; import { Pagination, ToggleTemplateProps, @@ -22,7 +22,7 @@ type TableToolbarProps = { newInput: string, event: React.FormEvent ) => void; - inputGroupOnClick?: MouseEventHandler; + inputGroupOnEnter?: (value: string) => void; }; export const PaginatingTableToolbar = ({ @@ -38,7 +38,7 @@ export const PaginatingTableToolbar = ({ inputGroupName, inputGroupPlaceholder, inputGroupOnChange, - inputGroupOnClick, + inputGroupOnEnter, }: TableToolbarProps) => { const page = Math.round(first / max); const pagination = (variant: "top" | "bottom" = "top") => ( @@ -59,24 +59,23 @@ export const PaginatingTableToolbar = ({ /> ); + if (count === 0) { + <>{children}; + } return ( {toolbarItem} - {count !== 0 && ( - {pagination()} - )} + {pagination()} } - toolbarItemFooter={ - count !== 0 && {pagination("bottom")} - } + toolbarItemFooter={{pagination("bottom")}} inputGroupName={inputGroupName} inputGroupPlaceholder={inputGroupPlaceholder} inputGroupOnChange={inputGroupOnChange} - inputGroupOnClick={inputGroupOnClick} + inputGroupOnEnter={inputGroupOnEnter} > {children} diff --git a/src/components/table-toolbar/TableToolbar.tsx b/src/components/table-toolbar/TableToolbar.tsx index 88a0027e00..0c4c9d080a 100644 --- a/src/components/table-toolbar/TableToolbar.tsx +++ b/src/components/table-toolbar/TableToolbar.tsx @@ -1,9 +1,4 @@ -import React, { - FormEvent, - Fragment, - MouseEventHandler, - ReactNode, -} from "react"; +import React, { FormEvent, Fragment, ReactNode } from "react"; import { Toolbar, ToolbarContent, @@ -28,7 +23,7 @@ type TableToolbarProps = { newInput: string, event: FormEvent ) => void; - inputGroupOnClick?: MouseEventHandler; + inputGroupOnEnter?: (value: string) => void; }; export const TableToolbar = ({ @@ -39,9 +34,35 @@ export const TableToolbar = ({ inputGroupName, inputGroupPlaceholder, inputGroupOnChange, - inputGroupOnClick, + inputGroupOnEnter, }: TableToolbarProps) => { const { t } = useTranslation(); + const [searchValue, setSearchValue] = React.useState(""); + + const onSearch = () => { + if (searchValue !== "") { + setSearchValue(searchValue); + inputGroupOnEnter && inputGroupOnEnter(searchValue); + } else { + setSearchValue(""); + inputGroupOnEnter && inputGroupOnEnter(""); + } + }; + + const handleKeyDown = (e: any) => { + if (e.key === "Enter") { + onSearch(); + } + }; + + const handleInputChange = ( + value: string, + event: FormEvent + ) => { + inputGroupOnChange && inputGroupOnChange(value, event); + setSearchValue(value); + }; + return ( <> @@ -59,12 +80,13 @@ export const TableToolbar = ({ type="search" aria-label={t("search")} placeholder={inputGroupPlaceholder} - onChange={inputGroupOnChange} + onChange={handleInputChange} + onKeyDown={handleKeyDown} /> diff --git a/src/realm-roles/AssociatedRolesTab.tsx b/src/realm-roles/AssociatedRolesTab.tsx index 1ee4362355..e27b7efd30 100644 --- a/src/realm-roles/AssociatedRolesTab.tsx +++ b/src/realm-roles/AssociatedRolesTab.tsx @@ -123,8 +123,6 @@ export const AssociatedRolesTab = ({ ); }; - console.log(inheritanceMap); - const toggleModal = () => setOpen(!open); const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ @@ -173,7 +171,7 @@ export const AssociatedRolesTab = ({ const goToCreate = () => history.push(`${url}/add-role`); return ( <> - + ; - save: (role: RoleFormType) => void; + save: () => void; editMode: boolean; reset: () => void; }; export const RealmRoleForm = ({ - form, + form: { handleSubmit, errors, register }, save, editMode, reset, }: RealmRoleFormProps) => { const { t } = useTranslation("roles"); + return ( @@ -38,11 +38,11 @@ export const RealmRoleForm = ({ label={t("roleName")} fieldId="kc-name" isRequired - validated={form.errors.name ? "error" : "default"} + validated={errors.name ? "error" : "default"} helperTextInvalid={t("common:required")} >