From 3726f5441c797f180d4015c36f9a9c7cff3b158d Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Tue, 16 Apr 2024 17:28:01 +0530 Subject: [PATCH 1/7] feat(ui/tasks): add pagination on tasks listing page --- .../app/entity/dataFlow/DataFlowEntity.tsx | 63 ++++++------ .../containers/profile/EntityProfile.tsx | 4 +- .../profile/useGetDataForProfile.ts | 17 +++- .../shared/tabs/Entity/DataFlowJobsTab.tsx | 16 +++- .../tabs/Entity/components/EntityList.tsx | 95 +++++++++++++++++-- .../components/TaskPaginationContext.tsx | 30 ++++++ .../src/graphql/dataFlow.graphql | 4 +- 7 files changed, 183 insertions(+), 46 deletions(-) create mode 100644 datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx diff --git a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx index 25c1af09e7e5c8..3f3c996647d604 100644 --- a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx +++ b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx @@ -19,6 +19,7 @@ import { capitalizeFirstLetterOnly } from '../../shared/textUtil'; import DataProductSection from '../shared/containers/profile/sidebar/DataProduct/DataProductSection'; import { getDataProduct } from '../shared/utils'; import { IncidentTab } from '../shared/tabs/Incident/IncidentTab'; +import { TaskPaginationProvider } from '../shared/tabs/Entity/components/TaskPaginationContext'; /** * Definition of the DataHub DataFlow entity. @@ -62,37 +63,39 @@ export class DataFlowEntity implements Entity { useEntityQuery = useGetDataFlowQuery; renderProfile = (urn: string) => ( - { - const activeIncidentCount = dataFlow?.dataFlow?.activeIncidents.total; - return `Incidents${(activeIncidentCount && ` (${activeIncidentCount})`) || ''}`; + + + { + name: 'Properties', + component: PropertiesTab, + }, + { + name: 'Tasks', + component: DataFlowJobsTab, + }, + { + name: 'Incidents', + component: IncidentTab, + getDynamicName: (_, dataFlow) => { + const activeIncidentCount = dataFlow?.dataFlow?.activeIncidents.total; + return `Incidents${(activeIncidentCount && ` (${activeIncidentCount})`) || ''}`; + }, + }, + ]} + sidebarSections={this.getSidebarSections()} + /> + ); getSidebarSections = () => [ diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx index a9737c9698f7b2..acadfcc87c84b4 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx @@ -46,6 +46,7 @@ import { useAppConfig } from '../../../../useAppConfig'; import { useUpdateDomainEntityDataOnChange } from '../../../../domain/utils'; import ProfileSidebar from './sidebar/ProfileSidebar'; import SidebarFormInfoWrapper from './sidebar/FormInfo/SidebarFormInfoWrapper'; +import { useTaskPagination } from '../../tabs/Entity/components/TaskPaginationContext'; type Props = { urn: string; @@ -164,6 +165,7 @@ export const EntityProfile = ({ const entityRegistry = useEntityRegistry(); const history = useHistory(); const appConfig = useAppConfig(); + const { count, start } = useTaskPagination(); const isCompact = React.useContext(CompactContext); const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } })); @@ -214,7 +216,7 @@ export const EntityProfile = ({ ); const { entityData, dataPossiblyCombinedWithSiblings, dataNotCombinedWithSiblings, loading, error, refetch } = - useGetDataForProfile({ urn, entityType, useEntityQuery, getOverrideProperties }); + useGetDataForProfile({ urn, entityType, count ,start , useEntityQuery, getOverrideProperties }); useUpdateGlossaryEntityDataOnChange(entityData, entityType); useUpdateDomainEntityDataOnChange(entityData, entityType); diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts b/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts index ae87eeb1a84507..9b321ff2b63e6f 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts +++ b/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts @@ -6,24 +6,37 @@ import { EntityType, Exact } from '../../../../../types.generated'; interface Props { urn: string; + count?: number; + start?: number; entityType: EntityType; useEntityQuery: ( baseOptions: QueryHookOptions< T, Exact<{ urn: string; + count?: number; + start?: number; }> >, ) => QueryResult< T, Exact<{ urn: string; + count?: number; + start?: number; }> >; getOverrideProperties: (T) => GenericEntityProperties; } -export default function useGetDataForProfile({ urn, entityType, useEntityQuery, getOverrideProperties }: Props) { +export default function useGetDataForProfile({ + urn, + count, + start, + entityType, + useEntityQuery, + getOverrideProperties, +}: Props) { const isHideSiblingMode = useIsSeparateSiblingsMode(); const { loading, @@ -31,7 +44,7 @@ export default function useGetDataForProfile({ urn, entityType, useEntityQuer data: dataNotCombinedWithSiblings, refetch, } = useEntityQuery({ - variables: { urn }, + variables: { urn, count, start }, fetchPolicy: 'cache-first', }); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx index fe43ee7dc518a9..fd86c867c1a117 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx @@ -10,10 +10,24 @@ export const DataFlowJobsTab = () => { const dataJobs = dataFlow?.childJobs?.relationships.map((relationship) => relationship.entity); const entityRegistry = useEntityRegistry(); const totalJobs = dataFlow?.childJobs?.total || 0; + const pageSize = dataFlow?.childJobs?.count || 0; + const pageStart = dataFlow?.childJobs?.start || 0; + const lastResultIndex = pageStart + pageSize > totalJobs ? totalJobs : pageStart + pageSize; + const title = `Contains ${totalJobs} ${ totalJobs === 1 ? entityRegistry.getEntityName(EntityType.DataJob) : entityRegistry.getCollectionName(EntityType.DataJob) }`; - return ; + return ( + + ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx index 3a9061fd97d6e7..d7e1dea6d7f181 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx @@ -1,9 +1,16 @@ -import React from 'react'; -import { List } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { List, Pagination, Typography } from 'antd'; import styled from 'styled-components'; import { useEntityRegistry } from '../../../../../useEntityRegistry'; import { PreviewType } from '../../../../Entity'; import { EntityType } from '../../../../../../types.generated'; +import { SearchCfg } from '../../../../../../conf'; +import { useTaskPagination } from './TaskPaginationContext'; + +const ScrollWrapper = styled.div` + overflow: auto; + max-height: 100%; +`; const StyledList = styled(List)` padding-left: 40px; @@ -28,22 +35,90 @@ const StyledListItem = styled(List.Item)` padding-top: 20px; `; +const PaginationInfoContainer = styled.span` + padding: 8px; + padding-left: 16px; + border-top: 1px solid; + border-color: ${(props) => props.theme.styles['border-color-base']}; + display: flex; + justify-content: space-between; + align-items: center; +`; + +const StyledPagination = styled(Pagination)` + margin: 0px; + padding: 0px; +`; + +const PaginationInfo = styled(Typography.Text)` + padding: 0px; +`; + type EntityListProps = { type: EntityType; entities: Array; title?: string; + totalJobs?: number | null; + pageSize?: any; + lastResultIndex?: any; + showTaskPagination?: boolean; }; -export const EntityList = ({ type, entities, title }: EntityListProps) => { +export const EntityList = ({ + type, + entities, + title, + totalJobs, + pageSize, + lastResultIndex, + showTaskPagination = false, +}: EntityListProps) => { const entityRegistry = useEntityRegistry(); + const { updateData } = useTaskPagination(); + + const [page, setPage] = useState(1); + const [numResultsPerPage, setNumResultsPerPage] = useState(SearchCfg.RESULTS_PER_PAGE); + + const onChangePage = (newPage: number) => { + setPage(newPage); + }; + + useEffect(() => { + updateData(numResultsPerPage, (page - 1) * numResultsPerPage); + }, [page, numResultsPerPage, updateData]); + return ( - ( - {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} + <> + + ( + {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} + )} + /> + + {showTaskPagination && ( + + + + {lastResultIndex > 0 ? (page - 1) * pageSize + 1 : 0} - {lastResultIndex} + {' '} + of {totalJobs} + + SearchCfg.RESULTS_PER_PAGE} + onShowSizeChange={(_currNum, newNum) => setNumResultsPerPage(newNum)} + pageSizeOptions={['10', '20', '50', '100']} + /> + )} - /> + ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx new file mode 100644 index 00000000000000..54733c26b02521 --- /dev/null +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx @@ -0,0 +1,30 @@ +import React, { createContext, useContext, useState } from 'react'; +import { SearchCfg } from '../../../../../../conf'; + +type PaginationUpdateFunction = (newCount: number, newStart: number) => void; + +const TaskPaginationContext = createContext({ + count: SearchCfg.RESULTS_PER_PAGE, + start: 1, + updateData: (() => {}) as PaginationUpdateFunction, +}); + +export const useTaskPagination = () => useContext(TaskPaginationContext); + +export const TaskPaginationProvider = ({ children }: { children: React.ReactNode }) => { + const [count, setCount] = useState(SearchCfg.RESULTS_PER_PAGE); + const [start, setStart] = useState(1); + + const updateData: PaginationUpdateFunction = (newCount, newStart) => { + setCount(newCount); + setStart(newStart); + }; + + const contextValue = { + count, + start, + updateData, + }; + + return {children}; +}; diff --git a/datahub-web-react/src/graphql/dataFlow.graphql b/datahub-web-react/src/graphql/dataFlow.graphql index e4284225e55b9a..5408747b67f7ea 100644 --- a/datahub-web-react/src/graphql/dataFlow.graphql +++ b/datahub-web-react/src/graphql/dataFlow.graphql @@ -61,7 +61,7 @@ fragment dataFlowFields on DataFlow { } } -query getDataFlow($urn: String!) { +query getDataFlow($urn: String!, $start: Int, $count: Int) { dataFlow(urn: $urn) { ...dataFlowFields upstream: lineage(input: { direction: UPSTREAM, start: 0, count: 100 }) { @@ -70,7 +70,7 @@ query getDataFlow($urn: String!) { downstream: lineage(input: { direction: DOWNSTREAM, start: 0, count: 100 }) { ...partialLineageResults } - childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: 0, count: 100 }) { + childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: $start, count: $count }) { start count total From 28fe1e4781b03b139e399e788ec0676b7e0c12e1 Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Tue, 16 Apr 2024 21:58:21 +0530 Subject: [PATCH 2/7] add conditional pagination for tabname task --- .../containers/profile/EntityProfile.tsx | 10 ++++++-- .../shared/tabs/Entity/DataFlowJobsTab.tsx | 12 +++++++++- .../components/TaskPaginationContext.tsx | 24 ++++++++++++++++--- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx index acadfcc87c84b4..9911ee9e8979d1 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx @@ -165,7 +165,7 @@ export const EntityProfile = ({ const entityRegistry = useEntityRegistry(); const history = useHistory(); const appConfig = useAppConfig(); - const { count, start } = useTaskPagination(); + const { count, start, tabNamePagination } = useTaskPagination(); const isCompact = React.useContext(CompactContext); const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } })); @@ -216,7 +216,13 @@ export const EntityProfile = ({ ); const { entityData, dataPossiblyCombinedWithSiblings, dataNotCombinedWithSiblings, loading, error, refetch } = - useGetDataForProfile({ urn, entityType, count ,start , useEntityQuery, getOverrideProperties }); + useGetDataForProfile({ + urn, + entityType, + ...(tabNamePagination === 'Task' && { count, start }), + useEntityQuery, + getOverrideProperties, + }); useUpdateGlossaryEntityDataOnChange(entityData, entityType); useUpdateDomainEntityDataOnChange(entityData, entityType); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx index fd86c867c1a117..df62452083dad2 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx @@ -1,11 +1,13 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useBaseEntity } from '../../EntityContext'; import { EntityType } from '../../../../../types.generated'; import { EntityList } from './components/EntityList'; import { useEntityRegistry } from '../../../../useEntityRegistry'; +import { useTaskPagination } from './components/TaskPaginationContext'; export const DataFlowJobsTab = () => { const entity = useBaseEntity() as any; + const { setTab } = useTaskPagination(); const dataFlow = entity && entity.dataFlow; const dataJobs = dataFlow?.childJobs?.relationships.map((relationship) => relationship.entity); const entityRegistry = useEntityRegistry(); @@ -19,6 +21,14 @@ export const DataFlowJobsTab = () => { ? entityRegistry.getEntityName(EntityType.DataJob) : entityRegistry.getCollectionName(EntityType.DataJob) }`; + + useEffect(() => { + setTab('Task'); + return () => { + setTab(''); + }; + }, [setTab]); + return ( void; +type TabNameUpdateFunction = (newTabName: string) => void; -const TaskPaginationContext = createContext({ +interface TaskPaginationContextType { + count: number; + start: number; + tabNamePagination: string | undefined; + updateData: PaginationUpdateFunction; + setTab: TabNameUpdateFunction; +} + +const TaskPaginationContext = createContext({ count: SearchCfg.RESULTS_PER_PAGE, start: 1, - updateData: (() => {}) as PaginationUpdateFunction, + tabNamePagination: '', + updateData: () => {}, + setTab: () => {}, }); export const useTaskPagination = () => useContext(TaskPaginationContext); @@ -14,16 +25,23 @@ export const useTaskPagination = () => useContext(TaskPaginationContext); export const TaskPaginationProvider = ({ children }: { children: React.ReactNode }) => { const [count, setCount] = useState(SearchCfg.RESULTS_PER_PAGE); const [start, setStart] = useState(1); + const [tabNamePagination, setTabName] = useState(''); const updateData: PaginationUpdateFunction = (newCount, newStart) => { setCount(newCount); setStart(newStart); }; - const contextValue = { + const setTab: TabNameUpdateFunction = (newTabName) => { + setTabName(newTabName); + }; + + const contextValue: TaskPaginationContextType = { count, start, + tabNamePagination, updateData, + setTab, }; return {children}; From 685020166d8a387f9e8fa1c51a998c93d75025ed Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Wed, 17 Apr 2024 22:38:34 +0530 Subject: [PATCH 3/7] Revert "add conditional pagination for tabname task" This reverts commit 28fe1e4781b03b139e399e788ec0676b7e0c12e1. --- .../containers/profile/EntityProfile.tsx | 10 ++------ .../shared/tabs/Entity/DataFlowJobsTab.tsx | 12 +--------- .../components/TaskPaginationContext.tsx | 24 +++---------------- 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx index 9911ee9e8979d1..acadfcc87c84b4 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx @@ -165,7 +165,7 @@ export const EntityProfile = ({ const entityRegistry = useEntityRegistry(); const history = useHistory(); const appConfig = useAppConfig(); - const { count, start, tabNamePagination } = useTaskPagination(); + const { count, start } = useTaskPagination(); const isCompact = React.useContext(CompactContext); const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } })); @@ -216,13 +216,7 @@ export const EntityProfile = ({ ); const { entityData, dataPossiblyCombinedWithSiblings, dataNotCombinedWithSiblings, loading, error, refetch } = - useGetDataForProfile({ - urn, - entityType, - ...(tabNamePagination === 'Task' && { count, start }), - useEntityQuery, - getOverrideProperties, - }); + useGetDataForProfile({ urn, entityType, count ,start , useEntityQuery, getOverrideProperties }); useUpdateGlossaryEntityDataOnChange(entityData, entityType); useUpdateDomainEntityDataOnChange(entityData, entityType); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx index df62452083dad2..fd86c867c1a117 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx @@ -1,13 +1,11 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import { useBaseEntity } from '../../EntityContext'; import { EntityType } from '../../../../../types.generated'; import { EntityList } from './components/EntityList'; import { useEntityRegistry } from '../../../../useEntityRegistry'; -import { useTaskPagination } from './components/TaskPaginationContext'; export const DataFlowJobsTab = () => { const entity = useBaseEntity() as any; - const { setTab } = useTaskPagination(); const dataFlow = entity && entity.dataFlow; const dataJobs = dataFlow?.childJobs?.relationships.map((relationship) => relationship.entity); const entityRegistry = useEntityRegistry(); @@ -21,14 +19,6 @@ export const DataFlowJobsTab = () => { ? entityRegistry.getEntityName(EntityType.DataJob) : entityRegistry.getCollectionName(EntityType.DataJob) }`; - - useEffect(() => { - setTab('Task'); - return () => { - setTab(''); - }; - }, [setTab]); - return ( void; -type TabNameUpdateFunction = (newTabName: string) => void; -interface TaskPaginationContextType { - count: number; - start: number; - tabNamePagination: string | undefined; - updateData: PaginationUpdateFunction; - setTab: TabNameUpdateFunction; -} - -const TaskPaginationContext = createContext({ +const TaskPaginationContext = createContext({ count: SearchCfg.RESULTS_PER_PAGE, start: 1, - tabNamePagination: '', - updateData: () => {}, - setTab: () => {}, + updateData: (() => {}) as PaginationUpdateFunction, }); export const useTaskPagination = () => useContext(TaskPaginationContext); @@ -25,23 +14,16 @@ export const useTaskPagination = () => useContext(TaskPaginationContext); export const TaskPaginationProvider = ({ children }: { children: React.ReactNode }) => { const [count, setCount] = useState(SearchCfg.RESULTS_PER_PAGE); const [start, setStart] = useState(1); - const [tabNamePagination, setTabName] = useState(''); const updateData: PaginationUpdateFunction = (newCount, newStart) => { setCount(newCount); setStart(newStart); }; - const setTab: TabNameUpdateFunction = (newTabName) => { - setTabName(newTabName); - }; - - const contextValue: TaskPaginationContextType = { + const contextValue = { count, start, - tabNamePagination, updateData, - setTab, }; return {children}; From da65e3717e3f92ca18d3d2465c12a9ae1545a120 Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Wed, 17 Apr 2024 22:39:50 +0530 Subject: [PATCH 4/7] Revert "feat(ui/tasks): add pagination on tasks listing page" This reverts commit 3726f5441c797f180d4015c36f9a9c7cff3b158d. --- .../app/entity/dataFlow/DataFlowEntity.tsx | 63 ++++++------ .../containers/profile/EntityProfile.tsx | 4 +- .../profile/useGetDataForProfile.ts | 17 +--- .../shared/tabs/Entity/DataFlowJobsTab.tsx | 16 +--- .../tabs/Entity/components/EntityList.tsx | 95 ++----------------- .../components/TaskPaginationContext.tsx | 30 ------ .../src/graphql/dataFlow.graphql | 4 +- 7 files changed, 46 insertions(+), 183 deletions(-) delete mode 100644 datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx diff --git a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx index 3f3c996647d604..25c1af09e7e5c8 100644 --- a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx +++ b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx @@ -19,7 +19,6 @@ import { capitalizeFirstLetterOnly } from '../../shared/textUtil'; import DataProductSection from '../shared/containers/profile/sidebar/DataProduct/DataProductSection'; import { getDataProduct } from '../shared/utils'; import { IncidentTab } from '../shared/tabs/Incident/IncidentTab'; -import { TaskPaginationProvider } from '../shared/tabs/Entity/components/TaskPaginationContext'; /** * Definition of the DataHub DataFlow entity. @@ -63,39 +62,37 @@ export class DataFlowEntity implements Entity { useEntityQuery = useGetDataFlowQuery; renderProfile = (urn: string) => ( - - { + const activeIncidentCount = dataFlow?.dataFlow?.activeIncidents.total; + return `Incidents${(activeIncidentCount && ` (${activeIncidentCount})`) || ''}`; }, - { - name: 'Properties', - component: PropertiesTab, - }, - { - name: 'Tasks', - component: DataFlowJobsTab, - }, - { - name: 'Incidents', - component: IncidentTab, - getDynamicName: (_, dataFlow) => { - const activeIncidentCount = dataFlow?.dataFlow?.activeIncidents.total; - return `Incidents${(activeIncidentCount && ` (${activeIncidentCount})`) || ''}`; - }, - }, - ]} - sidebarSections={this.getSidebarSections()} - /> - + }, + ]} + sidebarSections={this.getSidebarSections()} + /> ); getSidebarSections = () => [ diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx index acadfcc87c84b4..a9737c9698f7b2 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx +++ b/datahub-web-react/src/app/entity/shared/containers/profile/EntityProfile.tsx @@ -46,7 +46,6 @@ import { useAppConfig } from '../../../../useAppConfig'; import { useUpdateDomainEntityDataOnChange } from '../../../../domain/utils'; import ProfileSidebar from './sidebar/ProfileSidebar'; import SidebarFormInfoWrapper from './sidebar/FormInfo/SidebarFormInfoWrapper'; -import { useTaskPagination } from '../../tabs/Entity/components/TaskPaginationContext'; type Props = { urn: string; @@ -165,7 +164,6 @@ export const EntityProfile = ({ const entityRegistry = useEntityRegistry(); const history = useHistory(); const appConfig = useAppConfig(); - const { count, start } = useTaskPagination(); const isCompact = React.useContext(CompactContext); const tabsWithDefaults = tabs.map((tab) => ({ ...tab, display: { ...defaultTabDisplayConfig, ...tab.display } })); @@ -216,7 +214,7 @@ export const EntityProfile = ({ ); const { entityData, dataPossiblyCombinedWithSiblings, dataNotCombinedWithSiblings, loading, error, refetch } = - useGetDataForProfile({ urn, entityType, count ,start , useEntityQuery, getOverrideProperties }); + useGetDataForProfile({ urn, entityType, useEntityQuery, getOverrideProperties }); useUpdateGlossaryEntityDataOnChange(entityData, entityType); useUpdateDomainEntityDataOnChange(entityData, entityType); diff --git a/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts b/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts index 9b321ff2b63e6f..ae87eeb1a84507 100644 --- a/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts +++ b/datahub-web-react/src/app/entity/shared/containers/profile/useGetDataForProfile.ts @@ -6,37 +6,24 @@ import { EntityType, Exact } from '../../../../../types.generated'; interface Props { urn: string; - count?: number; - start?: number; entityType: EntityType; useEntityQuery: ( baseOptions: QueryHookOptions< T, Exact<{ urn: string; - count?: number; - start?: number; }> >, ) => QueryResult< T, Exact<{ urn: string; - count?: number; - start?: number; }> >; getOverrideProperties: (T) => GenericEntityProperties; } -export default function useGetDataForProfile({ - urn, - count, - start, - entityType, - useEntityQuery, - getOverrideProperties, -}: Props) { +export default function useGetDataForProfile({ urn, entityType, useEntityQuery, getOverrideProperties }: Props) { const isHideSiblingMode = useIsSeparateSiblingsMode(); const { loading, @@ -44,7 +31,7 @@ export default function useGetDataForProfile({ data: dataNotCombinedWithSiblings, refetch, } = useEntityQuery({ - variables: { urn, count, start }, + variables: { urn }, fetchPolicy: 'cache-first', }); diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx index fd86c867c1a117..fe43ee7dc518a9 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx @@ -10,24 +10,10 @@ export const DataFlowJobsTab = () => { const dataJobs = dataFlow?.childJobs?.relationships.map((relationship) => relationship.entity); const entityRegistry = useEntityRegistry(); const totalJobs = dataFlow?.childJobs?.total || 0; - const pageSize = dataFlow?.childJobs?.count || 0; - const pageStart = dataFlow?.childJobs?.start || 0; - const lastResultIndex = pageStart + pageSize > totalJobs ? totalJobs : pageStart + pageSize; - const title = `Contains ${totalJobs} ${ totalJobs === 1 ? entityRegistry.getEntityName(EntityType.DataJob) : entityRegistry.getCollectionName(EntityType.DataJob) }`; - return ( - - ); + return ; }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx index d7e1dea6d7f181..3a9061fd97d6e7 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx @@ -1,16 +1,9 @@ -import React, { useEffect, useState } from 'react'; -import { List, Pagination, Typography } from 'antd'; +import React from 'react'; +import { List } from 'antd'; import styled from 'styled-components'; import { useEntityRegistry } from '../../../../../useEntityRegistry'; import { PreviewType } from '../../../../Entity'; import { EntityType } from '../../../../../../types.generated'; -import { SearchCfg } from '../../../../../../conf'; -import { useTaskPagination } from './TaskPaginationContext'; - -const ScrollWrapper = styled.div` - overflow: auto; - max-height: 100%; -`; const StyledList = styled(List)` padding-left: 40px; @@ -35,90 +28,22 @@ const StyledListItem = styled(List.Item)` padding-top: 20px; `; -const PaginationInfoContainer = styled.span` - padding: 8px; - padding-left: 16px; - border-top: 1px solid; - border-color: ${(props) => props.theme.styles['border-color-base']}; - display: flex; - justify-content: space-between; - align-items: center; -`; - -const StyledPagination = styled(Pagination)` - margin: 0px; - padding: 0px; -`; - -const PaginationInfo = styled(Typography.Text)` - padding: 0px; -`; - type EntityListProps = { type: EntityType; entities: Array; title?: string; - totalJobs?: number | null; - pageSize?: any; - lastResultIndex?: any; - showTaskPagination?: boolean; }; -export const EntityList = ({ - type, - entities, - title, - totalJobs, - pageSize, - lastResultIndex, - showTaskPagination = false, -}: EntityListProps) => { +export const EntityList = ({ type, entities, title }: EntityListProps) => { const entityRegistry = useEntityRegistry(); - const { updateData } = useTaskPagination(); - - const [page, setPage] = useState(1); - const [numResultsPerPage, setNumResultsPerPage] = useState(SearchCfg.RESULTS_PER_PAGE); - - const onChangePage = (newPage: number) => { - setPage(newPage); - }; - - useEffect(() => { - updateData(numResultsPerPage, (page - 1) * numResultsPerPage); - }, [page, numResultsPerPage, updateData]); - return ( - <> - - ( - {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} - )} - /> - - {showTaskPagination && ( - - - - {lastResultIndex > 0 ? (page - 1) * pageSize + 1 : 0} - {lastResultIndex} - {' '} - of {totalJobs} - - SearchCfg.RESULTS_PER_PAGE} - onShowSizeChange={(_currNum, newNum) => setNumResultsPerPage(newNum)} - pageSizeOptions={['10', '20', '50', '100']} - /> - + ( + {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} )} - + /> ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx deleted file mode 100644 index 54733c26b02521..00000000000000 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/TaskPaginationContext.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { createContext, useContext, useState } from 'react'; -import { SearchCfg } from '../../../../../../conf'; - -type PaginationUpdateFunction = (newCount: number, newStart: number) => void; - -const TaskPaginationContext = createContext({ - count: SearchCfg.RESULTS_PER_PAGE, - start: 1, - updateData: (() => {}) as PaginationUpdateFunction, -}); - -export const useTaskPagination = () => useContext(TaskPaginationContext); - -export const TaskPaginationProvider = ({ children }: { children: React.ReactNode }) => { - const [count, setCount] = useState(SearchCfg.RESULTS_PER_PAGE); - const [start, setStart] = useState(1); - - const updateData: PaginationUpdateFunction = (newCount, newStart) => { - setCount(newCount); - setStart(newStart); - }; - - const contextValue = { - count, - start, - updateData, - }; - - return {children}; -}; diff --git a/datahub-web-react/src/graphql/dataFlow.graphql b/datahub-web-react/src/graphql/dataFlow.graphql index 5408747b67f7ea..e4284225e55b9a 100644 --- a/datahub-web-react/src/graphql/dataFlow.graphql +++ b/datahub-web-react/src/graphql/dataFlow.graphql @@ -61,7 +61,7 @@ fragment dataFlowFields on DataFlow { } } -query getDataFlow($urn: String!, $start: Int, $count: Int) { +query getDataFlow($urn: String!) { dataFlow(urn: $urn) { ...dataFlowFields upstream: lineage(input: { direction: UPSTREAM, start: 0, count: 100 }) { @@ -70,7 +70,7 @@ query getDataFlow($urn: String!, $start: Int, $count: Int) { downstream: lineage(input: { direction: DOWNSTREAM, start: 0, count: 100 }) { ...partialLineageResults } - childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: $start, count: $count }) { + childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: 0, count: 100 }) { start count total From 180a1a08f751e802726adafe31380dfcd17d2c7e Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Thu, 18 Apr 2024 15:17:55 +0530 Subject: [PATCH 5/7] added new query getDataFlowChildJobs for DataFlowJobsTab and handle pagination for component itself --- .../app/entity/dataFlow/DataFlowEntity.tsx | 3 + .../shared/tabs/Entity/DataFlowJobsTab.tsx | 53 +++++++++-- .../tabs/Entity/components/EntityList.tsx | 93 +++++++++++++++++-- .../src/graphql/dataFlow.graphql | 47 ++++++++++ 4 files changed, 181 insertions(+), 15 deletions(-) diff --git a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx index 25c1af09e7e5c8..fb5ea280087412 100644 --- a/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx +++ b/datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx @@ -81,6 +81,9 @@ export class DataFlowEntity implements Entity { { name: 'Tasks', component: DataFlowJobsTab, + properties: { + urn, + }, }, { name: 'Incidents', diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx index fe43ee7dc518a9..36e8c035c0d236 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/DataFlowJobsTab.tsx @@ -1,19 +1,60 @@ -import React from 'react'; -import { useBaseEntity } from '../../EntityContext'; +import React, { useState } from 'react'; import { EntityType } from '../../../../../types.generated'; import { EntityList } from './components/EntityList'; import { useEntityRegistry } from '../../../../useEntityRegistry'; +import { useGetDataFlowChildJobsQuery } from '../../../../../graphql/dataFlow.generated'; +import { SearchCfg } from '../../../../../conf'; -export const DataFlowJobsTab = () => { - const entity = useBaseEntity() as any; - const dataFlow = entity && entity.dataFlow; +interface Props { + properties?: { + urn: string; + }; +} + +export const DataFlowJobsTab = ({ properties = { urn: '' } }: Props) => { + const [page, setPage] = useState(1); + const [numResultsPerPage, setNumResultsPerPage] = useState(SearchCfg.RESULTS_PER_PAGE); + + const start: number = (page - 1) * numResultsPerPage; + + const { data, loading, error } = useGetDataFlowChildJobsQuery({ + variables: { + urn: properties.urn, + start, + count: numResultsPerPage, + }, + }); + + const onChangePage = (newPage: number) => { + setPage(newPage); + }; + + const dataFlow = data && data?.dataFlow; const dataJobs = dataFlow?.childJobs?.relationships.map((relationship) => relationship.entity); const entityRegistry = useEntityRegistry(); const totalJobs = dataFlow?.childJobs?.total || 0; + const pageSize = data?.dataFlow?.childJobs?.count || 0; + const pageStart = data?.dataFlow?.childJobs?.start || 0; + const lastResultIndex = pageStart + pageSize > totalJobs ? totalJobs : pageStart + pageSize; const title = `Contains ${totalJobs} ${ totalJobs === 1 ? entityRegistry.getEntityName(EntityType.DataJob) : entityRegistry.getCollectionName(EntityType.DataJob) }`; - return ; + return ( + + ); }; diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx index 3a9061fd97d6e7..19da07668fa377 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx @@ -1,9 +1,16 @@ import React from 'react'; -import { List } from 'antd'; +import { List, Pagination, Typography } from 'antd'; import styled from 'styled-components'; import { useEntityRegistry } from '../../../../../useEntityRegistry'; import { PreviewType } from '../../../../Entity'; import { EntityType } from '../../../../../../types.generated'; +import { SearchCfg } from '../../../../../../conf'; +import { Message } from '../../../../../shared/Message'; + +const ScrollWrapper = styled.div` + overflow: auto; + max-height: 100%; +`; const StyledList = styled(List)` padding-left: 40px; @@ -28,22 +35,90 @@ const StyledListItem = styled(List.Item)` padding-top: 20px; `; +const PaginationInfoContainer = styled.span` + padding: 8px; + padding-left: 16px; + border-top: 1px solid; + border-color: ${(props) => props.theme.styles['border-color-base']}; + display: flex; + justify-content: space-between; + align-items: center; +`; + +const StyledPagination = styled(Pagination)` + margin: 0px; + padding: 0px; +`; + +const PaginationInfo = styled(Typography.Text)` + padding: 0px; +`; + type EntityListProps = { type: EntityType; entities: Array; title?: string; + totalAssets?: number; + pageSize?: any; + page?: number; + lastResultIndex?: any; + showPagination?: boolean; + loading?: boolean; + error?: any; + onChangePage?: (number: any) => void; + setNumResultsPerPage?: (number: any) => void; }; -export const EntityList = ({ type, entities, title }: EntityListProps) => { +export const EntityList = ({ + type, + entities, + title, + totalAssets, + pageSize, + page, + lastResultIndex, + showPagination = false, + loading = false, + error = undefined, + onChangePage, + setNumResultsPerPage, +}: EntityListProps) => { const entityRegistry = useEntityRegistry(); + return ( - ( - {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} + <> + + ( + {entityRegistry.renderPreview(type, PreviewType.PREVIEW, item)} + )} + /> + + {loading && } + {error && } + {showPagination && ( + + + + {lastResultIndex > 0 ? ((page as number) - 1) * pageSize + 1 : 0} - {lastResultIndex} + {' '} + of {totalAssets} + + SearchCfg.RESULTS_PER_PAGE} + onShowSizeChange={(_currNum, newNum) => setNumResultsPerPage?.(newNum)} + pageSizeOptions={['10', '20', '50', '100']} + /> + )} - /> + ); }; diff --git a/datahub-web-react/src/graphql/dataFlow.graphql b/datahub-web-react/src/graphql/dataFlow.graphql index e4284225e55b9a..0772164450f028 100644 --- a/datahub-web-react/src/graphql/dataFlow.graphql +++ b/datahub-web-react/src/graphql/dataFlow.graphql @@ -125,6 +125,53 @@ query getDataFlow($urn: String!) { } } +query getDataFlowChildJobs($urn: String!, $start: Int, $count: Int) { + dataFlow(urn: $urn) { + ...dataFlowFields + childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: $start, count: $count }) { + start + count + total + relationships { + entity { + ... on DataJob { + urn + type + jobId + dataFlow { + urn + type + orchestrator + platform { + ...platformFields + } + } + ownership { + ...ownershipFields + } + properties { + name + description + } + editableProperties { + description + } + globalTags { + ...globalTagsFields + } + glossaryTerms { + ...glossaryTerms + } + deprecation { + ...deprecationFields + } + } + } + } + } + } +} + mutation updateDataFlow($urn: String!, $input: DataFlowUpdateInput!) { updateDataFlow(urn: $urn, input: $input) { urn From 294e41ab7d64a2b3dde33224fbf8808eec7b7264 Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Thu, 18 Apr 2024 17:49:45 +0530 Subject: [PATCH 6/7] fix Cypress test failure in schema blame unrelated to current feature changes --- .../tests/cypress/cypress/e2e/schema_blame/schema_blame.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smoke-test/tests/cypress/cypress/e2e/schema_blame/schema_blame.js b/smoke-test/tests/cypress/cypress/e2e/schema_blame/schema_blame.js index 1ce1fbe900172a..2218cbd95cf9dd 100644 --- a/smoke-test/tests/cypress/cypress/e2e/schema_blame/schema_blame.js +++ b/smoke-test/tests/cypress/cypress/e2e/schema_blame/schema_blame.js @@ -12,9 +12,9 @@ describe('schema blame', () => { cy.contains('field_foo'); cy.contains('field_baz'); cy.contains('field_bar').should('not.exist'); + cy.clickOptionWithText("field_foo"); cy.contains('Foo field description has changed'); cy.contains('Baz field description'); - cy.clickOptionWithText("field_foo"); cy.get('[data-testid="schema-field-field_foo-tags"]').contains('Legacy'); // Make sure the schema blame is accurate From ba43e412c81d85a5254e6a6aa7d00d6f19cee5fb Mon Sep 17 00:00:00 2001 From: gaurav2733 Date: Fri, 19 Apr 2024 10:48:53 +0530 Subject: [PATCH 7/7] remove child jobs from dataflow query and fix css for pagination --- .../tabs/Entity/components/EntityList.tsx | 21 ++++++++-- .../src/graphql/dataFlow.graphql | 41 ------------------- 2 files changed, 18 insertions(+), 44 deletions(-) diff --git a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx index 19da07668fa377..9e07e928be55e4 100644 --- a/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx +++ b/datahub-web-react/src/app/entity/shared/tabs/Entity/components/EntityList.tsx @@ -9,7 +9,18 @@ import { Message } from '../../../../../shared/Message'; const ScrollWrapper = styled.div` overflow: auto; - max-height: 100%; + height: 100%; + + &::-webkit-scrollbar { + height: 12px; + width: 5px; + background: #f2f2f2; + } + &::-webkit-scrollbar-thumb { + background: #cccccc; + -webkit-border-radius: 1ex; + -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75); + } `; const StyledList = styled(List)` @@ -46,12 +57,16 @@ const PaginationInfoContainer = styled.span` `; const StyledPagination = styled(Pagination)` - margin: 0px; - padding: 0px; + padding: 12px 12px 12px 12px; + width: 100%; + display: flex; + align-items: center; + justify-content: center; `; const PaginationInfo = styled(Typography.Text)` padding: 0px; + width: 20%; `; type EntityListProps = { diff --git a/datahub-web-react/src/graphql/dataFlow.graphql b/datahub-web-react/src/graphql/dataFlow.graphql index 0772164450f028..2441ce600c3c55 100644 --- a/datahub-web-react/src/graphql/dataFlow.graphql +++ b/datahub-web-react/src/graphql/dataFlow.graphql @@ -70,47 +70,6 @@ query getDataFlow($urn: String!) { downstream: lineage(input: { direction: DOWNSTREAM, start: 0, count: 100 }) { ...partialLineageResults } - childJobs: relationships(input: { types: ["IsPartOf"], direction: INCOMING, start: 0, count: 100 }) { - start - count - total - relationships { - entity { - ... on DataJob { - urn - type - jobId - dataFlow { - urn - type - orchestrator - platform { - ...platformFields - } - } - ownership { - ...ownershipFields - } - properties { - name - description - } - editableProperties { - description - } - globalTags { - ...globalTagsFields - } - glossaryTerms { - ...glossaryTerms - } - deprecation { - ...deprecationFields - } - } - } - } - } autoRenderAspects: aspects(input: { autoRenderOnly: true }) { ...autoRenderAspectFields }