Fix #4391 UI : Use user API to get owns and following data on home page. (#6431)

This commit is contained in:
Sachin Chaurasiya 2022-07-29 21:29:07 +05:30 committed by GitHub
parent 173b820c22
commit e11b409d70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 72 deletions

View File

@ -12,7 +12,6 @@
*/ */
import { Button, Card, Typography } from 'antd'; import { Button, Card, Typography } from 'antd';
import { FormattedTableData } from 'Models';
import React, { Fragment, FunctionComponent } from 'react'; import React, { Fragment, FunctionComponent } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { EntityReference } from '../../generated/type/entityReference'; import { EntityReference } from '../../generated/type/entityReference';
@ -21,14 +20,14 @@ import { getEntityIcon, getEntityLink } from '../../utils/TableUtils';
import Ellipses from '../common/Ellipses/Ellipses'; import Ellipses from '../common/Ellipses/Ellipses';
import { leftPanelAntCardStyle } from '../containers/PageLayout'; import { leftPanelAntCardStyle } from '../containers/PageLayout';
interface Prop { interface Prop {
entityList: Array<FormattedTableData>; entityList: Array<EntityReference>;
headerText: string | JSX.Element; headerText: string | JSX.Element;
noDataPlaceholder: JSX.Element; noDataPlaceholder: JSX.Element;
testIDText: string; testIDText: string;
} }
interface AntdEntityListProp { interface AntdEntityListProp {
entityList: Array<FormattedTableData>; entityList: Array<EntityReference>;
headerText?: string | JSX.Element; headerText?: string | JSX.Element;
headerTextLabel: string; headerTextLabel: string;
noDataPlaceholder: JSX.Element; noDataPlaceholder: JSX.Element;
@ -58,12 +57,12 @@ const EntityList: FunctionComponent<Prop> = ({
)}`} )}`}
key={index}> key={index}>
<div className="tw-flex"> <div className="tw-flex">
{getEntityIcon(item.index || item.type || '')} {getEntityIcon(item.type || '')}
<Link <Link
className="tw-font-medium" className="tw-font-medium"
to={getEntityLink( to={getEntityLink(
item.index || item.type || '', item.type || '',
item.fullyQualifiedName item.fullyQualifiedName as string
)}> )}>
<Button <Button
className="tw-text-grey-body hover:tw-text-primary-hover hover:tw-underline" className="tw-text-grey-body hover:tw-text-primary-hover hover:tw-underline"
@ -103,12 +102,12 @@ export const EntityListWithAntd: FunctionComponent<AntdEntityListProp> = ({
)}`} )}`}
key={index}> key={index}>
<div className="tw-flex"> <div className="tw-flex">
{getEntityIcon(item.index || item.type || '')} {getEntityIcon(item.type || '')}
<Link <Link
className="tw-font-medium" className="tw-font-medium"
to={getEntityLink( to={getEntityLink(
item.index || item.type || '', item.type || '',
item.fullyQualifiedName item.fullyQualifiedName as string
)}> )}>
<Button <Button
className="tw-text-grey-body hover:tw-text-primary-hover hover:tw-underline" className="tw-text-grey-body hover:tw-text-primary-hover hover:tw-underline"

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { FormattedTableData, SearchDataFunctionType } from 'Models'; import { EntityReference, SearchDataFunctionType } from 'Models';
import { FeedFilter } from '../../enums/mydata.enum'; import { FeedFilter } from '../../enums/mydata.enum';
import { Thread, ThreadType } from '../../generated/entity/feed/thread'; import { Thread, ThreadType } from '../../generated/entity/feed/thread';
import { User } from '../../generated/entity/teams/user'; import { User } from '../../generated/entity/teams/user';
@ -34,8 +34,8 @@ export interface MyDataProps {
ownedDataCount: number; ownedDataCount: number;
countPipelines: number; countPipelines: number;
userDetails?: User; userDetails?: User;
ownedData: Array<FormattedTableData>; ownedData: Array<EntityReference>;
followedData: Array<FormattedTableData>; followedData: Array<EntityReference>;
feedData: Thread[]; feedData: Thread[];
paging: Paging; paging: Paging;
isFeedLoading: boolean; isFeedLoading: boolean;

View File

@ -19,6 +19,7 @@ import {
findByText, findByText,
render, render,
} from '@testing-library/react'; } from '@testing-library/react';
import { EntityReference } from 'Models';
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { User } from '../../generated/entity/teams/user'; import { User } from '../../generated/entity/teams/user';
@ -233,6 +234,16 @@ const mockUserDetails = {
}, },
}; };
const currentUserMockData = {
id: '7b26a534-25e8-4112-ae08-ee059f8918c4',
type: 'table',
name: 'test_dim_staff',
fullyQualifiedName: 'test_sample.test_db.test_dim_staff',
description: 'test test_dim_staff',
deleted: false,
href: 'http://localhost:8585/api/v1/tables/7b26a534-25e8-4112-ae08-ee059f8918c4',
} as EntityReference;
jest.mock('../../axiosAPIs/miscAPI', () => ({ jest.mock('../../axiosAPIs/miscAPI', () => ({
searchData: jest searchData: jest
.fn() .fn()
@ -333,14 +344,14 @@ const mockProp: MyDataProps = {
feedData: formatDataResponse(mockData.data.hits.hits), feedData: formatDataResponse(mockData.data.hits.hits),
fetchData: fetchData, fetchData: fetchData,
fetchFeedHandler: mockFetchFeedHandler, fetchFeedHandler: mockFetchFeedHandler,
followedData: formatDataResponse(mockData.data.hits.hits), followedData: currentUserMockData,
isFeedLoading: false, isFeedLoading: false,
ownedData: formatDataResponse(mockData.data.hits.hits), ownedData: currentUserMockData,
paging: mockPaging, paging: mockPaging,
postFeedHandler: postFeed, postFeedHandler: postFeed,
userDetails: mockUserDetails as unknown as User, userDetails: mockUserDetails as unknown as User,
updateThreadHandler: jest.fn(), updateThreadHandler: jest.fn(),
}; } as unknown as MyDataProps;
const mockObserve = jest.fn(); const mockObserve = jest.fn();
const mockunObserve = jest.fn(); const mockunObserve = jest.fn();

View File

@ -11,7 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { FormattedTableData } from 'Models'; import { EntityReference } from 'Models';
import React, { Fragment, FunctionComponent, useEffect, useState } from 'react'; import React, { Fragment, FunctionComponent, useEffect, useState } from 'react';
import { getRecentlyViewedData, prepareLabel } from '../../utils/CommonUtils'; import { getRecentlyViewedData, prepareLabel } from '../../utils/CommonUtils';
import { EntityListWithAntd } from '../EntityList/EntityList'; import { EntityListWithAntd } from '../EntityList/EntityList';
@ -19,7 +19,7 @@ import Loader from '../Loader/Loader';
const RecentlyViewed: FunctionComponent = () => { const RecentlyViewed: FunctionComponent = () => {
const recentlyViewedData = getRecentlyViewedData(); const recentlyViewedData = getRecentlyViewedData();
const [data, setData] = useState<Array<FormattedTableData>>([]); const [data, setData] = useState<Array<EntityReference>>([]);
const [isLoading, setIsloading] = useState<boolean>(false); const [isLoading, setIsloading] = useState<boolean>(false);
const prepareData = () => { const prepareData = () => {
@ -31,11 +31,11 @@ const RecentlyViewed: FunctionComponent = () => {
serviceType: item.serviceType, serviceType: item.serviceType,
name: item.displayName || prepareLabel(item.entityType, item.fqn), name: item.displayName || prepareLabel(item.entityType, item.fqn),
fullyQualifiedName: item.fqn, fullyQualifiedName: item.fqn,
index: item.entityType, type: item.entityType,
}; };
}) })
.filter((item) => item.name); .filter((item) => item.name);
setData(formattedData as unknown as FormattedTableData[]); setData(formattedData as unknown as EntityReference[]);
setIsloading(false); setIsloading(false);
} }
}; };

View File

@ -491,6 +491,7 @@ declare module 'Models' {
fqn: string; fqn: string;
serviceType?: string; serviceType?: string;
timestamp: number; timestamp: number;
id: number;
} }
interface RecentlySearchedData { interface RecentlySearchedData {

View File

@ -376,6 +376,7 @@ const DashboardDetailsPage = () => {
fqn: fullyQualifiedName, fqn: fullyQualifiedName,
serviceType: serviceType, serviceType: serviceType,
timestamp: 0, timestamp: 0,
id: id,
}); });
fetchServiceDetails(service.type, service.name) fetchServiceDetails(service.type, service.name)

View File

@ -369,6 +369,7 @@ const DatasetDetailsPage: FunctionComponent = () => {
fqn: fullyQualifiedName, fqn: fullyQualifiedName,
serviceType: serviceType, serviceType: serviceType,
timestamp: 0, timestamp: 0,
id: id,
}); });
setName(name); setName(name);

View File

@ -15,7 +15,7 @@ import { AxiosError, AxiosResponse } from 'axios';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { isEmpty, isNil, isUndefined } from 'lodash'; import { isEmpty, isNil, isUndefined } from 'lodash';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { FormattedTableData } from 'Models'; import { EntityReference } from 'Models';
import React, { import React, {
Fragment, Fragment,
useCallback, useCallback,
@ -27,13 +27,13 @@ import { useLocation } from 'react-router-dom';
import AppState from '../../AppState'; import AppState from '../../AppState';
import { getAllDashboards } from '../../axiosAPIs/dashboardAPI'; import { getAllDashboards } from '../../axiosAPIs/dashboardAPI';
import { getFeedsWithFilter, postFeedById } from '../../axiosAPIs/feedsAPI'; import { getFeedsWithFilter, postFeedById } from '../../axiosAPIs/feedsAPI';
import { fetchSandboxConfig, searchData } from '../../axiosAPIs/miscAPI'; import { fetchSandboxConfig } from '../../axiosAPIs/miscAPI';
import { getAllMlModal } from '../../axiosAPIs/mlModelAPI'; import { getAllMlModal } from '../../axiosAPIs/mlModelAPI';
import { getAllPipelines } from '../../axiosAPIs/pipelineAPI'; import { getAllPipelines } from '../../axiosAPIs/pipelineAPI';
import { getAllTables } from '../../axiosAPIs/tableAPI'; import { getAllTables } from '../../axiosAPIs/tableAPI';
import { getTeams } from '../../axiosAPIs/teamsAPI'; import { getTeams } from '../../axiosAPIs/teamsAPI';
import { getAllTopics } from '../../axiosAPIs/topicsAPI'; import { getAllTopics } from '../../axiosAPIs/topicsAPI';
import { getUsers } from '../../axiosAPIs/userAPI'; import { getUserById, getUsers } from '../../axiosAPIs/userAPI';
import PageContainerV1 from '../../components/containers/PageContainerV1'; import PageContainerV1 from '../../components/containers/PageContainerV1';
import GithubStarButton from '../../components/GithubStarButton/GithubStarButton'; import GithubStarButton from '../../components/GithubStarButton/GithubStarButton';
import Loader from '../../components/Loader/Loader'; import Loader from '../../components/Loader/Loader';
@ -44,19 +44,17 @@ import {
onErrorText, onErrorText,
onUpdatedConversastionError, onUpdatedConversastionError,
} from '../../constants/feed.constants'; } from '../../constants/feed.constants';
import { myDataSearchIndex } from '../../constants/Mydata.constants'; import { AssetsType } from '../../enums/entity.enum';
import { FeedFilter, Ownership } from '../../enums/mydata.enum'; import { FeedFilter } from '../../enums/mydata.enum';
import { Thread, ThreadType } from '../../generated/entity/feed/thread'; import { Thread, ThreadType } from '../../generated/entity/feed/thread';
import { Paging } from '../../generated/type/paging'; import { Paging } from '../../generated/type/paging';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
import jsonData from '../../jsons/en'; import jsonData from '../../jsons/en';
import { formatDataResponse } from '../../utils/APIUtils';
import { import {
deletePost, deletePost,
getUpdatedThread, getUpdatedThread,
updateThreadData, updateThreadData,
} from '../../utils/FeedUtils'; } from '../../utils/FeedUtils';
import { getMyDataFilters } from '../../utils/MyDataUtils';
import { getAllServices } from '../../utils/ServiceUtils'; import { getAllServices } from '../../utils/ServiceUtils';
import { showErrorToast } from '../../utils/ToastUtils'; import { showErrorToast } from '../../utils/ToastUtils';
@ -73,8 +71,8 @@ const MyDataPage = () => {
const [countUsers, setCountUsers] = useState<number>(); const [countUsers, setCountUsers] = useState<number>();
const [countTeams, setCountTeams] = useState<number>(); const [countTeams, setCountTeams] = useState<number>();
const [ownedData, setOwnedData] = useState<Array<FormattedTableData>>(); const [ownedData, setOwnedData] = useState<Array<EntityReference>>();
const [followedData, setFollowedData] = useState<Array<FormattedTableData>>(); const [followedData, setFollowedData] = useState<Array<EntityReference>>();
const [ownedDataCount, setOwnedDataCount] = useState(0); const [ownedDataCount, setOwnedDataCount] = useState(0);
const [followedDataCount, setFollowedDataCount] = useState(0); const [followedDataCount, setFollowedDataCount] = useState(0);
const [pendingTaskCount, setPendingTaskCount] = useState(0); const [pendingTaskCount, setPendingTaskCount] = useState(0);
@ -263,52 +261,38 @@ const MyDataPage = () => {
} }
}; };
const fetchMyData = () => { const fetchMyData = async () => {
const ownedEntity = searchData( if (!currentUser || !currentUser.id) {
'', return;
1, }
8, try {
getMyDataFilters( const { data: userData } = await getUserById(
Ownership.OWNER, currentUser?.id,
AppState.userDetails, 'follows, owns'
AppState.nonSecureUserDetails
),
'',
'',
myDataSearchIndex
); );
const followedEntity = searchData( if (userData) {
'', const includeData = Object.values(AssetsType);
1, const owns: EntityReference[] = userData.owns ?? [];
8, const follows: EntityReference[] = userData.follows ?? [];
getMyDataFilters(
Ownership.FOLLOWERS, setFollowedDataCount(follows.length);
AppState.userDetails, setOwnedDataCount(owns.length);
AppState.nonSecureUserDetails
), const includedOwnsData = owns.filter((data) =>
'', includeData.includes(data.type as AssetsType)
'', );
myDataSearchIndex const includedFollowsData = follows.filter((data) =>
includeData.includes(data.type as AssetsType)
); );
Promise.allSettled([ownedEntity, followedEntity]) setFollowedData(includedFollowsData.slice(0, 8));
.then(([resOwnedEntity, resFollowedEntity]) => { setOwnedData(includedOwnsData.slice(0, 8));
if (resOwnedEntity.status === 'fulfilled') {
setOwnedData(formatDataResponse(resOwnedEntity.value.data.hits.hits));
setOwnedDataCount(resOwnedEntity.value.data.hits.total.value);
} }
if (resFollowedEntity.status === 'fulfilled') { } catch (err) {
setFollowedDataCount(resFollowedEntity.value.data.hits.total.value);
setFollowedData(
formatDataResponse(resFollowedEntity.value.data.hits.hits)
);
}
})
.catch(() => {
setOwnedData([]); setOwnedData([]);
setFollowedData([]); setFollowedData([]);
}); }
}; };
const getFeedData = ( const getFeedData = (

View File

@ -317,6 +317,7 @@ const PipelineDetailsPage = () => {
fqn: fullyQualifiedName, fqn: fullyQualifiedName,
serviceType: serviceType, serviceType: serviceType,
timestamp: 0, timestamp: 0,
id: id,
}); });
setPipelineUrl(pipelineUrl); setPipelineUrl(pipelineUrl);

View File

@ -428,6 +428,7 @@ const TopicDetailsPage: FunctionComponent = () => {
fqn: fullyQualifiedName, fqn: fullyQualifiedName,
serviceType: serviceType, serviceType: serviceType,
timestamp: 0, timestamp: 0,
id: id,
}); });
} else { } else {
showErrorToast( showErrorToast(