mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactoring PR #10068
This commit is contained in:
parent
cc2349f6aa
commit
90da964a14
@ -96,7 +96,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
|||||||
Children: []*dtos.NavLink{
|
Children: []*dtos.NavLink{
|
||||||
{Text: "Dashboard", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/dashboard/new"},
|
{Text: "Dashboard", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/dashboard/new"},
|
||||||
{Text: "Folder", Icon: "gicon gicon-folder-new", Url: setting.AppSubUrl + "/dashboard/new/?editview=new-folder"},
|
{Text: "Folder", Icon: "gicon gicon-folder-new", Url: setting.AppSubUrl + "/dashboard/new/?editview=new-folder"},
|
||||||
{Text: "Import", Id: "import", Icon: "gicon gicon-dashboard-import", Url: setting.AppSubUrl + "/dashboard/import"},
|
{Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "gicon gicon-dashboard-import", Url: setting.AppSubUrl + "/dashboard/import"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
|
|
||||||
<div class="modal-header">
|
|
||||||
<h2 class="modal-header-title">
|
|
||||||
<i class="gicon gicon-dashboard-import"></i>
|
|
||||||
<span class="p-l-1">Import Dashboard</span>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<a class="modal-header-close" ng-click="dismiss();">
|
|
||||||
<i class="fa fa-remove"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-content" ng-cloak>
|
|
||||||
<div ng-if="ctrl.step === 1">
|
|
||||||
|
|
||||||
<form class="gf-form-group">
|
|
||||||
<dash-upload on-upload="ctrl.onUpload(dash)"></dash-upload>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h5 class="section-heading">Grafana.com Dashboard</h5>
|
|
||||||
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<div class="gf-form">
|
|
||||||
<input type="text" class="gf-form-input" ng-model="ctrl.gnetUrl" placeholder="Paste Grafana.com dashboard url or id" ng-blur="ctrl.checkGnetDashboard()"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form" ng-if="ctrl.gnetError">
|
|
||||||
<label class="gf-form-label text-warning">
|
|
||||||
<i class="fa fa-warning"></i>
|
|
||||||
{{ctrl.gnetError}}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h5 class="section-heading">Or paste JSON</h5>
|
|
||||||
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<div class="gf-form">
|
|
||||||
<textarea rows="7" data-share-panel-url="" class="gf-form-input" ng-model="ctrl.jsonText"></textarea>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-secondary" ng-click="ctrl.loadJsonText()">
|
|
||||||
<i class="fa fa-paste"></i>
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<span ng-if="ctrl.parseError" class="text-error p-l-1">
|
|
||||||
<i class="fa fa-warning"></i>
|
|
||||||
{{ctrl.parseError}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div ng-if="ctrl.step === 2">
|
|
||||||
<div class="gf-form-group" ng-if="ctrl.dash.gnetId">
|
|
||||||
<h3 class="section-heading">
|
|
||||||
Importing Dashboard from
|
|
||||||
<a href="https://grafana.com/dashboards/{{ctrl.dash.gnetId}}" class="external-link" target="_blank">Grafana.com</a>
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label width-15">Published by</label>
|
|
||||||
<label class="gf-form-label width-15">{{ctrl.gnetInfo.orgName}}</label>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label width-15">Updated on</label>
|
|
||||||
<label class="gf-form-label width-15">{{ctrl.gnetInfo.updatedAt | date : 'yyyy-MM-dd HH:mm:ss'}}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="section-heading">
|
|
||||||
Options
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<div class="gf-form-inline">
|
|
||||||
<div class="gf-form gf-form--grow">
|
|
||||||
<label class="gf-form-label width-15">Name</label>
|
|
||||||
<input type="text" class="gf-form-input" ng-model="ctrl.dash.title" give-focus="true" ng-change="ctrl.titleChanged()" ng-class="{'validation-error': ctrl.nameExists || !ctrl.dash.title}">
|
|
||||||
<label class="gf-form-label text-success" ng-if="!ctrl.nameExists && ctrl.dash.title">
|
|
||||||
<i class="fa fa-check"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="ctrl.nameExists">
|
|
||||||
<div class="gf-form offset-width-15 gf-form--grow">
|
|
||||||
<label class="gf-form-label text-warning gf-form-label--grow">
|
|
||||||
<i class="fa fa-warning"></i>
|
|
||||||
A Dashboard with the same name already exists
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-if="!ctrl.dash.title">
|
|
||||||
<div class="gf-form offset-width-15 gf-form--grow">
|
|
||||||
<label class="gf-form-label text-warning gf-form-label--grow">
|
|
||||||
<i class="fa fa-warning"></i>
|
|
||||||
A Dashboard should have a name
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div ng-repeat="input in ctrl.inputs">
|
|
||||||
<div class="gf-form">
|
|
||||||
<label class="gf-form-label width-15">
|
|
||||||
{{input.label}}
|
|
||||||
<info-popover mode="right-normal">
|
|
||||||
{{input.info}}
|
|
||||||
</info-popover>
|
|
||||||
</label>
|
|
||||||
<!-- Data source input -->
|
|
||||||
<div class="gf-form-select-wrapper" style="width: 100%" ng-if="input.type === 'datasource'">
|
|
||||||
<select class="gf-form-input" ng-model="input.value" ng-options="v.value as v.text for v in input.options" ng-change="ctrl.inputValueChanged()">
|
|
||||||
<option value="" ng-hide="input.value">{{input.info}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<!-- Constant input -->
|
|
||||||
<input ng-if="input.type === 'constant'" type="text" class="gf-form-input" ng-model="input.value" placeholder="{{input.default}}" ng-change="ctrl.inputValueChanged()">
|
|
||||||
<label class="gf-form-label text-success" ng-show="input.value">
|
|
||||||
<i class="fa fa-check"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-button-row">
|
|
||||||
<button type="button" class="btn gf-form-btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
|
||||||
<i class="fa fa-save"></i> Import
|
|
||||||
</button>
|
|
||||||
<button type="button" class="btn gf-form-btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
|
||||||
<i class="fa fa-save"></i> Import (Overwrite)
|
|
||||||
</button>
|
|
||||||
<a class="btn btn-link" ng-click="dismiss()">Cancel</a>
|
|
||||||
<a class="btn btn-link" ng-click="ctrl.back()">Back</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
|||||||
///<reference path="../../../headers/common.d.ts" />
|
|
||||||
|
|
||||||
import coreModule from 'app/core/core_module';
|
|
||||||
import config from 'app/core/config';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
export class DashImportCtrl {
|
|
||||||
step: number;
|
|
||||||
jsonText: string;
|
|
||||||
parseError: string;
|
|
||||||
nameExists: boolean;
|
|
||||||
dash: any;
|
|
||||||
inputs: any[];
|
|
||||||
inputsValid: boolean;
|
|
||||||
gnetUrl: string;
|
|
||||||
gnetError: string;
|
|
||||||
gnetInfo: any;
|
|
||||||
|
|
||||||
/** @ngInject */
|
|
||||||
constructor(private backendSrv, private $location, private $scope, $routeParams) {
|
|
||||||
this.step = 1;
|
|
||||||
this.nameExists = false;
|
|
||||||
|
|
||||||
// check gnetId in url
|
|
||||||
if ($routeParams.gnetId) {
|
|
||||||
this.gnetUrl = $routeParams.gnetId ;
|
|
||||||
this.checkGnetDashboard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onUpload(dash) {
|
|
||||||
this.dash = dash;
|
|
||||||
this.dash.id = null;
|
|
||||||
this.step = 2;
|
|
||||||
this.inputs = [];
|
|
||||||
|
|
||||||
if (this.dash.__inputs) {
|
|
||||||
for (let input of this.dash.__inputs) {
|
|
||||||
var inputModel = {
|
|
||||||
name: input.name,
|
|
||||||
label: input.label,
|
|
||||||
info: input.description,
|
|
||||||
value: input.value,
|
|
||||||
type: input.type,
|
|
||||||
pluginId: input.pluginId,
|
|
||||||
options: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (input.type === 'datasource') {
|
|
||||||
this.setDatasourceOptions(input, inputModel);
|
|
||||||
} else if (!inputModel.info) {
|
|
||||||
inputModel.info = 'Specify a string constant';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inputs.push(inputModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inputsValid = this.inputs.length === 0;
|
|
||||||
this.titleChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDatasourceOptions(input, inputModel) {
|
|
||||||
var sources = _.filter(config.datasources, val => {
|
|
||||||
return val.type === input.pluginId;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (sources.length === 0) {
|
|
||||||
inputModel.info = "No data sources of type " + input.pluginName + " found";
|
|
||||||
} else if (!inputModel.info) {
|
|
||||||
inputModel.info = "Select a " + input.pluginName + " data source";
|
|
||||||
}
|
|
||||||
|
|
||||||
inputModel.options = sources.map(val => {
|
|
||||||
return {text: val.name, value: val.name};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
inputValueChanged() {
|
|
||||||
this.inputsValid = true;
|
|
||||||
for (let input of this.inputs) {
|
|
||||||
if (!input.value) {
|
|
||||||
this.inputsValid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
titleChanged() {
|
|
||||||
this.backendSrv.search({query: this.dash.title}).then(res => {
|
|
||||||
this.nameExists = false;
|
|
||||||
for (let hit of res) {
|
|
||||||
if (this.dash.title === hit.title) {
|
|
||||||
this.nameExists = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
saveDashboard() {
|
|
||||||
var inputs = this.inputs.map(input => {
|
|
||||||
return {
|
|
||||||
name: input.name,
|
|
||||||
type: input.type,
|
|
||||||
pluginId: input.pluginId,
|
|
||||||
value: input.value
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.backendSrv.post('api/dashboards/import', {
|
|
||||||
dashboard: this.dash,
|
|
||||||
overwrite: true,
|
|
||||||
inputs: inputs
|
|
||||||
}).then(res => {
|
|
||||||
this.$location.url('dashboard/' + res.importedUri);
|
|
||||||
this.$scope.dismiss();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadJsonText() {
|
|
||||||
try {
|
|
||||||
this.parseError = '';
|
|
||||||
var dash = JSON.parse(this.jsonText);
|
|
||||||
this.onUpload(dash);
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
this.parseError = err.message;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkGnetDashboard() {
|
|
||||||
this.gnetError = '';
|
|
||||||
|
|
||||||
var match = /(^\d+$)|dashboards\/(\d+)/.exec(this.gnetUrl);
|
|
||||||
var dashboardId;
|
|
||||||
|
|
||||||
if (match && match[1]) {
|
|
||||||
dashboardId = match[1];
|
|
||||||
} else if (match && match[2]) {
|
|
||||||
dashboardId = match[2];
|
|
||||||
} else {
|
|
||||||
this.gnetError = 'Could not find dashboard';
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.backendSrv.get('api/gnet/dashboards/' + dashboardId).then(res => {
|
|
||||||
this.gnetInfo = res;
|
|
||||||
// store reference to grafana.com
|
|
||||||
res.json.gnetId = res.id;
|
|
||||||
this.onUpload(res.json);
|
|
||||||
}).catch(err => {
|
|
||||||
err.isHandled = true;
|
|
||||||
this.gnetError = err.data.message || err;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
back() {
|
|
||||||
this.gnetUrl = '';
|
|
||||||
this.step = 1;
|
|
||||||
this.gnetError = '';
|
|
||||||
this.gnetInfo = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function dashImportDirective() {
|
|
||||||
return {
|
|
||||||
restrict: 'E',
|
|
||||||
templateUrl: 'public/app/features/dashboard/import/dash_import.html',
|
|
||||||
controller: DashImportCtrl,
|
|
||||||
bindToController: true,
|
|
||||||
controllerAs: 'ctrl',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
coreModule.directive('dashImport', dashImportDirective);
|
|
@ -3,7 +3,8 @@
|
|||||||
<div class="page-container page-body" ng-cloak>
|
<div class="page-container page-body" ng-cloak>
|
||||||
<div ng-if="ctrl.step === 1">
|
<div ng-if="ctrl.step === 1">
|
||||||
|
|
||||||
<form class="gf-form-group">
|
<form class="page-action-bar">
|
||||||
|
<div class="page-action-bar__spacer"></div>
|
||||||
<dash-upload on-upload="ctrl.onUpload(dash)"></dash-upload>
|
<dash-upload on-upload="ctrl.onUpload(dash)"></dash-upload>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@ -112,10 +113,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-button-row">
|
<div class="gf-form-button-row">
|
||||||
<button type="button" class="btn gf-form-btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
<button type="button" class="btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
||||||
<i class="fa fa-save"></i> Import
|
<i class="fa fa-save"></i> Import
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn gf-form-btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
<button type="button" class="btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
|
||||||
<i class="fa fa-save"></i> Import (Overwrite)
|
<i class="fa fa-save"></i> Import (Overwrite)
|
||||||
</button>
|
</button>
|
||||||
<a class="btn btn-link" ng-click="ctrl.back()">Cancel</a>
|
<a class="btn btn-link" ng-click="ctrl.back()">Cancel</a>
|
||||||
|
@ -4,7 +4,7 @@ import coreModule from 'app/core/core_module';
|
|||||||
|
|
||||||
var template = `
|
var template = `
|
||||||
<input type="file" id="dashupload" name="dashupload" class="hide"/>
|
<input type="file" id="dashupload" name="dashupload" class="hide"/>
|
||||||
<label class="btn btn-secondary" for="dashupload">
|
<label class="btn btn-success" for="dashupload">
|
||||||
<i class="fa fa-upload"></i>
|
<i class="fa fa-upload"></i>
|
||||||
Upload .json File
|
Upload .json File
|
||||||
</label>
|
</label>
|
||||||
|
Loading…
Reference in New Issue
Block a user