-
Notifications
You must be signed in to change notification settings - Fork 12
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] Adapt fields and sync data #135
Changes from 1 commit
4e6b910
0ae1535
1b29f79
6fc47f2
e615727
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from "react"; | ||
// PatternFly | ||
import { Select, SelectOption, SelectVariant } from "@patternfly/react-core"; | ||
// Utils | ||
import { | ||
IPAParamDefinitionSelect, | ||
getParamPropertiesSelect, | ||
} from "src/utils/ipaObjectUtils"; | ||
|
||
const IpaSelect = (props: IPAParamDefinitionSelect) => { | ||
const { required, readOnly, value } = getParamPropertiesSelect(props); | ||
|
||
return ( | ||
<Select | ||
id={props.id} | ||
name={props.name} | ||
variant={props.variant || SelectVariant.single} | ||
aria-label={props.name} | ||
onToggle={props.onToggle} | ||
onSelect={props.onSelect} | ||
selections={value?.toString()} | ||
isOpen={props.isOpen} | ||
aria-labelledby={props.ariaLabelledBy || props.id} | ||
readOnly={readOnly} | ||
isDisabled={readOnly} | ||
required={required} | ||
> | ||
{props.elementsOptions.map((option, index) => ( | ||
<SelectOption key={index} value={option} /> | ||
))} | ||
</Select> | ||
); | ||
}; | ||
|
||
export default IpaSelect; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import React, { useState } from "react"; | ||
import React, { useEffect, useState } from "react"; | ||
// PatternFly | ||
import { | ||
Flex, | ||
FlexItem, | ||
Form, | ||
FormGroup, | ||
TextInput, | ||
Select, | ||
SelectVariant, | ||
SelectOption, | ||
DropdownItem, | ||
CalendarMonth, | ||
Button, | ||
} from "@patternfly/react-core"; | ||
// Data types | ||
import { IDPServer, Metadata, User } from "src/utils/datatypes/globalDataTypes"; | ||
import { | ||
IDPServer, | ||
Metadata, | ||
RadiusServer, | ||
User, | ||
} from "src/utils/datatypes/globalDataTypes"; | ||
// Layouts | ||
import SecondaryButton from "src/components/layouts/SecondaryButton"; | ||
import DataTimePickerLayout from "src/components/layouts/Calendar/DataTimePickerLayout"; | ||
|
@@ -40,12 +42,15 @@ import useAlerts from "src/hooks/useAlerts"; | |
import DeletionConfirmationModal from "../modals/DeletionConfirmationModal"; | ||
// Form | ||
import IpaCheckbox from "../Form/IpaCheckbox"; | ||
import IpaSelect from "../Form/IpaSelect"; | ||
|
||
interface PropsToUsersAccountSettings { | ||
user: Partial<User>; | ||
onUserChange: (element: Partial<User>) => void; | ||
metadata: Metadata; | ||
onRefresh: () => void; | ||
radiusProxyConf: RadiusServer[]; | ||
idpConf: IDPServer[]; | ||
} | ||
|
||
// Generic data to pass to the Textbox adder | ||
|
@@ -197,6 +202,59 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => { | |
</Button>, | ||
]; | ||
|
||
// Dropdown 'Radius proxy configuration' | ||
const [isRadiusConfOpen, setIsRadiusConfOpen] = useState(false); | ||
const [radiusConfSelected, setRadiusConfSelected] = useState( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "selected" state is not needed as the value is already part of user/ipaObject. |
||
ipaObject.ipatokenradiusconfiglink | ||
); | ||
const [radiusConfOptions, setRadiusConfOptions] = useState<string[]>([]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't need to be a state. And the conversion from |
||
const radiusConfOnToggle = (isOpen: boolean) => { | ||
setIsRadiusConfOpen(isOpen); | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const radiusConfOnSelect = (selection: any) => { | ||
setRadiusConfSelected(selection.target.textContent as string); | ||
updateIpaObject( | ||
selection.target.textContent as string, | ||
"ipatokenradiusconfiglink" | ||
); | ||
setIsRadiusConfOpen(false); | ||
}; | ||
|
||
useEffect(() => { | ||
const radiusProxyList: string[] = []; | ||
props.radiusProxyConf.map((item) => { | ||
const itemString = item.cn.toString(); | ||
radiusProxyList.push(itemString); | ||
}); | ||
setRadiusConfOptions(radiusProxyList); | ||
}, [props.radiusProxyConf]); | ||
|
||
// Dropdown 'External IdP configuration' | ||
const [isIdpConfOpen, setIsIdpConfOpen] = useState(false); | ||
const [idpConfSelected, setIdpConfSelected] = useState(""); | ||
const [idpConfOptions, setIdpConfOptions] = useState<string[]>([]); | ||
|
||
const idpConfOnToggle = (isOpen: boolean) => { | ||
setIsIdpConfOpen(isOpen); | ||
}; | ||
|
||
const idpConfOnSelect = (selection: any) => { | ||
setIdpConfSelected(selection.target.textContent as string); | ||
updateIpaObject(selection.target.textContent as string, "ipaidpconfiglink"); | ||
setIsIdpConfOpen(false); | ||
}; | ||
|
||
useEffect(() => { | ||
const idpList: string[] = []; | ||
props.idpConf.map((item) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be an additional "empty" item which allows users to remove radius proxy or display nothing when a user doesn't have a proxy defined. Atm, after adding a radius proxy to IPA, this control shows that the users have it even though they don't. |
||
const itemString = item.cn.toString(); | ||
idpList.push(itemString); | ||
}); | ||
setIdpConfOptions(idpList); | ||
}, [props.idpConf]); | ||
|
||
// TODO: This state variables should update the user data via the IPA API (`user_mod`) | ||
const [userLogin] = useState(props.user.uid); | ||
const [password] = useState(""); | ||
|
@@ -553,38 +611,6 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => { | |
/> | ||
); | ||
|
||
// Dropdown 'Radius proxy configuration' | ||
const [isRadiusConfOpen, setIsRadiusConfOpen] = useState(false); | ||
const [radiusConfSelected, setRadiusConfSelected] = useState(""); | ||
const radiusConfOptions = [ | ||
{ value: "Option 1", disabled: false }, | ||
{ value: "Option 2", disabled: false }, | ||
{ value: "Option 3", disabled: false }, | ||
]; | ||
const radiusConfOnToggle = (isOpen: boolean) => { | ||
setIsRadiusConfOpen(isOpen); | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const radiusConfOnSelect = (selection: any) => { | ||
setRadiusConfSelected(selection.target.textContent); | ||
setIsRadiusConfOpen(false); | ||
}; | ||
|
||
// Dropdown 'External IdP configuration' | ||
const [isIdpConfOpen, setIsIdpConfOpen] = useState(false); | ||
const [idpConfSelected, setIdpConfSelected] = useState(""); | ||
const [idpConfOptions] = useState<IDPServer[]>([]); | ||
|
||
const idpConfOnToggle = (isOpen: boolean) => { | ||
setIsIdpConfOpen(isOpen); | ||
}; | ||
|
||
const idpConfOnSelect = (selection: any) => { | ||
setIdpConfSelected(selection.target.textContent); | ||
setIsIdpConfOpen(false); | ||
}; | ||
|
||
// Messages for the popover | ||
const certificateMappingDataMessage = () => ( | ||
<div> | ||
|
@@ -846,26 +872,18 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => { | |
label="Radius proxy configuration" | ||
fieldId="radius-proxy-configuration" | ||
> | ||
<Select | ||
<IpaSelect | ||
id="radius-proxy-configuration" | ||
name="ipatokenradiusconfiglink" | ||
variant={SelectVariant.single} | ||
placeholderText=" " | ||
aria-label="Select Input with descriptions" | ||
onToggle={radiusConfOnToggle} | ||
onSelect={radiusConfOnSelect} | ||
selections={radiusConfSelected} | ||
elementsOptions={radiusConfOptions} | ||
isOpen={isRadiusConfOpen} | ||
aria-labelledby="radius-proxy-conf" | ||
> | ||
{radiusConfOptions.map((option, index) => ( | ||
<SelectOption | ||
isDisabled={option.disabled} | ||
key={index} | ||
value={option.value} | ||
/> | ||
))} | ||
</Select> | ||
ipaObject={ipaObject} | ||
objectName="user" | ||
metadata={props.metadata} | ||
value={radiusConfSelected} | ||
/> | ||
</FormGroup> | ||
<FormGroup | ||
label="Radius proxy username" | ||
|
@@ -884,22 +902,18 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => { | |
label="External IdP configuration" | ||
fieldId="external-idp-configuration" | ||
> | ||
<Select | ||
<IpaSelect | ||
id="external-idp-configuration" | ||
name="ipaidpconfiglink" | ||
variant={SelectVariant.single} | ||
placeholderText=" " | ||
aria-label="Select Input with descriptions" | ||
onToggle={idpConfOnToggle} | ||
onSelect={idpConfOnSelect} | ||
selections={idpConfSelected} | ||
elementsOptions={idpConfOptions} | ||
isOpen={isIdpConfOpen} | ||
aria-labelledby="external-idp-conf" | ||
> | ||
{idpConfOptions.map((option, index) => ( | ||
<SelectOption key={index} value={option.cn} /> | ||
))} | ||
</Select> | ||
ipaObject={ipaObject} | ||
objectName="user" | ||
metadata={props.metadata} | ||
value={idpConfSelected} | ||
/> | ||
</FormGroup> | ||
<FormGroup | ||
label="External IdP user identifier" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this logic could be generalized and be part of IpaSelect - thus reusable for other parts. The only specific part is translation of radius proxy objects into list of strings. The same applies for idp config.