Skip to content

Commit

Permalink
chore: proper tags fetching on main overview page. Prepare useQuery h…
Browse files Browse the repository at this point in the history
…ooks to upgrade to 5v (#1486)
  • Loading branch information
AndreyNenashev authored Oct 26, 2023
1 parent 518e4ea commit 090f1db
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 186 deletions.
24 changes: 11 additions & 13 deletions odd-platform-ui/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import React, { lazy, useEffect } from 'react';
import { Route, Routes } from 'react-router-dom';
import { Toaster } from 'react-hot-toast';
import { toolbarHeight } from 'lib/constants';
Expand All @@ -13,20 +13,18 @@ import {
import { useAppPaths } from 'lib/hooks';

// lazy elements
const Management = React.lazy(() => import('./Management/Management'));
const ManagementRoutes = React.lazy(
const Management = lazy(() => import('./Management/Management'));
const ManagementRoutes = lazy(
() => import('./Management/ManagementRoutes/ManagementRoutes')
);
const DataEntityDetails = React.lazy(
() => import('./DataEntityDetails/DataEntityDetails')
);
const TermDetails = React.lazy(() => import('./Terms/TermDetails/TermDetails'));
const Overview = React.lazy(() => import('./Overview/Overview'));
const Search = React.lazy(() => import('./Search/Search'));
const TermSearch = React.lazy(() => import('./Terms/TermSearch/TermSearch'));
const Alerts = React.lazy(() => import('./Alerts/Alerts'));
const Activity = React.lazy(() => import('./Activity/Activity'));
const DirectoryRoutes = React.lazy(() => import('./Directory/DirectoryRoutes'));
const DataEntityDetails = lazy(() => import('./DataEntityDetails/DataEntityDetails'));
const TermDetails = lazy(() => import('./Terms/TermDetails/TermDetails'));
const Overview = lazy(() => import('./Overview/Overview'));
const Search = lazy(() => import('./Search/Search'));
const TermSearch = lazy(() => import('./Terms/TermSearch/TermSearch'));
const Alerts = lazy(() => import('./Alerts/Alerts'));
const Activity = lazy(() => import('./Activity/Activity'));
const DirectoryRoutes = lazy(() => import('./Directory/DirectoryRoutes'));

const App: React.FC = () => {
const dispatch = useAppDispatch();
Expand Down
10 changes: 7 additions & 3 deletions odd-platform-ui/src/components/Overview/Overview.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Grid } from '@mui/material';
import React from 'react';
import { getIdentityFetchingStatuses, getTagListFetchingStatuses } from 'redux/selectors';
import { getIdentityFetchingStatuses } from 'redux/selectors';
import { MainSearch, SkeletonWrapper } from 'components/shared/elements';
import { WithPermissionsProvider } from 'components/shared/contexts';
import { Permission } from 'generated-sources';
import { useAppSelector } from 'redux/lib/hooks';
import Domains from 'components/Overview/Domains/Domains';
import { useGetPopularTags } from 'lib/hooks/api/tags';
import DataEntitiesUsageInfo from './DataEntitiesUsageInfo/DataEntitiesUsageInfo';
import OverviewSkeleton from './OverviewSkeleton/OverviewSkeleton';
import * as S from './OverviewStyles';
Expand All @@ -14,8 +15,11 @@ import TopTagsList from './TopTagsList/TopTagsList';
import Directory from './Directory/Directory';

const Overview: React.FC = () => {
const { isLoading: isTagsFetching } = useAppSelector(getTagListFetchingStatuses);
const { isLoading: isIdentityFetching } = useAppSelector(getIdentityFetchingStatuses);
const { isLoading: isTagsFetching, data: tags } = useGetPopularTags({
page: 1,
size: 30,
});

const isLoading = React.useMemo(
() => isIdentityFetching || isTagsFetching,
Expand All @@ -38,7 +42,7 @@ const Overview: React.FC = () => {
<MainSearch mainSearch />
</Grid>
<S.TagsContainer container>
<TopTagsList />
{tags ? <TopTagsList tags={tags} /> : null}
</S.TagsContainer>
<Domains />
<DataEntitiesUsageInfo />
Expand Down
42 changes: 20 additions & 22 deletions odd-platform-ui/src/components/Overview/TopTagsList/TopTagsList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { type FC, useCallback, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import { TagItem } from 'components/shared/elements';
import { useCreateSearch } from 'lib/hooks';
import { useAppSelector } from 'redux/lib/hooks';
import { getTagListFetchingStatuses, getTagsList } from 'redux/selectors';
import type { Tag } from 'generated-sources';

const TopTagsList: FC = () => {
const createSearch = useCreateSearch();
interface Props {
tags: Tag[];
}

const topTags = useAppSelector(getTagsList);
const { isNotLoaded: isTagsNotFetched } = useAppSelector(getTagListFetchingStatuses);
const TopTagsList = ({ tags }: Props) => {
const createSearch = useCreateSearch();

const handleTagClick = useCallback(
(id: number, name: string) => () => {
Expand All @@ -23,31 +23,29 @@ const TopTagsList: FC = () => {

const sortedTags = useMemo(
() =>
[...topTags].sort((a, b) => {
[...tags].sort((a, b) => {
if (a.usedCount !== b.usedCount) {
return (b.usedCount ?? 0) - (a.usedCount ?? 0);
}

return b.important ? 1 : -1;
}),
[topTags]
[tags]
);

return (
<>
{isTagsNotFetched
? null
: sortedTags.map(tag => (
<TagItem
onClick={handleTagClick(tag.id, tag.name)}
key={tag.id}
label={tag.name}
important={tag.important}
count={tag.usedCount}
cursorPointer
sx={{ m: 0.5 }}
/>
))}
{sortedTags.map(tag => (
<TagItem
onClick={handleTagClick(tag.id, tag.name)}
key={tag.id}
label={tag.name}
important={tag.important}
count={tag.usedCount}
cursorPointer
sx={{ m: 0.5 }}
/>
))}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import React, { type FC, useEffect, useState } from 'react';
import { Grid, Typography } from '@mui/material';
import InfiniteScroll from 'react-infinite-scroll-component';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { EmptyContentPlaceholder, Input } from 'components/shared/elements';
import { useAppParams } from 'lib/hooks';
import { termApi } from 'lib/api';
import { useAppParams, useGetTermLinkedColumns } from 'lib/hooks';
import LinkedColumn from './LinkedColumn/LinkedColumn';
import {
TermLinkedColumnsColContainer,
Expand All @@ -25,11 +23,7 @@ const LinkedColumnsList: FC = () => {
isFetching,
isFetched,
refetch: search,
} = useQuery(
['termLinkedColumns', termId],
() => termApi.getTermLinkedColumns({ termId, page: 1, size, query }),
{ enabled: false, initialData: { pageInfo: { total: 0, hasNext: false }, items: [] } }
);
} = useGetTermLinkedColumns({ termId, page: 1, size, query });

useEffect(() => {
search();
Expand Down
16 changes: 9 additions & 7 deletions odd-platform-ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';

import {
StyledEngineProvider,
Expand All @@ -28,16 +28,18 @@ declare module 'styled-components' {
}

const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: async e => {
if ((e as Error).message === '401') {
window.location.reload();
}
await showServerErrorToast(e as Response);
},
}),
defaultOptions: {
queries: {
retry: false,
refetchOnWindowFocus: false,
async onError(e) {
if ((e as Error).message === '401') {
window.location.reload();
}
await showServerErrorToast(e as Response);
},
},
mutations: {
async onError(e) {
Expand Down
8 changes: 6 additions & 2 deletions odd-platform-ui/src/lib/hooks/api/appInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import { useQuery } from '@tanstack/react-query';
import { appInfoApi, linksApi } from 'lib/api';

export function useAppInfo() {
return useQuery(['appInfo'], () => appInfoApi.getAppInfo(), {
return useQuery({
queryKey: ['appInfo'],
queryFn: () => appInfoApi.getAppInfo(),
select: data => data.projectVersion,
});
}

export function useAppLinks() {
return useQuery(['appLinks'], () => linksApi.getLinks(), {
return useQuery({
queryKey: ['appLinks'],
queryFn: () => linksApi.getLinks(),
select: data => data.items,
});
}
119 changes: 61 additions & 58 deletions odd-platform-ui/src/lib/hooks/api/dataEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,62 +22,63 @@ export function useDataEntityMetrics({
dataEntityId,
enabled,
}: UseDataEntityMetricsProps) {
return useQuery(
['dataEntityMetrics', dataEntityId],
() => dataEntityApi.getDataEntityMetrics({ dataEntityId }),
{
retry: false,
refetchOnWindowFocus: false,
onError: err =>
return useQuery({
queryKey: ['dataEntityMetrics', dataEntityId],
queryFn: () =>
dataEntityApi.getDataEntityMetrics({ dataEntityId }).catch(err => {
showServerErrorToast(err as Response, {
additionalMessage: 'while loading metrics',
}),
enabled,
}
);
});
}),
retry: false,
refetchOnWindowFocus: false,
enabled,
});
}

export function useDataEntityGroupLineage({ dataEntityId }: { dataEntityId: number }) {
return useQuery(
['dataEntityGroupLineage', dataEntityId],
() => dataEntityApi.getDataEntityGroupsLineage({ dataEntityGroupId: dataEntityId }),
{
cacheTime: 0,
select: (data): DataEntityGroupLineage =>
data.items.reduce(
(memo, lineage) => {
const nodes = lineage.nodes.map<Node>(node => ({
id: String(node.id),
data: {
oddrn: node.oddrn,
externalName: node.externalName,
internalName: node.internalName,
dataSource: node.dataSource,
entityClasses: node.entityClasses,
status: node.status,
isStale: node.isStale,
},
}));
const edges = lineage.edges.map<Edge>(({ sourceId, targetId }) => ({
id: `${sourceId}-${targetId}`,
targets: [String(targetId)],
sources: [String(sourceId)],
}));
return useQuery({
queryKey: ['dataEntityGroupLineage', dataEntityId],
queryFn: () =>
dataEntityApi.getDataEntityGroupsLineage({ dataEntityGroupId: dataEntityId }),
cacheTime: 0,
select: (data): DataEntityGroupLineage =>
data.items.reduce(
(memo, lineage) => {
const nodes = lineage.nodes.map<Node>(node => ({
id: String(node.id),
data: {
oddrn: node.oddrn,
externalName: node.externalName,
internalName: node.internalName,
dataSource: node.dataSource,
entityClasses: node.entityClasses,
status: node.status,
isStale: node.isStale,
},
}));
const edges = lineage.edges.map<Edge>(({ sourceId, targetId }) => ({
id: `${sourceId}-${targetId}`,
targets: [String(targetId)],
sources: [String(sourceId)],
}));

return {
...memo,
nodes: [...memo.nodes, ...nodes],
edges: [...memo.edges, ...edges],
};
},
{ nodes: [], edges: [] } as DataEntityGroupLineage
),
}
);
return {
...memo,
nodes: [...memo.nodes, ...nodes],
edges: [...memo.edges, ...edges],
};
},
{ nodes: [], edges: [] } as DataEntityGroupLineage
),
});
}

export function useDataEntitiesUsage() {
return useQuery(['dataEntitiesUsage'], () => dataEntityApi.getDataEntitiesUsage());
return useQuery({
queryKey: ['dataEntitiesUsage'],
queryFn: () => dataEntityApi.getDataEntitiesUsage(),
});
}

interface UseDataEntityDetailsParams {
Expand All @@ -89,15 +90,17 @@ export function useDataEntityDetails({
dataEntityId,
enabled = true,
}: UseDataEntityDetailsParams) {
return useQuery(
['dataEntityDetails', dataEntityId],
() => dataEntityApi.getDataEntityDetails({ dataEntityId }),
{ enabled }
);
return useQuery({
queryKey: ['dataEntityDetails', dataEntityId],
queryFn: () => dataEntityApi.getDataEntityDetails({ dataEntityId }),
enabled,
});
}

export function useGetDomains() {
return useQuery(['domains'], () => dataEntityApi.getDomains(), {
return useQuery({
queryKey: ['domains'],
queryFn: () => dataEntityApi.getDomains(),
select: data => data.items,
});
}
Expand All @@ -112,9 +115,9 @@ export function useGetDataEntityGroupItems({
size,
query,
}: UseGetDataEntityGroupItems) {
return useInfiniteQuery<DataEntityGroupList, ErrorState, DataEntityGroupList>(
['dataEntityGroupItems', { dataEntityGroupId, size, query }],
async ({ pageParam = 1 }) => {
return useInfiniteQuery<DataEntityGroupList, ErrorState, DataEntityGroupList>({
queryKey: ['dataEntityGroupItems', { dataEntityGroupId, size, query }],
queryFn: async ({ pageParam = 1 }) => {
const response = await dataEntityApi.getDataEntityGroupsItems({
dataEntityGroupId,
size,
Expand All @@ -135,8 +138,8 @@ export function useGetDataEntityGroupItems({
pageInfo: { ...response.pageInfo, nextPage },
};
},
{ getNextPageParam: lastPage => lastPage.pageInfo.nextPage }
);
getNextPageParam: lastPage => lastPage.pageInfo.nextPage,
});
}

export function useUpdateDataEntityStatus() {
Expand Down
Loading

0 comments on commit 090f1db

Please sign in to comment.