diff --git a/web/package/cockpit-agama.changes b/web/package/cockpit-agama.changes index e13348923d..f3a3b55f71 100644 --- a/web/package/cockpit-agama.changes +++ b/web/package/cockpit-agama.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Sep 19 19:11:12 UTC 2023 - Balsa Asanovic + +- Allow users to show password values (gh#openSUSE/agama#750). + ------------------------------------------------------------------- Tue Sep 19 11:18:05 UTC 2023 - José Iván López González diff --git a/web/src/assets/styles/patternfly-overrides.scss b/web/src/assets/styles/patternfly-overrides.scss index e88a4e6e9d..758bb3c6b3 100644 --- a/web/src/assets/styles/patternfly-overrides.scss +++ b/web/src/assets/styles/patternfly-overrides.scss @@ -165,3 +165,8 @@ table td > .pf-c-empty-state { outline: none; box-shadow: 0 0 0 1px var(--focus-color); } + +// Center icon in the visibility button of password input form fields +.password-toggler span.pf-c-button__icon { + display: flex; +} diff --git a/web/src/assets/styles/utilities.scss b/web/src/assets/styles/utilities.scss index 146bb6b57c..81a8ec0db6 100644 --- a/web/src/assets/styles/utilities.scss +++ b/web/src/assets/styles/utilities.scss @@ -44,6 +44,11 @@ height: 14px; } +.icon-size-15 { + width: 15px; + height: 15px; +} + .icon-size-16 { width: 16px; height: 16px; diff --git a/web/src/components/core/PasswordAndConfirmationInput.jsx b/web/src/components/core/PasswordAndConfirmationInput.jsx index 0358b902ba..d94b088c25 100644 --- a/web/src/components/core/PasswordAndConfirmationInput.jsx +++ b/web/src/components/core/PasswordAndConfirmationInput.jsx @@ -20,13 +20,11 @@ */ import React, { useState } from "react"; -import { - FormGroup, - TextInput -} from "@patternfly/react-core"; +import { FormGroup } from "@patternfly/react-core"; +import { PasswordInput } from "~/components/core"; import { _ } from "~/i18n"; -const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisabled, split = false }) => { +const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisabled }) => { const [confirmation, setConfirmation] = useState(value || ""); const [error, setError] = useState(""); @@ -54,12 +52,11 @@ const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisable }; return ( -
+ <> - - -
+ ); }; diff --git a/web/src/components/core/PasswordInput.jsx b/web/src/components/core/PasswordInput.jsx new file mode 100644 index 0000000000..14a55ab58d --- /dev/null +++ b/web/src/components/core/PasswordInput.jsx @@ -0,0 +1,67 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +/** + * Renders a password input field and a toggle button that can be used to reveal + * and hide the password + * @component + * + * @param {string} id - the identifier for the field. + * @param {Object} props - props matching the {@link https://www.patternfly.org/components/forms/text-input PF/TextInput}, + * except `type` that will be ignored. + */ +import React, { useState } from "react"; +import { + Button, + InputGroup, + TextInput +} from "@patternfly/react-core"; +import { Icon } from "~/components/layout"; +import { _ } from "~/i18n"; + +export default function PasswordInput({ id, ...props }) { + const [showPassword, setShowPassword] = useState(false); + const visibilityIconName = showPassword ? "visibility_off" : "visibility"; + + if (!id) { + const field = props.label || props["aria-label"] || props.name; + console.error(`The PasswordInput component must have an 'id' but it was not given for '${field}'`); + } + + return ( + + +