frontend-plugin-api: add support for sub page icons
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -71,6 +71,13 @@ const examplePlugin: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -1799,6 +1799,13 @@ export const PageBlueprint: ExtensionBlueprint_2<{
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef_2<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
@@ -1843,6 +1850,8 @@ export interface PageTab {
|
||||
// (undocumented)
|
||||
href: string;
|
||||
// (undocumented)
|
||||
icon?: IconElement;
|
||||
// (undocumented)
|
||||
id: string;
|
||||
// (undocumented)
|
||||
label: string;
|
||||
@@ -2023,6 +2032,7 @@ export const SubPageBlueprint: ExtensionBlueprint_2<{
|
||||
params: {
|
||||
path: string;
|
||||
title: string;
|
||||
icon?: IconElement;
|
||||
loader: () => Promise<JSX.Element>;
|
||||
routeRef?: RouteRef;
|
||||
};
|
||||
@@ -2036,7 +2046,14 @@ export const SubPageBlueprint: ExtensionBlueprint_2<{
|
||||
}
|
||||
>
|
||||
| ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
|
||||
| ExtensionDataRef_2<string, 'core.title', {}>;
|
||||
| ExtensionDataRef_2<string, 'core.title', {}>
|
||||
| ExtensionDataRef_2<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>;
|
||||
inputs: {};
|
||||
config: {
|
||||
path: string | undefined;
|
||||
|
||||
@@ -50,6 +50,7 @@ export const PageBlueprint = createExtensionBlueprint({
|
||||
coreExtensionData.routeRef.optional(),
|
||||
coreExtensionData.reactElement,
|
||||
coreExtensionData.title.optional(),
|
||||
coreExtensionData.icon.optional(),
|
||||
]),
|
||||
},
|
||||
output: [
|
||||
@@ -104,9 +105,11 @@ export const PageBlueprint = createExtensionBlueprint({
|
||||
const tabs: PageTab[] = inputs.pages.map(page => {
|
||||
const path = page.get(coreExtensionData.routePath);
|
||||
const tabTitle = page.get(coreExtensionData.title);
|
||||
const tabIcon = page.get(coreExtensionData.icon);
|
||||
return {
|
||||
id: path,
|
||||
label: tabTitle || path,
|
||||
icon: tabIcon,
|
||||
href: path,
|
||||
matchStrategy: 'prefix' as const,
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IconElement } from '../icons/types';
|
||||
import { RouteRef } from '../routing';
|
||||
import { coreExtensionData, createExtensionBlueprint } from '../wiring';
|
||||
import { ExtensionBoundary } from '../components';
|
||||
@@ -47,6 +48,7 @@ export const SubPageBlueprint = createExtensionBlueprint({
|
||||
coreExtensionData.reactElement,
|
||||
coreExtensionData.title,
|
||||
coreExtensionData.routeRef.optional(),
|
||||
coreExtensionData.icon.optional(),
|
||||
],
|
||||
config: {
|
||||
schema: {
|
||||
@@ -66,6 +68,10 @@ export const SubPageBlueprint = createExtensionBlueprint({
|
||||
* The title displayed in the tab for this sub-page.
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Optional icon for this sub-page, displayed in the tab.
|
||||
*/
|
||||
icon?: IconElement;
|
||||
/**
|
||||
* A function that returns a promise resolving to the React element to render.
|
||||
* This enables lazy loading of the sub-page content.
|
||||
@@ -86,5 +92,8 @@ export const SubPageBlueprint = createExtensionBlueprint({
|
||||
if (params.routeRef) {
|
||||
yield coreExtensionData.routeRef(params.routeRef);
|
||||
}
|
||||
if (params.icon) {
|
||||
yield coreExtensionData.icon(params.icon);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ import { createSwappableComponent } from './createSwappableComponent';
|
||||
export interface PageTab {
|
||||
id: string;
|
||||
label: string;
|
||||
icon?: IconElement;
|
||||
href: string;
|
||||
matchStrategy?: 'prefix' | 'exact';
|
||||
}
|
||||
@@ -96,12 +97,16 @@ function DefaultPageLayout(props: PageLayoutProps): JSX.Element {
|
||||
key={tab.id}
|
||||
href={tab.href}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '4px',
|
||||
padding: '8px 12px',
|
||||
textDecoration: 'none',
|
||||
color: '#333',
|
||||
borderBottom: '2px solid transparent',
|
||||
}}
|
||||
>
|
||||
{tab.icon}
|
||||
{tab.label}
|
||||
</a>
|
||||
))}
|
||||
|
||||
@@ -545,6 +545,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -110,6 +110,13 @@ const visualizerPlugin: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
@@ -148,11 +155,19 @@ const visualizerPlugin: OverridableFrontendPlugin<
|
||||
}
|
||||
>
|
||||
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
|
||||
| ExtensionDataRef<string, 'core.title', {}>;
|
||||
| ExtensionDataRef<string, 'core.title', {}>
|
||||
| ExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>;
|
||||
inputs: {};
|
||||
params: {
|
||||
path: string;
|
||||
title: string;
|
||||
icon?: IconElement;
|
||||
loader: () => Promise<JSX.Element>;
|
||||
routeRef?: RouteRef;
|
||||
};
|
||||
@@ -178,11 +193,19 @@ const visualizerPlugin: OverridableFrontendPlugin<
|
||||
}
|
||||
>
|
||||
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
|
||||
| ExtensionDataRef<string, 'core.title', {}>;
|
||||
| ExtensionDataRef<string, 'core.title', {}>
|
||||
| ExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>;
|
||||
inputs: {};
|
||||
params: {
|
||||
path: string;
|
||||
title: string;
|
||||
icon?: IconElement;
|
||||
loader: () => Promise<JSX.Element>;
|
||||
routeRef?: RouteRef;
|
||||
};
|
||||
@@ -208,11 +231,19 @@ const visualizerPlugin: OverridableFrontendPlugin<
|
||||
}
|
||||
>
|
||||
| ExtensionDataRef<JSX_2.Element, 'core.reactElement', {}>
|
||||
| ExtensionDataRef<string, 'core.title', {}>;
|
||||
| ExtensionDataRef<string, 'core.title', {}>
|
||||
| ExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>;
|
||||
inputs: {};
|
||||
params: {
|
||||
path: string;
|
||||
title: string;
|
||||
icon?: IconElement;
|
||||
loader: () => Promise<JSX.Element>;
|
||||
routeRef?: RouteRef;
|
||||
};
|
||||
|
||||
@@ -72,6 +72,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -220,6 +220,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -165,6 +165,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -114,6 +114,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -1054,6 +1054,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
@@ -1151,6 +1158,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -111,6 +111,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -152,6 +152,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -212,6 +212,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -86,6 +86,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -92,6 +92,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -242,6 +242,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -117,6 +117,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
@@ -279,6 +286,13 @@ export const searchPage: OverridableExtensionDefinition<{
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -332,6 +332,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
@@ -403,6 +410,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
@@ -94,6 +94,13 @@ const _default: OverridableFrontendPlugin<
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>
|
||||
| ConfigurableExtensionDataRef<
|
||||
IconElement,
|
||||
'core.icon',
|
||||
{
|
||||
optional: true;
|
||||
}
|
||||
>,
|
||||
{
|
||||
singleton: false;
|
||||
|
||||
Reference in New Issue
Block a user