-
Notifications
You must be signed in to change notification settings - Fork 13
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,164 @@ | ||
import React from "react"; | ||
// PatternFly | ||
import { CalendarMonth, DropdownItem } from "@patternfly/react-core"; | ||
// Layouts | ||
import DataTimePickerLayout from "src/components/layouts/Calendar/DataTimePickerLayout"; | ||
// Components | ||
import CalendarButton from "src/components/layouts/Calendar/CalendarButton"; | ||
// Data types | ||
import { User } from "src/utils/datatypes/globalDataTypes"; | ||
// Utils | ||
import { | ||
getFullDate, | ||
getFullTime, | ||
getLDAPGeneralizedTime, | ||
parseFullDateStringToUTCFormat, | ||
} from "src/utils/utils"; | ||
// ipaObject Utils | ||
import { | ||
IPAParamDefinition, | ||
getParamProperties, | ||
updateIpaObject, | ||
} from "src/utils/ipaObjectUtils"; | ||
import CalendarLayout from "src/components/layouts/Calendar/CalendarLayout"; | ||
|
||
const IpaCalendar = (props: IPAParamDefinition) => { | ||
// Date and time picker (Calendar) | ||
const [isCalendarOpen, setIsCalendarOpen] = React.useState(false); | ||
const [isTimeOpen, setIsTimeOpen] = React.useState(false); | ||
const [valueDate, setValueDate] = React.useState("YYYY-MM-DD"); | ||
const [valueTime, setValueTime] = React.useState("HH:MM"); | ||
const times = Array.from(new Array(10), (_, i) => i + 10); | ||
const defaultTime = "10:00"; | ||
|
||
const { readOnly } = getParamProperties(props); | ||
|
||
// Initialize parameters got from the 'User' object | ||
React.useEffect(() => { | ||
if (props.ipaObject !== undefined) { | ||
// Parse ipaObject into 'User' type to access the 'datetime' parameter | ||
const user = props.ipaObject as unknown as User; | ||
if (user[props.name] && user[props.name][0].__datetime__) { | ||
// Parse to UTC format | ||
const paramUtcDate = parseFullDateStringToUTCFormat( | ||
user[props.name][0].__datetime__ | ||
); | ||
|
||
// Get date | ||
const fullDate = getFullDate(paramUtcDate); | ||
setValueDate(fullDate); | ||
|
||
// Get time | ||
const fullTime = getFullTime(paramUtcDate); | ||
setValueTime(fullTime); | ||
} | ||
} | ||
}, [props.ipaObject]); | ||
|
||
// 'onToggle' calendar function | ||
const onToggleCalendar = () => { | ||
setIsCalendarOpen(!isCalendarOpen); | ||
setIsTimeOpen(false); | ||
}; | ||
|
||
// 'onToggle' time function | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars | ||
const onToggleTime = (_ev: any) => { | ||
setIsTimeOpen(!isTimeOpen); | ||
setIsCalendarOpen(false); | ||
}; | ||
|
||
// On selecting a date from the calendar | ||
const onSelectCalendar = (newValueDate: Date) => { | ||
const newValue = getFullDate(newValueDate); | ||
setValueDate(newValue); | ||
|
||
setIsCalendarOpen(!isCalendarOpen); | ||
// setting default time when it is not picked | ||
let valTime = valueTime; | ||
if (valueTime === "HH:MM") { | ||
setValueTime(defaultTime); | ||
valTime = defaultTime; | ||
} | ||
|
||
// Convert to LDAP format | ||
const newFullDate = new Date(newValue + " " + valTime); | ||
const LDAPDate = getLDAPGeneralizedTime(newFullDate); | ||
|
||
// Update 'ipaObject' with the new date | ||
if (props.ipaObject !== undefined && props.onChange !== undefined) { | ||
updateIpaObject(props.ipaObject, props.onChange, LDAPDate, props.name); | ||
} | ||
}; | ||
|
||
// On selecting a time from the dropdown | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const onSelectTime = (ev: any) => { | ||
const newTime = ev.target.value as string; | ||
|
||
setValueTime(newTime); | ||
setIsTimeOpen(!isTimeOpen); | ||
|
||
const newFullDate = new Date(valueDate + " " + newTime); | ||
const LDAPDate = getLDAPGeneralizedTime(newFullDate); | ||
|
||
// Update 'ipaObject' with the new date | ||
// - Parse to ISO format (to return to the "user_mod" API call) | ||
if (props.ipaObject !== undefined && props.onChange !== undefined) { | ||
updateIpaObject(props.ipaObject, props.onChange, LDAPDate, props.name); | ||
} | ||
}; | ||
|
||
const timeOptions = times.map((time) => ( | ||
<DropdownItem key={time} component="button" value={`${time}:00`}> | ||
{`${time}:00`} | ||
</DropdownItem> | ||
)); | ||
|
||
const calendar = ( | ||
<CalendarMonth | ||
date={new Date(valueDate)} | ||
onChange={onSelectCalendar} | ||
disabled={readOnly} | ||
/> | ||
); | ||
|
||
const time = ( | ||
<DataTimePickerLayout | ||
dropdownOnSelect={onSelectTime} | ||
toggleAriaLabel="Toggle the time picker menu" | ||
toggleIndicator={null} | ||
toggleOnToggle={onToggleTime} | ||
toggleStyle={{ padding: "6px 16px" }} | ||
dropdownIsOpen={isTimeOpen} | ||
dropdownItems={timeOptions} | ||
/> | ||
); | ||
|
||
const calendarButton = ( | ||
<CalendarButton | ||
ariaLabel="Toggle the calendar" | ||
onClick={onToggleCalendar} | ||
/> | ||
); | ||
|
||
return ( | ||
<CalendarLayout | ||
name={props.name} | ||
position="bottom" | ||
bodyContent={calendar} | ||
showClose={false} | ||
isVisible={isCalendarOpen} | ||
hasNoPadding={true} | ||
hasAutoWidth={true} | ||
textInputId="date-time" | ||
textInputAriaLabel="date and time picker" | ||
textInputValue={valueDate + " " + valueTime} | ||
> | ||
{readOnly ? <></> : calendarButton} | ||
{readOnly ? <></> : time} | ||
</CalendarLayout> | ||
); | ||
}; | ||
|
||
export default IpaCalendar; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ interface PropsToDataTimePicker { | |
toggleIndicator?: React.ElementType | null; | ||
toggleOnToggle?: (value: boolean, event: any) => void; | ||
toggleStyle?: React.CSSProperties | undefined; | ||
// isDisabled: boolean; | ||
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. Changes in this file looks like forgotten leftovers. |
||
} | ||
|
||
const DataTimePickerLayout = (props: PropsToDataTimePicker) => { | ||
|
@@ -26,6 +27,7 @@ const DataTimePickerLayout = (props: PropsToDataTimePicker) => { | |
toggleIndicator={props.toggleIndicator} | ||
onToggle={props.toggleOnToggle} | ||
style={props.toggleStyle} | ||
// isDisabled={props.isDisabled} | ||
> | ||
<OutlinedClockIcon /> | ||
</DropdownToggle> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -459,3 +459,18 @@ export function convertApiObj( | |
} | ||
return obj; | ||
} | ||
|
||
// Updates 'ipaObject' | ||
export const updateIpaObject = ( | ||
ipaObject: Record<string, unknown>, | ||
setIpaObject: (ipaObject: Record<string, unknown>) => void, | ||
newValue: string | string[], | ||
paramName: string | ||
) => { | ||
if (!isSimpleValue(paramName)) { | ||
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.
In this form, this method should be in To be generic for other objects, we would need to find a different way, e.g. pass the |
||
const paramToModify = newValue as string[]; | ||
setIpaObject({ ...ipaObject, [paramName]: paramToModify }); | ||
} else { | ||
setIpaObject({ ...ipaObject, [paramName]: newValue }); | ||
} | ||
}; |
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.
IpaCalendar component should not have any reference to a specific object type (in this case user). The raw value should be obtained the same way as in text input, e.g.:
const { required, readOnly, value, onChange } = getParamProperties(props);
After that you can extract the base64 value and change it into
Date
object. There is also no need to do it in an effect as it is simple conversion of value from props.But the question is whether we should be doing this parsing here. I think that the conversion from base64 to Date or string (depending what we find more useful) should happen in
apiToUser
method inuserUtils
or any similar method that is used in rpc for other object types.The reason is that in
ipaObject
should be of the same type/structure after changing it. Or in other words, it should be possible to set it to the same value and be regarded as a same value. Atm the source is object with base64 string and after modification it is string, thus this doesn't apply.