mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Inspector: remove feature flag and angular "Export CSV" menu option (#23160)
This commit is contained in:
parent
6366e43a44
commit
a1157b1744
@ -14,10 +14,9 @@ export interface BuildInfo {
|
|||||||
|
|
||||||
interface FeatureToggles {
|
interface FeatureToggles {
|
||||||
transformations: boolean;
|
transformations: boolean;
|
||||||
inspect: boolean;
|
|
||||||
expressions: boolean;
|
expressions: boolean;
|
||||||
newEdit: boolean;
|
newEdit: boolean;
|
||||||
meta: boolean;
|
meta: boolean; // enterprise
|
||||||
newVariables: boolean;
|
newVariables: boolean;
|
||||||
tracingIntegration: boolean;
|
tracingIntegration: boolean;
|
||||||
}
|
}
|
||||||
@ -67,7 +66,6 @@ export class GrafanaBootConfig {
|
|||||||
pluginsToPreload: string[] = [];
|
pluginsToPreload: string[] = [];
|
||||||
featureToggles: FeatureToggles = {
|
featureToggles: FeatureToggles = {
|
||||||
transformations: false,
|
transformations: false,
|
||||||
inspect: false,
|
|
||||||
expressions: false,
|
expressions: false,
|
||||||
newEdit: false,
|
newEdit: false,
|
||||||
meta: false,
|
meta: false,
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
import angular from 'angular';
|
|
||||||
import * as fileExport from 'app/core/utils/file_export';
|
|
||||||
import appEvents from 'app/core/app_events';
|
|
||||||
import { DashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
|
||||||
import { CoreEvents } from 'app/types';
|
|
||||||
|
|
||||||
export class ExportDataModalCtrl {
|
|
||||||
private data: any;
|
|
||||||
private panel: string;
|
|
||||||
asRows = true;
|
|
||||||
dateTimeFormat = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
||||||
excel = false;
|
|
||||||
|
|
||||||
/** @ngInject */
|
|
||||||
constructor(private dashboardSrv: DashboardSrv) {}
|
|
||||||
|
|
||||||
export() {
|
|
||||||
const timezone = this.dashboardSrv.getCurrent().timezone;
|
|
||||||
const options = {
|
|
||||||
excel: this.excel,
|
|
||||||
dateTimeFormat: this.dateTimeFormat,
|
|
||||||
timezone,
|
|
||||||
};
|
|
||||||
if (this.panel === 'table') {
|
|
||||||
fileExport.exportTableDataToCsv(this.data, this.excel);
|
|
||||||
} else {
|
|
||||||
if (this.asRows) {
|
|
||||||
fileExport.exportSeriesListToCsv(this.data, options);
|
|
||||||
} else {
|
|
||||||
fileExport.exportSeriesListToCsvColumns(this.data, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
dismiss() {
|
|
||||||
appEvents.emit(CoreEvents.hideModal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function exportDataModal() {
|
|
||||||
return {
|
|
||||||
restrict: 'E',
|
|
||||||
templateUrl: 'public/app/features/dashboard/components/ExportDataModal/template.html',
|
|
||||||
controller: ExportDataModalCtrl,
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
scope: {
|
|
||||||
panel: '<',
|
|
||||||
data: '<', // The difference to '=' is that the bound properties are not watched
|
|
||||||
},
|
|
||||||
bindToController: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
angular.module('grafana.directives').directive('exportDataModal', exportDataModal);
|
|
@ -1 +0,0 @@
|
|||||||
export { ExportDataModalCtrl } from './ExportDataModalCtrl';
|
|
@ -1,36 +0,0 @@
|
|||||||
<div class="modal-body">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h2 class="modal-header-title">
|
|
||||||
Export CSV
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<a class="modal-header-close" ng-click="ctrl.dismiss();">
|
|
||||||
<i class="fa fa-remove"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="p-t-2">
|
|
||||||
<div class="gf-form" ng-hide="ctrl.panel === 'table'">
|
|
||||||
<label class="gf-form-label width-10">Mode</label>
|
|
||||||
<div class="gf-form-select-wrapper">
|
|
||||||
<select class="gf-form-input" ng-model="ctrl.asRows" ng-options="f.value as f.text for f in [{text: 'Series as rows', value: true}, {text: 'Series as columns', value: false}]">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form" ng-hide="ctrl.panel === 'table'">
|
|
||||||
<label class="gf-form-label width-10">Date Time Format</label>
|
|
||||||
<input type="text" class="gf-form-input" ng-model="ctrl.dateTimeFormat">
|
|
||||||
</div>
|
|
||||||
<gf-form-switch class="gf-form"
|
|
||||||
label="Excel CSV Dialect" label-class="width-10" switch-class="max-width-6"
|
|
||||||
checked="ctrl.excel">
|
|
||||||
</gf-form-switch>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-button-row text-center">
|
|
||||||
<a class="btn btn-primary" ng-click="ctrl.export();">Export</a>
|
|
||||||
<a class="btn-text" ng-click="ctrl.dismiss();">Cancel</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -7,7 +7,6 @@ import './services/DashboardSrv';
|
|||||||
import './components/DashLinks';
|
import './components/DashLinks';
|
||||||
import './components/DashExportModal';
|
import './components/DashExportModal';
|
||||||
import './components/DashNav';
|
import './components/DashNav';
|
||||||
import './components/ExportDataModal';
|
|
||||||
import './components/VersionHistory';
|
import './components/VersionHistory';
|
||||||
import './components/DashboardSettings';
|
import './components/DashboardSettings';
|
||||||
import './components/SubMenu';
|
import './components/SubMenu';
|
||||||
|
@ -27,6 +27,12 @@ describe('getPanelMenu', () => {
|
|||||||
"shortcut": "p s",
|
"shortcut": "p s",
|
||||||
"text": "Share",
|
"text": "Share",
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"iconClassName": "fa fa-fw fa-info-circle",
|
||||||
|
"onClick": [Function],
|
||||||
|
"shortcut": "p i",
|
||||||
|
"text": "Inspect",
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"iconClassName": "fa fa-fw fa-cube",
|
"iconClassName": "fa fa-fw fa-cube",
|
||||||
"onClick": [Function],
|
"onClick": [Function],
|
||||||
|
@ -136,14 +136,12 @@ export function getPanelMenu(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.featureToggles.inspect) {
|
menu.push({
|
||||||
menu.push({
|
text: 'Inspect',
|
||||||
text: 'Inspect',
|
iconClassName: 'fa fa-fw fa-info-circle',
|
||||||
iconClassName: 'fa fa-fw fa-info-circle',
|
onClick: onInspectPanel,
|
||||||
onClick: onInspectPanel,
|
shortcut: 'p i',
|
||||||
shortcut: 'p i',
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.featureToggles.newEdit) {
|
if (config.featureToggles.newEdit) {
|
||||||
menu.push({
|
menu.push({
|
||||||
|
@ -178,7 +178,6 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onInitPanelActions(actions: any[]) {
|
onInitPanelActions(actions: any[]) {
|
||||||
actions.push({ text: 'Export CSV', click: 'ctrl.exportCsv()' });
|
|
||||||
actions.push({ text: 'Toggle legend', click: 'ctrl.toggleLegend()', shortcut: 'p l' });
|
actions.push({ text: 'Toggle legend', click: 'ctrl.toggleLegend()', shortcut: 'p l' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,18 +338,6 @@ class GraphCtrl extends MetricsPanelCtrl {
|
|||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
exportCsv() {
|
|
||||||
const scope = this.$scope.$new(true);
|
|
||||||
scope.seriesList = this.seriesList
|
|
||||||
.filter(series => !this.panel.legend.hideEmpty || !series.allIsNull)
|
|
||||||
.filter(series => !this.panel.legend.hideZero || !series.allIsZero);
|
|
||||||
this.publishAppEvent(CoreEvents.showModal, {
|
|
||||||
templateHtml: '<export-data-modal data="seriesList"></export-data-modal>',
|
|
||||||
scope,
|
|
||||||
modalClass: 'modal--narrow',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onContextMenuClose = () => {
|
onContextMenuClose = () => {
|
||||||
this.contextMenuCtrl.toggleMenu();
|
this.contextMenuCtrl.toggleMenu();
|
||||||
};
|
};
|
||||||
|
@ -143,49 +143,5 @@ describe('GraphCtrl', () => {
|
|||||||
// allIsNull / allIsZero are set by getFlotPairs
|
// allIsNull / allIsZero are set by getFlotPairs
|
||||||
ctx.ctrl.seriesList.forEach((series: TimeSeries) => series.getFlotPairs(''));
|
ctx.ctrl.seriesList.forEach((series: TimeSeries) => series.getFlotPairs(''));
|
||||||
});
|
});
|
||||||
|
|
||||||
const thenExportYieldedNSeries = (n: number) => {
|
|
||||||
expect(appEventMock.mock.calls.length).toBe(1);
|
|
||||||
const eventPayload = appEventMock.mock.calls[0][1];
|
|
||||||
expect(eventPayload.scope.seriesList).toHaveLength(n);
|
|
||||||
};
|
|
||||||
|
|
||||||
const thenExportDidNotYieldSeriesName = (unexpectedName: string) => {
|
|
||||||
expect(appEventMock.mock.calls.length).toBe(1);
|
|
||||||
const eventPayload = appEventMock.mock.calls[0][1];
|
|
||||||
expect(
|
|
||||||
eventPayload.scope.seriesList.filter((series: TimeSeries) => series.label === unexpectedName)
|
|
||||||
).toHaveLength(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should not ignore anything if not asked to', () => {
|
|
||||||
ctx.ctrl.exportCsv();
|
|
||||||
thenExportYieldedNSeries(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore all-null series when asked to', () => {
|
|
||||||
ctx.ctrl.panel.legend.hideEmpty = true;
|
|
||||||
ctx.ctrl.exportCsv();
|
|
||||||
thenExportYieldedNSeries(2);
|
|
||||||
thenExportDidNotYieldSeriesName('test.nulls');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore all-zero series when asked to', () => {
|
|
||||||
ctx.ctrl.panel.legend.hideZero = true;
|
|
||||||
ctx.ctrl.exportCsv();
|
|
||||||
// impl treats all-null series as all-zero as well
|
|
||||||
thenExportYieldedNSeries(1);
|
|
||||||
thenExportDidNotYieldSeriesName('test.zeros');
|
|
||||||
thenExportDidNotYieldSeriesName('test.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore both when asked to', () => {
|
|
||||||
ctx.ctrl.panel.legend.hideZero = true;
|
|
||||||
ctx.ctrl.panel.legend.hideEmpty = true;
|
|
||||||
ctx.ctrl.exportCsv();
|
|
||||||
thenExportYieldedNSeries(1);
|
|
||||||
thenExportDidNotYieldSeriesName('test.zeros');
|
|
||||||
thenExportDidNotYieldSeriesName('test.empty');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,6 @@ import { columnOptionsTab } from './column_options';
|
|||||||
import { TableRenderer } from './renderer';
|
import { TableRenderer } from './renderer';
|
||||||
import { isTableData, PanelEvents, PanelPlugin } from '@grafana/data';
|
import { isTableData, PanelEvents, PanelPlugin } from '@grafana/data';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { CoreEvents } from 'app/types';
|
|
||||||
import { dispatch } from 'app/store/store';
|
import { dispatch } from 'app/store/store';
|
||||||
import { applyFilterFromTable } from 'app/features/variables/adhoc/actions';
|
import { applyFilterFromTable } from 'app/features/variables/adhoc/actions';
|
||||||
|
|
||||||
@ -76,7 +75,6 @@ export class TablePanelCtrl extends MetricsPanelCtrl {
|
|||||||
this.events.on(PanelEvents.dataReceived, this.onDataReceived.bind(this));
|
this.events.on(PanelEvents.dataReceived, this.onDataReceived.bind(this));
|
||||||
this.events.on(PanelEvents.dataSnapshotLoad, this.onDataReceived.bind(this));
|
this.events.on(PanelEvents.dataSnapshotLoad, this.onDataReceived.bind(this));
|
||||||
this.events.on(PanelEvents.editModeInitialized, this.onInitEditMode.bind(this));
|
this.events.on(PanelEvents.editModeInitialized, this.onInitEditMode.bind(this));
|
||||||
this.events.on(PanelEvents.initPanelActions, this.onInitPanelActions.bind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onInitEditMode() {
|
onInitEditMode() {
|
||||||
@ -84,10 +82,6 @@ export class TablePanelCtrl extends MetricsPanelCtrl {
|
|||||||
this.addEditorTab('Column Styles', columnOptionsTab, 3);
|
this.addEditorTab('Column Styles', columnOptionsTab, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
onInitPanelActions(actions: any[]) {
|
|
||||||
actions.push({ text: 'Export CSV', click: 'ctrl.exportCsv()' });
|
|
||||||
}
|
|
||||||
|
|
||||||
issueQueries(datasource: any) {
|
issueQueries(datasource: any) {
|
||||||
this.pageIndex = 0;
|
this.pageIndex = 0;
|
||||||
|
|
||||||
@ -167,17 +161,6 @@ export class TablePanelCtrl extends MetricsPanelCtrl {
|
|||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
exportCsv() {
|
|
||||||
const scope = this.$scope.$new(true);
|
|
||||||
scope.tableData = this.renderer.render_values();
|
|
||||||
scope.panel = 'table';
|
|
||||||
this.publishAppEvent(CoreEvents.showModal, {
|
|
||||||
templateHtml: '<export-data-modal panel="panel" data="tableData"></export-data-modal>',
|
|
||||||
scope,
|
|
||||||
modalClass: 'modal--narrow',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
link(scope: any, elem: JQuery, attrs: any, ctrl: TablePanelCtrl) {
|
link(scope: any, elem: JQuery, attrs: any, ctrl: TablePanelCtrl) {
|
||||||
let data: any;
|
let data: any;
|
||||||
const panel = ctrl.panel;
|
const panel = ctrl.panel;
|
||||||
|
Loading…
Reference in New Issue
Block a user