diff --git a/src/@types/pageTypes.ts b/src/@types/pageTypes.ts index 29a88cef..30356872 100644 --- a/src/@types/pageTypes.ts +++ b/src/@types/pageTypes.ts @@ -3,7 +3,8 @@ export interface TabProps { path: string } -export interface DropdownItems { +export interface DropdownItem { id: string title: string + disabled: boolean } diff --git a/src/pages/TeamDetail/AddTeamMember.tsx b/src/pages/TeamDetail/AddTeamMember.tsx index c0ab79d3..286a2af6 100644 --- a/src/pages/TeamDetail/AddTeamMember.tsx +++ b/src/pages/TeamDetail/AddTeamMember.tsx @@ -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 @@ -55,7 +56,7 @@ const AddTeamMember = ({ ...defaultSelectedGroup, key: defaultAddUserKey, }) - const [teamGroupTags, setTeamGroupTags] = useState([]) + const [teamGroupTags, setTeamGroupTags] = useState([]) const [teamGroupTagsError, setTeamGroupTagsError] = useState({ error: false, errorMessage: 'Velg minst én tilgangsgruppe', @@ -63,19 +64,19 @@ const AddTeamMember = ({ const [addUserToTeamErrors, setAddUserToTeamErrors] = useState>([]) const [showAddUserSpinner, setShowAddUserSpinner] = useState(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) } @@ -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 @@ -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} /> diff --git a/src/pages/TeamDetail/EditTeamMember.tsx b/src/pages/TeamDetail/EditTeamMember.tsx index dfb3b648..5857211f 100644 --- a/src/pages/TeamDetail/EditTeamMember.tsx +++ b/src/pages/TeamDetail/EditTeamMember.tsx @@ -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' @@ -47,7 +48,7 @@ const EditTeamMember = ({ ...defaultSelectedGroup, key: defaultEditUserKey, }) - const [userGroupTags, setUserGroupTags] = useState([]) + const [userGroupTags, setUserGroupTags] = useState([]) const [editUserErrors, setEditUserErrors] = useState({}) const [showEditUserSpinner, setShowEditUserSpinner] = useState({}) @@ -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({ @@ -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) } @@ -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)} />
{userGroupTags && - userGroupTags.map((group) => ( + userGroupTags.map((group: DropdownItem) => ( } - onClick={() => handleDeleteGroupTag(group)} + onClick={() => (group.disabled ? undefined : handleDeleteGroupTag(group))} > {group.title} @@ -296,7 +295,6 @@ const EditTeamMember = ({ /> ) } - return } export default EditTeamMember diff --git a/src/pages/TeamDetail/TeamDetail.tsx b/src/pages/TeamDetail/TeamDetail.tsx index e6fc5417..ec4d9913 100644 --- a/src/pages/TeamDetail/TeamDetail.tsx +++ b/src/pages/TeamDetail/TeamDetail.tsx @@ -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 @@ -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(() => { diff --git a/src/pages/TeamDetail/common.ts b/src/pages/TeamDetail/common.ts new file mode 100644 index 00000000..10ba177b --- /dev/null +++ b/src/pages/TeamDetail/common.ts @@ -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), + } + }