mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-15 10:48:31 +00:00
parent
87335137e5
commit
c586bb1aed
@ -44,3 +44,7 @@ export const patchTeamDetail: Function = (id: string, data: Team) => {
|
||||
|
||||
return APIClient.patch(`/teams/${id}`, data, configOptions);
|
||||
};
|
||||
|
||||
export const deleteTeam = (id: string): Promise<AxiosResponse> => {
|
||||
return APIClient.delete(`/teams/${id}`);
|
||||
};
|
||||
|
@ -19,6 +19,7 @@ import { Link } from 'react-router-dom';
|
||||
import AppState from '../../AppState';
|
||||
import {
|
||||
getExplorePathWithSearch,
|
||||
getTeamDetailsPath,
|
||||
ROUTES,
|
||||
TITLE_FOR_NON_ADMIN_ACTION,
|
||||
} from '../../constants/constants';
|
||||
@ -103,7 +104,7 @@ const MyAssetStats: FunctionComponent<Props> = ({
|
||||
icon: Icons.TEAMS_GREY,
|
||||
data: 'Teams',
|
||||
count: userTeams.length,
|
||||
link: ROUTES.TEAMS,
|
||||
link: getTeamDetailsPath(),
|
||||
dataTestId: 'terms',
|
||||
},
|
||||
};
|
||||
|
@ -274,9 +274,12 @@ export const getPipelineDetailsPath = (pipelineFQN: string, tab?: string) => {
|
||||
return path;
|
||||
};
|
||||
|
||||
export const getTeamDetailsPath = (teamName: string) => {
|
||||
let path = ROUTES.TEAM_DETAILS;
|
||||
path = path.replace(PLACEHOLDER_ROUTE_TEAM, teamName);
|
||||
export const getTeamDetailsPath = (teamName?: string) => {
|
||||
let path = ROUTES.TEAMS;
|
||||
if (teamName) {
|
||||
path = ROUTES.TEAM_DETAILS;
|
||||
path = path.replace(PLACEHOLDER_ROUTE_TEAM, teamName);
|
||||
}
|
||||
|
||||
return path;
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ const jsonData = {
|
||||
'add-glossary-term-error': 'Error while adding glossary term!',
|
||||
'delete-glossary-error': 'Error while deleting glossary!',
|
||||
'delete-glossary-term-error': 'Error while deleting glossary term!',
|
||||
'delete-team-error': 'Error while deleting team!',
|
||||
'elastic-search-error': 'Error while fetch data from Elasticsearch!',
|
||||
'fetch-data-error': 'Error while fetching data!',
|
||||
'fetch-glossary-error': 'Error while fetching glossary!',
|
||||
|
@ -107,6 +107,7 @@ jest.mock('../../axiosAPIs/teamsAPI', () => ({
|
||||
Promise.resolve({ data: { data: mockTeamsData } })
|
||||
),
|
||||
patchTeamDetail: jest.fn(),
|
||||
deleteTeam: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock(
|
||||
@ -269,4 +270,30 @@ describe('Test Teams page', () => {
|
||||
|
||||
expect(await findByTestId(container, 'form-modal')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('onClick of delete team button, delete modal should open', async () => {
|
||||
const { container } = render(<TeamsPage />);
|
||||
|
||||
const deleteTeamButton = await findByTestId(
|
||||
container,
|
||||
'delete-team-button'
|
||||
);
|
||||
|
||||
expect(deleteTeamButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(
|
||||
deleteTeamButton,
|
||||
new MouseEvent('click', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
})
|
||||
);
|
||||
|
||||
const confirmationModal = await findByTestId(
|
||||
container,
|
||||
'confirmation-modal'
|
||||
);
|
||||
|
||||
expect(confirmationModal).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -11,6 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { AxiosError, AxiosResponse } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { compare } from 'fast-json-patch';
|
||||
@ -23,6 +24,7 @@ import AppState from '../../AppState';
|
||||
import { useAuthContext } from '../../auth-provider/AuthProvider';
|
||||
import {
|
||||
createTeam,
|
||||
deleteTeam,
|
||||
getTeamByName,
|
||||
getTeams,
|
||||
patchTeamDetail,
|
||||
@ -50,6 +52,7 @@ import {
|
||||
} from '../../generated/entity/teams/user';
|
||||
import { useAuth } from '../../hooks/authHooks';
|
||||
import useToastContext from '../../hooks/useToastContext';
|
||||
import jsonData from '../../jsons/en';
|
||||
import {
|
||||
getActiveCatClass,
|
||||
getCountBadge,
|
||||
@ -58,7 +61,6 @@ import {
|
||||
import AddUsersModal from './AddUsersModal';
|
||||
import Form from './Form';
|
||||
import UserCard from './UserCard';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
const TeamsPage = () => {
|
||||
const { team } = useParams() as Record<string, string>;
|
||||
@ -79,9 +81,20 @@ const TeamsPage = () => {
|
||||
user: EntityReference | undefined;
|
||||
state: boolean;
|
||||
}>({ user: undefined, state: false });
|
||||
const [deletingTeam, setDeletingTeam] = useState<{
|
||||
team: Team | undefined;
|
||||
state: boolean;
|
||||
}>({ team: undefined, state: false });
|
||||
|
||||
const showToast = useToastContext();
|
||||
|
||||
const handleShowErrorToast = (errMessage: string) => {
|
||||
showToast({
|
||||
variant: 'error',
|
||||
body: errMessage,
|
||||
});
|
||||
};
|
||||
|
||||
const fetchTeams = () => {
|
||||
setIsLoading(true);
|
||||
getTeams(['users', 'owns', 'defaultRoles'])
|
||||
@ -102,6 +115,15 @@ const TeamsPage = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const goToTeams = () => {
|
||||
if (team) {
|
||||
history.push(getTeamDetailsPath());
|
||||
} else {
|
||||
fetchTeams();
|
||||
setCurrentTab(1);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchCurrentTeam = (name: string, update = false) => {
|
||||
if (currentTeam?.name !== name || update) {
|
||||
setIsLoading(true);
|
||||
@ -226,6 +248,33 @@ const TeamsPage = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const deleteTeamHandler = () => {
|
||||
const team = currentTeam;
|
||||
setDeletingTeam({ team: team, state: true });
|
||||
};
|
||||
|
||||
const deleteTeamById = (id: string) => {
|
||||
deleteTeam(id)
|
||||
.then((res: AxiosResponse) => {
|
||||
if (res.data) {
|
||||
goToTeams();
|
||||
} else {
|
||||
handleShowErrorToast(
|
||||
jsonData['api-error-messages']['delete-team-error']
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((err: AxiosError) => {
|
||||
handleShowErrorToast(
|
||||
err.response?.data?.message ||
|
||||
jsonData['api-error-messages']['delete-team-error']
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeletingTeam({ team: undefined, state: false });
|
||||
});
|
||||
};
|
||||
|
||||
const getActiveTabClass = (tab: number) => {
|
||||
return tab === currentTab ? 'active' : '';
|
||||
};
|
||||
@ -514,27 +563,50 @@ const TeamsPage = () => {
|
||||
title={currentTeam?.displayName ?? currentTeam?.name}>
|
||||
{currentTeam?.displayName ?? currentTeam?.name}
|
||||
</div>
|
||||
<NonAdminAction
|
||||
html={
|
||||
<>You do not have permission to update the team.</>
|
||||
}
|
||||
permission={Operation.UpdateTeam}
|
||||
position="bottom">
|
||||
<Button
|
||||
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
|
||||
'tw-opacity-40':
|
||||
!isAdminUser &&
|
||||
!isAuthDisabled &&
|
||||
!userPermissions[Operation.UpdateTeam],
|
||||
})}
|
||||
data-testid="add-new-user-button"
|
||||
size="small"
|
||||
theme="primary"
|
||||
variant="contained"
|
||||
onClick={() => setIsAddingUsers(true)}>
|
||||
Add new user
|
||||
</Button>
|
||||
</NonAdminAction>
|
||||
<div>
|
||||
<NonAdminAction
|
||||
html={
|
||||
<>You do not have permission to update the team.</>
|
||||
}
|
||||
permission={Operation.UpdateTeam}
|
||||
position="bottom">
|
||||
<Button
|
||||
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
|
||||
'tw-opacity-40':
|
||||
!isAdminUser &&
|
||||
!isAuthDisabled &&
|
||||
!userPermissions[Operation.UpdateTeam],
|
||||
})}
|
||||
data-testid="add-new-user-button"
|
||||
size="small"
|
||||
theme="primary"
|
||||
variant="contained"
|
||||
onClick={() => setIsAddingUsers(true)}>
|
||||
Add new user
|
||||
</Button>
|
||||
</NonAdminAction>
|
||||
<NonAdminAction
|
||||
html={
|
||||
<>You do not have permission to delete the team.</>
|
||||
}
|
||||
position="bottom">
|
||||
<Button
|
||||
className={classNames(
|
||||
'tw-h-8 tw-rounded tw-mb-3 tw-ml-2',
|
||||
{
|
||||
'tw-opacity-40':
|
||||
!isAdminUser && !isAuthDisabled,
|
||||
}
|
||||
)}
|
||||
data-testid="delete-team-button"
|
||||
size="small"
|
||||
theme="primary"
|
||||
variant="contained"
|
||||
onClick={() => deleteTeamHandler()}>
|
||||
Delete Team
|
||||
</Button>
|
||||
</NonAdminAction>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="tw-mb-3 tw--ml-5"
|
||||
@ -625,6 +697,22 @@ const TeamsPage = () => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{deletingTeam.state && (
|
||||
<ConfirmationModal
|
||||
bodyText={`Are you sure you want to delete the team "${
|
||||
deletingTeam.team?.displayName || deletingTeam.team?.name
|
||||
}"?`}
|
||||
cancelText="Cancel"
|
||||
confirmText="Confirm"
|
||||
header="Delete Team"
|
||||
onCancel={() =>
|
||||
setDeletingTeam({ team: undefined, state: false })
|
||||
}
|
||||
onConfirm={() => {
|
||||
deleteTeamById(deletingTeam.team?.id as string);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</PageLayout>
|
||||
|
Loading…
x
Reference in New Issue
Block a user