1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-27 11:02:16 +01:00
unleash.unleash/frontend/src/hooks/api/getters/useProjectAccess/useProjectAccess.ts
Nuno Góis a9e9ae8c3e
feat: use new role components in project access (#4018)
https://linear.app/unleash/issue/2-1143/adapt-project-roles-to-use-the-new-role-selector-and-role-description

This PR further unifies roles, by having a single `IRole` interface to
cover both types, and re-using the same components for project roles.
2023-06-21 08:16:37 +01:00

115 lines
3.2 KiB
TypeScript

import useSWR, { mutate, SWRConfiguration } from 'swr';
import { useState, useEffect, useMemo } from 'react';
import { formatApiPath } from 'utils/formatPath';
import handleErrorResponses from '../httpErrorResponseHandler';
import { IRole } from 'interfaces/role';
import { IGroup } from 'interfaces/group';
import { IUser } from 'interfaces/user';
import { mapGroupUsers } from '../useGroup/useGroup';
import { IServiceAccount } from 'interfaces/service-account';
export enum ENTITY_TYPE {
USER = 'USERS',
GROUP = 'GROUPS',
SERVICE_ACCOUNT = 'SERVICE ACCOUNTS',
}
export interface IProjectAccess {
entity: IProjectAccessUser | IProjectAccessGroup;
type: ENTITY_TYPE;
}
export interface IProjectAccessUser extends IUser {
roleId: number;
}
export interface IProjectAccessGroup extends IGroup {
roleId: number;
}
export interface IProjectAccessOutput {
users: IProjectAccessUser[];
groups: IProjectAccessGroup[];
roles: IRole[];
rows: IProjectAccess[];
}
const useProjectAccess = (
projectId: string,
options: SWRConfiguration = {}
) => {
const path = formatApiPath(`api/admin/projects/${projectId}/access`);
const fetcher = () => {
return fetch(path, {
method: 'GET',
})
.then(handleErrorResponses('project access'))
.then(res => res.json());
};
const CACHE_KEY = `api/admin/projects/${projectId}/users`;
const { data, error } = useSWR(CACHE_KEY, fetcher, options);
const [loading, setLoading] = useState(!error && !data);
const refetchProjectAccess = () => {
mutate(CACHE_KEY);
};
useEffect(() => {
setLoading(!error && !data);
}, [data, error]);
const access: IProjectAccessOutput | undefined = useMemo(() => {
if (data) {
return formatAccessData({
roles: data.roles,
users: (data.users as IUser[]).filter(
({ accountType }) => !accountType || accountType === 'User'
),
serviceAccounts: (data.users as IUser[]).filter(
({ accountType }) => accountType === 'Service Account'
),
groups:
data?.groups.map((group: any) => ({
...group,
users: mapGroupUsers(group.users ?? []),
})) ?? [],
});
}
}, [data]);
return {
access,
error,
loading,
refetchProjectAccess,
};
};
const formatAccessData = (access: any): IProjectAccessOutput => {
const users = access.users || [];
const serviceAccounts = access.serviceAccounts || [];
const groups = access.groups || [];
return {
...access,
rows: [
...users.map((user: IUser) => ({
entity: user,
type: ENTITY_TYPE.USER,
})),
...serviceAccounts.map((serviceAccount: IServiceAccount) => ({
entity: serviceAccount,
type: ENTITY_TYPE.SERVICE_ACCOUNT,
})),
...groups.map((group: IGroup) => ({
entity: group,
type: ENTITY_TYPE.GROUP,
})),
],
};
};
export default useProjectAccess;