mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TextPanel: Removes Angular Text Panel (#25504)
* TextPanel: Removes Angular Text Panel * Tests: updates snapshots
This commit is contained in:
parent
aa3d893079
commit
55f304f15d
@ -78,7 +78,7 @@ exports[`DashboardPage Dashboard init completed Should render dashboard grid 1`
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -191,7 +191,7 @@ exports[`DashboardPage Dashboard init completed Should render dashboard grid 1`
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -285,7 +285,7 @@ exports[`DashboardPage Dashboard init completed Should render dashboard grid 1`
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -434,7 +434,7 @@ exports[`DashboardPage When dashboard has editview url state should render setti
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -547,7 +547,7 @@ exports[`DashboardPage When dashboard has editview url state should render setti
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -641,7 +641,7 @@ exports[`DashboardPage When dashboard has editview url state should render setti
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -741,7 +741,7 @@ exports[`DashboardPage When dashboard has editview url state should render setti
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
|
@ -235,7 +235,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -477,7 +477,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -719,7 +719,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
@ -961,7 +961,7 @@ exports[`DashboardGrid Can render dashboard grid Should render 1`] = `
|
||||
],
|
||||
"refresh": undefined,
|
||||
"revision": undefined,
|
||||
"schemaVersion": 25,
|
||||
"schemaVersion": 26,
|
||||
"snapshot": undefined,
|
||||
"style": "dark",
|
||||
"tags": Array [],
|
||||
|
@ -132,7 +132,7 @@ describe('DashboardModel', () => {
|
||||
});
|
||||
|
||||
it('dashboard schema version should be set to latest', () => {
|
||||
expect(model.schemaVersion).toBe(25);
|
||||
expect(model.schemaVersion).toBe(26);
|
||||
});
|
||||
|
||||
it('graph thresholds should be migrated', () => {
|
||||
@ -715,6 +715,89 @@ describe('DashboardModel', () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when migrating to new Text Panel', () => {
|
||||
let model: DashboardModel;
|
||||
|
||||
beforeEach(() => {
|
||||
model = new DashboardModel({
|
||||
panels: [
|
||||
{
|
||||
id: 2,
|
||||
type: 'text',
|
||||
title: 'Angular Text Panel',
|
||||
content:
|
||||
'# Angular Text Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text\n\n',
|
||||
mode: 'markdown',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
type: 'text2',
|
||||
title: 'React Text Panel from scratch',
|
||||
options: {
|
||||
mode: 'markdown',
|
||||
content:
|
||||
'# React Text Panel from scratch\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
type: 'text2',
|
||||
title: 'React Text Panel from Angular Panel',
|
||||
options: {
|
||||
mode: 'markdown',
|
||||
content:
|
||||
'# React Text Panel from Angular Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text',
|
||||
angular: {
|
||||
content:
|
||||
'# React Text Panel from Angular Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text\n',
|
||||
mode: 'markdown',
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should have 3 panels after migration', () => {
|
||||
expect(model.panels.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should not migrate panel with old Text Panel id', () => {
|
||||
const oldAngularPanel: any = model.panels[0];
|
||||
expect(oldAngularPanel.id).toEqual(2);
|
||||
expect(oldAngularPanel.type).toEqual('text');
|
||||
expect(oldAngularPanel.title).toEqual('Angular Text Panel');
|
||||
expect(oldAngularPanel.content).toEqual(
|
||||
'# Angular Text Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text\n\n'
|
||||
);
|
||||
expect(oldAngularPanel.mode).toEqual('markdown');
|
||||
});
|
||||
|
||||
it('should migrate panels with new Text Panel id', () => {
|
||||
const reactPanel: any = model.panels[1];
|
||||
expect(reactPanel.id).toEqual(3);
|
||||
expect(reactPanel.type).toEqual('text');
|
||||
expect(reactPanel.title).toEqual('React Text Panel from scratch');
|
||||
expect(reactPanel.options.content).toEqual(
|
||||
'# React Text Panel from scratch\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text'
|
||||
);
|
||||
expect(reactPanel.options.mode).toEqual('markdown');
|
||||
});
|
||||
|
||||
it('should clean up old angular options for panels with new Text Panel id', () => {
|
||||
const reactPanel: any = model.panels[2];
|
||||
expect(reactPanel.id).toEqual(4);
|
||||
expect(reactPanel.type).toEqual('text');
|
||||
expect(reactPanel.title).toEqual('React Text Panel from Angular Panel');
|
||||
expect(reactPanel.options.content).toEqual(
|
||||
'# React Text Panel from Angular Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text'
|
||||
);
|
||||
expect(reactPanel.options.mode).toEqual('markdown');
|
||||
expect(reactPanel.options.angular).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createRow(options: any, panelDescriptions: any[]) {
|
||||
|
@ -31,7 +31,7 @@ export class DashboardMigrator {
|
||||
let i, j, k, n;
|
||||
const oldVersion = this.dashboard.schemaVersion;
|
||||
const panelUpgrades = [];
|
||||
this.dashboard.schemaVersion = 25;
|
||||
this.dashboard.schemaVersion = 26;
|
||||
|
||||
if (oldVersion === this.dashboard.schemaVersion) {
|
||||
return;
|
||||
@ -564,6 +564,18 @@ export class DashboardMigrator {
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 26) {
|
||||
panelUpgrades.push((panel: any) => {
|
||||
const wasReactText = panel.type === 'text2';
|
||||
if (!wasReactText) {
|
||||
return;
|
||||
}
|
||||
|
||||
panel.type = 'text';
|
||||
delete panel.options.angular;
|
||||
});
|
||||
}
|
||||
|
||||
if (panelUpgrades.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ const azureMonitorPlugin = async () =>
|
||||
);
|
||||
|
||||
import * as textPanel from 'app/plugins/panel/text/module';
|
||||
import * as text2Panel from 'app/plugins/panel/text2/module';
|
||||
import * as graph2Panel from 'app/plugins/panel/graph2/module';
|
||||
import * as graphPanel from 'app/plugins/panel/graph/module';
|
||||
import * as dashListPanel from 'app/plugins/panel/dashlist/module';
|
||||
@ -79,7 +78,6 @@ const builtInPlugins: any = {
|
||||
'app/plugins/datasource/grafana-azure-monitor-datasource/module': azureMonitorPlugin,
|
||||
|
||||
'app/plugins/panel/text/module': textPanel,
|
||||
'app/plugins/panel/text2/module': text2Panel,
|
||||
'app/plugins/panel/graph2/module': graph2Panel,
|
||||
'app/plugins/panel/graph/module': graphPanel,
|
||||
'app/plugins/panel/dashlist/module': dashListPanel,
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
The Text Panel is **included** with Grafana.
|
||||
|
||||
The Text Panel is a very simple panel that displays text. The source text is written in the Markdown syntax meaning you can format the text. Read [GitHub's Mastering Markdown](https://guides.github.com/features/mastering-markdown/) to learn more.
|
||||
The Text Panel is a very simple panel that displays text. The source text is written in the Markdown syntax meaning you can format the text. Read [GitHub's Mastering Markdown](https://guides.github.com/features/mastering-markdown/) to learn more.
|
||||
|
@ -1,15 +0,0 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Mode</span>
|
||||
<span class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown']"></select>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form gf-form--grow">
|
||||
<code-editor content="ctrl.panel.content" on-change="ctrl.render()" data-mode="markdown" data-max-lines=20>
|
||||
</code-editor>
|
||||
</div>
|
||||
</div>
|
@ -1,2 +0,0 @@
|
||||
<p class="markdown-html panel-text-content" ng-bind-html="ctrl.content" ng-show="ctrl.content">
|
||||
</p>
|
@ -1,101 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import { PanelCtrl } from 'app/plugins/sdk';
|
||||
|
||||
import config from 'app/core/config';
|
||||
import { auto, ISCEService } from 'angular';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { PanelEvents, textUtil } from '@grafana/data';
|
||||
import { renderMarkdown } from '@grafana/data';
|
||||
|
||||
const defaultContent = `
|
||||
# Title
|
||||
|
||||
For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)
|
||||
|
||||
|
||||
|
||||
`;
|
||||
|
||||
export class TextPanelCtrl extends PanelCtrl {
|
||||
static templateUrl = `public/app/plugins/panel/text/module.html`;
|
||||
static scrollable = true;
|
||||
|
||||
content: string;
|
||||
// Set and populate defaults
|
||||
panelDefaults = {
|
||||
mode: 'markdown', // 'html', 'markdown', 'text'
|
||||
content: defaultContent,
|
||||
};
|
||||
|
||||
/** @ngInject */
|
||||
constructor(
|
||||
$scope: any,
|
||||
$injector: auto.IInjectorService,
|
||||
private templateSrv: TemplateSrv,
|
||||
private $sce: ISCEService
|
||||
) {
|
||||
super($scope, $injector);
|
||||
|
||||
_.defaults(this.panel, this.panelDefaults);
|
||||
|
||||
this.events.on(PanelEvents.editModeInitialized, this.onInitEditMode.bind(this));
|
||||
this.events.on(PanelEvents.refresh, this.onRefresh.bind(this));
|
||||
this.events.on(PanelEvents.render, this.onRender.bind(this));
|
||||
|
||||
const renderWhenChanged = (scope: any) => {
|
||||
const { panel } = scope.ctrl;
|
||||
return [panel.content, panel.mode].join();
|
||||
};
|
||||
|
||||
$scope.$watch(
|
||||
renderWhenChanged,
|
||||
_.throttle(() => {
|
||||
this.render();
|
||||
}, 100)
|
||||
);
|
||||
}
|
||||
|
||||
onInitEditMode() {
|
||||
this.addEditorTab('Options', 'public/app/plugins/panel/text/editor.html');
|
||||
|
||||
if (this.panel.mode === 'text') {
|
||||
this.panel.mode = 'markdown';
|
||||
}
|
||||
}
|
||||
|
||||
onRefresh() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
onRender() {
|
||||
if (this.panel.mode === 'markdown') {
|
||||
this.renderMarkdown(this.panel.content);
|
||||
} else if (this.panel.mode === 'html') {
|
||||
this.updateContent(this.panel.content);
|
||||
}
|
||||
this.renderingCompleted();
|
||||
}
|
||||
|
||||
renderText(content: string) {
|
||||
const safeContent = textUtil.escapeHtml(content).replace(/\n/g, '<br/>');
|
||||
this.updateContent(safeContent);
|
||||
}
|
||||
|
||||
renderMarkdown(content: string) {
|
||||
this.$scope.$applyAsync(() => {
|
||||
this.updateContent(renderMarkdown(content));
|
||||
});
|
||||
}
|
||||
|
||||
updateContent(html: string) {
|
||||
try {
|
||||
html = this.templateSrv.replace(html, this.panel.scopedVars, 'html');
|
||||
} catch (e) {
|
||||
console.log('Text panel error: ', e);
|
||||
}
|
||||
|
||||
this.content = this.$sce.trustAsHtml(config.disableSanitizeHtml ? html : textUtil.sanitize(html));
|
||||
}
|
||||
}
|
||||
|
||||
export { TextPanelCtrl as PanelCtrl };
|
@ -1,7 +1,8 @@
|
||||
import { PanelModel, PanelPlugin } from '@grafana/data';
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
|
||||
import { TextPanel } from './TextPanel';
|
||||
import { TextOptions } from './types';
|
||||
import { textPanelMigrationHandler } from './textPanelMigrationHandler';
|
||||
|
||||
export const plugin = new PanelPlugin<TextOptions>(TextPanel)
|
||||
.setPanelOptions(builder => {
|
||||
@ -28,14 +29,9 @@ export const plugin = new PanelPlugin<TextOptions>(TextPanel)
|
||||
rows: 5,
|
||||
},
|
||||
defaultValue: `# Title
|
||||
|
||||
|
||||
For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)
|
||||
`,
|
||||
});
|
||||
})
|
||||
.setPanelChangeHandler((panel: PanelModel<TextOptions>, prevPluginId: string, prevOptions: any) => {
|
||||
if (prevPluginId === 'text') {
|
||||
return prevOptions as TextOptions;
|
||||
}
|
||||
return panel.options;
|
||||
});
|
||||
.setMigrationHandler(textPanelMigrationHandler);
|
@ -0,0 +1,43 @@
|
||||
import { textPanelMigrationHandler } from './textPanelMigrationHandler';
|
||||
import { TextOptions } from './types';
|
||||
import { FieldConfigSource, PanelModel } from '@grafana/data';
|
||||
|
||||
describe('textPanelMigrationHandler', () => {
|
||||
describe('when invoked and previous version was old Angular text panel', () => {
|
||||
it('then should migrate options', () => {
|
||||
const panel: any = {
|
||||
content: '<span>Hello World<span>',
|
||||
mode: 'html',
|
||||
};
|
||||
|
||||
const result = textPanelMigrationHandler(panel);
|
||||
|
||||
expect(result.content).toEqual('<span>Hello World<span>');
|
||||
expect(result.mode).toEqual('html');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when invoked and previous version was not old Angular text panel', () => {
|
||||
it('then should just pass options through', () => {
|
||||
const panel: PanelModel<TextOptions> = {
|
||||
id: 1,
|
||||
fieldConfig: ({} as unknown) as FieldConfigSource,
|
||||
options: {
|
||||
content: `# Title
|
||||
|
||||
For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)
|
||||
`,
|
||||
mode: 'markdown',
|
||||
},
|
||||
};
|
||||
|
||||
const result = textPanelMigrationHandler(panel);
|
||||
|
||||
expect(result.content).toEqual(`# Title
|
||||
|
||||
For markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)
|
||||
`);
|
||||
expect(result.mode).toEqual('markdown');
|
||||
});
|
||||
});
|
||||
});
|
15
public/app/plugins/panel/text/textPanelMigrationHandler.ts
Normal file
15
public/app/plugins/panel/text/textPanelMigrationHandler.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { PanelModel } from '@grafana/data';
|
||||
import { TextMode, TextOptions } from './types';
|
||||
|
||||
export const textPanelMigrationHandler = (panel: PanelModel<TextOptions>): Partial<TextOptions> => {
|
||||
// Migrates old Angular based text panel props to new props
|
||||
if (panel.hasOwnProperty('content') && panel.hasOwnProperty('mode')) {
|
||||
const oldTextPanel: { content: string; mode: string } = (panel as unknown) as any;
|
||||
const content = oldTextPanel.content;
|
||||
const mode = (oldTextPanel.mode as unknown) as TextMode;
|
||||
|
||||
return { content, mode };
|
||||
}
|
||||
|
||||
return panel.options as TextOptions;
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
# Text Panel - Native Plugin
|
||||
|
||||
The Text Panel is **included** with Grafana.
|
||||
|
||||
The Text Panel is a very simple panel that displays text. The source text is written in the Markdown syntax meaning you can format the text. Read [GitHub's Mastering Markdown](https://guides.github.com/features/mastering-markdown/) to learn more.
|
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 84.72 84.72"><defs><style>.cls-1{fill:#3865ab;}.cls-2{fill:#84aff1;}.cls-3{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" x1="23.44" y1="42.36" x2="61.28" y2="42.36" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f2cc0c"/><stop offset="1" stop-color="#ff9830"/></linearGradient></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="8.53" y="8.53" width="67.66" height="67.66" rx="1"/><path class="cls-2" d="M83.72,84.72H1a1,1,0,0,1-1-1V1A1,1,0,0,1,1,0H83.72a1,1,0,0,1,1,1V83.72A1,1,0,0,1,83.72,84.72ZM5,80.72H79.72a1,1,0,0,0,1-1V5a1,1,0,0,0-1-1H5A1,1,0,0,0,4,5V79.72A1,1,0,0,0,5,80.72Z"/><path class="cls-3" d="M60.28,21.25H24.44a1,1,0,0,0-1,1V29a1,1,0,0,0,1,1H37a1,1,0,0,1,1,1V62.47a1,1,0,0,0,1,1h6.78a1,1,0,0,0,1-1V31a1,1,0,0,1,1-1H60.28a1,1,0,0,0,1-1V22.25A1,1,0,0,0,60.28,21.25Z"/></g></g></svg>
|
Before Width: | Height: | Size: 985 B |
@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "panel",
|
||||
"name": "Text v2",
|
||||
"id": "text2",
|
||||
"state": "alpha",
|
||||
|
||||
"skipDataQuery": true,
|
||||
|
||||
"info": {
|
||||
"author": {
|
||||
"name": "Grafana Labs",
|
||||
"url": "https://grafana.com"
|
||||
},
|
||||
"logos": {
|
||||
"small": "img/icn-text-panel.svg",
|
||||
"large": "img/icn-text-panel.svg"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user