mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-20 07:07:59 +00:00
feat(ui/glossary): Keep the same tab selected when browsing Glossary (#9469)
This commit is contained in:
parent
bf813d1d24
commit
50be329492
@ -180,6 +180,7 @@ function EntityDropdown(props: Props) {
|
|||||||
)}
|
)}
|
||||||
{menuItems.has(EntityMenuItems.ADD_TERM) && (
|
{menuItems.has(EntityMenuItems.ADD_TERM) && (
|
||||||
<StyledMenuItem
|
<StyledMenuItem
|
||||||
|
data-testid="entity-menu-add-term-button"
|
||||||
key="2"
|
key="2"
|
||||||
disabled={!canCreateGlossaryEntity}
|
disabled={!canCreateGlossaryEntity}
|
||||||
onClick={() => setIsCreateTermModalVisible(true)}
|
onClick={() => setIsCreateTermModalVisible(true)}
|
||||||
|
@ -39,6 +39,7 @@ export const EntityTabs = <T,>({ tabs, selectedTab }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<UnborderedTabs
|
<UnborderedTabs
|
||||||
|
data-testid="entity-tab-headers-test-id"
|
||||||
animated={false}
|
animated={false}
|
||||||
activeKey={selectedTab?.name || ''}
|
activeKey={selectedTab?.name || ''}
|
||||||
size="large"
|
size="large"
|
||||||
|
@ -134,6 +134,22 @@ export function useIsOnTab(tabName: string): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGlossaryActiveTabPath(): string {
|
||||||
|
const { pathname, search } = useLocation();
|
||||||
|
const trimmedPathName = pathname.endsWith('/') ? pathname.slice(0, pathname.length - 1) : pathname;
|
||||||
|
|
||||||
|
// Match against the regex
|
||||||
|
const match = trimmedPathName.match(ENTITY_TAB_NAME_REGEX_PATTERN);
|
||||||
|
|
||||||
|
if (match && match[1]) {
|
||||||
|
const selectedTabPath = match[1] + (search || ''); // Include all query parameters
|
||||||
|
return selectedTabPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match found!
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
export function formatDateString(time: number) {
|
export function formatDateString(time: number) {
|
||||||
const date = new Date(time);
|
const date = new Date(time);
|
||||||
return date.toLocaleDateString('en-US');
|
return date.toLocaleDateString('en-US');
|
||||||
|
@ -166,7 +166,7 @@ function NodeItem(props: Props) {
|
|||||||
))}
|
))}
|
||||||
{!hideTerms &&
|
{!hideTerms &&
|
||||||
(childTerms as GlossaryTerm[]).map((child) => (
|
(childTerms as GlossaryTerm[]).map((child) => (
|
||||||
<TermItem term={child} isSelecting={isSelecting} selectTerm={selectTerm} />
|
<TermItem term={child} isSelecting={isSelecting} selectTerm={selectTerm} includeActiveTabPath />
|
||||||
))}
|
))}
|
||||||
</ChildrenWrapper>
|
</ChildrenWrapper>
|
||||||
)}
|
)}
|
||||||
|
@ -5,6 +5,7 @@ import { useEntityRegistry } from '../../useEntityRegistry';
|
|||||||
import { ANTD_GRAY } from '../../entity/shared/constants';
|
import { ANTD_GRAY } from '../../entity/shared/constants';
|
||||||
import { ChildGlossaryTermFragment } from '../../../graphql/glossaryNode.generated';
|
import { ChildGlossaryTermFragment } from '../../../graphql/glossaryNode.generated';
|
||||||
import { useGlossaryEntityData } from '../../entity/shared/GlossaryEntityContext';
|
import { useGlossaryEntityData } from '../../entity/shared/GlossaryEntityContext';
|
||||||
|
import { useGlossaryActiveTabPath } from '../../entity/shared/containers/profile/utils';
|
||||||
|
|
||||||
const TermWrapper = styled.div`
|
const TermWrapper = styled.div`
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -47,13 +48,15 @@ interface Props {
|
|||||||
term: ChildGlossaryTermFragment;
|
term: ChildGlossaryTermFragment;
|
||||||
isSelecting?: boolean;
|
isSelecting?: boolean;
|
||||||
selectTerm?: (urn: string, displayName: string) => void;
|
selectTerm?: (urn: string, displayName: string) => void;
|
||||||
|
includeActiveTabPath?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TermItem(props: Props) {
|
function TermItem(props: Props) {
|
||||||
const { term, isSelecting, selectTerm } = props;
|
const { term, isSelecting, selectTerm, includeActiveTabPath } = props;
|
||||||
|
|
||||||
const { entityData } = useGlossaryEntityData();
|
const { entityData } = useGlossaryEntityData();
|
||||||
const entityRegistry = useEntityRegistry();
|
const entityRegistry = useEntityRegistry();
|
||||||
|
const activeTabPath = useGlossaryActiveTabPath();
|
||||||
|
|
||||||
function handleSelectTerm() {
|
function handleSelectTerm() {
|
||||||
if (selectTerm) {
|
if (selectTerm) {
|
||||||
@ -68,7 +71,9 @@ function TermItem(props: Props) {
|
|||||||
<TermWrapper>
|
<TermWrapper>
|
||||||
{!isSelecting && (
|
{!isSelecting && (
|
||||||
<TermLink
|
<TermLink
|
||||||
to={`${entityRegistry.getEntityUrl(term.type, term.urn)}`}
|
to={`${entityRegistry.getEntityUrl(term.type, term.urn)}${
|
||||||
|
includeActiveTabPath ? `/${activeTabPath}` : ''
|
||||||
|
}`}
|
||||||
isSelected={entityData?.urn === term.urn}
|
isSelected={entityData?.urn === term.urn}
|
||||||
>
|
>
|
||||||
{entityRegistry.getDisplayName(term.type, isOnEntityPage ? entityData : term)}
|
{entityRegistry.getDisplayName(term.type, isOnEntityPage ? entityData : term)}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const glossaryTerm = "CypressGlosssaryNavigationTerm";
|
const glossaryTerm = "CypressGlosssaryNavigationTerm";
|
||||||
|
const glossarySecondTerm = "CypressGlossarySecondTerm";
|
||||||
const glossaryTermGroup = "CypressGlosssaryNavigationGroup";
|
const glossaryTermGroup = "CypressGlosssaryNavigationGroup";
|
||||||
const glossaryParentGroup = "CypressNode";
|
const glossaryParentGroup = "CypressNode";
|
||||||
|
|
||||||
@ -30,6 +31,39 @@ describe("glossary sidebar navigation test", () => {
|
|||||||
cy.get('[data-testid="glossary-browser-sidebar"]').contains(glossaryTermGroup).click().wait(3000);
|
cy.get('[data-testid="glossary-browser-sidebar"]').contains(glossaryTermGroup).click().wait(3000);
|
||||||
cy.get('*[class^="GlossaryEntitiesList"]').contains(glossaryTerm).should("be.visible");
|
cy.get('*[class^="GlossaryEntitiesList"]').contains(glossaryTerm).should("be.visible");
|
||||||
|
|
||||||
|
// Create another term and move it to the same term group
|
||||||
|
cy.clickOptionWithText(glossaryTermGroup);
|
||||||
|
cy.openThreeDotDropdown();
|
||||||
|
cy.clickOptionWithTestId("entity-menu-add-term-button");
|
||||||
|
|
||||||
|
// Wait for the create term modal to be visible
|
||||||
|
cy.waitTextVisible("Create Glossary Term");
|
||||||
|
cy.enterTextInTestId("create-glossary-entity-modal-name", glossarySecondTerm);
|
||||||
|
cy.clickOptionWithTestId("glossary-entity-modal-create-button");
|
||||||
|
|
||||||
|
// Wait for the new term to be visible in the sidebar
|
||||||
|
cy.clickOptionWithText(glossarySecondTerm).wait(3000);
|
||||||
|
|
||||||
|
// Move the term to the created term group
|
||||||
|
cy.openThreeDotDropdown();
|
||||||
|
cy.clickOptionWithTestId("entity-menu-move-button");
|
||||||
|
cy.get('[data-testid="move-glossary-entity-modal"]').contains(glossaryTermGroup).click({ force: true });
|
||||||
|
cy.get('[data-testid="move-glossary-entity-modal"]').contains(glossaryTermGroup).should("be.visible");
|
||||||
|
cy.clickOptionWithTestId("glossary-entity-modal-move-button");
|
||||||
|
cy.waitTextVisible("Moved Glossary Term!");
|
||||||
|
|
||||||
|
// Ensure the new term is under the parent term group in the navigation sidebar
|
||||||
|
cy.get('[data-testid="glossary-browser-sidebar"]').contains(glossaryTermGroup).click();
|
||||||
|
cy.get('*[class^="GlossaryEntitiesList"]').contains(glossarySecondTerm).should("be.visible");
|
||||||
|
|
||||||
|
|
||||||
|
// Switch between terms and ensure the "Properties" tab is active
|
||||||
|
cy.clickOptionWithText(glossaryTerm);
|
||||||
|
cy.get('[data-testid="entity-tab-headers-test-id"]').contains("Properties").click({ force: true });
|
||||||
|
cy.get('[data-node-key="Properties"]').contains("Properties").should("have.attr", "aria-selected", "true");
|
||||||
|
cy.clickOptionWithText(glossarySecondTerm);
|
||||||
|
cy.get('[data-node-key="Properties"]').contains("Properties").should("have.attr", "aria-selected", "true");
|
||||||
|
|
||||||
// Move a term group from the root level to be under a parent term group
|
// Move a term group from the root level to be under a parent term group
|
||||||
cy.goToGlossaryList();
|
cy.goToGlossaryList();
|
||||||
cy.clickOptionWithText(glossaryTermGroup);
|
cy.clickOptionWithText(glossaryTermGroup);
|
||||||
@ -52,6 +86,10 @@ describe("glossary sidebar navigation test", () => {
|
|||||||
cy.clickOptionWithText(glossaryTerm).wait(3000);
|
cy.clickOptionWithText(glossaryTerm).wait(3000);
|
||||||
cy.deleteFromDropdown();
|
cy.deleteFromDropdown();
|
||||||
cy.waitTextVisible("Deleted Glossary Term!");
|
cy.waitTextVisible("Deleted Glossary Term!");
|
||||||
|
cy.clickOptionWithText(glossaryTermGroup);
|
||||||
|
cy.clickOptionWithText(glossarySecondTerm).wait(3000);
|
||||||
|
cy.deleteFromDropdown();
|
||||||
|
cy.waitTextVisible("Deleted Glossary Term!");
|
||||||
cy.clickOptionWithText(glossaryParentGroup);
|
cy.clickOptionWithText(glossaryParentGroup);
|
||||||
cy.clickOptionWithText(glossaryTermGroup).wait(3000);
|
cy.clickOptionWithText(glossaryTermGroup).wait(3000);
|
||||||
cy.deleteFromDropdown();
|
cy.deleteFromDropdown();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user