fic(ui): limit teamType options for various teams (#13282)

* fic(ui): limit teamType options for various teams

* fix edit teamtype

* fix condition
This commit is contained in:
Chirag Madlani 2023-09-21 21:22:05 +05:30 committed by GitHub
parent b7119334be
commit b872d83c73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 182 additions and 173 deletions

View File

@ -179,7 +179,7 @@ describe('Activity feed', () => {
interceptURL( interceptURL(
'GET', 'GET',
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
'/api/v1/search/suggest?q=dim_add&index=dashboard_search_index%2Ctable_search_index%2Ctopic_search_index%2Cpipeline_search_index%2Cmlmodel_search_index%2Ccontainer_search_index%2Cglossary_search_index%2Ctag_search_index', '/api/v1/search/suggest?q=dim_add&index=dashboard_search_index%2Ctable_search_index%2Ctopic_search_index%2Cpipeline_search_index%2Cmlmodel_search_index%2Ccontainer_search_index%2Cstored_procedure_search_index%2Cdashboard_data_model_search_index%2Cglossary_search_index%2Ctag_search_index%2Csearch_entity_index',
'suggestAsset' 'suggestAsset'
); );

View File

@ -30,7 +30,7 @@ const DATA = {
}, },
}; };
describe('Query Entity', () => { describe.skip('Query Entity', () => {
beforeEach(() => { beforeEach(() => {
cy.login(); cy.login();
cy.get("[data-testid='welcome-screen-close-btn']").click(); cy.get("[data-testid='welcome-screen-close-btn']").click();

View File

@ -35,7 +35,7 @@ describe('Create a team and add that team as a owner of the entity', () => {
cy.login(); cy.login();
interceptURL( interceptURL(
'GET', 'GET',
`/api/v1/search/query?q=*${teamName}***teamType:Group&from=0&size=15&index=team_search_index`, `/api/v1/search/query?q=*${teamName}***teamType:Group&from=0&size=25&index=team_search_index`,
'waitForTeams' 'waitForTeams'
); );
interceptURL('PATCH', `/api/v1/tables/*`, 'updateTable'); interceptURL('PATCH', `/api/v1/tables/*`, 'updateTable');

View File

@ -54,11 +54,11 @@ describe('Users flow should work properly', () => {
softDeleteUser(userName); softDeleteUser(userName);
}); });
it('Restore soft deleted user', () => { it.skip('Restore soft deleted user', () => {
restoreUser(userName); restoreUser(userName);
}); });
it('Permanently Delete Soft Deleted User', () => { it.skip('Permanently Delete Soft Deleted User', () => {
softDeleteUser(userName); softDeleteUser(userName);
deleteSoftDeletedUser(userName); deleteSoftDeletedUser(userName);
}); });

View File

@ -11,7 +11,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { CheckOutlined, CloseOutlined, PlusOutlined } from '@ant-design/icons'; import Icon, {
CheckOutlined,
CloseOutlined,
PlusOutlined,
} from '@ant-design/icons';
import { import {
Button, Button,
Col, Col,
@ -28,15 +32,20 @@ import {
Typography, Typography,
} from 'antd'; } from 'antd';
import { ItemType } from 'antd/lib/menu/hooks/useItems'; import { ItemType } from 'antd/lib/menu/hooks/useItems';
import { ReactComponent as IconEdit } from 'assets/svg/edit-new.svg'; import {
ReactComponent as EditIcon,
ReactComponent as IconEdit,
} from 'assets/svg/edit-new.svg';
import { ReactComponent as ExportIcon } from 'assets/svg/ic-export.svg'; import { ReactComponent as ExportIcon } from 'assets/svg/ic-export.svg';
import { ReactComponent as ImportIcon } from 'assets/svg/ic-import.svg'; import { ReactComponent as ImportIcon } from 'assets/svg/ic-import.svg';
import { ReactComponent as IconRestore } from 'assets/svg/ic-restore.svg'; import { ReactComponent as IconRestore } from 'assets/svg/ic-restore.svg';
import { ReactComponent as IconOpenLock } from 'assets/svg/open-lock.svg'; import { ReactComponent as IconOpenLock } from 'assets/svg/open-lock.svg';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import classNames from 'classnames';
import { ManageButtonItemLabel } from 'components/common/ManageButtonContentItem/ManageButtonContentItem.component'; import { ManageButtonItemLabel } from 'components/common/ManageButtonContentItem/ManageButtonContentItem.component';
import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component'; import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component';
import TableDataCardV2 from 'components/common/table-data-card-v2/TableDataCardV2'; import TableDataCardV2 from 'components/common/table-data-card-v2/TableDataCardV2';
import TeamTypeSelect from 'components/common/TeamTypeSelect/TeamTypeSelect.component';
import { useEntityExportModalProvider } from 'components/Entity/EntityExportModalProvider/EntityExportModalProvider.component'; import { useEntityExportModalProvider } from 'components/Entity/EntityExportModalProvider/EntityExportModalProvider.component';
import { import {
GlobalSettingOptions, GlobalSettingOptions,
@ -52,10 +61,9 @@ import {
isEmpty, isEmpty,
isNil, isNil,
isUndefined, isUndefined,
last,
lowerCase, lowerCase,
uniqueId,
} from 'lodash'; } from 'lodash';
import { ExtraInfo } from 'Models';
import AddAttributeModal from 'pages/RolesPage/AddAttributeModal/AddAttributeModal'; import AddAttributeModal from 'pages/RolesPage/AddAttributeModal/AddAttributeModal';
import { ImportType } from 'pages/teams/ImportTeamsPage/ImportTeamsPage.interface'; import { ImportType } from 'pages/teams/ImportTeamsPage/ImportTeamsPage.interface';
import Qs from 'qs'; import Qs from 'qs';
@ -102,7 +110,6 @@ import {
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils'; import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
import Description from '../../common/description/Description'; import Description from '../../common/description/Description';
import ManageButton from '../../common/entityPageInfo/ManageButton/ManageButton'; import ManageButton from '../../common/entityPageInfo/ManageButton/ManageButton';
import EntitySummaryDetails from '../../common/EntitySummaryDetails/EntitySummaryDetails';
import ErrorPlaceHolder from '../../common/error-with-placeholder/ErrorPlaceHolder'; import ErrorPlaceHolder from '../../common/error-with-placeholder/ErrorPlaceHolder';
import NextPrevious from '../../common/next-previous/NextPrevious'; import NextPrevious from '../../common/next-previous/NextPrevious';
import Searchbar from '../../common/searchbar/Searchbar'; import Searchbar from '../../common/searchbar/Searchbar';
@ -200,6 +207,7 @@ const TeamDetailsV1 = ({
}>(); }>();
const [isModalLoading, setIsModalLoading] = useState<boolean>(false); const [isModalLoading, setIsModalLoading] = useState<boolean>(false);
const [isEmailEdit, setIsEmailEdit] = useState<boolean>(false); const [isEmailEdit, setIsEmailEdit] = useState<boolean>(false);
const [showTypeSelector, setShowTypeSelector] = useState(false);
const { showModal } = useEntityExportModalProvider(); const { showModal } = useEntityExportModalProvider();
const addPolicy = t('label.add-entity', { const addPolicy = t('label.add-entity', {
@ -300,17 +308,6 @@ const TeamDetailsV1 = ({
[] []
); );
const extraInfo: ExtraInfo[] = [
...(isOrganization
? []
: [
{
key: 'TeamType',
value: currentTeam.teamType || '',
},
]),
];
const searchTeams = async (text: string) => { const searchTeams = async (text: string) => {
try { try {
const res = await getSuggestions<SearchIndex.TEAM>( const res = await getSuggestions<SearchIndex.TEAM>(
@ -427,17 +424,16 @@ const TeamDetailsV1 = ({
[currentTeam] [currentTeam]
); );
const updateTeamType = (type: TeamType) => { const updateTeamType = async (type: TeamType) => {
if (currentTeam) { if (currentTeam) {
const updatedData: Team = { const updatedData: Team = {
...currentTeam, ...currentTeam,
teamType: type, teamType: type,
}; };
return updateTeamHandler(updatedData); await updateTeamHandler(updatedData);
setShowTypeSelector(false);
} }
return;
}; };
const handleTeamSearch = (value: string) => { const handleTeamSearch = (value: string) => {
@ -850,6 +846,65 @@ const TeamDetailsV1 = ({
); );
}; };
const teamTypeElement = useMemo(() => {
if (currentTeam.teamType === TeamType.Organization) {
return null;
}
return (
<>
{t('label.type') + ' - '}
{currentTeam.teamType ? (
showTypeSelector ? (
<TeamTypeSelect
handleShowTypeSelector={setShowTypeSelector}
parentTeamType={
last(parentTeams)?.teamType ?? TeamType.Organization
}
showGroupOption={!childTeams.length}
teamType={currentTeam.teamType ?? TeamType.Department}
updateTeamType={
entityPermissions.EditAll ? updateTeamType : undefined
}
/>
) : (
<>
{currentTeam.teamType}
{entityPermissions.EditAll && (
<Icon
className={classNames('vertical-middle m-l-xs', {
'opacity-50': isGroupType,
})}
data-testid="edit-team-type-icon"
title={
isGroupType
? t('message.group-team-type-change-message')
: t('label.edit-entity', {
entity: t('label.team-type'),
})
}
onClick={
isGroupType ? undefined : () => setShowTypeSelector(true)
}>
<EditIcon />
</Icon>
)}
</>
)
) : (
<span>{currentTeam.teamType}</span>
)}
</>
);
}, [
currentTeam,
showTypeSelector,
setShowTypeSelector,
parentTeams,
isGroupType,
childTeams,
]);
const emailElement = useMemo( const emailElement = useMemo(
() => ( () => (
<Space align="start" className="m-y-xs"> <Space align="start" className="m-y-xs">
@ -992,27 +1047,7 @@ const TeamDetailsV1 = ({
onUpdate={updateOwner} onUpdate={updateOwner}
/> />
{!isOrganization && <Divider type="vertical" />} {!isOrganization && <Divider type="vertical" />}
{teamTypeElement}
{extraInfo.map((info) => (
<Fragment key={uniqueId()}>
<EntitySummaryDetails
allowTeamOwner={false}
currentOwner={currentTeam.owner}
data={info}
isGroupType={isGroupType}
showGroupOption={!childTeams.length}
teamType={currentTeam.teamType}
updateOwner={
entityPermissions.EditAll || entityPermissions.EditOwner
? updateOwner
: undefined
}
updateTeamType={
entityPermissions.EditAll ? updateTeamType : undefined
}
/>
</Fragment>
))}
</Space> </Space>
<div className="m-b-sm m-t-xs" data-testid="description-container"> <div className="m-b-sm m-t-xs" data-testid="description-container">
<Description <Description

View File

@ -11,8 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { act, findByTestId, render, screen } from '@testing-library/react'; import { act, findByTestId, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import EntitySummaryDetails from './EntitySummaryDetails'; import EntitySummaryDetails from './EntitySummaryDetails';
@ -69,34 +68,4 @@ describe('EntitySummaryDetails Component', () => {
expect(EntitySummary).toBeInTheDocument(); expect(EntitySummary).toBeInTheDocument();
}); });
}); });
it('Edit team type should render the appropriate component', async () => {
render(
<EntitySummaryDetails data={{ key: 'TeamType', value: 'Department' }} />
);
const editTeamTypeBtn = screen.getByTestId('edit-TeamType-icon');
await act(async () => {
userEvent.click(editTeamTypeBtn);
});
// should show the team type select box and action buttons
expect(screen.getByTestId('team-type-select')).toBeInTheDocument();
const cancelBtn = screen.getByTestId('cancel-btn');
const saveBtn = screen.getByTestId('save-btn');
expect(cancelBtn).toBeInTheDocument();
expect(saveBtn).toBeInTheDocument();
// should hide the team type select box and action buttons after save
await act(async () => {
userEvent.click(saveBtn);
});
expect(screen.queryByTestId('team-type-select')).toBeNull();
expect(screen.queryByTestId('cancel-btn')).toBeNull();
expect(screen.queryByTestId('save-btn')).toBeNull();
});
}); });

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Button as AntdButton, Button, Space } from 'antd'; import { Button, Space } from 'antd';
import Tooltip, { RenderFunction } from 'antd/lib/tooltip'; import Tooltip, { RenderFunction } from 'antd/lib/tooltip';
import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg'; import { ReactComponent as EditIcon } from 'assets/svg/edit-new.svg';
import { ReactComponent as IconExternalLink } from 'assets/svg/external-links.svg'; import { ReactComponent as IconExternalLink } from 'assets/svg/external-links.svg';
@ -20,16 +20,14 @@ import classNames from 'classnames';
import { DE_ACTIVE_COLOR } from 'constants/constants'; import { DE_ACTIVE_COLOR } from 'constants/constants';
import { isString, isUndefined, lowerCase, noop, toLower } from 'lodash'; import { isString, isUndefined, lowerCase, noop, toLower } from 'lodash';
import { ExtraInfo } from 'Models'; import { ExtraInfo } from 'Models';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Dashboard } from '../../../generated/entity/data/dashboard'; import { Dashboard } from '../../../generated/entity/data/dashboard';
import { Table } from '../../../generated/entity/data/table'; import { Table } from '../../../generated/entity/data/table';
import { TeamType } from '../../../generated/entity/teams/team';
import { TagLabel } from '../../../generated/type/tagLabel'; import { TagLabel } from '../../../generated/type/tagLabel';
import { getTeamsUser } from '../../../utils/CommonUtils'; import { getTeamsUser } from '../../../utils/CommonUtils';
import SVGIcons from '../../../utils/SvgUtils'; import SVGIcons from '../../../utils/SvgUtils';
import ProfilePicture from '../ProfilePicture/ProfilePicture'; import ProfilePicture from '../ProfilePicture/ProfilePicture';
import TeamTypeSelect from '../TeamTypeSelect/TeamTypeSelect.component';
import TierCard from '../TierCard/TierCard'; import TierCard from '../TierCard/TierCard';
import { UserSelectableList } from '../UserSelectableList/UserSelectableList.component'; import { UserSelectableList } from '../UserSelectableList/UserSelectableList.component';
import { UserTeamSelectableList } from '../UserTeamSelectableList/UserTeamSelectableList.component'; import { UserTeamSelectableList } from '../UserTeamSelectableList/UserTeamSelectableList.component';
@ -40,11 +38,7 @@ export interface GetInfoElementsProps {
updateOwner?: (value: Table['owner']) => void; updateOwner?: (value: Table['owner']) => void;
tier?: TagLabel; tier?: TagLabel;
currentTier?: string; currentTier?: string;
teamType?: TeamType;
showGroupOption?: boolean;
isGroupType?: boolean;
updateTier?: (value?: string) => void; updateTier?: (value?: string) => void;
updateTeamType?: (type: TeamType) => void;
currentOwner?: Dashboard['owner']; currentOwner?: Dashboard['owner'];
deleted?: boolean; deleted?: boolean;
allowTeamOwner?: boolean; allowTeamOwner?: boolean;
@ -62,13 +56,9 @@ const InfoIcon = ({
const EntitySummaryDetails = ({ const EntitySummaryDetails = ({
data, data,
isGroupType,
tier, tier,
teamType,
showGroupOption,
updateOwner, updateOwner,
updateTier, updateTier,
updateTeamType,
currentOwner, currentOwner,
deleted = false, deleted = false,
allowTeamOwner = true, allowTeamOwner = true,
@ -77,17 +67,6 @@ const EntitySummaryDetails = ({
const { t } = useTranslation(); const { t } = useTranslation();
const displayVal = data.placeholderText || data.value; const displayVal = data.placeholderText || data.value;
const [showTypeSelector, setShowTypeSelector] = useState(false);
const handleShowTypeSelector = useCallback((value: boolean) => {
setShowTypeSelector(value);
}, []);
const handleUpdateTeamType = (type: TeamType) => {
updateTeamType?.(type);
handleShowTypeSelector(false);
};
const ownerDropdown = allowTeamOwner ? ( const ownerDropdown = allowTeamOwner ? (
<UserTeamSelectableList <UserTeamSelectableList
hasPermission={Boolean(updateOwner)} hasPermission={Boolean(updateOwner)}
@ -108,7 +87,7 @@ const EntitySummaryDetails = ({
userDetails, userDetails,
isTier, isTier,
isOwner, isOwner,
isTeamType,
isTeamOwner, isTeamOwner,
} = useMemo(() => { } = useMemo(() => {
const userDetails = getTeamsUser(data); const userDetails = getTeamsUser(data);
@ -119,7 +98,6 @@ const EntitySummaryDetails = ({
userDetails, userDetails,
isTier: data.key === 'Tier', isTier: data.key === 'Tier',
isOwner: data.key === 'Owner', isOwner: data.key === 'Owner',
isTeamType: data.key === 'TeamType',
isTeamOwner: isString(data.value) ? data.value.includes('teams/') : false, isTeamOwner: isString(data.value) ? data.value.includes('teams/') : false,
}; };
}, [data]); }, [data]);
@ -200,13 +178,6 @@ const EntitySummaryDetails = ({
break; break;
case 'TeamType':
{
retVal = displayVal ? <>{`${t('label.type')} - `}</> : <></>;
}
break;
case 'Usage': case 'Usage':
{ {
retVal = <>{`${t('label.usage')} - `}</>; retVal = <>{`${t('label.usage')} - `}</>;
@ -334,34 +305,6 @@ const EntitySummaryDetails = ({
</TierCard> </TierCard>
) : null} ) : null}
</Space> </Space>
) : isTeamType ? (
showTypeSelector ? (
<TeamTypeSelect
handleShowTypeSelector={handleShowTypeSelector}
showGroupOption={showGroupOption ?? false}
teamType={teamType ?? TeamType.Department}
updateTeamType={handleUpdateTeamType}
/>
) : (
<>
{displayVal}
<AntdButton
data-testid={`edit-${data.key}-icon`}
disabled={isGroupType}
title={
isGroupType
? t('message.group-team-type-change-message')
: t('label.edit-entity', {
entity: t('label.team-type'),
})
}
onClick={() => setShowTypeSelector(true)}>
{updateTeamType ? (
<EditIcon className="cursor-pointer" width={14} />
) : null}
</AntdButton>
</>
)
) : ( ) : (
<span>{displayVal}</span> <span>{displayVal}</span>
)} )}

View File

@ -14,16 +14,17 @@
import { CheckOutlined, CloseOutlined } from '@ant-design/icons'; import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Select, Space } from 'antd'; import { Button, Select, Space } from 'antd';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { getTeamOptionsFromType } from 'utils/TeamUtils';
import { TeamType } from '../../../generated/entity/teams/team'; import { TeamType } from '../../../generated/entity/teams/team';
import { TeamTypeSelectProps } from './TeamTypeSelect.interface'; import { TeamTypeSelectProps } from './TeamTypeSelect.interface';
import './TeamTypeSelect.style.less'; import './TeamTypeSelect.style.less';
import { getTeamTypeOptions } from './TeamTypeSelect.utils';
function TeamTypeSelect({ function TeamTypeSelect({
handleShowTypeSelector, handleShowTypeSelector,
showGroupOption, showGroupOption,
teamType, teamType,
updateTeamType, updateTeamType,
parentTeamType,
}: TeamTypeSelectProps) { }: TeamTypeSelectProps) {
const [value, setValue] = useState<TeamType>(teamType); const [value, setValue] = useState<TeamType>(teamType);
@ -39,7 +40,16 @@ function TeamTypeSelect({
updateTeamType && updateTeamType(value); updateTeamType && updateTeamType(value);
}; };
const options = useMemo(() => getTeamTypeOptions(showGroupOption), []); const options = useMemo(() => {
const options = getTeamOptionsFromType(parentTeamType).map((type) => ({
label: type,
value: type,
}));
return showGroupOption
? options
: options.filter((opt) => opt.value !== TeamType.Group);
}, [parentTeamType, showGroupOption]);
return ( return (
<Space <Space

View File

@ -18,4 +18,5 @@ export interface TeamTypeSelectProps {
teamType: TeamType; teamType: TeamType;
showGroupOption: boolean; showGroupOption: boolean;
updateTeamType?: (type: TeamType) => void; updateTeamType?: (type: TeamType) => void;
parentTeamType: TeamType;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 Collate. * Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -10,16 +10,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Team, TeamType } from 'generated/entity/teams/team';
import { TeamType } from '../../../generated/entity/teams/team'; export interface AddTeamFormType {
visible: boolean;
export const getTeamTypeOptions = (showGroupOption: boolean) => { onCancel: () => void;
const teamTypesArray = Object.values(TeamType).filter((key) => onSave: (data: Team) => void;
key === TeamType.Group ? showGroupOption : key !== TeamType.Organization isLoading: boolean;
); parentTeamType: TeamType;
}
return teamTypesArray.map((teamType) => ({
label: teamType,
value: teamType,
}));
};

View File

@ -0,0 +1,38 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { render } from '@testing-library/react';
import { TeamType } from 'generated/entity/teams/team';
import React from 'react';
import AddTeamForm from './AddTeamForm';
const mockCancel = jest.fn();
const mockSave = jest.fn();
describe('AddTeamForm component', () => {
it('should render form with required fields', () => {
const { getByTestId } = render(
<AddTeamForm
visible
isLoading={false}
parentTeamType={TeamType.Organization}
onCancel={mockCancel}
onSave={mockSave}
/>
);
expect(getByTestId('name')).toBeInTheDocument();
expect(getByTestId('email')).toBeInTheDocument();
expect(getByTestId('editor')).toBeInTheDocument();
expect(getByTestId('team-selector')).toBeInTheDocument();
});
});

View File

@ -21,21 +21,17 @@ import { toLower, trim } from 'lodash';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { getTeams } from 'rest/teamsAPI'; import { getTeams } from 'rest/teamsAPI';
import { getTeamOptionsFromType } from 'utils/TeamUtils';
import { Team, TeamType } from '../../generated/entity/teams/team'; import { Team, TeamType } from '../../generated/entity/teams/team';
import { showErrorToast } from '../../utils/ToastUtils'; import { showErrorToast } from '../../utils/ToastUtils';
import { AddTeamFormType } from './AddTeamForm.interface';
type AddTeamFormType = {
visible: boolean;
onCancel: () => void;
onSave: (data: Team) => void;
isLoading: boolean;
};
const AddTeamForm: React.FC<AddTeamFormType> = ({ const AddTeamForm: React.FC<AddTeamFormType> = ({
visible, visible,
onCancel, onCancel,
onSave, onSave,
isLoading, isLoading,
parentTeamType,
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [description, setDescription] = useState<string>(''); const [description, setDescription] = useState<string>('');
@ -43,13 +39,11 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
const markdownRef = useRef<EditorContentRef>(); const markdownRef = useRef<EditorContentRef>();
const teamTypeOptions = useMemo(() => { const teamTypeOptions = useMemo(() => {
return Object.values(TeamType) return getTeamOptionsFromType(parentTeamType).map((type) => ({
.filter((type) => type !== TeamType.Organization)
.map((type) => ({
label: type, label: type,
value: type, value: type,
})); }));
}, []); }, [parentTeamType]);
const handleSubmit = (data: Team) => { const handleSubmit = (data: Team) => {
data = { data = {

View File

@ -672,12 +672,15 @@ const TeamsPage = () => {
onShowDeletedTeamChange={toggleShowDeletedTeam} onShowDeletedTeamChange={toggleShowDeletedTeam}
onTeamExpand={fetchAllTeamsAdvancedDetails} onTeamExpand={fetchAllTeamsAdvancedDetails}
/> />
{selectedTeam.teamType && (
<AddTeamForm <AddTeamForm
isLoading={isLoading} isLoading={isLoading}
parentTeamType={selectedTeam.teamType}
visible={isAddingTeam} visible={isAddingTeam}
onCancel={() => setIsAddingTeam(false)} onCancel={() => setIsAddingTeam(false)}
onSave={(data) => createNewTeam(data as Team)} onSave={(data) => createNewTeam(data)}
/> />
)}
</> </>
); );
}; };

View File

@ -85,3 +85,23 @@ export const getMovedTeamData = (team: Team, parents: string[]): CreateTeam => {
users: getEntityValue(users), users: getEntityValue(users),
} as CreateTeam; } as CreateTeam;
}; };
export const getTeamOptionsFromType = (parentType: TeamType) => {
switch (parentType) {
case TeamType.Organization:
return [
TeamType.BusinessUnit,
TeamType.Division,
TeamType.Department,
TeamType.Group,
];
case TeamType.BusinessUnit:
return [TeamType.Division, TeamType.Department, TeamType.Group];
case TeamType.Division:
return [TeamType.Division, TeamType.Department, TeamType.Group];
case TeamType.Department:
return [TeamType.Department, TeamType.Group];
case TeamType.Group:
return [TeamType.Group];
}
};