From 2a88d01e5e4bf3898ce5d367ee6a4ce29235d387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bl=C3=A4ttlinger?= <69153350+andreas-blaettlinger@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:00:45 +0200 Subject: [PATCH] Unify save-buttons in admin-ui (#30119) * #30118 Unify save-buttons in admin-ui Signed-off-by: Andreas Blaettlinger * #30118 Unify save-buttons in admin-ui Signed-off-by: Andreas Blaettlinger * Introduced props for naming the buttons in FixedButtonGroup Signed-off-by: Andreas Blaettlinger --------- Signed-off-by: Andreas Blaettlinger --- .../pages/admin-ui/manage/AttributesTab.ts | 2 +- .../pages/admin-ui/manage/KeyValueInput.ts | 2 +- .../realm_settings/RealmSettingsPage.ts | 4 +- .../admin-ui/manage/users/CreateUserPage.ts | 6 +- .../users/user_details/UserDetailsPage.ts | 2 +- .../src/components/form/FixedButtonGroup.tsx | 8 ++- .../key-value-form/AttributeForm.tsx | 23 +------- .../src/realm-settings/GeneralTab.tsx | 28 +++------- js/apps/admin-ui/src/user/UserForm.tsx | 55 +++++++------------ 9 files changed, 45 insertions(+), 85 deletions(-) diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/AttributesTab.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/AttributesTab.ts index 96fa33b39f..65624b3744 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/AttributesTab.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/AttributesTab.ts @@ -1,5 +1,5 @@ export default class AttributesTab { - #saveAttributeBtn = "save-attributes"; + #saveAttributeBtn = "attributes-save"; #attributesTab = "attributes"; #emptyState = "attributes-empty-state"; #addAttributeBtn: string; diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/KeyValueInput.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/KeyValueInput.ts index 8073b0c378..4a0d15b9e2 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/KeyValueInput.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/KeyValueInput.ts @@ -31,7 +31,7 @@ export default class KeyValueInput { } save() { - cy.findByTestId("save-attributes").click(); + cy.findByTestId("attributes-save").click(); return this; } diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts index 5de3fe8bc8..d947606805 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts @@ -11,8 +11,8 @@ enum RealmSettingsTab { const expect = chai.expect; export default class RealmSettingsPage extends CommonPage { - generalSaveBtn = "general-tab-save"; - generalRevertBtn = "general-tab-revert"; + generalSaveBtn = "realmSettingsGeneralTab-save"; + generalRevertBtn = "realmSettingsGeneralTab-revert"; themesSaveBtn = "themes-tab-save"; loginTab = "rs-login-tab"; emailTab = "rs-email-tab"; diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/CreateUserPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/CreateUserPage.ts index 854a6beb29..df19539f56 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/CreateUserPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/CreateUserPage.ts @@ -21,9 +21,9 @@ export default class CreateUserPage { this.addUserBtn = "add-user"; this.joinGroupsBtn = "join-groups-button"; this.joinBtn = "join-button"; - this.createBtn = "create-user"; - this.saveBtn = "save-user"; - this.cancelBtn = "cancel-create-user"; + this.createBtn = "user-creation-save"; + this.saveBtn = "user-creation-save"; + this.cancelBtn = "user-creation-revert"; } //#region General Settings diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/user_details/UserDetailsPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/user_details/UserDetailsPage.ts index beb3d9e474..52a9502922 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/user_details/UserDetailsPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/users/user_details/UserDetailsPage.ts @@ -19,7 +19,7 @@ export default class UserDetailsPage extends PageObject { constructor() { super(); - this.saveBtn = "save-user"; + this.saveBtn = "user-creation-save"; this.cancelBtn = "cancel-create-user"; this.emailInput = "email"; this.emailValue = () => "example" + "_" + uuid() + "@example.com"; diff --git a/js/apps/admin-ui/src/components/form/FixedButtonGroup.tsx b/js/apps/admin-ui/src/components/form/FixedButtonGroup.tsx index c7c4966423..0c8159357d 100644 --- a/js/apps/admin-ui/src/components/form/FixedButtonGroup.tsx +++ b/js/apps/admin-ui/src/components/form/FixedButtonGroup.tsx @@ -7,7 +7,9 @@ import style from "./fixed-buttons.module.css"; type FixedButtonGroupProps = ActionGroupProps & { name: string; save?: () => void; + saveText?: string; reset?: () => void; + resetText?: string; isSubmit?: boolean; isActive?: boolean; }; @@ -15,7 +17,9 @@ type FixedButtonGroupProps = ActionGroupProps & { export const FixedButtonsGroup = ({ name, save, + saveText, reset, + resetText, isSubmit = false, isActive = true, children, @@ -31,7 +35,7 @@ export const FixedButtonsGroup = ({ onClick={() => save?.()} type={isSubmit ? "submit" : "button"} > - {t("save")} + {!saveText ? t("save") : saveText} )} {reset && ( @@ -41,7 +45,7 @@ export const FixedButtonsGroup = ({ variant="link" onClick={() => reset()} > - {t("revert")} + {!resetText ? t("revert") : resetText} )} {children} diff --git a/js/apps/admin-ui/src/components/key-value-form/AttributeForm.tsx b/js/apps/admin-ui/src/components/key-value-form/AttributeForm.tsx index fcb6f19ae8..0953a55092 100644 --- a/js/apps/admin-ui/src/components/key-value-form/AttributeForm.tsx +++ b/js/apps/admin-ui/src/components/key-value-form/AttributeForm.tsx @@ -1,11 +1,10 @@ import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation"; -import { ActionGroup, Button } from "@patternfly/react-core"; import { FormProvider, UseFormReturn } from "react-hook-form"; -import { useTranslation } from "react-i18next"; import { FormAccess } from "../form/FormAccess"; import type { KeyValueType } from "./key-value-convert"; import { KeyValueInput } from "./KeyValueInput"; +import { FixedButtonsGroup } from "../form/FixedButtonGroup"; export type AttributeForm = Omit & { attributes?: KeyValueType[]; @@ -28,12 +27,8 @@ export const AttributesForm = ({ name = "attributes", isDisabled = false, }: AttributesFormProps) => { - const { t } = useTranslation(); const noSaveCancelButtons = !save && !reset; - const { - formState: { isDirty }, - handleSubmit, - } = form; + const { handleSubmit } = form; return ( {!noSaveCancelButtons && ( - - - - + )} ); diff --git a/js/apps/admin-ui/src/realm-settings/GeneralTab.tsx b/js/apps/admin-ui/src/realm-settings/GeneralTab.tsx index 2abac57ea7..a94bc190de 100644 --- a/js/apps/admin-ui/src/realm-settings/GeneralTab.tsx +++ b/js/apps/admin-ui/src/realm-settings/GeneralTab.tsx @@ -4,8 +4,6 @@ import { UserProfileConfig, } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata"; import { - ActionGroup, - Button, ClipboardCopy, FormGroup, PageSection, @@ -27,6 +25,7 @@ import { FormattedLink } from "../components/external-link/FormattedLink"; import { FormAccess } from "../components/form/FormAccess"; import { KeyValueInput } from "../components/key-value-form/KeyValueInput"; import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner"; +import { FixedButtonsGroup } from "../components/form/FixedButtonGroup"; import { useRealm } from "../context/realm-context/RealmContext"; import { addTrailingSlash, @@ -105,7 +104,7 @@ function RealmSettingsGeneralTabForm({ control, handleSubmit, setValue, - formState: { isDirty, errors }, + formState: { errors }, } = form; const isFeatureEnabled = useIsFeatureEnabled(); const isOrganizationsEnabled = isFeatureEnabled(Feature.Organizations); @@ -266,23 +265,12 @@ function RealmSettingsGeneralTabForm({ - - - - + diff --git a/js/apps/admin-ui/src/user/UserForm.tsx b/js/apps/admin-ui/src/user/UserForm.tsx index 3a60abf4e1..a2b348b296 100644 --- a/js/apps/admin-ui/src/user/UserForm.tsx +++ b/js/apps/admin-ui/src/user/UserForm.tsx @@ -4,14 +4,12 @@ import { UserProfileMetadata } from "@keycloak/keycloak-admin-client/lib/defs/us import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation"; import { FormErrorText, - FormSubmitButton, HelpItem, SwitchControl, TextControl, UserProfileFields, } from "@keycloak/keycloak-ui-shared"; import { - ActionGroup, AlertVariant, Button, Chip, @@ -26,7 +24,6 @@ import { TFunction } from "i18next"; import { useEffect, useState } from "react"; import { Controller, FormProvider, UseFormReturn } from "react-hook-form"; import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; import { useAdminClient } from "../admin-client"; import { DefaultSwitchControl } from "../components/SwitchControl"; import { useAlerts } from "../components/alert/Alerts"; @@ -39,7 +36,9 @@ import useFormatDate from "../utils/useFormatDate"; import { FederatedUserLink } from "./FederatedUserLink"; import { UserFormFields, toUserFormFields } from "./form-state"; import { toUsers } from "./routes/Users"; +import { FixedButtonsGroup } from "../components/form/FixedButtonGroup"; import { RequiredActionMultiSelect } from "./user-credentials/RequiredActionMultiSelect"; +import { useNavigate } from "react-router-dom"; export type BruteForced = { isBruteForceProtected?: boolean; @@ -79,15 +78,15 @@ export const UserForm = ({ const { whoAmI } = useWhoAmI(); const currentLocale = whoAmI.getLocale(); - const { handleSubmit, setValue, watch, control, reset, formState } = form; + const { handleSubmit, setValue, control, reset, formState } = form; const { errors } = formState; - const watchUsernameInput = watch("username"); const [selectedGroups, setSelectedGroups] = useState( [], ); const [open, setOpen] = useState(false); const [locked, setLocked] = useState(isLocked); + const navigate = useNavigate(); useEffect(() => { setValue("requiredActions", user?.requiredActions || []); @@ -132,6 +131,14 @@ export const UserForm = ({ setOpen(!open); }; + const onFormReset = () => { + if (user?.id) { + reset(toUserFormFields(user)); + } else { + navigate(toUsers({ realm: realm.realm! })); + } + }; + return ( )} - - - - {user?.id ? t("save") : t("create")} - - - + ); };