Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Editor, ReactRenderer } from '@tiptap/react';
import { isEmpty, isNil } from 'lodash';
import { forwardRef, useImperativeHandle, useState } from 'react';
import tippy, { Instance, Props } from 'tippy.js';
import { inCurrentAppContext } from '../../utils/RouterUtils';
import { EditorSlotsProps, EditorSlotsRef } from './BlockEditor.interface';
import BlockMenu from './BlockMenu/BlockMenu';
import BubbleMenu from './BubbleMenu/BubbleMenu';
Expand Down Expand Up @@ -90,7 +91,7 @@ const EditorSlots = forwardRef<EditorSlotsRef, EditorSlotsProps>(
const href = target.getAttribute('href');
const linkTarget = target.getAttribute('target');
if (href && linkTarget) {
window.open(href, linkTarget);
window.open(inCurrentAppContext(href), linkTarget);
Comment thread
gitar-bot[bot] marked this conversation as resolved.
}

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
import {
getEntityDetailsPath,
getGlossaryTermDetailsPath,
inCurrentAppContext,
} from '../../../utils/RouterUtils';
import { getTermQuery } from '../../../utils/SearchUtils';
import { showErrorToast } from '../../../utils/ToastUtils';
Expand Down Expand Up @@ -1467,7 +1468,7 @@ export function useOntologyExplorer({
if (!path) {
return;
}
window.open(path, '_blank');
window.open(inCurrentAppContext(path), '_blank');
},
[getNodePath]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,15 @@ const GlobalSettingCategoryPage = () => {

break;
default:
if (
connectionsRouterClassBase.isEmbeddedMode() &&
category === GlobalSettingsMenuCategory.SERVICES
) {
if (isEmbedded && category === GlobalSettingsMenuCategory.SERVICES) {
navigate(connectionsRouterClassBase.getSettingsServicesPath(option));
} else {
navigate(getSettingPath(category, option));
}

break;
}
}, []);
}, [isEmbedded, navigate]);

return (
<PageLayoutV1 pageTitle={t('label.setting-plural')}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import { ReactComponent as IconFormatVideo } from '../assets/svg/ic-format-video.svg';
import { FileType } from '../components/BlockEditor/BlockEditor.interface';
import { ENTITY_URL_MAP } from '../constants/Feeds.constants';
import { inCurrentAppContext } from './RouterUtils';
import blockEditorExtensionsClassBase from './BlockEditorExtensionsClassBase';
Comment thread
gitar-bot[bot] marked this conversation as resolved.
Outdated
import { ENTITY_LINK_SEPARATOR } from './EntityUtils';
import { getEntityDetail, getHashTagList, getMentionList } from './FeedUtils';
Expand Down Expand Up @@ -66,7 +67,10 @@
const entityType = urlEntries.find((e) => e[1] === rawEntityType)?.[0];

if (entityType) {
const entityLink = `<a href="${href}/${rawEntityType}/${fqn}" data-type="mention" data-entityType="${entityType}" data-fqn="${fqn}" data-label="${fqn}">@${fqn}</a>`;
const fullHref = inCurrentAppContext(
`${href}/${rawEntityType}/${fqn}`
);
const entityLink = `<a href="${fullHref}" data-type="mention" data-entityType="${entityType}" data-fqn="${fqn}" data-label="${fqn}">@${fqn}</a>`;
updatedMessage = updatedMessage.replaceAll(key, entityLink);
}
}
Expand All @@ -76,7 +80,8 @@
if (value) {
const [, href, rawEntityType, fqn] = value;

const entityLink = `<a href="${href}/${rawEntityType}/${fqn}" data-type="hashtag" data-entityType="${rawEntityType}" data-fqn="${fqn}" data-label="${fqn}">#${fqn}</a>`;
const fullHref = inCurrentAppContext(`${href}/${rawEntityType}/${fqn}`);
const entityLink = `<a href="${fullHref}" data-type="hashtag" data-entityType="${rawEntityType}" data-fqn="${fqn}" data-label="${fqn}">#${fqn}</a>`;
updatedMessage = updatedMessage.replaceAll(key, entityLink);
}
});
Expand Down Expand Up @@ -104,7 +109,7 @@
const parser = new DOMParser();

// Only convert markdown to HTML if the content is not already HTML
const processedContent = isHTMLString(htmlString)

Check warning on line 112 in openmetadata-ui/src/main/resources/ui/src/utils/BlockEditorUtils.ts

View workflow job for this annotation

GitHub Actions / lint-src

'isHTMLString' was used before it was defined
? htmlString
: _convertMarkdownFormatToHtmlString(htmlString);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,6 @@ describe('ConnectionsRouterClassBase', () => {
router = new ConnectionsRouterClassBase();
});

describe('embeddedMode', () => {
it('setEmbeddedMode should be a no-op', () => {
router.setEmbeddedMode(true);

expect(router.isEmbeddedMode()).toBe(false);
});

it('isEmbeddedMode should always return false', () => {
expect(router.isEmbeddedMode()).toBe(false);
});
});

describe('getSettingsServicesPath', () => {
it('should return the generic settings services path when no category given', () => {
expect(router.getSettingsServicesPath()).toBe('/settings/services');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ import {
import { getServiceRouteFromServiceType } from './ServiceUtils';

class ConnectionsRouterClassBase {
public setEmbeddedMode(_flag: boolean): void {
// no-op in base; overridden in Collate
}

public isEmbeddedMode(): boolean {
return false;
}

public getSettingsServicesPath(serviceCategory?: string): string {
if (serviceCategory) {
return getSettingPath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import { PRIMARY_COLOR } from '../constants/Color.constants';
import { EntityType } from '../enums/entity.enum';
import { getEntityLinkFromType } from './EntityUtils';
import { inCurrentAppContext } from './RouterUtils';
import ELKLayout from './Lineage/Layout/ELKUtil/ELKUtil';

// Layout: padding(8) + icon(14) + gap(8) + label + gap(8) + typeChip + padding(8)
Expand Down Expand Up @@ -873,7 +874,12 @@ export const setupGraphEventHandlers = (ctx: GraphInteractionCtx): void => {
const node = graphDataNodes.find((n) => n.id === nodeId);
if (node?.type && node?.fullyQualifiedName) {
window.open(
getEntityLinkFromType(node.fullyQualifiedName, node.type as EntityType),
inCurrentAppContext(
getEntityLinkFromType(
node.fullyQualifiedName,
node.type as EntityType
)
),
'_blank',
'noopener,noreferrer'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@ describe('ObservabilityRouterClassBase', () => {
router = new ObservabilityRouterClassBase();
});

describe('embeddedMode', () => {
it('setEmbeddedMode should be a no-op', () => {
router.setEmbeddedMode(true);

expect(router.isEmbeddedMode()).toBe(false);
});

it('isEmbeddedMode should always return false', () => {
expect(router.isEmbeddedMode()).toBe(false);
});
});

describe('getDataQualityPagePath', () => {
it('should return base path without tab', () => {
expect(router.getDataQualityPagePath()).toBe('/data-quality');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ import {
} from './RouterUtils';

class ObservabilityRouterClassBase {
public setEmbeddedMode(_flag: boolean): void {
// no-op in base; overridden in Collate
}

public isEmbeddedMode(): boolean {
return false;
}

public getDataQualityPagePath(
tab?: DataQualityPageTabs,
subTab?: string
Expand Down
19 changes: 19 additions & 0 deletions openmetadata-ui/src/main/resources/ui/src/utils/RouterUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,25 @@ export const getLogsViewerPath = (
return path;
};

// Extension hook for escape-hatch navigation (window.open, target=_blank,
// raw <a href>) that bypasses React Router's basename. Hosts that embed OM
// under a sub-path register a provider; without one, input passes through.
export type AppContextProvider = (urlOrPath: string) => string;

const identityAppContextProvider: AppContextProvider = (urlOrPath) =>
urlOrPath;

let currentAppContextProvider: AppContextProvider = identityAppContextProvider;

export const registerAppContextProvider = (
provider: AppContextProvider | null
): void => {
currentAppContextProvider = provider ?? identityAppContextProvider;
};

export const inCurrentAppContext = (urlOrPath: string): string =>
currentAppContextProvider(urlOrPath);

export const getGlossaryPathWithAction = (
fqn: string,
action: EntityAction
Expand Down
Loading