Files
redash/client/app/pages/users/components/UserInfoForm.jsx
Jesse 21ea72fdc5 Get the user's current groups from props instead of useEffect(). (#5450)
useEffect() doesn't run until _after_ the component renders. Before the
hook runs, the value of `groups` === []. And this is passed to
<DynamicForm>'s `initialValue` prop. The `initialValue` is not re-evaluated
after useEffect() completes. So the users groups are never updated.

This change pulls the user's current groups from `user` prop on the
page.
2021-03-31 16:18:59 +03:00

96 lines
2.8 KiB
JavaScript

import { get, map } from "lodash";
import React, { useMemo, useCallback } from "react";
import PropTypes from "prop-types";
import { UserProfile } from "@/components/proptypes";
import DynamicComponent from "@/components/DynamicComponent";
import DynamicForm from "@/components/dynamic-form/DynamicForm";
import UserGroups from "@/components/UserGroups";
import User from "@/services/user";
import { currentUser } from "@/services/auth";
import useImmutableCallback from "@/lib/hooks/useImmutableCallback";
import useUserGroups from "../hooks/useUserGroups";
export default function UserInfoForm(props) {
const { user, onChange } = props;
const { groups, allGroups, isLoading: isLoadingGroups } = useUserGroups(user);
const handleChange = useImmutableCallback(onChange);
const saveUser = useCallback(
(values, successCallback, errorCallback) => {
const data = {
...values,
id: user.id,
};
User.save(data)
.then(user => {
successCallback("Saved.");
handleChange(User.convertUserInfo(user));
})
.catch(error => {
errorCallback(get(error, "response.data.message", "Failed saving."));
});
},
[user, handleChange]
);
const formFields = useMemo(
() =>
map(
[
{
name: "name",
title: "Name",
type: "text",
initialValue: user.name,
},
{
name: "email",
title: "Email",
type: "email",
initialValue: user.email,
},
!user.isDisabled && currentUser.id !== user.id
? {
name: "group_ids",
title: "Groups",
type: "select",
mode: "multiple",
options: map(allGroups, group => ({ name: group.name, value: group.id })),
initialValue: user.groupIds,
loading: isLoadingGroups,
placeholder: isLoadingGroups ? "Loading..." : "",
}
: {
name: "group_ids",
title: "Groups",
type: "content",
required: false,
content: isLoadingGroups ? "Loading..." : <UserGroups data-test="Groups" groups={groups} />,
},
],
field => ({ readOnly: user.isDisabled, required: true, ...field })
),
[user, groups, allGroups, isLoadingGroups]
);
return (
<DynamicComponent name="UserProfile.UserInfoForm" {...props}>
<DynamicForm fields={formFields} onSubmit={saveUser} hideSubmitButton={user.isDisabled} />
</DynamicComponent>
);
}
UserInfoForm.propTypes = {
user: UserProfile.isRequired,
onChange: PropTypes.func,
};
UserInfoForm.defaultProps = {
onChange: () => {},
};