Unify save-buttons in admin-ui (#30119)
* #30118 Unify save-buttons in admin-ui Signed-off-by: Andreas Blaettlinger <bln1imb@bosch.com> * #30118 Unify save-buttons in admin-ui Signed-off-by: Andreas Blaettlinger <bln1imb@bosch.com> * Introduced props for naming the buttons in FixedButtonGroup Signed-off-by: Andreas Blaettlinger <bln1imb@bosch.com> --------- Signed-off-by: Andreas Blaettlinger <bln1imb@bosch.com>
This commit is contained in:
parent
5ad3abaa96
commit
2a88d01e5e
9 changed files with 45 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
|||
export default class AttributesTab {
|
||||
#saveAttributeBtn = "save-attributes";
|
||||
#saveAttributeBtn = "attributes-save";
|
||||
#attributesTab = "attributes";
|
||||
#emptyState = "attributes-empty-state";
|
||||
#addAttributeBtn: string;
|
||||
|
|
|
@ -31,7 +31,7 @@ export default class KeyValueInput {
|
|||
}
|
||||
|
||||
save() {
|
||||
cy.findByTestId("save-attributes").click();
|
||||
cy.findByTestId("attributes-save").click();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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}
|
||||
</Button>
|
||||
)}
|
||||
{reset && (
|
||||
|
@ -41,7 +45,7 @@ export const FixedButtonsGroup = ({
|
|||
variant="link"
|
||||
onClick={() => reset()}
|
||||
>
|
||||
{t("revert")}
|
||||
{!resetText ? t("revert") : resetText}
|
||||
</Button>
|
||||
)}
|
||||
{children}
|
||||
|
|
|
@ -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<RoleRepresentation, "attributes"> & {
|
||||
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 (
|
||||
<FormAccess
|
||||
|
@ -45,19 +40,7 @@ export const AttributesForm = ({
|
|||
<KeyValueInput name={name} isDisabled={isDisabled} />
|
||||
</FormProvider>
|
||||
{!noSaveCancelButtons && (
|
||||
<ActionGroup className="kc-attributes__action-group">
|
||||
<Button
|
||||
data-testid="save-attributes"
|
||||
variant="primary"
|
||||
type="submit"
|
||||
isDisabled={!isDirty}
|
||||
>
|
||||
{t("save")}
|
||||
</Button>
|
||||
<Button onClick={reset} variant="link" isDisabled={!isDirty}>
|
||||
{t("revert")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
<FixedButtonsGroup name="attributes" reset={reset} isActive isSubmit />
|
||||
)}
|
||||
</FormAccess>
|
||||
);
|
||||
|
|
|
@ -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({
|
|||
</StackItem>
|
||||
</Stack>
|
||||
</FormGroup>
|
||||
<ActionGroup>
|
||||
<Button
|
||||
variant="primary"
|
||||
type="submit"
|
||||
data-testid="general-tab-save"
|
||||
isDisabled={!isDirty}
|
||||
>
|
||||
{t("save")}
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="general-tab-revert"
|
||||
variant="link"
|
||||
onClick={setupForm}
|
||||
>
|
||||
{t("revert")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
<FixedButtonsGroup
|
||||
name="realmSettingsGeneralTab"
|
||||
reset={setupForm}
|
||||
isActive
|
||||
isSubmit
|
||||
/>
|
||||
</FormAccess>
|
||||
</FormProvider>
|
||||
</PageSection>
|
||||
|
|
|
@ -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<GroupRepresentation[]>(
|
||||
[],
|
||||
);
|
||||
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 (
|
||||
<FormAccess
|
||||
isHorizontal
|
||||
|
@ -327,37 +334,15 @@ export const UserForm = ({
|
|||
)}
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
<ActionGroup>
|
||||
<FormSubmitButton
|
||||
formState={formState}
|
||||
data-testid={!user?.id ? "create-user" : "save-user"}
|
||||
isDisabled={
|
||||
!user?.id &&
|
||||
!watchUsernameInput &&
|
||||
realm.registrationEmailAsUsername === false
|
||||
}
|
||||
allowNonDirty
|
||||
allowInvalid
|
||||
>
|
||||
{user?.id ? t("save") : t("create")}
|
||||
</FormSubmitButton>
|
||||
<Button
|
||||
data-testid="cancel-create-user"
|
||||
variant="link"
|
||||
onClick={user?.id ? () => reset(toUserFormFields(user)) : undefined}
|
||||
component={
|
||||
!user?.id
|
||||
? (props) => (
|
||||
<Link {...props} to={toUsers({ realm: realm.realm! })} />
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{user?.id ? t("revert") : t("cancel")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
</FormProvider>
|
||||
<FixedButtonsGroup
|
||||
name="user-creation"
|
||||
saveText={user?.id ? t("save") : t("create")}
|
||||
reset={onFormReset}
|
||||
resetText={user?.id ? t("revert") : t("cancel")}
|
||||
isActive
|
||||
isSubmit
|
||||
/>
|
||||
</FormAccess>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue