diff --git a/datahub-web-react/src/app/entity/glossaryNode/ChildrenTab.tsx b/datahub-web-react/src/app/entity/glossaryNode/ChildrenTab.tsx index 6030a8698b..9aa4f40c2c 100644 --- a/datahub-web-react/src/app/entity/glossaryNode/ChildrenTab.tsx +++ b/datahub-web-react/src/app/entity/glossaryNode/ChildrenTab.tsx @@ -1,16 +1,22 @@ import React from 'react'; import { EntityType, GlossaryNode, GlossaryTerm } from '../../../types.generated'; import GlossaryEntitiesList from '../../glossary/GlossaryEntitiesList'; +import { useEntityRegistry } from '../../useEntityRegistry'; +import { sortGlossaryTerms } from '../glossaryTerm/utils'; import { useEntityData } from '../shared/EntityContext'; +import { sortGlossaryNodes } from './utils'; function ChildrenTab() { const { entityData } = useEntityData(); + const entityRegistry = useEntityRegistry(); const childNodes = entityData?.children?.relationships .filter((child) => child.entity?.type === EntityType.GlossaryNode) + .sort((nodeA, nodeB) => sortGlossaryNodes(entityRegistry, nodeA.entity, nodeB.entity)) .map((child) => child.entity); const childTerms = entityData?.children?.relationships .filter((child) => child.entity?.type === EntityType.GlossaryTerm) + .sort((termA, termB) => sortGlossaryTerms(entityRegistry, termA.entity, termB.entity)) .map((child) => child.entity); return ( diff --git a/datahub-web-react/src/app/entity/glossaryNode/utils.ts b/datahub-web-react/src/app/entity/glossaryNode/utils.ts new file mode 100644 index 0000000000..4cf214e810 --- /dev/null +++ b/datahub-web-react/src/app/entity/glossaryNode/utils.ts @@ -0,0 +1,8 @@ +import { Entity, EntityType } from '../../../types.generated'; +import EntityRegistry from '../EntityRegistry'; + +export function sortGlossaryNodes(entityRegistry: EntityRegistry, nodeA?: Entity | null, nodeB?: Entity | null) { + const nodeAName = entityRegistry.getDisplayName(EntityType.GlossaryNode, nodeA); + const nodeBName = entityRegistry.getDisplayName(EntityType.GlossaryNode, nodeB); + return nodeAName.localeCompare(nodeBName); +} diff --git a/datahub-web-react/src/app/entity/glossaryTerm/utils.ts b/datahub-web-react/src/app/entity/glossaryTerm/utils.ts new file mode 100644 index 0000000000..3a2a3d35a8 --- /dev/null +++ b/datahub-web-react/src/app/entity/glossaryTerm/utils.ts @@ -0,0 +1,8 @@ +import { Entity, EntityType } from '../../../types.generated'; +import EntityRegistry from '../EntityRegistry'; + +export function sortGlossaryTerms(entityRegistry: EntityRegistry, nodeA?: Entity | null, nodeB?: Entity | null) { + const nodeAName = entityRegistry.getDisplayName(EntityType.GlossaryTerm, nodeA) || ''; + const nodeBName = entityRegistry.getDisplayName(EntityType.GlossaryTerm, nodeB) || ''; + return nodeAName.localeCompare(nodeBName); +} diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx index b49bbc0b29..f136ea76d7 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/CreateGlossaryEntityModal.tsx @@ -49,11 +49,7 @@ function CreateGlossaryEntityModal(props: Props) { }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to create: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.loading({ content: 'Updating...', duration: 2 }); setTimeout(() => { message.success({ @@ -65,6 +61,10 @@ function CreateGlossaryEntityModal(props: Props) { refetchData(); } }, 2000); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to create: \n ${e.message || ''}`, duration: 3 }); }); onClose(); } diff --git a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx index e2228c8be5..6315306529 100644 --- a/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx +++ b/datahub-web-react/src/app/entity/shared/EntityDropdown/MoveGlossaryEntityModal.tsx @@ -43,11 +43,7 @@ function MoveGlossaryEntityModal(props: Props) { }, }, }) - .catch((e) => { - message.destroy(); - message.error({ content: `Failed to move: \n ${e.message || ''}`, duration: 3 }); - }) - .finally(() => { + .then(() => { message.loading({ content: 'Updating...', duration: 2 }); setTimeout(() => { message.success({ @@ -59,6 +55,10 @@ function MoveGlossaryEntityModal(props: Props) { refetchData(); } }, 2000); + }) + .catch((e) => { + message.destroy(); + message.error({ content: `Failed to move: \n ${e.message || ''}`, duration: 3 }); }); onClose(); } diff --git a/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx b/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx index 4b1197605c..f0527f298b 100644 --- a/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx +++ b/datahub-web-react/src/app/glossary/BusinessGlossaryPage.tsx @@ -14,6 +14,9 @@ import EmptyGlossarySection from './EmptyGlossarySection'; import CreateGlossaryEntityModal from '../entity/shared/EntityDropdown/CreateGlossaryEntityModal'; import { EntityType } from '../../types.generated'; import { Message } from '../shared/Message'; +import { sortGlossaryTerms } from '../entity/glossaryTerm/utils'; +import { useEntityRegistry } from '../useEntityRegistry'; +import { sortGlossaryNodes } from '../entity/glossaryNode/utils'; export const HeaderWrapper = styled(TabToolbar)` padding: 15px 45px 10px 24px; @@ -44,9 +47,14 @@ function BusinessGlossaryPage() { const [browserWidth, setBrowserWidth] = useState(window.innerWidth * 0.2); const { data: termsData, refetch: refetchForTerms, loading: termsLoading } = useGetRootGlossaryTermsQuery(); const { data: nodesData, refetch: refetchForNodes, loading: nodesLoading } = useGetRootGlossaryNodesQuery(); + const entityRegistry = useEntityRegistry(); - const terms = termsData?.getRootGlossaryTerms?.terms; - const nodes = nodesData?.getRootGlossaryNodes?.nodes; + const terms = termsData?.getRootGlossaryTerms?.terms.sort((termA, termB) => + sortGlossaryTerms(entityRegistry, termA, termB), + ); + const nodes = nodesData?.getRootGlossaryNodes?.nodes.sort((nodeA, nodeB) => + sortGlossaryNodes(entityRegistry, nodeA, nodeB), + ); const hasTermsOrNodes = !!nodes?.length || !!terms?.length; diff --git a/datahub-web-react/src/app/glossary/GlossaryBrowser/GlossaryBrowser.tsx b/datahub-web-react/src/app/glossary/GlossaryBrowser/GlossaryBrowser.tsx index b5c256f478..d5303061e5 100644 --- a/datahub-web-react/src/app/glossary/GlossaryBrowser/GlossaryBrowser.tsx +++ b/datahub-web-react/src/app/glossary/GlossaryBrowser/GlossaryBrowser.tsx @@ -2,6 +2,9 @@ import React, { useEffect } from 'react'; import styled from 'styled-components/macro'; import { useGetRootGlossaryNodesQuery, useGetRootGlossaryTermsQuery } from '../../../graphql/glossary.generated'; import { GlossaryNode, GlossaryTerm } from '../../../types.generated'; +import { sortGlossaryNodes } from '../../entity/glossaryNode/utils'; +import { sortGlossaryTerms } from '../../entity/glossaryTerm/utils'; +import { useEntityRegistry } from '../../useEntityRegistry'; import NodeItem from './NodeItem'; import TermItem from './TermItem'; @@ -44,6 +47,10 @@ function GlossaryBrowser(props: Props) { const displayedNodes = rootNodes || nodesData?.getRootGlossaryNodes?.nodes || []; const displayedTerms = rootTerms || termsData?.getRootGlossaryTerms?.terms || []; + const entityRegistry = useEntityRegistry(); + const sortedNodes = displayedNodes.sort((nodeA, nodeB) => sortGlossaryNodes(entityRegistry, nodeA, nodeB)); + const sortedTerms = displayedTerms.sort((termA, termB) => sortGlossaryTerms(entityRegistry, termA, termB)); + useEffect(() => { if (refreshBrowser) { refetchNodes(); @@ -53,7 +60,7 @@ function GlossaryBrowser(props: Props) { return ( - {displayedNodes.map((node) => ( + {sortedNodes.map((node) => ( ))} {!hideTerms && - displayedTerms.map((term) => ( + sortedTerms.map((term) => ( ))} diff --git a/datahub-web-react/src/app/glossary/GlossaryBrowser/NodeItem.tsx b/datahub-web-react/src/app/glossary/GlossaryBrowser/NodeItem.tsx index aa64d58493..b51093cf67 100644 --- a/datahub-web-react/src/app/glossary/GlossaryBrowser/NodeItem.tsx +++ b/datahub-web-react/src/app/glossary/GlossaryBrowser/NodeItem.tsx @@ -7,6 +7,8 @@ import { useEntityRegistry } from '../../useEntityRegistry'; import { useGetGlossaryNodeQuery } from '../../../graphql/glossaryNode.generated'; import TermItem, { TermLink as NodeLink, NameWrapper } from './TermItem'; import { useEntityData } from '../../entity/shared/EntityContext'; +import { sortGlossaryNodes } from '../../entity/glossaryNode/utils'; +import { sortGlossaryTerms } from '../../entity/glossaryTerm/utils'; const ItemWrapper = styled.div` display: flex; @@ -93,10 +95,12 @@ function NodeItem(props: Props) { const childNodes = (children as any) ?.filter((child) => child.entity?.type === EntityType.GlossaryNode) + .sort((nodeA, nodeB) => sortGlossaryNodes(entityRegistry, nodeA.entity, nodeB.entity)) .map((child) => child.entity) || []; const childTerms = (children as any) ?.filter((child) => child.entity?.type === EntityType.GlossaryTerm) + .sort((termA, termB) => sortGlossaryTerms(entityRegistry, termA.entity, termB.entity)) .map((child) => child.entity) || []; if (shouldHideNode) return null;