1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

fix: disable project access tab when no access (#1057)

* refactor: remove unused import

* fix: disable project access tab when no access

* refactor: improve access denied text
This commit is contained in:
olav 2022-06-03 08:14:47 +02:00 committed by GitHub
parent 006b853f6c
commit 32ada96220
4 changed files with 117 additions and 96 deletions

View File

@ -1,4 +1,3 @@
import { Chip } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { IOverride, IPayload } from 'interfaces/featureToggle';

View File

@ -80,9 +80,6 @@ const Project = () => {
});
}
// @ts-expect-error
tabData.filter(tab => !tab.disabled);
/* eslint-disable-next-line */
}, []);

View File

@ -1,58 +1,29 @@
/* eslint-disable react/jsx-no-target-blank */
import React, { useCallback, useState } from 'react';
import { Alert, SelectChangeEvent } from '@mui/material';
import { ProjectAccessAddUser } from './ProjectAccessAddUser/ProjectAccessAddUser';
import React, { useContext } from 'react';
import { ProjectAccessPage } from 'component/project/ProjectAccess/ProjectAccessPage';
import { PageContent } from 'component/common/PageContent/PageContent';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useStyles } from './ProjectAccess.styles';
import useToast from 'hooks/useToast';
import { Dialogue as ConfirmDialogue } from 'component/common/Dialogue/Dialogue';
import useProjectAccess, {
IProjectAccessUser,
} from 'hooks/api/getters/useProjectAccess/useProjectAccess';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
import { Alert } from '@mui/material';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import AccessContext from 'contexts/AccessContext';
import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { ProjectAccessTable } from './ProjectAccessTable/ProjectAccessTable';
export const ProjectAccess = () => {
const projectId = useRequiredPathParam('projectId');
const { classes: styles } = useStyles();
const { access, refetchProjectAccess } = useProjectAccess(projectId);
const { setToastData } = useToast();
const { hasAccess } = useContext(AccessContext);
const { isOss } = useUiConfig();
const { removeUserFromRole, changeUserRole } = useProjectApi();
const [showDelDialogue, setShowDelDialogue] = useState(false);
const [user, setUser] = useState<IProjectAccessUser | undefined>();
const handleRoleChange = useCallback(
(userId: number) => async (evt: SelectChangeEvent) => {
const roleId = Number(evt.target.value);
try {
await changeUserRole(projectId, roleId, userId);
refetchProjectAccess();
setToastData({
type: 'success',
title: 'Success',
text: 'User role changed successfully',
});
} catch (err: any) {
setToastData({
type: 'error',
title: err.message || 'Server problems when adding users.',
});
}
},
[changeUserRole, projectId, refetchProjectAccess, setToastData]
);
if (isOss()) {
return (
<PageContent header={<PageHeader title="Project Access" />}>
<PageContent header={<PageHeader title="Project access" />}>
<Alert severity="error">
Controlling access to projects requires a paid version of
Unleash. Check out{' '}
<a href="https://www.getunleash.io" target="_blank">
<a
href="https://www.getunleash.io"
target="_blank"
rel="noreferrer"
>
getunleash.io
</a>{' '}
to find out more.
@ -61,56 +32,15 @@ export const ProjectAccess = () => {
);
}
const handleRemoveAccess = (user: IProjectAccessUser) => {
setUser(user);
setShowDelDialogue(true);
};
if (!hasAccess(UPDATE_PROJECT, projectId)) {
return (
<PageContent header={<PageHeader title="Project access" />}>
<Alert severity="error">
You need project owner permissions to access this section.
</Alert>
</PageContent>
);
}
const removeAccess = (user: IProjectAccessUser | undefined) => async () => {
if (!user) return;
const { id, roleId } = user;
try {
await removeUserFromRole(projectId, roleId, id);
refetchProjectAccess();
setToastData({
type: 'success',
title: 'The user has been removed from project',
});
} catch (err: any) {
setToastData({
type: 'error',
title: err.message || 'Server problems when adding users.',
});
}
setShowDelDialogue(false);
};
return (
<PageContent
header={<PageHeader title="Project Roles"></PageHeader>}
className={styles.pageContent}
>
<ProjectAccessAddUser roles={access?.roles} />
<div className={styles.divider}></div>
<ProjectAccessTable
access={access}
handleRoleChange={handleRoleChange}
handleRemoveAccess={handleRemoveAccess}
projectId={projectId}
/>
<ConfirmDialogue
open={showDelDialogue}
onClick={removeAccess(user)}
onClose={() => {
setUser(undefined);
setShowDelDialogue(false);
}}
title="Really remove user from this project"
/>
</PageContent>
);
return <ProjectAccessPage />;
};

View File

@ -0,0 +1,95 @@
import React, { useCallback, useState } from 'react';
import { SelectChangeEvent } from '@mui/material';
import { ProjectAccessAddUser } from './ProjectAccessAddUser/ProjectAccessAddUser';
import { PageContent } from 'component/common/PageContent/PageContent';
import { useStyles } from './ProjectAccess.styles';
import useToast from 'hooks/useToast';
import { Dialogue as ConfirmDialogue } from 'component/common/Dialogue/Dialogue';
import useProjectAccess, {
IProjectAccessUser,
} from 'hooks/api/getters/useProjectAccess/useProjectAccess';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { ProjectAccessTable } from './ProjectAccessTable/ProjectAccessTable';
export const ProjectAccessPage = () => {
const projectId = useRequiredPathParam('projectId');
const { classes: styles } = useStyles();
const { access, refetchProjectAccess } = useProjectAccess(projectId);
const { setToastData } = useToast();
const { removeUserFromRole, changeUserRole } = useProjectApi();
const [showDelDialogue, setShowDelDialogue] = useState(false);
const [user, setUser] = useState<IProjectAccessUser | undefined>();
const handleRoleChange = useCallback(
(userId: number) => async (evt: SelectChangeEvent) => {
const roleId = Number(evt.target.value);
try {
await changeUserRole(projectId, roleId, userId);
refetchProjectAccess();
setToastData({
type: 'success',
title: 'Success',
text: 'User role changed successfully',
});
} catch (err: any) {
setToastData({
type: 'error',
title: err.message || 'Server problems when adding users.',
});
}
},
[changeUserRole, projectId, refetchProjectAccess, setToastData]
);
const handleRemoveAccess = (user: IProjectAccessUser) => {
setUser(user);
setShowDelDialogue(true);
};
const removeAccess = (user: IProjectAccessUser | undefined) => async () => {
if (!user) return;
const { id, roleId } = user;
try {
await removeUserFromRole(projectId, roleId, id);
refetchProjectAccess();
setToastData({
type: 'success',
title: 'The user has been removed from project',
});
} catch (err: any) {
setToastData({
type: 'error',
title: err.message || 'Server problems when adding users.',
});
}
setShowDelDialogue(false);
};
return (
<PageContent
header={<PageHeader title="Project roles" />}
className={styles.pageContent}
>
<ProjectAccessAddUser roles={access?.roles} />
<div className={styles.divider} />
<ProjectAccessTable
access={access}
handleRoleChange={handleRoleChange}
handleRemoveAccess={handleRemoveAccess}
projectId={projectId}
/>
<ConfirmDialogue
open={showDelDialogue}
onClick={removeAccess(user)}
onClose={() => {
setUser(undefined);
setShowDelDialogue(false);
}}
title="Really remove user from this project"
/>
</PageContent>
);
};