Commit ca8df679 by Torkel Ödegaard

feat(import): things are starting to work

parent 0d3e06e6
{
"url": "https://floobits.com/raintank/grafana"
}
\ No newline at end of file
#*
*.o
*.pyc
*.pyo
*~
extern/
node_modules/
tmp
vendor/
\ No newline at end of file
<div class="modal-body">
<div class="modal-header">
<h2 class="modal-header-title">
<i class="fa fa-upload"></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="model.step === 0">
<form class="gf-form-group">
<dash-upload on-upload="model.onUpload(dash)"></dash-upload>
</form>
<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="model.jsonText"></textarea>
</div>
<button type="button" class="btn btn-secondary" ng-click="model.loadJsonText()">
<i class="fa fa-paste"></i>
Load
</button>
<span ng-if="model.parseError" class="text-error p-l-1">
<i class="fa fa-warning"></i>
{{model.parseError}}
</span>
</div>
</div>
<div ng-if="model.step === 2">
<div class="gf-form-group">
<h3 class="section-heading p-b-1" ng-if="model.nameExists">
<i class="fa fa-warning"></i> Dashboard with same title already exists
</h3>
<h3 class="section-heading p-b-1" ng-if="!model.nameExists">
<i class="fa fa-check"></i> Dashboard title available
</h3>
<div class="gf-form-inline">
<div class="gf-form gf-form--grow">
<label class="gf-form-label">New title</label>
<input type="text" class="gf-form-input" ng-model="model.dash.title" give-focus="true" ng-change="model.titleChanged()" ng-class="{'validation-error': model.nameExists}">
<button type="button" class="btn btn-success gf-form-btn width-10" ng-click="model.saveDashboard()">
<i class="fa fa-save"></i>
<span ng-show="model.nameExists">Overwrite &amp; Open</span>
<span ng-show="!model.nameExists">Save &amp; Open</span>
</button>
</div>
</div>
</div>
</div>
<!-- <table class="filter&#45;table"> -->
<!-- <tbody> -->
<!-- <tr ng&#45;repeat="step in model.steps"> -->
<!-- <td>{{step.name}}</td> -->
<!-- <td>{{step.status}}</td> -->
<!-- <td width="1%"> -->
<!-- <i class="fa fa&#45;check" style="color: #39A039"></i> -->
<!-- </td> -->
<!-- </tr> -->
<!-- </tbody> -->
<!-- </table> -->
<div class="gf-form-button-row text-right">
<a class="btn-text" ng-click="dismiss();">Cancel</a>
</div>
</div>
</div>
///<reference path="../../../headers/common.d.ts" />
import kbn from 'app/core/utils/kbn';
import coreModule from 'app/core/core_module';
import appEvents from 'app/core/app_events';
import {WizardFlow} from 'app/core/core';
var wnd: any = window;
export class DashImporter {
step: number;
jsonText: string;
parseError: string;
nameExists: boolean;
dash: any;
dismiss: any;
constructor(private backendSrv, private $location) {
}
onUpload(dash) {
this.dash = dash;
this.dash.id = null;
this.backendSrv.saveDashboard(this.dash, {overwrite: false}).then(res => {
}).catch(err => {
if (err.data.status === 'name-exists') {
err.isHandled = true;
this.step = 2;
this.nameExists = true;
}
console.log(err);
});
}
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() {
return this.backendSrv.saveDashboard(this.dash, {overwrite: true}).then(res => {
this.$location.url('dashboard/db/' + res.slug);
this.dismiss();
});
}
loadJsonText() {
try {
this.parseError = '';
var dash = JSON.parse(this.jsonText);
this.onUpload(dash);
} catch (err) {
console.log(err);
this.parseError = err.message;
return;
}
}
run() {
this.step = 0;
appEvents.emit('show-modal', {
src: 'public/app/core/components/dash_importer/dash_importer.html',
model: this
});
}
}
......@@ -67,13 +67,10 @@
Create New
</button>
<form class="pull-left p-r-1">
<input type="file" id="dashupload" dash-upload name="dashupload" class="hide"/>
<label class="btn btn-inverse" for="dashupload">
<button class="btn btn-inverse pull-left" ng-click="ctrl.import()" ng-show="ctrl.contextSrv.isEditor">
<i class="fa fa-upload"></i>
Upload Dashboard
</label>
</form>
Import
</button>
<div class="clearfix"></div>
</div>
......
......@@ -5,6 +5,7 @@ import config from 'app/core/config';
import _ from 'lodash';
import $ from 'jquery';
import coreModule from '../../core_module';
import {DashImporter} from '../dash_importer/dash_importer';
export class SearchCtrl {
isOpen: boolean;
......@@ -151,6 +152,10 @@ export class SearchCtrl {
newDashboard() {
this.$location.url('dashboard/new');
};
import() {
new DashImporter(this.backendSrv, this.$location).run();
}
}
export function searchDirective() {
......
......@@ -11,19 +11,21 @@
</div>
<div class="modal-content">
<div ng-if="activeStep">
<table class="filter-table">
<tbody>
<tr ng-repeat="step in model.steps">
<td>{{step.name}}</td>
<td>{{step.status}}</td>
<td width="1%">
<i class="fa fa-check" style="color: #39A039"></i>
</td>
</tr>
</tbody>
</table>
</div>
<!-- <table class="filter&#45;table"> -->
<!-- <tbody> -->
<!-- <tr ng&#45;repeat="step in model.steps"> -->
<!-- <td>{{step.name}}</td> -->
<!-- <td>{{step.status}}</td> -->
<!-- <td width="1%"> -->
<!-- <i class="fa fa&#45;check" style="color: #39A039"></i> -->
<!-- </td> -->
<!-- </tr> -->
<!-- </tbody> -->
<!-- </table> -->
</div>
</div>
......
......@@ -8,40 +8,50 @@ import coreModule from 'app/core/core_module';
import appEvents from 'app/core/app_events';
export class WizardSrv {
/** @ngInject */
constructor() {
}
}
export interface WizardStep {
name: string;
type: string;
process: any;
}
export class WizardStep {
export class SelectOptionStep {
type: string;
name: string;
fn: any;
fulfill: any;
constructor() {
this.type = 'select';
}
process() {
return new Promise((fulfill, reject) => {
});
}
}
export class WizardFlow {
name: string;
steps: WizardStep[];
reject: any;
fulfill: any;
constructor(name) {
this.name = name;
this.steps = [];
}
addStep(name, stepFn) {
this.steps.push({
name: name,
fn: stepFn
});
addStep(step) {
this.steps.push(step);
}
next(index) {
var step = this.steps[0];
return step.fn().then(() => {
return step.process().then(() => {
if (this.steps.length === index+1) {
return;
}
......
......@@ -34,6 +34,7 @@ export class UtilSrv {
Promise.resolve(modal).then(function(modalEl) {
modalEl.modal('show');
options.scope.model.dismiss = options.scope.dismiss;
});
}
}
......
......@@ -3,34 +3,22 @@
import kbn from 'app/core/utils/kbn';
import coreModule from 'app/core/core_module';
import {WizardFlow} from 'app/core/core';
var wnd: any = window;
class DashboardImporter {
prepareForImport(dash) {
dash.id = null;
var wizard = new WizardFlow('Import Dashboard');
wizard.addStep("Importing dashboard", function() {
return new Promise(done => {
setTimeout(done, 2000);
});
});
return wizard.start().then(() => {
return dash;
});
}
}
var template = `
<input type="file" id="dashupload" name="dashupload" class="hide"/>
<label class="btn btn-secondary" for="dashupload">
<i class="fa fa-upload"></i>
Upload .json File
</label>
`;
/** @ngInject */
function uploadDashboardDirective(timer, alertSrv, $location) {
return {
restrict: 'A',
restrict: 'E',
template: template,
scope: {
onUpload: '&',
},
link: function(scope) {
function file_selected(evt) {
var files = evt.target.files; // FileList object
......@@ -45,15 +33,7 @@ function uploadDashboardDirective(timer, alertSrv, $location) {
return;
}
var importer = new DashboardImporter();
importer.prepareForImport(dash).then(modified => {
wnd.grafanaImportDashboard = modified;
var title = kbn.slugifyForUrl(dash.title);
scope.$apply(function() {
$location.path('/dashboard-import/' + title);
});
});
scope.onUpload({dash: dash});
};
};
......@@ -63,6 +43,8 @@ function uploadDashboardDirective(timer, alertSrv, $location) {
reader.readAsText(f);
}
}
var wnd: any = window;
// Check for the various File API support.
if (wnd.File && wnd.FileReader && wnd.FileList && wnd.Blob) {
// Something
......
......@@ -235,7 +235,7 @@ $paginationActiveBackground: $blue;
$state-warning-text: darken(#c09853, 10%);
$state-warning-bg: $brand-warning;
$errorText: #b94a48;
$errorText: #E84D4D;
$errorBackground: $btn-danger-bg;
$successText: #468847;
......
input[type=text].ng-dirty.ng-invalid {
}
input.validation-error,
input.ng-dirty.ng-invalid {
box-shadow: inset 0 0px 5px $red;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment