Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Active users][Settings][Account settings] Add functionality for Text inputs #136

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/UserSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,12 @@ const UserSettings = (props: PropsToUserSettings) => {
id="account-settings"
text="Account settings"
/>
<UsersAccountSettings user={props.user} />
<UsersAccountSettings
user={props.user}
onUserChange={props.onUserChange}
metadata={props.metadata}
onRefresh={props.onRefresh}
/>
<TitleLayout
key={2}
headingLevel="h2"
Expand Down
162 changes: 65 additions & 97 deletions src/components/UsersSections/UsersAccountSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
Button,
} from "@patternfly/react-core";
// Data types
import { IDPServer, User } from "src/utils/datatypes/globalDataTypes";
import { IDPServer, Metadata, User } from "src/utils/datatypes/globalDataTypes";
// Layouts
import SecondaryButton from "src/components/layouts/SecondaryButton";
import DataTimePickerLayout from "src/components/layouts/Calendar/DataTimePickerLayout";
Expand All @@ -26,9 +26,16 @@ import PopoverWithIconLayout from "src/components/layouts/PopoverWithIconLayout"
import ModalWithTextAreaLayout from "src/components/layouts/ModalWithTextAreaLayout";
// Modals
import CertificateMappingDataModal from "src/components/modals/CertificateMappingDataModal";
// Utils
import { asRecord } from "src/utils/userUtils";
// Form
import IpaTextInput from "src/components/Form/IpaTextInput";

interface PropsToUsersAccountSettings {
user: Partial<User>;
onUserChange: (element: Partial<User>) => void;
metadata: Metadata;
onRefresh: () => void;
}

// Generic data to pass to the Textbox adder
Expand All @@ -38,32 +45,21 @@ interface ElementData {
}

const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
// TODO: This state variables should update the user data via the IPA API (`user_mod`)
const [userLogin] = useState(props.user.uid);
// TODO: Handle the `has_password` variable (boolean) by another Ipa component
const [password] = useState("");
const [passwordExpiration] = useState("");
const [uid, setUid] = useState(props.user.uidnumber);
const [gid, setGid] = useState("");

// Get 'ipaObject' and 'recordOnChange' to use in 'IpaTextInput'
const { ipaObject, recordOnChange } = asRecord(
props.user,
props.onUserChange
);

const [principalAliasList, setPrincipalAliasList] = useState<ElementData[]>([
{
id: 0,
element: props.user.uid + "@IPAEXAMPLE.TEST",
},
]);
const [homeDirectory, setHomeDirectory] = useState("/home/" + userLogin);
const [loginShell, setLoginShell] = useState("/bin/sh");
const [radiusUsername, setRadiusUsername] = useState("");
const [idpIdentifier, setIdpIdentifier] = useState("");

// UID
const uidInputHandler = (value: string) => {
setUid(value);
};

// GID
const gidInputHandler = (value: string) => {
setGid(value);
};

// Principal alias
// - 'Add principal alias' handler
Expand Down Expand Up @@ -96,16 +92,6 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
setPrincipalAliasList(principalAliasListCopy);
};

// Home directory
const homeDirectoryInputHandler = (value: string) => {
setHomeDirectory(value);
};

// Login shell
const loginShellInputHandler = (value: string) => {
setLoginShell(value);
};

// SSH public keys
// -Text area
const [textAreaSshPublicKeysValue, setTextAreaSshPublicKeysValue] =
Expand Down Expand Up @@ -347,16 +333,6 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
</Button>,
];

// RADIUS username
const radiusUsernameInputHandler = (value: string) => {
setRadiusUsername(value);
};

// Track changes on External IdP user identifier textbox field
const idpIdentifierInputHandler = (value: string) => {
setIdpIdentifier(value);
};

// Checkboxes
const [passwordCheckbox] = useState(false);
const [radiusCheckbox] = useState(false);
Expand Down Expand Up @@ -503,13 +479,12 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
<FlexItem flex={{ default: "flex_1" }}>
<Form className="pf-u-mb-lg">
<FormGroup label="User login" fieldId="user-login">
<TextInput
id="user-login"
name="uid"
value={userLogin}
type="text"
aria-label="user login"
isDisabled
<IpaTextInput
name={"uid"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup label="Password" fieldId="password">
Expand All @@ -519,40 +494,37 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
value={password}
type="password"
aria-label="password"
isDisabled
readOnlyVariant="plain"
/>
</FormGroup>
<FormGroup
label="Password expiration"
fieldId="password-expiration"
>
<TextInput
id="password-expiration"
name="krbpasswordexpiration"
value={passwordExpiration}
type="text"
aria-label="password expiration"
isDisabled
<IpaTextInput
name={"krbpasswordexpiration"}
carma12 marked this conversation as resolved.
Show resolved Hide resolved
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup label="UID" fieldId="uid">
<TextInput
id="uid"
name="uidnumber"
value={uid}
type="text"
onChange={uidInputHandler}
aria-label="uid"
<IpaTextInput
name={"uidnumber"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup label="GID" fieldId="gid">
<TextInput
id="gid"
name="gidnumber"
value={gid}
type="text"
onChange={gidInputHandler}
aria-label="gid"
<IpaTextInput
name={"gidnumber"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup label="Principal alias" fieldId="principal-alias">
Expand Down Expand Up @@ -620,27 +592,25 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
</CalendarLayout>
</FormGroup>
<FormGroup label="Login shell" fieldId="login-shell">
<TextInput
id="login-shell"
name="loginshell"
value={loginShell}
type="text"
onChange={loginShellInputHandler}
aria-label="login shell"
<IpaTextInput
name={"loginshell"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
</Form>
</FlexItem>
<FlexItem flex={{ default: "flex_1" }}>
<Form className="pf-u-mb-lg">
<FormGroup label="Home directory" fieldId="home-directory">
<TextInput
id="home-directory"
name="homedirectory"
value={homeDirectory}
type="text"
onChange={homeDirectoryInputHandler}
aria-label="home directory"
<IpaTextInput
name={"homedirectory"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup label="SSH public keys" fieldId="ssh-public-keys">
Expand Down Expand Up @@ -758,13 +728,12 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
label="Radius proxy username"
fieldId="radius-proxy-username"
>
<TextInput
id="radius-proxy-username"
name="ipatokenradiususername"
value={radiusUsername}
type="text"
onChange={radiusUsernameInputHandler}
aria-label="radius proxy username"
<IpaTextInput
name={"ipatokenradiususername"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup
Expand Down Expand Up @@ -792,13 +761,12 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
label="External IdP user identifier"
fieldId="external-idp-user-identifier"
>
<TextInput
id="external-idp-user-identifier"
name="ipaidpsub"
value={idpIdentifier}
type="text"
onChange={idpIdentifierInputHandler}
aria-label="idp user identifier"
<IpaTextInput
name={"ipaidpsub"}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
</Form>
Expand Down
14 changes: 11 additions & 3 deletions src/hooks/useUserSettingsData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,17 @@ const useUserSettingsData = (userId: string): UserSettingsData => {
}
let modified = false;
for (const [key, value] of Object.entries(user)) {
if (userFullData.user[key] !== value) {
modified = true;
break;
if (Array.isArray(value)) {
// Using 'JSON.stringify' when comparing arrays (to prevent data type false positives)
if (JSON.stringify(userFullData.user[key]) !== JSON.stringify(value)) {
modified = true;
break;
}
} else {
if (userFullData.user[key] !== value) {
modified = true;
break;
}
}
}
setModified(modified);
Expand Down
Loading