UI Extensions: Add openInNewTab property to link extensions (#114831)
feat: add `openInNewTab` property for link extensions
This commit is contained in:
@@ -30,6 +30,7 @@ export type PluginExtensionLink = PluginExtensionBase & {
|
||||
onClick?: (event?: React.MouseEvent) => void;
|
||||
icon?: IconName;
|
||||
category?: string;
|
||||
openInNewTab?: boolean;
|
||||
};
|
||||
|
||||
export type PluginExtensionComponentMeta = Omit<PluginExtensionComponent, 'component'>;
|
||||
@@ -86,6 +87,7 @@ export type PluginExtensionAddedComponentConfig<Props = {}> = PluginExtensionCon
|
||||
*/
|
||||
component: React.ComponentType<Props>;
|
||||
};
|
||||
|
||||
export type PluginExtensionAddedFunctionConfig<Signature = unknown> = PluginExtensionConfigBase & {
|
||||
/**
|
||||
* The target extension points where the component will be added
|
||||
@@ -106,6 +108,7 @@ export type PluginAddedLinksConfigureFunc<Context extends object> = (context: Re
|
||||
onClick: (event: React.MouseEvent | undefined, helpers: PluginExtensionEventHelpers<Context>) => void;
|
||||
icon: IconName;
|
||||
category: string;
|
||||
openInNewTab: boolean;
|
||||
}>
|
||||
| undefined;
|
||||
|
||||
@@ -137,6 +140,10 @@ export type PluginExtensionAddedLinkConfig<Context extends object = object> = Pl
|
||||
|
||||
// (Optional) A category to be used when grouping the options in the ui
|
||||
category?: string;
|
||||
|
||||
// (Optional) If true, opens the link in a new tab (renders with target="_blank")
|
||||
// (Important: this is not guaranteed, depends on the extension point if it implements it.)
|
||||
openInNewTab?: boolean;
|
||||
};
|
||||
|
||||
export type PluginExtensionExposedComponentConfig<Props = {}> = PluginExtensionConfigBase & {
|
||||
|
||||
@@ -95,6 +95,7 @@ describe('AddedLinksRegistry', () => {
|
||||
path: `/a/${pluginId}/declare-incident`,
|
||||
targets: 'plugins/myorg-basic-app/start',
|
||||
configure: jest.fn().mockImplementation((context) => ({ title: context?.title })),
|
||||
openInNewTab: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -120,6 +121,7 @@ describe('AddedLinksRegistry', () => {
|
||||
path: `/a/${pluginId}/declare-incident`,
|
||||
extensionPointId: 'plugins/myorg-basic-app/start',
|
||||
configure: expect.any(Function),
|
||||
openInNewTab: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ export type AddedLinkRegistryItem<Context extends object = object> = {
|
||||
configure?: PluginAddedLinksConfigureFunc<Context>;
|
||||
icon?: IconName;
|
||||
category?: string;
|
||||
openInNewTab?: boolean;
|
||||
};
|
||||
|
||||
export class AddedLinksRegistry extends Registry<AddedLinkRegistryItem[], PluginExtensionAddedLinkConfig> {
|
||||
@@ -40,13 +41,14 @@ export class AddedLinksRegistry extends Registry<AddedLinkRegistryItem[], Plugin
|
||||
const { pluginId, configs } = item;
|
||||
|
||||
for (const config of configs) {
|
||||
const { path, title, description, configure, onClick, targets } = config;
|
||||
const { path, title, description, configure, onClick, targets, openInNewTab } = config;
|
||||
const configLog = this.logger.child({
|
||||
path: path ?? '',
|
||||
description: description ?? '',
|
||||
title,
|
||||
pluginId,
|
||||
onClick: typeof onClick,
|
||||
openInNewTab: openInNewTab ? 'true' : 'false',
|
||||
});
|
||||
|
||||
if (!title) {
|
||||
|
||||
@@ -167,6 +167,7 @@ describe('usePluginLinks()', () => {
|
||||
title: '2',
|
||||
description: '2',
|
||||
path: `/a/${pluginId}/2`,
|
||||
openInNewTab: true,
|
||||
},
|
||||
{
|
||||
targets: 'plugins/another-extension/v1',
|
||||
@@ -181,7 +182,9 @@ describe('usePluginLinks()', () => {
|
||||
|
||||
expect(result.current.links.length).toBe(2);
|
||||
expect(result.current.links[0].title).toBe('1');
|
||||
expect(result.current.links[0].openInNewTab).toBeUndefined();
|
||||
expect(result.current.links[1].title).toBe('2');
|
||||
expect(result.current.links[1].openInNewTab).toBe(true);
|
||||
});
|
||||
|
||||
it('should dynamically update the extensions registered for a certain extension point', () => {
|
||||
|
||||
@@ -51,6 +51,7 @@ export function usePluginLinks({
|
||||
title: addedLink.title,
|
||||
description: addedLink.description ?? '',
|
||||
onClick: typeof addedLink.onClick,
|
||||
openInNewTab: addedLink.openInNewTab ? 'true' : 'false',
|
||||
});
|
||||
|
||||
// Only limit if the `limitPerPlugin` is set
|
||||
@@ -84,6 +85,7 @@ export function usePluginLinks({
|
||||
description: overrides?.description || addedLink.description || '',
|
||||
path: isString(path) ? getLinkExtensionPathWithTracking(pluginId, path, extensionPointId) : undefined,
|
||||
category: overrides?.category || addedLink.category,
|
||||
openInNewTab: overrides?.openInNewTab ?? addedLink.openInNewTab,
|
||||
};
|
||||
|
||||
extensions.push(extension);
|
||||
|
||||
@@ -474,12 +474,14 @@ export function getLinkExtensionOverrides(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Only allowing to override the following properties
|
||||
let {
|
||||
title = config.title,
|
||||
description = config.description,
|
||||
path = config.path,
|
||||
icon = config.icon,
|
||||
category = config.category,
|
||||
openInNewTab = config.openInNewTab,
|
||||
...rest
|
||||
} = overrides;
|
||||
|
||||
@@ -504,6 +506,7 @@ export function getLinkExtensionOverrides(
|
||||
path,
|
||||
icon,
|
||||
category,
|
||||
openInNewTab,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
|
||||
Reference in New Issue
Block a user