Skip to content

Commit

Permalink
[SiteSettings] Enable add user to project (#2372)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Jul 20, 2023
1 parent bc88e66 commit 2f66be5
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 12 deletions.
1 change: 1 addition & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
},
"siteSettings": {
"projectRoles": "Project roles",
"addProjectUsers": "Add project users",
"archiveProjectText": "This project will not be accessible to any users.",
"restoreProjectText": "Somebody probably had a good reason to archive this project. Are you sure you want to restore it?",
"userList": "Users",
Expand Down
22 changes: 15 additions & 7 deletions src/components/ProjectSettings/ProjectUsers/AddProjectUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ const customStyles = {
},
};

export default function AddProjectUsers(): ReactElement {
const projectId = useAppSelector(
(state: StoreState) => state.currentProjectState.project.id
);
interface AddProjectUsersProps {
projectId: string;
siteAdmin?: boolean;
}

export default function AddProjectUsers(
props: AddProjectUsersProps
): ReactElement {
const projectUsers = useAppSelector(
(state: StoreState) => state.currentProjectState.users
);
Expand All @@ -42,10 +46,10 @@ export default function AddProjectUsers(): ReactElement {
function addToProject(user: User): void {
if (!projectUsers.map((u) => u.id).includes(user.id)) {
backend
.addOrUpdateUserRole(projectId, Role.Harvester, user.id)
.addOrUpdateUserRole(props.projectId, Role.Harvester, user.id)
.then(() => {
toast.success(t("projectSettings.invite.toastSuccess"));
dispatch(asyncRefreshProjectUsers(projectId));
dispatch(asyncRefreshProjectUsers(props.projectId));
})
.catch((err) => {
console.error(err);
Expand All @@ -57,7 +61,11 @@ export default function AddProjectUsers(): ReactElement {
return (
<>
<Grid container spacing={1}>
<UserList projectUsers={projectUsers} addToProject={addToProject} />
<UserList
addToProject={addToProject}
minSearchLength={props.siteAdmin ? 1 : 3}
projectUsers={projectUsers}
/>
</Grid>

{RuntimeConfig.getInstance().emailServicesEnabled() && (
Expand Down
5 changes: 3 additions & 2 deletions src/components/ProjectSettings/ProjectUsers/UserList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ export function doesTextMatchUser(text: string, user: User): boolean {
}

interface UserListProps {
projectUsers: User[];
addToProject: (user: User) => void;
minSearchLength: number;
projectUsers: User[];
}

export default function UserList(props: UserListProps): ReactElement {
Expand Down Expand Up @@ -68,7 +69,7 @@ export default function UserList(props: UserListProps): ReactElement {

const updateUsers = (text: string): void => {
setFilterInput(text);
if (text.length >= 3) {
if (text.length >= props.minSearchLength) {
const filterUsers = (users: User[]): User[] =>
users.filter((u) => doesTextMatchUser(text, u));
setFilteredNonProjUsers(filterUsers(nonProjUsers));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ let testRenderer: renderer.ReactTestRenderer;
const renderUserList = async (users: User[] = []): Promise<void> => {
await renderer.act(async () => {
testRenderer = renderer.create(
<UserList projectUsers={users} addToProject={jest.fn()} />
<UserList
addToProject={jest.fn()}
minSearchLength={3}
projectUsers={users}
/>
);
});
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProjectSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export default function ProjectSettingsComponent() {
<BaseSettingsComponent
icon={<PersonAdd />}
title={t("projectSettings.user.addUser")}
body={<AddProjectUsers />}
body={<AddProjectUsers projectId={project.id} />}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import {
Dialog,
DialogContent,
DialogTitle,
Divider,
IconButton,
Typography,
} from "@mui/material";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";

import { asyncRefreshProjectUsers } from "components/Project/ProjectActions";
import ActiveProjectUsers from "components/ProjectSettings/ProjectUsers/ActiveProjectUsers";
import AddProjectUsers from "components/ProjectSettings/ProjectUsers/AddProjectUsers";
import { useAppDispatch } from "types/hooks";
import theme from "types/theme";

Expand Down Expand Up @@ -40,7 +43,7 @@ export default function ProjectUsersButtonWithConfirmation(
</Button>
<Dialog maxWidth={false} onClose={() => setOpen(false)} open={open}>
<DialogTitle>
{t("siteSettings.projectRoles")}
<Typography variant="h5">{t("siteSettings.projectRoles")}</Typography>
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
Expand All @@ -58,13 +61,20 @@ export default function ProjectUsersButtonWithConfirmation(
function ProjUsersDialogContent(props: { projectId: string }) {
const dispatch = useAppDispatch();

const { t } = useTranslation();

useEffect(() => {
dispatch(asyncRefreshProjectUsers(props.projectId));
}, [dispatch, props.projectId]);

return (
<DialogContent>
<ActiveProjectUsers projectId={props.projectId} />
<Divider sx={{ my: 2 }} />
<Typography variant="h6" sx={{ mb: 1 }}>
{t("siteSettings.addProjectUsers")}
</Typography>
<AddProjectUsers projectId={props.projectId} siteAdmin />
</DialogContent>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "tests/reactI18nextMock";
import ExportButton from "components/ProjectExport/ExportButton";
import ProjectButtonWithConfirmation from "components/SiteSettings/ProjectManagement/ProjectButtonWithConfirmation";
import { ProjectList } from "components/SiteSettings/ProjectManagement/ProjectManagement";
import ProjectUsersButtonWithConfirmation from "components/SiteSettings/ProjectManagement/ProjectUsersButtonWithConfirmation";
import { randomProject } from "types/project";

const mockProjects = [randomProject(), randomProject(), randomProject()];
Expand Down Expand Up @@ -37,4 +38,11 @@ describe("ProjectList", () => {
);
expect(projectButtons.length).toEqual(mockProjects.length);
});

it("Has the right number of project roles buttons", () => {
const projectButtons = testRenderer.root.findAllByType(
ProjectUsersButtonWithConfirmation
);
expect(projectButtons.length).toEqual(mockProjects.length);
});
});

0 comments on commit 2f66be5

Please sign in to comment.