mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Renamed parts of the UI extension APIs (#63070)
* Renamed target -> id and href -> path after feedback. * fixed type issues in test page. * chore(pluginschemajson): update extensions props target -> id * this is the final. * fixed typings...again... --------- Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
This commit is contained in:
parent
b88206d98f
commit
f46f8bdd3a
@ -480,7 +480,7 @@
|
||||
"type": "object",
|
||||
"description": "Expose a page link that can be used by Grafana core or other plugins to navigate users to the plugin",
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "title", "target", "path"],
|
||||
"required": ["type", "title", "placement", "path"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
@ -491,7 +491,7 @@
|
||||
"minLength": 3,
|
||||
"maxLength": 22
|
||||
},
|
||||
"target": {
|
||||
"placement": {
|
||||
"type": "string",
|
||||
"pattern": "^(plugins|grafana)/[a-z-/0-9]*$"
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ export enum PluginExtensionTypes {
|
||||
}
|
||||
|
||||
export type PluginsExtensionLinkConfig = {
|
||||
target: string;
|
||||
placement: string;
|
||||
type: PluginExtensionTypes.link;
|
||||
title: string;
|
||||
description: string;
|
||||
|
@ -13,7 +13,7 @@ describe('getPluginExtensions', () => {
|
||||
type: 'link',
|
||||
title: 'Declare incident',
|
||||
description: 'Declaring an incident in the app',
|
||||
href: `/a/${pluginId}/declare-incident`,
|
||||
path: `/a/${pluginId}/declare-incident`,
|
||||
key: 1,
|
||||
},
|
||||
],
|
||||
@ -22,26 +22,26 @@ describe('getPluginExtensions', () => {
|
||||
|
||||
it('should return a collection of extensions to the plugin', () => {
|
||||
const { extensions, error } = getPluginExtensions({
|
||||
target: `plugins/${pluginId}/${linkId}`,
|
||||
placement: `plugins/${pluginId}/${linkId}`,
|
||||
});
|
||||
|
||||
expect(extensions[0].href).toBe(`/a/${pluginId}/declare-incident`);
|
||||
expect(extensions[0].path).toBe(`/a/${pluginId}/declare-incident`);
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return a description for the requested link', () => {
|
||||
const { extensions, error } = getPluginExtensions({
|
||||
target: `plugins/${pluginId}/${linkId}`,
|
||||
placement: `plugins/${pluginId}/${linkId}`,
|
||||
});
|
||||
|
||||
expect(extensions[0].href).toBe(`/a/${pluginId}/declare-incident`);
|
||||
expect(extensions[0].path).toBe(`/a/${pluginId}/declare-incident`);
|
||||
expect(extensions[0].description).toBe('Declaring an incident in the app');
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return an empty array when no links can be found', () => {
|
||||
const { extensions, error } = getPluginExtensions({
|
||||
target: `an-unknown-app/${linkId}`,
|
||||
placement: `an-unknown-app/${linkId}`,
|
||||
});
|
||||
|
||||
expect(extensions.length).toBe(0);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { getPluginsExtensionRegistry, PluginsExtension } from './registry';
|
||||
|
||||
export type GetPluginExtensionsOptions = {
|
||||
target: string;
|
||||
placement: string;
|
||||
};
|
||||
|
||||
export type PluginExtensionsResult = {
|
||||
@ -10,23 +10,23 @@ export type PluginExtensionsResult = {
|
||||
};
|
||||
|
||||
export class PluginExtensionsMissingError extends Error {
|
||||
readonly target: string;
|
||||
readonly placement: string;
|
||||
|
||||
constructor(target: string) {
|
||||
super(`Could not find extensions for '${target}'`);
|
||||
this.target = target;
|
||||
constructor(placement: string) {
|
||||
super(`Could not find extensions for '${placement}'`);
|
||||
this.placement = placement;
|
||||
this.name = PluginExtensionsMissingError.name;
|
||||
}
|
||||
}
|
||||
|
||||
export function getPluginExtensions({ target }: GetPluginExtensionsOptions): PluginExtensionsResult {
|
||||
export function getPluginExtensions({ placement }: GetPluginExtensionsOptions): PluginExtensionsResult {
|
||||
const registry = getPluginsExtensionRegistry();
|
||||
const extensions = registry[target];
|
||||
const extensions = registry[placement];
|
||||
|
||||
if (!Array.isArray(extensions)) {
|
||||
return {
|
||||
extensions: [],
|
||||
error: new PluginExtensionsMissingError(target),
|
||||
error: new PluginExtensionsMissingError(placement),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ export type PluginsExtensionLink = {
|
||||
type: 'link';
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
path: string;
|
||||
key: number;
|
||||
};
|
||||
|
||||
|
@ -244,7 +244,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
||||
return &plugins.FakePluginStore{
|
||||
PluginList: newPlugins("test-app", []*plugindef.ExtensionsLink{
|
||||
{
|
||||
Target: "core/home/menu",
|
||||
Placement: "core/home/menu",
|
||||
Type: plugindef.ExtensionsLinkTypeLink,
|
||||
Title: "Title",
|
||||
Description: "Home route of app",
|
||||
@ -267,7 +267,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
||||
Version: "0.5.0",
|
||||
Extensions: []*plugindef.ExtensionsLink{
|
||||
{
|
||||
Target: "core/home/menu",
|
||||
Placement: "core/home/menu",
|
||||
Type: plugindef.ExtensionsLinkTypeLink,
|
||||
Title: "Title",
|
||||
Description: "Home route of app",
|
||||
@ -284,7 +284,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
||||
return &plugins.FakePluginStore{
|
||||
PluginList: newPlugins("test-app", []*plugindef.ExtensionsLink{
|
||||
{
|
||||
Target: "core/home/menu",
|
||||
Placement: "core/home/menu",
|
||||
Type: plugindef.ExtensionsLinkTypeLink,
|
||||
Title: "Title",
|
||||
Description: "Home route of app",
|
||||
|
@ -502,14 +502,14 @@ func TestLoader_Load(t *testing.T) {
|
||||
},
|
||||
Extensions: []*plugindef.ExtensionsLink{
|
||||
{
|
||||
Target: "plugins/grafana-slo-app/slo-breach",
|
||||
Placement: "plugins/grafana-slo-app/slo-breach",
|
||||
Title: "Declare incident",
|
||||
Type: plugindef.ExtensionsLinkTypeLink,
|
||||
Description: "Declares a new incident",
|
||||
Path: "/incidents/declare",
|
||||
},
|
||||
{
|
||||
Target: "plugins/grafana-slo-app/slo-breach",
|
||||
Placement: "plugins/grafana-slo-app/slo-breach",
|
||||
Title: "Declare incident",
|
||||
Type: plugindef.ExtensionsLinkTypeLink,
|
||||
Description: "Declares a new incident (path without backslash)",
|
||||
|
@ -36,14 +36,14 @@
|
||||
],
|
||||
"extensions": [
|
||||
{
|
||||
"target": "plugins/grafana-slo-app/slo-breach",
|
||||
"placement": "plugins/grafana-slo-app/slo-breach",
|
||||
"type": "link",
|
||||
"title": "Declare incident",
|
||||
"description": "Declares a new incident",
|
||||
"path": "/incidents/declare"
|
||||
},
|
||||
{
|
||||
"target": "plugins/grafana-slo-app/slo-breach",
|
||||
"placement": "plugins/grafana-slo-app/slo-breach",
|
||||
"type": "link",
|
||||
"title": "Declare incident",
|
||||
"description": "Declares a new incident (path without backslash)",
|
||||
|
@ -101,7 +101,7 @@ seqs: [
|
||||
component?: string
|
||||
|
||||
// The minimum role a user must have to see this page in the navigation menu.
|
||||
role?: "Admin" | "Editor" | "Viewer"
|
||||
role?: "Admin" | "Editor" | "Viewer"
|
||||
|
||||
// RBAC action the user must have to access the route
|
||||
action?: string
|
||||
@ -124,7 +124,7 @@ seqs: [
|
||||
|
||||
#ExtensionsLink: {
|
||||
// Target where the link will be rendered
|
||||
target: =~"^(plugins|grafana)\/[a-z-/0-9]*$"
|
||||
placement: =~"^(plugins|grafana)\/[a-z-/0-9]*$"
|
||||
// Type of extension
|
||||
type: "link"
|
||||
// Title that will be displayed for the rendered link
|
||||
|
@ -162,7 +162,7 @@ type ExtensionsLink struct {
|
||||
Path string `json:"path"`
|
||||
|
||||
// Target where the link will be rendered
|
||||
Target string `json:"target"`
|
||||
Placement string `json:"placement"`
|
||||
|
||||
// Title that will be displayed for the rendered link
|
||||
Title string `json:"title"`
|
||||
|
@ -7,7 +7,7 @@ describe('Plugin registry', () => {
|
||||
const registry = createPluginExtensionsRegistry({
|
||||
'belugacdn-app': createConfig([
|
||||
{
|
||||
target: 'plugins/belugacdn-app/menu',
|
||||
placement: 'plugins/belugacdn-app/menu',
|
||||
title: 'The title',
|
||||
type: PluginExtensionTypes.link,
|
||||
description: 'Incidents are occurring!',
|
||||
@ -16,7 +16,7 @@ describe('Plugin registry', () => {
|
||||
]),
|
||||
'strava-app': createConfig([
|
||||
{
|
||||
target: 'plugins/strava-app/menu',
|
||||
placement: 'plugins/strava-app/menu',
|
||||
title: 'The title',
|
||||
type: PluginExtensionTypes.link,
|
||||
description: 'Incidents are occurring!',
|
||||
@ -25,14 +25,14 @@ describe('Plugin registry', () => {
|
||||
]),
|
||||
'duplicate-links-app': createConfig([
|
||||
{
|
||||
target: 'plugins/duplicate-links-app/menu',
|
||||
placement: 'plugins/duplicate-links-app/menu',
|
||||
title: 'The title',
|
||||
type: PluginExtensionTypes.link,
|
||||
description: 'Incidents are occurring!',
|
||||
path: '/incidents/declare',
|
||||
},
|
||||
{
|
||||
target: 'plugins/duplicate-links-app/menu',
|
||||
placement: 'plugins/duplicate-links-app/menu',
|
||||
title: 'The title',
|
||||
type: PluginExtensionTypes.link,
|
||||
description: 'Incidents are occurring!',
|
||||
@ -49,7 +49,7 @@ describe('Plugin registry', () => {
|
||||
title: 'The title',
|
||||
type: 'link',
|
||||
description: 'Incidents are occurring!',
|
||||
href: '/a/belugacdn-app/incidents/declare',
|
||||
path: '/a/belugacdn-app/incidents/declare',
|
||||
key: 539074708,
|
||||
});
|
||||
});
|
||||
@ -68,7 +68,7 @@ describe('Plugin registry', () => {
|
||||
title: 'The title',
|
||||
type: 'link',
|
||||
description: 'Incidents are occurring!',
|
||||
href: '/a/belugacdn-app/incidents/declare',
|
||||
path: '/a/belugacdn-app/incidents/declare',
|
||||
key: 539074708,
|
||||
});
|
||||
|
||||
@ -76,7 +76,7 @@ describe('Plugin registry', () => {
|
||||
title: 'The title',
|
||||
type: 'link',
|
||||
description: 'Incidents are occurring!',
|
||||
href: '/a/strava-app/incidents/declare',
|
||||
path: '/a/strava-app/incidents/declare',
|
||||
key: -1637066384,
|
||||
});
|
||||
});
|
||||
|
@ -17,15 +17,15 @@ export function createPluginExtensionsRegistry(apps: Record<string, AppPluginCon
|
||||
}
|
||||
|
||||
for (const extension of extensions) {
|
||||
const target = extension.target;
|
||||
const placement = extension.placement;
|
||||
const item = createRegistryItem(pluginId, extension);
|
||||
|
||||
if (!Array.isArray(registry[target])) {
|
||||
registry[target] = [item];
|
||||
if (!Array.isArray(registry[placement])) {
|
||||
registry[placement] = [item];
|
||||
continue;
|
||||
}
|
||||
|
||||
registry[target].push(item);
|
||||
registry[placement].push(item);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -38,14 +38,14 @@ export function createPluginExtensionsRegistry(apps: Record<string, AppPluginCon
|
||||
}
|
||||
|
||||
function createRegistryItem(pluginId: string, extension: PluginsExtensionLinkConfig): PluginsExtensionLink {
|
||||
const href = `/a/${pluginId}${extension.path}`;
|
||||
const path = `/a/${pluginId}${extension.path}`;
|
||||
|
||||
return Object.freeze({
|
||||
type: PluginExtensionTypes.link,
|
||||
title: extension.title,
|
||||
description: extension.description,
|
||||
href: href,
|
||||
key: hashKey(`${extension.title}${href}`),
|
||||
path: path,
|
||||
key: hashKey(`${extension.title}${path}`),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ export const TestStuffPage = () => {
|
||||
<Page navModel={{ node: node, main: node }}>
|
||||
<Page.Contents>
|
||||
<HorizontalGroup>
|
||||
<LinkToBasicApp target="grafana/sandbox/testing" />
|
||||
<LinkToBasicApp placement="grafana/sandbox/testing" />
|
||||
</HorizontalGroup>
|
||||
{data && (
|
||||
<AutoSizer style={{ width: '100%', height: '600px' }}>
|
||||
@ -148,8 +148,8 @@ export function getDefaultState(): State {
|
||||
};
|
||||
}
|
||||
|
||||
function LinkToBasicApp({ target }: { target: string }) {
|
||||
const { extensions, error } = getPluginExtensions({ target });
|
||||
function LinkToBasicApp({ placement }: { placement: string }) {
|
||||
const { extensions, error } = getPluginExtensions({ placement });
|
||||
|
||||
if (error) {
|
||||
return null;
|
||||
@ -159,7 +159,7 @@ function LinkToBasicApp({ target }: { target: string }) {
|
||||
<div>
|
||||
{extensions.map((extension) => {
|
||||
return (
|
||||
<LinkButton href={extension.href} title={extension.description} key={extension.key}>
|
||||
<LinkButton href={extension.path} title={extension.description} key={extension.key}>
|
||||
{extension.title}
|
||||
</LinkButton>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user