diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx index 6719e43e047..4b81c1742f8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.component.tsx @@ -449,7 +449,7 @@ const DashboardDetails = ({
- +
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx index 324476845e0..d3485e3d51d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardDetails/DashboardDetails.test.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { findByText, render } from '@testing-library/react'; +import { findByTestId, findByText, render } from '@testing-library/react'; import { LeafNodes, LoadingNodeState, TableDetail } from 'Models'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; @@ -94,11 +94,11 @@ const DashboardDetailsProps = { }; jest.mock('../ManageTab/ManageTab.component', () => { - return jest.fn().mockReturnValue(

ManageTab

); + return jest.fn().mockReturnValue(

ManageTab

); }); jest.mock('../common/description/Description', () => { - return jest.fn().mockReturnValue(

Description

); + return jest.fn().mockReturnValue(

Description Component

); }); jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => { return jest.fn().mockReturnValue(

RichTextEditorPreviwer

); @@ -116,10 +116,6 @@ jest.mock('../EntityLineage/EntityLineage.component', () => { return jest.fn().mockReturnValue(

EntityLineage

); }); -jest.mock('../common/TabsPane/TabsPane', () => { - return jest.fn().mockReturnValue(

TabsPane

); -}); - jest.mock('../common/entityPageInfo/EntityPageInfo', () => { return jest.fn().mockReturnValue(

EntityPageInfo

); }); @@ -128,8 +124,17 @@ jest.mock('../FeedEditor/FeedEditor', () => { return jest.fn().mockReturnValue(

FeedEditor

); }); +jest.mock('../ActivityFeed/ActivityFeedList/ActivityFeedList.tsx', () => { + return jest.fn().mockReturnValue(

ActivityFeedList

); +}); + +jest.mock('../EntityLineage/EntityLineage.component', () => { + return jest.fn().mockReturnValue(

Lineage

); +}); + jest.mock('../../utils/CommonUtils', () => ({ addToRecentViewed: jest.fn(), + getCountBadge: jest.fn(), getCurrentUserId: jest.fn().mockReturnValue('CurrentUserId'), getPartialNameFromFQN: jest.fn().mockReturnValue('PartialNameFromFQN'), getUserTeams: () => mockUserTeam, @@ -145,9 +150,67 @@ describe('Test DashboardDetails component', () => { } ); const EntityPageInfo = await findByText(container, /EntityPageInfo/i); - const TabsPane = await findByText(container, /TabsPane/i); + const description = await findByText(container, /Description Component/i); + const tabs = await findByTestId(container, 'tabs'); + const detailsTab = await findByTestId(tabs, 'Details'); + const activityFeedTab = await findByTestId(tabs, 'Activity Feed'); + const lineageTab = await findByTestId(tabs, 'Lineage'); + const manageTab = await findByTestId(tabs, 'Manage'); expect(EntityPageInfo).toBeInTheDocument(); - expect(TabsPane).toBeInTheDocument(); + expect(description).toBeInTheDocument(); + expect(tabs).toBeInTheDocument(); + expect(detailsTab).toBeInTheDocument(); + expect(activityFeedTab).toBeInTheDocument(); + expect(lineageTab).toBeInTheDocument(); + expect(manageTab).toBeInTheDocument(); + }); + + it('Check if active tab is details', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const activityFeedList = await findByTestId(container, 'charts-table'); + + expect(activityFeedList).toBeInTheDocument(); + }); + + it('Check if active tab is activity feed', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const activityFeedList = await findByText(container, /ActivityFeedList/i); + + expect(activityFeedList).toBeInTheDocument(); + }); + + it('Check if active tab is lineage', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const lineage = await findByTestId(container, 'lineage'); + + expect(lineage).toBeInTheDocument(); + }); + + it('Check if active tab is manage', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + const manage = await findByTestId(container, 'manage'); + + expect(manage).toBeInTheDocument(); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.test.tsx new file mode 100644 index 00000000000..45d5e559fb9 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.test.tsx @@ -0,0 +1,141 @@ +/* + * Copyright 2021 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 { findByTestId, queryByTestId, render } from '@testing-library/react'; +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import Users from './Users.component'; + +const mockUserData = { + id: 'd6764107-e8b4-4748-b256-c86fecc66064', + name: 'xyz', + displayName: 'XYZ', + version: 0.1, + updatedAt: 1648704499857, + updatedBy: 'xyz', + email: 'xyz@gmail.com', + href: 'http://localhost:8585/api/v1/users/d6764107-e8b4-4748-b256-c86fecc66064', + isAdmin: false, + profile: { + images: { + image: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s96-c', + image24: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s24-c', + image32: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s32-c', + image48: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s48-c', + image72: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s72-c', + image192: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s192-c', + image512: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s512-c', + }, + }, + teams: [ + { + id: '3362fe18-05ad-4457-9632-84f22887dda6', + type: 'team', + name: 'Finance', + description: 'This is Finance description.', + displayName: 'Finance', + deleted: false, + href: 'http://localhost:8585/api/v1/teams/3362fe18-05ad-4457-9632-84f22887dda6', + }, + { + id: '5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', + type: 'team', + name: 'Data_Platform', + description: 'This is Data_Platform description.', + displayName: 'Data_Platform', + deleted: false, + href: 'http://localhost:8585/api/v1/teams/5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', + }, + { + id: '7182cc43-aebc-419d-9452-ddbe2fc4e640', + type: 'team', + name: 'Customer_Support', + description: 'This is Customer_Support description.', + displayName: 'Customer_Support', + deleted: true, + href: 'http://localhost:8585/api/v1/teams/7182cc43-aebc-419d-9452-ddbe2fc4e640', + }, + ], + owns: [], + follows: [], + deleted: false, + roles: [ + { + id: 'ce4df2a5-aaf5-4580-8556-254f42574aa7', + type: 'role', + name: 'DataConsumer', + description: + 'Users with Data Consumer role use different data assets for their day to day work.', + displayName: 'Data Consumer', + deleted: false, + href: 'http://localhost:8585/api/v1/roles/ce4df2a5-aaf5-4580-8556-254f42574aa7', + }, + ], +}; + +jest.mock('../common/avatar/Avatar', () => { + return jest.fn().mockReturnValue(

Avatar

); +}); + +jest.mock('../../pages/teams/UserCard', () => { + return jest.fn().mockReturnValue(

UserCard

); +}); + +jest.mock('../common/TabsPane/TabsPane', () => { + return jest.fn().mockReturnValue(

Tabs

); +}); + +describe('Test User Component', () => { + it('Should render user component', async () => { + const { container } = render(, { + wrapper: MemoryRouter, + }); + + const tabs = await findByTestId(container, 'tabs'); + const noAssets = await findByTestId(container, 'no-assets'); + const leftPanel = await findByTestId(container, 'left-panel'); + + expect(tabs).toBeInTheDocument(); + expect(noAssets).toBeInTheDocument(); + expect(leftPanel).toBeInTheDocument(); + }); + + it('Should render non deleted teams', async () => { + const { container } = render(, { + wrapper: MemoryRouter, + }); + + const teamFinance = await findByTestId(container, 'Finance'); + const teamDataPlatform = await findByTestId(container, 'Data_Platform'); + + expect(teamFinance).toBeInTheDocument(); + expect(teamDataPlatform).toBeInTheDocument(); + }); + + it('Should not render deleted teams', async () => { + const { container } = render(, { + wrapper: MemoryRouter, + }); + + const deletedTeam = queryByTestId(container, 'Customer_Support'); + + expect(deletedTeam).not.toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx index bd559a4826c..5aae0cf7f46 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Users/Users.component.tsx @@ -1,7 +1,21 @@ +/* + * Copyright 2021 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 React, { useState } from 'react'; import { AssetsType } from '../../enums/entity.enum'; import { EntityReference, User } from '../../generated/entity/teams/user'; import UserCard from '../../pages/teams/UserCard'; +import { getNonDeletedTeams } from '../../utils/CommonUtils'; import SVGIcons, { Icons } from '../../utils/SvgUtils'; import Avatar from '../common/avatar/Avatar'; import TabsPane from '../common/TabsPane/TabsPane'; @@ -51,7 +65,7 @@ const Users = ({ userData }: Props) => { const fetchLeftPanel = () => { return ( -
+
{userData.profile?.images?.image ? (
@@ -77,9 +91,11 @@ const Users = ({ userData }: Props) => {
Teams
- - {userData.teams?.map((team, i) => ( -
+ {getNonDeletedTeams(userData.teams ?? []).map((team, i) => ( +
{team?.displayName || team?.name}
@@ -102,7 +118,9 @@ const Users = ({ userData }: Props) => { const getEntityData = (data: EntityReference[], placeholder: string) => { if ((data?.length as number) <= 0) { return ( -
+

{placeholder}

); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/app-bar/Appbar.tsx b/openmetadata-ui/src/main/resources/ui/src/components/app-bar/Appbar.tsx index 8b580e80cd8..83a90f3a9b7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/app-bar/Appbar.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/app-bar/Appbar.tsx @@ -30,7 +30,10 @@ import { } from '../../constants/constants'; import { urlGitbookDocs, urlJoinSlack } from '../../constants/url.const'; import { useAuth } from '../../hooks/authHooks'; -import { addToRecentSearched } from '../../utils/CommonUtils'; +import { + addToRecentSearched, + getNonDeletedTeams, +} from '../../utils/CommonUtils'; import SVGIcons, { Icons } from '../../utils/SvgUtils'; import { COOKIE_VERSION } from '../Modals/WhatsNewModal/whatsNewData'; import NavBar from '../nav-bar/NavBar'; @@ -146,7 +149,7 @@ const Appbar: React.FC = (): JSX.Element => { const roles = currentUser?.roles; - const teams = currentUser?.teams; + const teams = getNonDeletedTeams(currentUser?.teams ?? []); return (
@@ -166,10 +169,10 @@ const Appbar: React.FC = (): JSX.Element => {
) : null} - {(teams?.length ?? 0) > 0 ? ( + {teams.length > 0 ? (
Teams - {teams?.map((t, i) => ( + {teams.map((t, i) => (

{t.displayName} diff --git a/openmetadata-ui/src/main/resources/ui/src/generated/entity/teams/user.ts b/openmetadata-ui/src/main/resources/ui/src/generated/entity/teams/user.ts index fb98022334e..cc126b37cef 100644 --- a/openmetadata-ui/src/main/resources/ui/src/generated/entity/teams/user.ts +++ b/openmetadata-ui/src/main/resources/ui/src/generated/entity/teams/user.ts @@ -144,6 +144,10 @@ export interface FieldChange { * the relationship of a table `belongs to a` database. */ export interface EntityReference { + /** + * If true the entity referred to has been soft-deleted. + */ + deleted?: boolean; /** * Optional description of entity. */ diff --git a/openmetadata-ui/src/main/resources/ui/src/jsons/en.ts b/openmetadata-ui/src/main/resources/ui/src/jsons/en.ts index b7207d92214..628e5e637bf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/jsons/en.ts +++ b/openmetadata-ui/src/main/resources/ui/src/jsons/en.ts @@ -60,6 +60,7 @@ const jsonData = { 'fetch-thread-error': 'Error while fetching threads!', 'fetch-updated-conversation-error': 'Error while fetching updated conversation!', + 'fetch-user-details-error': 'Error while fetching user details!', 'fetch-service-error': 'Error while fetching service details!', 'fetch-teams-error': 'Error while fetching teams!', diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx index 99fc2efaa5e..c0aa1259c3c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx @@ -1,4 +1,17 @@ -import { AxiosResponse } from 'axios'; +/* + * Copyright 2021 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 { AxiosError, AxiosResponse } from 'axios'; import React, { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { getUserByName } from '../../axiosAPIs/userAPI'; @@ -6,30 +19,55 @@ import PageContainerV1 from '../../components/containers/PageContainerV1'; import Loader from '../../components/Loader/Loader'; import Users from '../../components/Users/Users.component'; import { User } from '../../generated/entity/teams/user'; +import useToastContext from '../../hooks/useToastContext'; +import jsonData from '../../jsons/en'; +import { getErrorText } from '../../utils/StringsUtils'; const UserPage = () => { + const showToast = useToastContext(); const { username } = useParams<{ [key: string]: string }>(); const [isLoading, setIsLoading] = useState(true); const [userData, setUserData] = useState({} as User); const [isError, setIsError] = useState(false); + const handleShowErrorToast = (errMessage: string) => { + showToast({ + variant: 'error', + body: errMessage, + }); + }; + const fetchUserData = () => { getUserByName(username, 'profile,roles,teams,follows,owns') .then((res: AxiosResponse) => { - setUserData(res.data); + if (res.data) { + setUserData(res.data); + } else { + throw jsonData['api-error-messages']['unexpected-server-response']; + } }) - .catch(() => { + .catch((err: AxiosError) => { + const errMsg = getErrorText( + err, + jsonData['api-error-messages']['fetch-user-details-error'] + ); + handleShowErrorToast(errMsg); setIsError(true); }) .finally(() => setIsLoading(false)); }; - const errorPlaceholder = () => { + const ErrorPlaceholder = () => { return ( -

-

+

+

No user available with{' '} - {username} username. + + {username} + {' '} + username.

); @@ -46,7 +84,7 @@ const UserPage = () => { ) : !isError ? ( ) : ( - errorPlaceholder() + )} ); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx new file mode 100644 index 00000000000..4542e71ffe1 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx @@ -0,0 +1,137 @@ +/* + * Copyright 2021 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 { findByTestId, findByText, render } from '@testing-library/react'; +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { getUserByName } from '../../axiosAPIs/userAPI'; +import UserPage from './UserPage.component'; + +const mockUserData = { + id: 'd6764107-e8b4-4748-b256-c86fecc66064', + name: 'xyz', + displayName: 'XYZ', + version: 0.1, + updatedAt: 1648704499857, + updatedBy: 'xyz', + email: 'xyz@gmail.com', + href: 'http://localhost:8585/api/v1/users/d6764107-e8b4-4748-b256-c86fecc66064', + isAdmin: false, + profile: { + images: { + image: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s96-c', + image24: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s24-c', + image32: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s32-c', + image48: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s48-c', + image72: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s72-c', + image192: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s192-c', + image512: + 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s512-c', + }, + }, + teams: [ + { + id: '3362fe18-05ad-4457-9632-84f22887dda6', + type: 'team', + name: 'Finance', + description: 'This is Finance description.', + displayName: 'Finance', + deleted: false, + href: 'http://localhost:8585/api/v1/teams/3362fe18-05ad-4457-9632-84f22887dda6', + }, + { + id: '5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', + type: 'team', + name: 'Data_Platform', + description: 'This is Data_Platform description.', + displayName: 'Data_Platform', + deleted: false, + href: 'http://localhost:8585/api/v1/teams/5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', + }, + { + id: '7182cc43-aebc-419d-9452-ddbe2fc4e640', + type: 'team', + name: 'Customer_Support', + description: 'This is Customer_Support description.', + displayName: 'Customer_Support', + deleted: false, + href: 'http://localhost:8585/api/v1/teams/7182cc43-aebc-419d-9452-ddbe2fc4e640', + }, + ], + owns: [], + follows: [], + deleted: false, + roles: [ + { + id: 'ce4df2a5-aaf5-4580-8556-254f42574aa7', + type: 'role', + name: 'DataConsumer', + description: + 'Users with Data Consumer role use different data assets for their day to day work.', + displayName: 'Data Consumer', + deleted: false, + href: 'http://localhost:8585/api/v1/roles/ce4df2a5-aaf5-4580-8556-254f42574aa7', + }, + ], +}; + +jest.mock('react-router-dom', () => ({ + useParams: jest.fn().mockImplementation(() => ({ username: 'xyz' })), +})); + +jest.mock('../../components/Loader/Loader', () => { + return jest.fn().mockReturnValue(

Loader

); +}); + +jest.mock('../../components/Users/Users.component', () => { + return jest.fn().mockReturnValue(

User Component

); +}); + +jest.mock('../../axiosAPIs/userAPI', () => ({ + getUserByName: jest + .fn() + .mockImplementation(() => Promise.resolve({ data: mockUserData })), +})); + +describe('Test the User Page', () => { + it('Should render the user component', async () => { + const { container } = render(, { wrapper: MemoryRouter }); + + const userComponent = await findByText(container, /User Component/i); + + expect(userComponent).toBeInTheDocument(); + }); + + it('Should render error placeholder if api fails', async () => { + (getUserByName as jest.Mock).mockImplementationOnce(() => + Promise.reject({ + response: { + data: { + message: 'Error', + }, + }, + }) + ); + const { container } = render(, { wrapper: MemoryRouter }); + + const errorPlaceholder = await findByTestId(container, 'error'); + + expect(errorPlaceholder).toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx index 4adc11cb305..bf8dbb94ff0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/CommonUtils.tsx @@ -35,6 +35,7 @@ import { UrlEntityCharRegEx } from '../constants/regex.constants'; import { TabSpecificField } from '../enums/entity.enum'; import { Ownership } from '../enums/mydata.enum'; import { + EntityReference, EntityReference as UserTeams, User, } from '../generated/entity/teams/user'; @@ -499,3 +500,12 @@ export const getRandomColor = (name: string) => { export const isUrlFriendlyName = (value: string) => { return !UrlEntityCharRegEx.test(value); }; + +/** + * Take teams data and filter out the non deleted teams + * @param teams - teams array + * @returns - non deleted team + */ +export const getNonDeletedTeams = (teams: EntityReference[]) => { + return teams.filter((t) => !t.deleted); +};
Chart Name