mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 04:04:00 -06:00
Plugins: Unifying alpha state & options for all plugins (#16530)
* app pages * app pages * workign example * started alpha support * remove app stuff * show warning on alpha/beta panels * put app back on plugin file * fix go * add enum for PluginType and PluginIncludeType * Refactoring and moving settings to plugins section fixes #16529
This commit is contained in:
parent
30dcf0f6c5
commit
3c21a121eb
@ -613,8 +613,13 @@ server_url =
|
|||||||
callback_url =
|
callback_url =
|
||||||
|
|
||||||
[panels]
|
[panels]
|
||||||
|
# here for to support old env variables, can remove after a few months
|
||||||
enable_alpha = false
|
enable_alpha = false
|
||||||
disable_sanitize_html = false
|
disable_sanitize_html = false
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
enable_alpha = false
|
||||||
|
app_tls_skip_verify_insecure = false
|
||||||
|
|
||||||
[enterprise]
|
[enterprise]
|
||||||
license_path =
|
license_path =
|
||||||
|
@ -540,7 +540,10 @@ log_queries =
|
|||||||
;license_path =
|
;license_path =
|
||||||
|
|
||||||
[panels]
|
[panels]
|
||||||
;enable_alpha = false
|
|
||||||
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
|
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
|
||||||
;disable_sanitize_html = false
|
;disable_sanitize_html = false
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
;enable_alpha = false
|
||||||
|
;app_tls_skip_verify_insecure = false
|
||||||
|
|
||||||
|
@ -666,11 +666,14 @@ Default setting for max attempts to sending alert notifications. Default value i
|
|||||||
|
|
||||||
## [panels]
|
## [panels]
|
||||||
|
|
||||||
### enable_alpha
|
|
||||||
Set to true if you want to test panels that are not yet ready for general usage.
|
|
||||||
|
|
||||||
### disable_sanitize_html
|
### disable_sanitize_html
|
||||||
|
|
||||||
If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities. Default
|
If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities. Default
|
||||||
is false. This settings was introduced in Grafana v6.0.
|
is false. This settings was introduced in Grafana v6.0.
|
||||||
|
|
||||||
|
## [plugins]
|
||||||
|
|
||||||
|
### enable_alpha
|
||||||
|
|
||||||
|
Set to true if you want to test alpha plugins that are not yet ready for general usage.
|
||||||
|
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
|
export enum PluginState {
|
||||||
|
alpha = 'alpha', // Only included it `enable_alpha` is true
|
||||||
|
beta = 'beta', // Will show a warning banner
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PluginType {
|
||||||
|
panel = 'panel',
|
||||||
|
datasource = 'datasource',
|
||||||
|
app = 'app',
|
||||||
|
}
|
||||||
|
|
||||||
export interface PluginMeta {
|
export interface PluginMeta {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
info: PluginMetaInfo;
|
info: PluginMetaInfo;
|
||||||
includes: PluginInclude[];
|
|
||||||
module: string;
|
module: string;
|
||||||
baseUrl: string;
|
includes?: PluginInclude[];
|
||||||
|
baseUrl?: string;
|
||||||
|
|
||||||
|
type: PluginType;
|
||||||
|
enabled?: boolean;
|
||||||
|
state?: PluginState;
|
||||||
|
|
||||||
// Datasource-specific
|
// Datasource-specific
|
||||||
builtIn?: boolean;
|
builtIn?: boolean;
|
||||||
@ -24,8 +39,17 @@ interface PluginMetaQueryOptions {
|
|||||||
minInterval?: boolean;
|
minInterval?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum PluginIncludeType {
|
||||||
|
dashboard = 'dashboard',
|
||||||
|
page = 'page',
|
||||||
|
|
||||||
|
// Only valid for apps
|
||||||
|
panel = 'panel',
|
||||||
|
datasource = 'datasource',
|
||||||
|
}
|
||||||
|
|
||||||
export interface PluginInclude {
|
export interface PluginInclude {
|
||||||
type: string;
|
type: PluginIncludeType;
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
macaron "gopkg.in/macaron.v1"
|
macaron "gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
@ -21,7 +20,7 @@ var pluginProxyTransport *http.Transport
|
|||||||
func (hs *HTTPServer) initAppPluginRoutes(r *macaron.Macaron) {
|
func (hs *HTTPServer) initAppPluginRoutes(r *macaron.Macaron) {
|
||||||
pluginProxyTransport = &http.Transport{
|
pluginProxyTransport = &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
InsecureSkipVerify: setting.PluginAppsSkipVerifyTLS,
|
InsecureSkipVerify: hs.Cfg.PluginsAppsSkipVerifyTLS,
|
||||||
Renegotiation: tls.RenegotiateFreelyAsClient,
|
Renegotiation: tls.RenegotiateFreelyAsClient,
|
||||||
},
|
},
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
@ -145,7 +145,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf
|
|||||||
|
|
||||||
panels := map[string]interface{}{}
|
panels := map[string]interface{}{}
|
||||||
for _, panel := range enabledPlugins.Panels {
|
for _, panel := range enabledPlugins.Panels {
|
||||||
if panel.State == plugins.PluginStateAlpha && !hs.Cfg.EnableAlphaPanels {
|
if panel.State == plugins.PluginStateAlpha && !hs.Cfg.PluginsEnableAlpha {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +162,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf
|
|||||||
"hideFromList": panel.HideFromList,
|
"hideFromList": panel.HideFromList,
|
||||||
"sort": getPanelSort(panel.Id),
|
"sort": getPanelSort(panel.Id),
|
||||||
"dataFormats": panel.DataFormats,
|
"dataFormats": panel.DataFormats,
|
||||||
|
"state": panel.State,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func (hs *HTTPServer) GetPluginList(c *m.ReqContext) Response {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if pluginDef.State == plugins.PluginStateAlpha && !hs.Cfg.EnableAlphaPanels {
|
if pluginDef.State == plugins.PluginStateAlpha && !hs.Cfg.PluginsEnableAlpha {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +142,6 @@ var (
|
|||||||
// Basic Auth
|
// Basic Auth
|
||||||
BasicAuthEnabled bool
|
BasicAuthEnabled bool
|
||||||
|
|
||||||
// Plugin settings
|
|
||||||
PluginAppsSkipVerifyTLS bool
|
|
||||||
|
|
||||||
// Session settings.
|
// Session settings.
|
||||||
SessionOptions session.Options
|
SessionOptions session.Options
|
||||||
SessionConnMaxLifetime int64
|
SessionConnMaxLifetime int64
|
||||||
@ -233,7 +230,8 @@ type Cfg struct {
|
|||||||
MetricsEndpointEnabled bool
|
MetricsEndpointEnabled bool
|
||||||
MetricsEndpointBasicAuthUsername string
|
MetricsEndpointBasicAuthUsername string
|
||||||
MetricsEndpointBasicAuthPassword string
|
MetricsEndpointBasicAuthPassword string
|
||||||
EnableAlphaPanels bool
|
PluginsEnableAlpha bool
|
||||||
|
PluginsAppsSkipVerifyTLS bool
|
||||||
DisableSanitizeHtml bool
|
DisableSanitizeHtml bool
|
||||||
EnterpriseLicensePath string
|
EnterpriseLicensePath string
|
||||||
|
|
||||||
@ -721,9 +719,6 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
|||||||
authBasic := iniFile.Section("auth.basic")
|
authBasic := iniFile.Section("auth.basic")
|
||||||
BasicAuthEnabled = authBasic.Key("enabled").MustBool(true)
|
BasicAuthEnabled = authBasic.Key("enabled").MustBool(true)
|
||||||
|
|
||||||
// global plugin settings
|
|
||||||
PluginAppsSkipVerifyTLS = iniFile.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false)
|
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
renderSec := iniFile.Section("rendering")
|
renderSec := iniFile.Section("rendering")
|
||||||
cfg.RendererUrl = renderSec.Key("server_url").String()
|
cfg.RendererUrl = renderSec.Key("server_url").String()
|
||||||
@ -771,9 +766,17 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
|||||||
explore := iniFile.Section("explore")
|
explore := iniFile.Section("explore")
|
||||||
ExploreEnabled = explore.Key("enabled").MustBool(true)
|
ExploreEnabled = explore.Key("enabled").MustBool(true)
|
||||||
|
|
||||||
panels := iniFile.Section("panels")
|
panelsSection := iniFile.Section("panels")
|
||||||
cfg.EnableAlphaPanels = panels.Key("enable_alpha").MustBool(false)
|
cfg.DisableSanitizeHtml = panelsSection.Key("disable_sanitize_html").MustBool(false)
|
||||||
cfg.DisableSanitizeHtml = panels.Key("disable_sanitize_html").MustBool(false)
|
|
||||||
|
pluginsSection := iniFile.Section("plugins")
|
||||||
|
cfg.PluginsEnableAlpha = pluginsSection.Key("enable_alpha").MustBool(false)
|
||||||
|
cfg.PluginsAppsSkipVerifyTLS = iniFile.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false)
|
||||||
|
|
||||||
|
// check old location for this option
|
||||||
|
if panelsSection.Key("enable_alpha").MustBool(false) {
|
||||||
|
cfg.PluginsEnableAlpha = true
|
||||||
|
}
|
||||||
|
|
||||||
cfg.readSessionConfig()
|
cfg.readSessionConfig()
|
||||||
cfg.readSmtpSettings()
|
cfg.readSmtpSettings()
|
||||||
|
@ -7,7 +7,7 @@ import { AlertBox } from 'app/core/components/AlertBox/AlertBox';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PanelPlugin, AppNotificationSeverity } from 'app/types';
|
import { PanelPlugin, AppNotificationSeverity } from 'app/types';
|
||||||
import { PanelProps, ReactPanelPlugin } from '@grafana/ui';
|
import { PanelProps, ReactPanelPlugin, PluginType } from '@grafana/ui';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
pluginId: string;
|
pluginId: string;
|
||||||
@ -45,6 +45,7 @@ export function getPanelPluginNotFound(id: string): PanelPlugin {
|
|||||||
id: id,
|
id: id,
|
||||||
name: id,
|
name: id,
|
||||||
sort: 100,
|
sort: 100,
|
||||||
|
type: PluginType.panel,
|
||||||
module: '',
|
module: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
dataFormats: [],
|
dataFormats: [],
|
||||||
|
@ -18,6 +18,7 @@ import { PanelModel } from '../state';
|
|||||||
import { DashboardModel } from '../state';
|
import { DashboardModel } from '../state';
|
||||||
import { PanelPlugin } from 'app/types/plugins';
|
import { PanelPlugin } from 'app/types/plugins';
|
||||||
import { VizPickerSearch } from './VizPickerSearch';
|
import { VizPickerSearch } from './VizPickerSearch';
|
||||||
|
import PluginStateinfo from 'app/features/plugins/PluginStateInfo';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
@ -238,6 +239,7 @@ export class VisualizationTab extends PureComponent<Props, State> {
|
|||||||
onClose={this.onCloseVizPicker}
|
onClose={this.onCloseVizPicker}
|
||||||
/>
|
/>
|
||||||
</FadeIn>
|
</FadeIn>
|
||||||
|
<PluginStateinfo state={plugin.state} />
|
||||||
{this.renderPanelOptions()}
|
{this.renderPanelOptions()}
|
||||||
</>
|
</>
|
||||||
</EditorTabBody>
|
</EditorTabBody>
|
||||||
|
@ -24,6 +24,7 @@ import { getRouteParamsId } from 'app/core/selectors/location';
|
|||||||
import { NavModel, Plugin, StoreState } from 'app/types/';
|
import { NavModel, Plugin, StoreState } from 'app/types/';
|
||||||
import { DataSourceSettings } from '@grafana/ui/src/types/';
|
import { DataSourceSettings } from '@grafana/ui/src/types/';
|
||||||
import { getDataSourceLoadingNav } from '../state/navModel';
|
import { getDataSourceLoadingNav } from '../state/navModel';
|
||||||
|
import PluginStateinfo from 'app/features/plugins/PluginStateInfo';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
navModel: NavModel;
|
navModel: NavModel;
|
||||||
@ -44,11 +45,6 @@ interface State {
|
|||||||
testingStatus?: string;
|
testingStatus?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DataSourceStates {
|
|
||||||
Alpha = 'alpha',
|
|
||||||
Beta = 'beta',
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DataSourceSettingsPage extends PureComponent<Props, State> {
|
export class DataSourceSettingsPage extends PureComponent<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -110,32 +106,6 @@ export class DataSourceSettingsPage extends PureComponent<Props, State> {
|
|||||||
return this.props.dataSource.readOnly === true;
|
return this.props.dataSource.readOnly === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldRenderInfoBox() {
|
|
||||||
const { state } = this.props.dataSourceMeta;
|
|
||||||
|
|
||||||
return state === DataSourceStates.Alpha || state === DataSourceStates.Beta;
|
|
||||||
}
|
|
||||||
|
|
||||||
getInfoText() {
|
|
||||||
const { dataSourceMeta } = this.props;
|
|
||||||
|
|
||||||
switch (dataSourceMeta.state) {
|
|
||||||
case DataSourceStates.Alpha:
|
|
||||||
return (
|
|
||||||
'This plugin is marked as being in alpha state, which means it is in early development phase and updates' +
|
|
||||||
' will include breaking changes.'
|
|
||||||
);
|
|
||||||
|
|
||||||
case DataSourceStates.Beta:
|
|
||||||
return (
|
|
||||||
'This plugin is marked as being in a beta development state. This means it is in currently in active' +
|
|
||||||
' development and could be missing important features.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderIsReadOnlyMessage() {
|
renderIsReadOnlyMessage() {
|
||||||
return (
|
return (
|
||||||
<div className="grafana-info-box span8">
|
<div className="grafana-info-box span8">
|
||||||
@ -196,7 +166,7 @@ export class DataSourceSettingsPage extends PureComponent<Props, State> {
|
|||||||
<div>
|
<div>
|
||||||
<form onSubmit={this.onSubmit}>
|
<form onSubmit={this.onSubmit}>
|
||||||
{this.isReadOnly() && this.renderIsReadOnlyMessage()}
|
{this.isReadOnly() && this.renderIsReadOnlyMessage()}
|
||||||
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
|
<PluginStateinfo state={dataSourceMeta.state} />
|
||||||
|
|
||||||
<BasicSettings
|
<BasicSettings
|
||||||
dataSourceName={dataSource.name}
|
dataSourceName={dataSource.name}
|
||||||
|
@ -11,11 +11,9 @@ exports[`Render should render alpha info text 1`] = `
|
|||||||
<form
|
<form
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<div
|
<PluginStateinfo
|
||||||
className="grafana-info-box"
|
state="alpha"
|
||||||
>
|
/>
|
||||||
This plugin is marked as being in alpha state, which means it is in early development phase and updates will include breaking changes.
|
|
||||||
</div>
|
|
||||||
<BasicSettings
|
<BasicSettings
|
||||||
dataSourceName="gdev-cloudwatch"
|
dataSourceName="gdev-cloudwatch"
|
||||||
isDefault={false}
|
isDefault={false}
|
||||||
@ -49,6 +47,7 @@ exports[`Render should render alpha info text 1`] = `
|
|||||||
}
|
}
|
||||||
dataSourceMeta={
|
dataSourceMeta={
|
||||||
Object {
|
Object {
|
||||||
|
"baseUrl": "path/to/plugin",
|
||||||
"defaultNavUrl": "some/url",
|
"defaultNavUrl": "some/url",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"hasUpdate": false,
|
"hasUpdate": false,
|
||||||
@ -78,11 +77,11 @@ exports[`Render should render alpha info text 1`] = `
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
},
|
},
|
||||||
"latestVersion": "1",
|
"latestVersion": "1",
|
||||||
"module": Object {},
|
"module": "path/to/module",
|
||||||
"name": "pretty cool plugin 1",
|
"name": "pretty cool plugin 1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"state": "alpha",
|
"state": "alpha",
|
||||||
"type": "",
|
"type": "panel",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onModelChange={[Function]}
|
onModelChange={[Function]}
|
||||||
@ -113,11 +112,9 @@ exports[`Render should render beta info text 1`] = `
|
|||||||
<form
|
<form
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<div
|
<PluginStateinfo
|
||||||
className="grafana-info-box"
|
state="beta"
|
||||||
>
|
/>
|
||||||
This plugin is marked as being in a beta development state. This means it is in currently in active development and could be missing important features.
|
|
||||||
</div>
|
|
||||||
<BasicSettings
|
<BasicSettings
|
||||||
dataSourceName="gdev-cloudwatch"
|
dataSourceName="gdev-cloudwatch"
|
||||||
isDefault={false}
|
isDefault={false}
|
||||||
@ -151,6 +148,7 @@ exports[`Render should render beta info text 1`] = `
|
|||||||
}
|
}
|
||||||
dataSourceMeta={
|
dataSourceMeta={
|
||||||
Object {
|
Object {
|
||||||
|
"baseUrl": "path/to/plugin",
|
||||||
"defaultNavUrl": "some/url",
|
"defaultNavUrl": "some/url",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"hasUpdate": false,
|
"hasUpdate": false,
|
||||||
@ -180,11 +178,11 @@ exports[`Render should render beta info text 1`] = `
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
},
|
},
|
||||||
"latestVersion": "1",
|
"latestVersion": "1",
|
||||||
"module": Object {},
|
"module": "path/to/module",
|
||||||
"name": "pretty cool plugin 1",
|
"name": "pretty cool plugin 1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"state": "beta",
|
"state": "beta",
|
||||||
"type": "",
|
"type": "panel",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onModelChange={[Function]}
|
onModelChange={[Function]}
|
||||||
@ -215,6 +213,7 @@ exports[`Render should render component 1`] = `
|
|||||||
<form
|
<form
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
|
<PluginStateinfo />
|
||||||
<BasicSettings
|
<BasicSettings
|
||||||
dataSourceName="gdev-cloudwatch"
|
dataSourceName="gdev-cloudwatch"
|
||||||
isDefault={false}
|
isDefault={false}
|
||||||
@ -248,6 +247,7 @@ exports[`Render should render component 1`] = `
|
|||||||
}
|
}
|
||||||
dataSourceMeta={
|
dataSourceMeta={
|
||||||
Object {
|
Object {
|
||||||
|
"baseUrl": "path/to/plugin",
|
||||||
"defaultNavUrl": "some/url",
|
"defaultNavUrl": "some/url",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"hasUpdate": false,
|
"hasUpdate": false,
|
||||||
@ -277,11 +277,10 @@ exports[`Render should render component 1`] = `
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
},
|
},
|
||||||
"latestVersion": "1",
|
"latestVersion": "1",
|
||||||
"module": Object {},
|
"module": "path/to/module",
|
||||||
"name": "pretty cool plugin 1",
|
"name": "pretty cool plugin 1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"state": "",
|
"type": "panel",
|
||||||
"type": "",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onModelChange={[Function]}
|
onModelChange={[Function]}
|
||||||
@ -317,6 +316,7 @@ exports[`Render should render is ready only message 1`] = `
|
|||||||
>
|
>
|
||||||
This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.
|
This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.
|
||||||
</div>
|
</div>
|
||||||
|
<PluginStateinfo />
|
||||||
<BasicSettings
|
<BasicSettings
|
||||||
dataSourceName="gdev-cloudwatch"
|
dataSourceName="gdev-cloudwatch"
|
||||||
isDefault={false}
|
isDefault={false}
|
||||||
@ -350,6 +350,7 @@ exports[`Render should render is ready only message 1`] = `
|
|||||||
}
|
}
|
||||||
dataSourceMeta={
|
dataSourceMeta={
|
||||||
Object {
|
Object {
|
||||||
|
"baseUrl": "path/to/plugin",
|
||||||
"defaultNavUrl": "some/url",
|
"defaultNavUrl": "some/url",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"hasUpdate": false,
|
"hasUpdate": false,
|
||||||
@ -379,11 +380,10 @@ exports[`Render should render is ready only message 1`] = `
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
},
|
},
|
||||||
"latestVersion": "1",
|
"latestVersion": "1",
|
||||||
"module": Object {},
|
"module": "path/to/module",
|
||||||
"name": "pretty cool plugin 1",
|
"name": "pretty cool plugin 1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"state": "",
|
"type": "panel",
|
||||||
"type": "",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onModelChange={[Function]}
|
onModelChange={[Function]}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NavModel, NavModelItem } from 'app/types';
|
import { NavModel, NavModelItem } from 'app/types';
|
||||||
import { PluginMeta, DataSourceSettings } from '@grafana/ui/src/types';
|
import { PluginMeta, DataSourceSettings, PluginType } from '@grafana/ui/src/types';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
|
|
||||||
export function buildNavModel(dataSource: DataSourceSettings, pluginMeta: PluginMeta): NavModelItem {
|
export function buildNavModel(dataSource: DataSourceSettings, pluginMeta: PluginMeta): NavModelItem {
|
||||||
@ -67,6 +67,7 @@ export function getDataSourceLoadingNav(pageName: string): NavModel {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
|
type: PluginType.datasource,
|
||||||
name: '',
|
name: '',
|
||||||
info: {
|
info: {
|
||||||
author: {
|
author: {
|
||||||
@ -83,7 +84,7 @@ export function getDataSourceLoadingNav(pageName: string): NavModel {
|
|||||||
updated: '',
|
updated: '',
|
||||||
version: '',
|
version: '',
|
||||||
},
|
},
|
||||||
includes: [{ type: '', name: '', path: '' }],
|
includes: [],
|
||||||
module: '',
|
module: '',
|
||||||
baseUrl: '',
|
baseUrl: '',
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,11 @@ import {
|
|||||||
} from './actions';
|
} from './actions';
|
||||||
import { getMockDataSources, getMockDataSource } from '../__mocks__/dataSourcesMocks';
|
import { getMockDataSources, getMockDataSource } from '../__mocks__/dataSourcesMocks';
|
||||||
import { LayoutModes } from 'app/core/components/LayoutSelector/LayoutSelector';
|
import { LayoutModes } from 'app/core/components/LayoutSelector/LayoutSelector';
|
||||||
import { DataSourcesState } from 'app/types';
|
import { DataSourcesState, Plugin } from 'app/types';
|
||||||
import { PluginMetaInfo } from '@grafana/ui';
|
import { PluginMetaInfo, PluginType } from '@grafana/ui';
|
||||||
|
|
||||||
const mockPlugin = () => ({
|
const mockPlugin = () =>
|
||||||
|
({
|
||||||
defaultNavUrl: 'defaultNavUrl',
|
defaultNavUrl: 'defaultNavUrl',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
hasUpdate: true,
|
hasUpdate: true,
|
||||||
@ -26,10 +27,9 @@ const mockPlugin = () => ({
|
|||||||
latestVersion: 'latestVersion',
|
latestVersion: 'latestVersion',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
pinned: true,
|
pinned: true,
|
||||||
state: 'state',
|
type: PluginType.datasource,
|
||||||
type: 'type',
|
module: 'path/to/module',
|
||||||
module: {},
|
} as Plugin);
|
||||||
});
|
|
||||||
|
|
||||||
describe('dataSourcesReducer', () => {
|
describe('dataSourcesReducer', () => {
|
||||||
describe('when dataSourcesLoaded is dispatched', () => {
|
describe('when dataSourcesLoaded is dispatched', () => {
|
||||||
|
34
public/app/features/plugins/PluginStateInfo.tsx
Normal file
34
public/app/features/plugins/PluginStateInfo.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React, { FC } from 'react';
|
||||||
|
import { PluginState } from '@grafana/ui';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
state?: PluginState;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPluginStateInfoText(state?: PluginState): string | null {
|
||||||
|
switch (state) {
|
||||||
|
case PluginState.alpha:
|
||||||
|
return (
|
||||||
|
'This plugin is marked as being in alpha state, which means it is in early development phase and updates' +
|
||||||
|
' will include breaking changes.'
|
||||||
|
);
|
||||||
|
|
||||||
|
case PluginState.beta:
|
||||||
|
return (
|
||||||
|
'This plugin is marked as being in a beta development state. This means it is in currently in active' +
|
||||||
|
' development and could be missing important features.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PluginStateinfo: FC<Props> = props => {
|
||||||
|
const text = getPluginStateInfoText(props.state);
|
||||||
|
if (!text) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="grafana-info-box">{text}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PluginStateinfo;
|
@ -1,4 +1,5 @@
|
|||||||
import { Plugin, PanelPlugin, PanelDataFormat } from 'app/types';
|
import { Plugin, PanelPlugin, PanelDataFormat } from 'app/types';
|
||||||
|
import { PluginType } from '@grafana/ui';
|
||||||
|
|
||||||
export const getMockPlugins = (amount: number): Plugin[] => {
|
export const getMockPlugins = (amount: number): Plugin[] => {
|
||||||
const plugins = [];
|
const plugins = [];
|
||||||
@ -36,6 +37,7 @@ export const getMockPlugins = (amount: number): Plugin[] => {
|
|||||||
export const getPanelPlugin = (options: Partial<PanelPlugin>): PanelPlugin => {
|
export const getPanelPlugin = (options: Partial<PanelPlugin>): PanelPlugin => {
|
||||||
return {
|
return {
|
||||||
id: options.id,
|
id: options.id,
|
||||||
|
type: PluginType.panel,
|
||||||
name: options.id,
|
name: options.id,
|
||||||
sort: options.sort || 1,
|
sort: options.sort || 1,
|
||||||
dataFormats: [PanelDataFormat.TimeSeries],
|
dataFormats: [PanelDataFormat.TimeSeries],
|
||||||
@ -81,9 +83,9 @@ export const getMockPlugin = () => {
|
|||||||
},
|
},
|
||||||
latestVersion: '1',
|
latestVersion: '1',
|
||||||
name: 'pretty cool plugin 1',
|
name: 'pretty cool plugin 1',
|
||||||
|
baseUrl: 'path/to/plugin',
|
||||||
pinned: false,
|
pinned: false,
|
||||||
state: '',
|
type: PluginType.panel,
|
||||||
type: '',
|
module: 'path/to/module',
|
||||||
module: {},
|
} as Plugin;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,9 @@ exports[`Render should render component 1`] = `
|
|||||||
className="card-item-type"
|
className="card-item-type"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="icon-gf icon-gf-"
|
className="icon-gf icon-gf-panel"
|
||||||
/>
|
/>
|
||||||
|
panel
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -63,8 +64,9 @@ exports[`Render should render has plugin section 1`] = `
|
|||||||
className="card-item-type"
|
className="card-item-type"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="icon-gf icon-gf-"
|
className="icon-gf icon-gf-panel"
|
||||||
/>
|
/>
|
||||||
|
panel
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="card-item-notice"
|
className="card-item-notice"
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import { AngularPanelPlugin, ReactPanelPlugin, PluginMetaInfo } from '@grafana/ui/src/types';
|
import { AngularPanelPlugin, ReactPanelPlugin, PluginMetaInfo, PluginMeta } from '@grafana/ui/src/types';
|
||||||
|
|
||||||
export interface PanelPlugin {
|
export interface PanelPlugin extends PluginMeta {
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
hideFromList?: boolean;
|
hideFromList?: boolean;
|
||||||
module: string;
|
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
info: PluginMetaInfo;
|
info: PluginMetaInfo;
|
||||||
sort: number;
|
sort: number;
|
||||||
@ -19,18 +16,11 @@ export enum PanelDataFormat {
|
|||||||
TimeSeries = 'time_series',
|
TimeSeries = 'time_series',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Plugin {
|
export interface Plugin extends PluginMeta {
|
||||||
defaultNavUrl: string;
|
defaultNavUrl: string;
|
||||||
enabled: boolean;
|
|
||||||
hasUpdate: boolean;
|
hasUpdate: boolean;
|
||||||
id: string;
|
|
||||||
info: PluginMetaInfo;
|
|
||||||
latestVersion: string;
|
latestVersion: string;
|
||||||
name: string;
|
|
||||||
pinned: boolean;
|
pinned: boolean;
|
||||||
state: string;
|
|
||||||
type: string;
|
|
||||||
module: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginDashboard {
|
export interface PluginDashboard {
|
||||||
|
Loading…
Reference in New Issue
Block a user