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