mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 11:09:14 +00:00
* Fixed #667 Add Loader to every page, wherever it's required before data renders . * changed service no found placeholder.
This commit is contained in:
parent
ec51fadf19
commit
79ca909f2f
@ -27,13 +27,16 @@ import { getRecentlyViewedData } from '../../utils/CommonUtils';
|
||||
import { getOwnerFromId, getTierFromTableTags } from '../../utils/TableUtils';
|
||||
import { getTableTags } from '../../utils/TagsUtils';
|
||||
import TableDataCard from '../common/table-data-card/TableDataCard';
|
||||
import Loader from '../Loader/Loader';
|
||||
import Onboarding from '../onboarding/Onboarding';
|
||||
|
||||
const RecentlyViewed: FunctionComponent = () => {
|
||||
const recentlyViewedData = getRecentlyViewedData();
|
||||
const [data, setData] = useState<Array<FormatedTableData>>([]);
|
||||
const [isLoading, setIsloading] = useState<boolean>(false);
|
||||
|
||||
const fetchRecentlyViewedEntity = async () => {
|
||||
setIsloading(true);
|
||||
const arrData: Array<FormatedTableData> = [];
|
||||
|
||||
for (const oData of recentlyViewedData) {
|
||||
@ -156,6 +159,7 @@ const RecentlyViewed: FunctionComponent = () => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
setIsloading(false);
|
||||
setData(arrData);
|
||||
};
|
||||
|
||||
@ -167,27 +171,33 @@ const RecentlyViewed: FunctionComponent = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.length ? (
|
||||
data.map((item, index) => {
|
||||
return (
|
||||
<div className="tw-mb-3" key={index}>
|
||||
<TableDataCard
|
||||
description={item.description}
|
||||
fullyQualifiedName={item.fullyQualifiedName}
|
||||
indexType={item.index}
|
||||
name={item.name}
|
||||
owner={item.owner}
|
||||
serviceType={item.serviceType || '--'}
|
||||
tableType={item.tableType}
|
||||
tags={item.tags}
|
||||
tier={item.tier?.split('.')[1]}
|
||||
usage={item.weeklyPercentileRank}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<Onboarding />
|
||||
<>
|
||||
{data.length ? (
|
||||
data.map((item, index) => {
|
||||
return (
|
||||
<div className="tw-mb-3" key={index}>
|
||||
<TableDataCard
|
||||
description={item.description}
|
||||
fullyQualifiedName={item.fullyQualifiedName}
|
||||
indexType={item.index}
|
||||
name={item.name}
|
||||
owner={item.owner}
|
||||
serviceType={item.serviceType || '--'}
|
||||
tableType={item.tableType}
|
||||
tags={item.tags}
|
||||
tier={item.tier?.split('.')[1]}
|
||||
usage={item.weeklyPercentileRank}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Onboarding />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@ -92,7 +92,7 @@ describe('Test SearchedData Component', () => {
|
||||
}
|
||||
);
|
||||
|
||||
const searchedDataContainer = getByTestId(container, 'fluid-container');
|
||||
const searchedDataContainer = getByTestId(container, 'search-container');
|
||||
|
||||
expect(searchedDataContainer).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@ -27,7 +27,6 @@ import {
|
||||
} from '../../utils/TableUtils';
|
||||
import ErrorPlaceHolderES from '../common/error-with-placeholder/ErrorPlaceHolderES';
|
||||
import TableDataCard from '../common/table-data-card/TableDataCard';
|
||||
import PageContainer from '../containers/PageContainer';
|
||||
import Loader from '../Loader/Loader';
|
||||
import Onboarding from '../onboarding/Onboarding';
|
||||
import Pagination from '../Pagination';
|
||||
@ -55,7 +54,6 @@ const SearchedData: React.FC<SearchedDataProp> = ({
|
||||
showOnlyChildren = false,
|
||||
searchText,
|
||||
totalValue,
|
||||
fetchLeftPanel,
|
||||
}: SearchedDataProp) => {
|
||||
const highlightSearchResult = () => {
|
||||
return data.map((table, index) => {
|
||||
@ -108,50 +106,46 @@ const SearchedData: React.FC<SearchedDataProp> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageContainer leftPanelContent={fetchLeftPanel?.()}>
|
||||
<div className="container-fluid" data-testid="fluid-container">
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<div data-testid="search-container">
|
||||
{totalValue > 0 || showOnboardingTemplate || showOnlyChildren ? (
|
||||
<>
|
||||
{children}
|
||||
{!showOnlyChildren ? (
|
||||
<>
|
||||
{showResultCount && searchText ? (
|
||||
<div className="tw-mb-1">
|
||||
{pluralize(totalValue, 'result')}
|
||||
</div>
|
||||
) : null}
|
||||
{data.length > 0 ? (
|
||||
<div className="tw-grid tw-grid-rows-1 tw-grid-cols-1">
|
||||
{highlightSearchResult()}
|
||||
{totalValue > PAGE_SIZE && data.length > 0 && (
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
paginate={paginate}
|
||||
sizePerPage={PAGE_SIZE}
|
||||
totalNumberOfValues={totalValue}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Onboarding />
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{totalValue > 0 || showOnboardingTemplate || showOnlyChildren ? (
|
||||
<>
|
||||
{children}
|
||||
{!showOnlyChildren ? (
|
||||
<>
|
||||
{showResultCount && searchText ? (
|
||||
<div className="tw-mb-1">
|
||||
{pluralize(totalValue, 'result')}
|
||||
</div>
|
||||
) : null}
|
||||
{data.length > 0 ? (
|
||||
<div className="tw-grid tw-grid-rows-1 tw-grid-cols-1">
|
||||
{highlightSearchResult()}
|
||||
{totalValue > PAGE_SIZE && data.length > 0 && (
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
paginate={paginate}
|
||||
sizePerPage={PAGE_SIZE}
|
||||
totalNumberOfValues={totalValue}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Onboarding />
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{children}
|
||||
<ErrorPlaceHolderES query={searchText} type="noData" />
|
||||
</>
|
||||
)}
|
||||
{children}
|
||||
<ErrorPlaceHolderES query={searchText} type="noData" />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</PageContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { ServiceTypes } from 'Models';
|
||||
import noDataFound from '../assets/img/no-data-placeholder.png';
|
||||
import noService from '../assets/img/no-service.png';
|
||||
import airflow from '../assets/img/service-icon-airflow.png';
|
||||
import athena from '../assets/img/service-icon-athena.png';
|
||||
@ -39,6 +40,7 @@ import tableau from '../assets/img/service-icon-tableau.png';
|
||||
import trino from '../assets/img/service-icon-trino.png';
|
||||
import plus from '../assets/svg/plus.svg';
|
||||
|
||||
export const NoDataFoundPlaceHolder = noDataFound;
|
||||
export const MYSQL = mysql;
|
||||
export const MSSQL = mssql;
|
||||
export const REDSHIFT = redshift;
|
||||
|
||||
@ -54,10 +54,12 @@ describe('Test Explore page', () => {
|
||||
const { container } = render(<ExplorePage />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
const pageContainer = await findByTestId(container, 'fluid-container');
|
||||
const searchData = await findByTestId(container, 'search-data');
|
||||
const wrappedContent = await findByTestId(container, 'wrapped-content');
|
||||
const tabs = await findAllByTestId(container, 'tab');
|
||||
|
||||
expect(pageContainer).toBeInTheDocument();
|
||||
expect(searchData).toBeInTheDocument();
|
||||
expect(wrappedContent).toBeInTheDocument();
|
||||
expect(tabs.length).toBe(4);
|
||||
|
||||
@ -32,6 +32,7 @@ import { searchData } from '../../axiosAPIs/miscAPI';
|
||||
import { Button } from '../../components/buttons/Button/Button';
|
||||
import ErrorPlaceHolderES from '../../components/common/error-with-placeholder/ErrorPlaceHolderES';
|
||||
import FacetFilter from '../../components/common/facetfilter/FacetFilter';
|
||||
import PageContainer from '../../components/containers/PageContainer';
|
||||
import DropDownList from '../../components/dropdown/DropDownList';
|
||||
import SearchedData from '../../components/searched-data/SearchedData';
|
||||
import {
|
||||
@ -577,6 +578,7 @@ const ExplorePage: React.FC = (): React.ReactElement => {
|
||||
setFieldList(tabsInfo[getCurrentTab(tab) - 1].sortingFields);
|
||||
setSortField(tabsInfo[getCurrentTab(tab) - 1].sortField);
|
||||
setSortOrder('desc');
|
||||
setError('');
|
||||
setCurrentTab(getCurrentTab(tab));
|
||||
setSearchIndex(getCurrentIndex(tab));
|
||||
setCurrentPage(1);
|
||||
@ -609,33 +611,38 @@ const ExplorePage: React.FC = (): React.ReactElement => {
|
||||
|
||||
const fetchLeftPanel = () => {
|
||||
return (
|
||||
<FacetFilter
|
||||
aggregations={getAggrWithDefaultValue(aggregations, visibleFilters)}
|
||||
filters={getFacetedFilter()}
|
||||
onClearFilter={(value) => onClearFilterHandler(value)}
|
||||
onSelectHandler={handleSelectedFilter}
|
||||
/>
|
||||
<>
|
||||
{!error && (
|
||||
<FacetFilter
|
||||
aggregations={getAggrWithDefaultValue(aggregations, visibleFilters)}
|
||||
filters={getFacetedFilter()}
|
||||
onClearFilter={(value) => onClearFilterHandler(value)}
|
||||
onSelectHandler={handleSelectedFilter}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{error ? (
|
||||
<ErrorPlaceHolderES errorMessage={error} type="error" />
|
||||
) : (
|
||||
<SearchedData
|
||||
showResultCount
|
||||
currentPage={currentPage}
|
||||
data={data}
|
||||
fetchLeftPanel={fetchLeftPanel}
|
||||
isLoading={isLoading}
|
||||
paginate={paginate}
|
||||
searchText={searchText}
|
||||
totalValue={totalNumberOfValue}>
|
||||
{getTabs()}
|
||||
</SearchedData>
|
||||
)}
|
||||
</>
|
||||
<PageContainer leftPanelContent={fetchLeftPanel()}>
|
||||
<div className="container-fluid" data-testid="fluid-container">
|
||||
{getTabs()}
|
||||
{error ? (
|
||||
<ErrorPlaceHolderES errorMessage={error} type="error" />
|
||||
) : (
|
||||
<SearchedData
|
||||
showResultCount
|
||||
currentPage={currentPage}
|
||||
data={data}
|
||||
isLoading={isLoading}
|
||||
paginate={paginate}
|
||||
searchText={searchText}
|
||||
totalValue={totalNumberOfValue}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -223,11 +223,13 @@ describe('Test MyData page', () => {
|
||||
const { container } = render(<MyDataPage />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
const pageContainer = await findByTestId(container, 'fluid-container');
|
||||
const searchData = await findByTestId(container, 'search-data');
|
||||
const wrappedContent = await findByTestId(container, 'wrapped-content');
|
||||
const tabs = await findAllByTestId(container, 'tab');
|
||||
const myDataHeader = await findByText(container, /MyDataHeader/i);
|
||||
|
||||
expect(pageContainer).toBeInTheDocument();
|
||||
expect(searchData).toBeInTheDocument();
|
||||
expect(wrappedContent).toBeInTheDocument();
|
||||
expect(myDataHeader).toBeInTheDocument();
|
||||
|
||||
@ -23,6 +23,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
||||
import AppState from '../../AppState';
|
||||
import { searchData } from '../../axiosAPIs/miscAPI';
|
||||
import ErrorPlaceHolderES from '../../components/common/error-with-placeholder/ErrorPlaceHolderES';
|
||||
import PageContainer from '../../components/containers/PageContainer';
|
||||
import Loader from '../../components/Loader/Loader';
|
||||
import MyDataHeader from '../../components/my-data/MyDataHeader';
|
||||
import RecentlyViewed from '../../components/recently-viewed/RecentlyViewed';
|
||||
@ -44,6 +45,7 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||
const [totalNumberOfValue, setTotalNumberOfValues] = useState<number>(0);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [isEntityLoading, setIsEntityLoading] = useState<boolean>(true);
|
||||
const [currentTab, setCurrentTab] = useState<number>(1);
|
||||
const [error, setError] = useState<string>('');
|
||||
const [filter, setFilter] = useState<string>('');
|
||||
@ -72,7 +74,9 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
};
|
||||
|
||||
const fetchTableData = (setAssetCount = false) => {
|
||||
setIsLoading(true);
|
||||
if (!isEntityLoading) {
|
||||
setIsLoading(true);
|
||||
}
|
||||
searchData(
|
||||
'',
|
||||
currentPage,
|
||||
@ -91,10 +95,12 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
setAggregations(res.data.aggregations);
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsEntityLoading(false);
|
||||
} else {
|
||||
setData([]);
|
||||
setTotalNumberOfValues(0);
|
||||
setIsLoading(false);
|
||||
setIsEntityLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((err: AxiosError) => {
|
||||
@ -104,6 +110,7 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
body: err.response?.data?.responseMessage ?? ERROR500,
|
||||
});
|
||||
setIsLoading(false);
|
||||
setIsEntityLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -115,6 +122,7 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
className={`tw-pb-2 tw-px-4 tw-gh-tabs ${getActiveTabClass(1)}`}
|
||||
data-testid="tab"
|
||||
onClick={() => {
|
||||
setIsEntityLoading(true);
|
||||
setCurrentTab(1);
|
||||
setFilter('');
|
||||
setCurrentPage(1);
|
||||
@ -125,6 +133,7 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
className={`tw-pb-2 tw-px-4 tw-gh-tabs ${getActiveTabClass(2)}`}
|
||||
data-testid="tab"
|
||||
onClick={() => {
|
||||
setIsEntityLoading(true);
|
||||
setCurrentTab(2);
|
||||
setFilter(Ownership.OWNER);
|
||||
setCurrentPage(1);
|
||||
@ -135,6 +144,7 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
className={`tw-pb-2 tw-px-4 tw-gh-tabs ${getActiveTabClass(3)}`}
|
||||
data-testid="tab"
|
||||
onClick={() => {
|
||||
setIsEntityLoading(true);
|
||||
setCurrentTab(3);
|
||||
setFilter(Ownership.FOLLOWERS);
|
||||
setCurrentPage(1);
|
||||
@ -163,23 +173,15 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
{error ? (
|
||||
<ErrorPlaceHolderES errorMessage={error} type="error" />
|
||||
) : (
|
||||
<>
|
||||
{error ? (
|
||||
<ErrorPlaceHolderES errorMessage={error} type="error" />
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<SearchedData
|
||||
showOnboardingTemplate
|
||||
currentPage={currentPage}
|
||||
data={data}
|
||||
paginate={paginate}
|
||||
searchText="*"
|
||||
showOnlyChildren={currentTab === 1}
|
||||
showResultCount={filter && data.length > 0 ? true : false}
|
||||
totalValue={totalNumberOfValue}>
|
||||
<>
|
||||
<PageContainer>
|
||||
<div className="container-fluid" data-testid="fluid-container">
|
||||
<MyDataHeader
|
||||
countAssets={getTotalEntityCountByService(
|
||||
aggregations?.['sterms#Service']?.buckets as Bucket[]
|
||||
@ -190,9 +192,20 @@ const MyDataPage: React.FC = (): React.ReactElement => {
|
||||
)}
|
||||
/>
|
||||
{getTabs()}
|
||||
{currentTab === 1 ? <RecentlyViewed /> : null}
|
||||
</>
|
||||
</SearchedData>
|
||||
<SearchedData
|
||||
showOnboardingTemplate
|
||||
currentPage={currentPage}
|
||||
data={data}
|
||||
isLoading={isEntityLoading}
|
||||
paginate={paginate}
|
||||
searchText="*"
|
||||
showOnlyChildren={currentTab === 1}
|
||||
showResultCount={filter && data.length > 0 ? true : false}
|
||||
totalValue={totalNumberOfValue}>
|
||||
{currentTab === 1 ? <RecentlyViewed /> : null}
|
||||
</SearchedData>
|
||||
</div>
|
||||
</PageContainer>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -44,7 +44,7 @@ import {
|
||||
} from '../../constants/constants';
|
||||
import {
|
||||
arrServiceTypes,
|
||||
NOSERVICE,
|
||||
NoDataFoundPlaceHolder,
|
||||
PLUS,
|
||||
servicesDisplayName,
|
||||
} from '../../constants/services.const';
|
||||
@ -81,7 +81,7 @@ export type ApiData = {
|
||||
|
||||
const ServicesPage = () => {
|
||||
const showToast = useToastContext();
|
||||
const { isAdminUser } = useAuth();
|
||||
const { isAdminUser, isAuthDisabled } = useAuth();
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [serviceName, setServiceName] =
|
||||
useState<ServiceTypes>('databaseServices');
|
||||
@ -328,6 +328,7 @@ const ServicesPage = () => {
|
||||
value: service.collection.name,
|
||||
};
|
||||
});
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@ -466,7 +467,7 @@ const ServicesPage = () => {
|
||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
||||
<div
|
||||
className={classNames('tw-inline-block', {
|
||||
'tw-opacity-40': !isAdminUser,
|
||||
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
|
||||
})}
|
||||
style={{ width: '100%' }}>
|
||||
<div
|
||||
@ -484,7 +485,11 @@ const ServicesPage = () => {
|
||||
) : (
|
||||
<div className="tw-flex tw-items-center tw-flex-col">
|
||||
<div className="tw-mt-24">
|
||||
<img alt="No Service" src={NOSERVICE} />
|
||||
<img
|
||||
alt="No Service"
|
||||
src={NoDataFoundPlaceHolder}
|
||||
width={250}
|
||||
/>
|
||||
</div>
|
||||
<div className="tw-mt-11">
|
||||
<p className="tw-text-lg">
|
||||
|
||||
@ -219,12 +219,12 @@ const TagsPage = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
{error ? (
|
||||
<p className="tw-text-2xl tw-text-center tw-m-auto">{error}</p>
|
||||
) : (
|
||||
<PageContainer className="py-0" leftPanelContent={fetchLeftPanel()}>
|
||||
{error ? (
|
||||
<p className="tw-text-2xl tw-text-center tw-m-auto">{error}</p>
|
||||
{isLoading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<div className="container-fluid py-3" data-testid="tags-container">
|
||||
{currentCategory && (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user