Skip to content

Commit

Permalink
implement support for managing non-standard teams
Browse files Browse the repository at this point in the history
allow management of non-standard teams, BUT only
for standard groups.
  • Loading branch information
skykanin committed Oct 11, 2024
1 parent aeda880 commit 1aca53b
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 43 deletions.
3 changes: 2 additions & 1 deletion src/@types/pageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export interface TabProps {
path: string
}

export interface DropdownItems {
export interface DropdownItem {
id: string
title: string
disabled: boolean
}
22 changes: 10 additions & 12 deletions src/pages/TeamDetail/AddTeamMember.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import styles from './teamDetail.module.scss'
import { useState } from 'react'
import { TeamDetailData, addUserToGroups, Group, Team } from '../../services/teamDetail'
import { User } from '../../services/teamMembers'
import { formatDisplayName, getErrorList, getGroupType, removeDuplicateDropdownItems } from '../../utils/utils'
import { DropdownItems } from '../../@types/pageTypes'
import { formatDisplayName, getErrorList, removeDuplicateDropdownItems } from '../../utils/utils'
import { DropdownItem } from '../../@types/pageTypes'
import SidebarModal, { SidebarHeader } from '../../components/SidebarModal/SidebarModal'
import { renderSidebarModalInfo, renderSidebarModalWarning } from './teamDetailDialog'

import { Dropdown, Tag } from '@statisticsnorway/ssb-component-library'
import { Skeleton, CircularProgress } from '@mui/material'
import { XCircle } from 'react-feather'
import { displayGroupItem } from './common'

interface AddMember {
loadingUsers: boolean
Expand Down Expand Up @@ -55,27 +56,27 @@ const AddTeamMember = ({
...defaultSelectedGroup,
key: defaultAddUserKey,
})
const [teamGroupTags, setTeamGroupTags] = useState<DropdownItems[]>([])
const [teamGroupTags, setTeamGroupTags] = useState<DropdownItem[]>([])
const [teamGroupTagsError, setTeamGroupTagsError] = useState({
error: false,
errorMessage: 'Velg minst én tilgangsgruppe',
})
const [addUserToTeamErrors, setAddUserToTeamErrors] = useState<Array<string>>([])
const [showAddUserSpinner, setShowAddUserSpinner] = useState<boolean>(false)

const handleAddUser = (item: DropdownItems) => {
const handleAddUser = (item: DropdownItem) => {
setSelectedUserDropdown({ ...selectedUserDropdown, key: `${defaultSelectedUserDropdown.key}-${item.id}` })
setSelectedUser(item)
}

const handleAddGroupTag = (item: DropdownItems) => {
const handleAddGroupTag = (item: DropdownItem) => {
const teamGroupsTags = removeDuplicateDropdownItems([...teamGroupTags, item])
setTeamGroupTags(teamGroupsTags)
setTeamGroupTagsError({ ...teamGroupTagsError, error: false })
setSelectedGroupAddUser({ ...item, key: `${defaultAddUserKey}-${item.id}` })
}

const handleDeleteGroupTag = (item: DropdownItems) => {
const handleDeleteGroupTag = (item: DropdownItem) => {
const teamGroupsTags = teamGroupTags.filter((items) => items !== item)
setTeamGroupTags(teamGroupsTags)
}
Expand Down Expand Up @@ -142,7 +143,7 @@ const AddTeamMember = ({
title: `${formatDisplayName(display_name)} (${principal_name})`,
}
})}
onSelect={(item: DropdownItems) => handleAddUser(item)}
onSelect={(item: DropdownItem) => handleAddUser(item)}
error={selectedUserDropdown.error}
errorMessage={selectedUserDropdown.errorMessage}
searchable
Expand All @@ -157,11 +158,8 @@ const AddTeamMember = ({
className={styles.dropdownSpacing}
header='Tilgangsgrupper(r)'
selectedItem={selectedGroupAddUser}
items={teamGroups.map(({ uniform_name }) => ({
id: uniform_name,
title: getGroupType((teamDetailData['team'] as Team).uniform_name, uniform_name),
}))}
onSelect={(item: DropdownItems) => handleAddGroupTag(item)}
items={teamGroups.map(displayGroupItem(teamDetailData['team'] as Team))}
onSelect={(item: DropdownItem) => handleAddGroupTag(item)}
error={teamGroupTagsError.error}
errorMessage={teamGroupTagsError.errorMessage}
/>
Expand Down
24 changes: 11 additions & 13 deletions src/pages/TeamDetail/EditTeamMember.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import styles from './teamDetail.module.scss'
import { useState, useEffect } from 'react'
import { UserInfo } from './TeamDetail'
import { TeamDetailData, Team, Group, addUserToGroups, removeUserFromGroups } from '../../services/teamDetail'
import { DropdownItems } from '../../@types/pageTypes'
import { DropdownItem } from '../../@types/pageTypes'
import { getErrorList, getGroupType, removeDuplicateDropdownItems } from '../../utils/utils'
import SidebarModal, { SidebarHeader } from '../../components/SidebarModal/SidebarModal'
import Modal from '../../components/Modal/Modal'
import DeleteLink from '../../components/DeleteLink/DeleteLink'
import { renderSidebarModalInfo, renderSidebarModalWarning } from './teamDetailDialog'
import { displayGroupItem, standardGroups } from './common'

import { Dropdown, Tag, Link, Button } from '@statisticsnorway/ssb-component-library'
import { CircularProgress } from '@mui/material'
Expand Down Expand Up @@ -47,7 +48,7 @@ const EditTeamMember = ({
...defaultSelectedGroup,
key: defaultEditUserKey,
})
const [userGroupTags, setUserGroupTags] = useState<DropdownItems[]>([])
const [userGroupTags, setUserGroupTags] = useState<DropdownItem[]>([])
const [editUserErrors, setEditUserErrors] = useState<EditUserStates>({})
const [showEditUserSpinner, setShowEditUserSpinner] = useState<EditUserStates>({})

Expand All @@ -60,7 +61,8 @@ const EditTeamMember = ({
) as Group[]
setUserGroupTags(
userGroups.map(({ uniform_name }) => {
return { id: uniform_name, title: getGroupType((teamDetailData['team'] as Team).uniform_name, uniform_name) }
const groupType = getGroupType((teamDetailData['team'] as Team).uniform_name, uniform_name)
return { id: uniform_name, title: groupType, disabled: !standardGroups.includes(groupType) }
})
)
setSelectedGroupEditUser({
Expand All @@ -71,13 +73,13 @@ const EditTeamMember = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [editUserInfo])

const handleAddGroupTag = (item: DropdownItems) => {
const handleAddGroupTag = (item: DropdownItem) => {
const userGroupsTagsList = removeDuplicateDropdownItems([...userGroupTags, item])
setUserGroupTags(userGroupsTagsList)
setSelectedGroupEditUser({ ...item, key: `${defaultEditUserKey}-${item.id}` })
}

const handleDeleteGroupTag = (item: DropdownItems) => {
const handleDeleteGroupTag = (item: DropdownItem) => {
const userGroupsTags = userGroupTags.filter((items) => items !== item)
setUserGroupTags(userGroupsTags)
}
Expand Down Expand Up @@ -258,19 +260,16 @@ const EditTeamMember = ({
className={styles.dropdownSpacing}
header='Tilgangsgrupper(r)'
selectedItem={selectedGroupEditUser}
items={teamGroups.map(({ uniform_name }) => ({
id: uniform_name,
title: getGroupType((teamDetailData['team'] as Team).uniform_name, uniform_name),
}))}
onSelect={(item: DropdownItems) => handleAddGroupTag(item)}
items={teamGroups.map(displayGroupItem(teamDetailData['team'] as Team))}
onSelect={(item: DropdownItem) => handleAddGroupTag(item)}
/>
<div className={styles.tagsContainer}>
{userGroupTags &&
userGroupTags.map((group) => (
userGroupTags.map((group: DropdownItem) => (
<Tag
key={`user-group-tag-${group.id}`}
icon={<XCircle size={14} />}
onClick={() => handleDeleteGroupTag(group)}
onClick={() => (group.disabled ? undefined : handleDeleteGroupTag(group))}
>
{group.title}
</Tag>
Expand All @@ -296,7 +295,6 @@ const EditTeamMember = ({
/>
)
}
return
}

export default EditTeamMember
26 changes: 9 additions & 17 deletions src/pages/TeamDetail/TeamDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import AddTeamMember from './AddTeamMember'
import EditTeamMember from './EditTeamMember'
import { AUTONOMY_LEVEL } from '../../content/glossary'

import { Effect } from 'effect'

export interface UserInfo {
name?: string
email?: string
Expand Down Expand Up @@ -169,30 +171,20 @@ const TeamDetail = () => {
)

useEffect(() => {
const checkIsTeamManager = async () => {
const checkIsTeamManager = Effect.gen(function* () {
const teamManagers = (teamDetailData && (teamDetailData.team as Team).managers) ?? []
let isManager = false
if (tokenData) {
const isAdmin = await isDaplaAdmin(tokenData.email.toLowerCase())
if (isAdmin) {
setIsManager(true)
return
}
// if autonomy_level is not 'MANAGED' then you should not be able to see
// what managers sees, unless you are an admin
if (teamDetailData && (teamDetailData.team as Team).autonomy_level !== 'MANAGED') {
setIsManager(false)
return
}
const isAdmin = yield* Effect.promise(() => isDaplaAdmin(tokenData.email.toLowerCase()))
const isManagerResult = teamManagers.some(
(manager) => manager.principal_name.toLowerCase() === tokenData.email.toLowerCase()
)
setIsManager(isManagerResult)
} else {
setIsManager(false)
isManager = isAdmin || isManagerResult
}
}
yield* Effect.sync(() => setIsManager(isManager))
})

checkIsTeamManager()
checkIsTeamManager.pipe(Effect.runPromise)
}, [tokenData, teamDetailData])

useEffect(() => {
Expand Down
22 changes: 22 additions & 0 deletions src/pages/TeamDetail/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getGroupType } from '../../utils/utils.ts'
import { Team, Group } from '../../services/teamDetail.ts'
import { DropdownItem } from '../../@types/pageTypes'

// The only valid groups for MANAGED dapla teams
export const standardGroups = ['developers', 'managers', 'data-admins']

/**
* Display groups for use in the Dropdown component. Disable the group
* if it's non-standard.
*
*/
export const displayGroupItem =
(teamDetailData: Team) =>
({ uniform_name }: Group): DropdownItem => {
const groupType = getGroupType(teamDetailData.uniform_name, uniform_name)
return {
id: uniform_name,
title: groupType,
disabled: !standardGroups.includes(groupType),
}
}

0 comments on commit 1aca53b

Please sign in to comment.