Skip to content

Commit

Permalink
feat: Summary of group permissions in the Project settings page (#3629)
Browse files Browse the repository at this point in the history
Co-authored-by: kyle-ssg <[email protected]>
  • Loading branch information
fabricanva and kyle-ssg authored Mar 26, 2024
1 parent 8c25cd6 commit da12c93
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 83 deletions.
10 changes: 8 additions & 2 deletions frontend/common/services/useGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { Req } from 'common/types/requests'
import { service } from 'common/service'

export const groupService = service
.enhanceEndpoints({ addTagTypes: ['Group'] })
.enhanceEndpoints({
addTagTypes: ['Group', 'UserGroupPermission', 'GroupSummary'],
})
.injectEndpoints({
endpoints: (builder) => ({
createGroupAdmin: builder.mutation<
Expand All @@ -18,7 +20,11 @@ export const groupService = service
}),
}),
deleteGroup: builder.mutation<Res['groups'], Req['deleteGroup']>({
invalidatesTags: [{ id: 'LIST', type: 'Group' }],
invalidatesTags: [
{ id: 'LIST', type: 'Group' },
{ type: 'UserGroupPermission' },
{ type: 'GroupSummary' },
],
query: (query: Req['deleteGroup']) => ({
body: query,
method: 'DELETE',
Expand Down
47 changes: 47 additions & 0 deletions frontend/common/services/useUserGroupPermission.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Res } from 'common/types/responses'
import { Req } from 'common/types/requests'
import { service } from 'common/service'

export const userGroupPermissionService = service
.enhanceEndpoints({ addTagTypes: ['UserGroupPermission'] })
.injectEndpoints({
endpoints: (builder) => ({
getUserGroupPermission: builder.query<
Res['userGroupPermissions'],
Req['getUserGroupPermission']
>({
providesTags: (res) => [{ id: res?.id, type: 'UserGroupPermission' }],
query: (query: Req['getUserGroupPermission']) => ({
url: `projects/${query.project_id}/user-group-permissions/`,
}),
}),
// END OF ENDPOINTS
}),
})

export async function getUserGroupPermission(
store: any,
data: Req['getUserGroupPermission'],
options?: Parameters<
typeof userGroupPermissionService.endpoints.getUserGroupPermission.initiate
>[1],
) {
return store.dispatch(
userGroupPermissionService.endpoints.getUserGroupPermission.initiate(
data,
options,
),
)
}
// END OF FUNCTION_EXPORTS

export const {
useGetUserGroupPermissionQuery,
// END OF EXPORTS
} = userGroupPermissionService

/* Usage examples:
const { data, isLoading } = useGetUserGroupPermissionQuery({ id: 2 }, {}) //get hook
const [createUserGroupPermission, { isLoading, data, isSuccess }] = useCreateUserGroupPermissionMutation() //create hook
userGroupPermissionService.endpoints.getUserGroupPermission.select({id: 2})(store.getState()) //access data from any function
*/
1 change: 1 addition & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,6 @@ export type Req = {
id: string
}
getProject: { id: string }
getUserGroupPermission: { project_id: string }
// END OF TYPES
}
1 change: 1 addition & 0 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,5 +486,6 @@ export type Res = {
flagsmithProjectImport: { id: string }
featureImports: PagedResponse<FeatureImport>
serversideEnvironmentKeys: APIKey[]
userGroupPermissions: GroupPermission[]
// END OF TYPES
}
32 changes: 32 additions & 0 deletions frontend/common/utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import _ from 'lodash'
import ErrorMessage from 'components/ErrorMessage'
import WarningMessage from 'components/WarningMessage'
import Constants from 'common/constants'
import Format from './format'

const semver = require('semver')

Expand Down Expand Up @@ -95,6 +96,7 @@ const Utils = Object.assign({}, require('./base/_utils'), {
/>
) : null
},

escapeHtml(html: string) {
const text = document.createTextNode(html)
const p = document.createElement('p')
Expand Down Expand Up @@ -255,6 +257,36 @@ const Utils = Object.assign({}, require('./base/_utils'), {
getManageUserPermissionDescription() {
return 'Manage Identities'
},
getPermissionList(
isAdmin: boolean,
permissions: string[] | undefined | null,
numberToTruncate = 3,
): {
items: string[]
truncatedItems: string[]
} {
if (isAdmin) {
return {
items: [],
truncatedItems: ['Project Administrator'],
}
}
if (!permissions) return { items: [], truncatedItems: [] }

const items =
permissions && permissions.length
? permissions
.slice(0, numberToTruncate)
.map((item) => `${Format.enumeration.get(item)}`)
: []

return {
items,
truncatedItems: (permissions || [])
.slice(numberToTruncate)
.map((item) => `${Format.enumeration.get(item)}`),
}
},
getPlanName: (plan: string) => {
if (plan && plan.includes('scale-up')) {
return planNames.scaleUp
Expand Down
1 change: 1 addition & 0 deletions frontend/web/components/EditPermissions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ const EditPermissions: FC<EditPermissionsType> = (props) => {
<UserGroupList
noTitle
orgId={AccountStore.getOrganisation().id}
projectId={level === 'project' && id}
onClick={(group: UserGroup) => editGroupPermissions(group)}
/>
</div>
Expand Down
42 changes: 42 additions & 0 deletions frontend/web/components/PermissionsSummaryList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { FC } from 'react'
import Tooltip from './Tooltip'
import Utils from 'common/utils/utils'

type PermissionsSummaryListType = {
isAdmin: boolean
permissions: string[] | null | undefined
numberToTruncate?: number
}

const PermissionsSummaryList: FC<PermissionsSummaryListType> = ({
isAdmin,
numberToTruncate = 3,
permissions,
}) => {
const { items, truncatedItems } = Utils.getPermissionList(
isAdmin,
permissions,
numberToTruncate,
)

return (
<div className='flex-row gap-1 align-items-center'>
{items.map((value: string, i: number) => (
<div key={i} className='chip chip--xs'>
{value}
</div>
))}
{!!truncatedItems.length && (
<Tooltip
title={
<span className='chip chip--xs'>+{truncatedItems.length}</span>
}
>
{truncatedItems.join(', ')}
</Tooltip>
)}
</div>
)
}

export default PermissionsSummaryList
Loading

0 comments on commit da12c93

Please sign in to comment.