Commit f2e6d440 by Rashid Khan

drag and drop panels, lots of visual tweaks

parent 3cd11770
......@@ -234,7 +234,8 @@ module.exports = function (grunt) {
'angular-strap',
'directives/all',
'jquery.flot.pie',
'angular-sanitize'
'angular-sanitize',
'angular-dragdrop'
]
}
];
......
......@@ -11,6 +11,7 @@ define([
'bootstrap',
'angular-sanitize',
'angular-strap',
'angular-dragdrop',
'extend-jquery'
],
function (angular, $, _, appLevelRequire) {
......@@ -83,7 +84,8 @@ function (angular, $, _, appLevelRequire) {
'elasticjs.service',
'$strap.directives',
'ngSanitize',
'kibana',
'ngDragDrop',
'kibana'
];
_.each('controllers directives factories services filters'.split(' '),
......
......@@ -15,6 +15,7 @@ require.config({
filesaver: '../vendor/filesaver',
angular: '../vendor/angular/angular',
'angular-dragdrop': '../vendor/angular/angular-dragdrop',
'angular-strap': '../vendor/angular/angular-strap',
'angular-sanitize': '../vendor/angular/angular-sanitize',
timepicker: '../vendor/angular/timepicker',
......@@ -25,6 +26,7 @@ require.config({
bootstrap: '../vendor/bootstrap/bootstrap',
jquery: '../vendor/jquery/jquery-1.8.0',
'jquery-ui': '../vendor/jquery/jquery-ui-1.10.3',
'extend-jquery': 'components/extend-jquery',
......@@ -61,6 +63,7 @@ require.config({
},
// simple dependency declaration
'jquery-ui': ['jquery'],
'jquery.flot': ['jquery'],
'jquery.flot.pie': ['jquery', 'jquery.flot'],
'jquery.flot.selection':['jquery', 'jquery.flot'],
......@@ -70,6 +73,7 @@ require.config({
'angular-sanitize': ['angular'],
'angular-cookies': ['angular'],
'angular-dragdrop': ['jquery','jquery-ui','angular'],
'angular-loader': ['angular'],
'angular-mocks': ['angular'],
'angular-resource': ['angular'],
......
define([
'./dash',
'./dashLoader',
'./row'
'./row',
], function () {});
\ No newline at end of file
......@@ -2,7 +2,6 @@ define([
'angular',
'config',
'underscore',
'services/all'
],
function (angular, config, _) {
......@@ -10,11 +9,22 @@ function (angular, config, _) {
var module = angular.module('kibana.controllers');
module.controller('DashCtrl', function($scope, $route, ejsResource, fields, dashboard, alertSrv) {
module.controller('DashCtrl', function(
$scope, $route, ejsResource, fields, dashboard, alertSrv, panelMove) {
$scope.editor = {
index: 0
};
// For moving stuff around the dashboard. Needs better names
$scope.panelMove = panelMove;
$scope.panelMoveDrop = panelMove.onDrop;
$scope.panelMoveStart = panelMove.onStart;
$scope.panelMoveStop = panelMove.onStop;
$scope.panelMoveOver = panelMove.onOver;
$scope.panelMoveOut = panelMove.onOut;
$scope.init = function() {
$scope.config = config;
// Make underscore.js available to views
......@@ -30,6 +40,14 @@ function (angular, config, _) {
$scope.ejs = ejsResource(config.elasticsearch);
};
$scope.isPanel = function(obj) {
if(!_.isNull(obj) && !_.isUndefined(obj) && !_.isUndefined(obj.type)) {
return true;
} else {
return false;
}
};
$scope.add_row = function(dash,row) {
dash.rows.push(row);
};
......
......@@ -38,7 +38,10 @@ function (angular, app, _) {
};
$scope.rowSpan = function(row) {
return _.reduce(_.pluck(row.panels,'span'), function(p,v) {
var panels = _.filter(row.panels, function(p) {
return $scope.isPanel(p);
});
return _.reduce(_.pluck(panels,'span'), function(p,v) {
return p+v;
},0);
};
......
......@@ -7,36 +7,47 @@ function (angular) {
angular
.module('kibana.directives')
.directive('kibanaPanel', function($compile) {
var container = '<div class="panelCont"></div>';
var editorTemplate =
'<i class="icon-spinner small icon-spin icon-large panel-loading"' +
'ng-show="panelMeta.loading == true && !panel.title"></i>' +
'<span class="panelextra">' +
'<div class="row-fluid panel-extra"><div class="panel-extra-container">' +
'<span ng-repeat="task in panelMeta.modals" ng-show="task.show">' +
'<span bs-modal="task.partial" class="pointer"><i ' +
'bs-tooltip="task.description" ng-class="task.icon" class="pointer"></i></span>'+
' / </span>' +
'<span class="extra row-button " ng-show="panel.editable != false">' +
'<span class="row-text pointer" bs-tooltip="\'Drag title to move\'" data-drag=true '+
'data-jqyoui-options="{revert: \'invalid\',helper:\'clone\'}"'+
' jqyoui-draggable="'+
'{'+
'animate:false,'+
'index:{{$index}},'+
'onStart:\'panelMoveStart\','+
'onStop:\'panelMoveStop\''+
'}" ng-model="row.panels">{{panel.type}}</span>'+
'</span>' +
'<span class="extra row-button" ng-show="panel.editable != false">' +
'<span confirm-click="row.panels = _.without(row.panels,panel)" '+
'confirmation="Are you sure you want to remove this {{panel.type}} panel?" class="pointer">'+
'<i class="icon-remove pointer" bs-tooltip="\'Remove\'"></i></span>'+
'</span>' +
'<span ng-show="panel.editable != false">' +
'<span class="row-button extra" ng-show="panel.editable != false">' +
'<span bs-modal="\'app/partials/paneleditor.html\'" class="pointer">'+
'<i class="icon-cog pointer" bs-tooltip="\'Configure\'"></i></span>'+
' / </span>' +
'</span>' +
'<span ng-show="panel.editable != false">' +
'<span confirm-click="row.panels = _.without(row.panels,panel)" '+
'confirmation="Are you sure you want to remove this {{panel.type}} panel?" class="pointer">'+
'<i class="icon-remove-sign pointer" bs-tooltip="\'Remove\'"></i></span>'+
' / </span>' +
'<span ng-repeat="task in panelMeta.modals" class="row-button extra" ng-show="task.show">' +
'<span bs-modal="task.partial" class="pointer"><i ' +
'bs-tooltip="task.description" ng-class="task.icon" class="pointer"></i></span>'+
'</span>' +
'<span class="small strong">{{panel.type}}</span> ' +
'</span>' +
'<span class="row-button row-text panel-title" ng-show="panel.title">' +
'{{panel.title}}&nbsp' +
'<i class="icon-spinner smaller icon-spin icon-large"' +
'ng-show="panelMeta.loading == true && panel.title"></i>' +
'</span>'+
'<h4 ng-show="panel.title" style="margin:0px;">' +
'{{panel.title}}&nbsp' +
'<i class="icon-spinner smaller icon-spin icon-large"' +
'ng-show="panelMeta.loading == true && panel.title"></i>' +
'</h4>';
'</div></div>';
return {
restrict: 'E',
link: function($scope, elem, attr) {
......@@ -46,6 +57,7 @@ function (angular) {
// compile the module and uncloack. We're done
function loadModule($module) {
$module.appendTo(elem);
elem.wrap(container);
/* jshint indent:false */
$compile(elem.contents())($scope);
elem.removeClass("ng-cloak");
......
<div ng-controller='query' ng-init="init()" class="query-panel">
<label class="small">{{panel.label}}</label>
<div ng-repeat="id in (unPinnedQueries = (querySrv.ids|pinnedQuery:false))" ng-class="{'short-query': unPinnedQueries.length>1}">
<form class="form-search" style="position:relative;margin-bottom:5px;" ng-submit="refresh()">
<span class="begin-query">
......
......@@ -3,7 +3,6 @@
## query
### Parameters
* label :: The label to stick over the field
* query :: A string or an array of querys. String if multi is off, array if it is on
This should be fixed, it should always be an array even if its only
one element
......@@ -29,7 +28,6 @@ define([
// Set and populate defaults
var _d = {
label : "Search",
query : "*",
pinned : true,
history : [],
......
......@@ -243,7 +243,11 @@ function (angular, app, _, kbn, moment) {
// Sort the data
$scope.data = _.sortBy($scope.data, function(v){
return v.sort[0];
if(!_.isUndefined(v.sort)) {
return v.sort[0];
} else {
return 0;
}
});
// Reverse if needed
......
......@@ -8,16 +8,15 @@
<div ng-switch-when="absolute" >
<div class="timepicker-block">
<form class="nomargin">
<label><small>From</small></label>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
</form>
</div>
<div class="timepicker-block" style="margin-left:10px">
to
<div class="timepicker-block" style="margin-left:5px">
<form class="nomargin">
<label style="margin-left:5px"><small>To (<a ng-click="to_now()">now</a>)</small></label>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.to.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.to.time" bs-timepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.to.time" bs-timepicker> <!--(<a ng-click="to_now()">now</a>)-->
</form>
</div>
<div class="timepicker-block">
......@@ -29,14 +28,12 @@
<div ng-switch-when="since">
<div class="timepicker-block">
<form class="nomargin">
<label><small>Since</small></label>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
</form>
</div>
<div class="timepicker-block" style="margin-left:10px">
<div class="timepicker-block" style="margin-left:5px">
<form class="nomargin">
<label><small><br></small></label>
<button class="btn" ng-click="time_apply()" ><i class="icon-ok"></i></button>
</form>
</div>
......@@ -44,7 +41,6 @@
<div ng-switch-when="relative">
<div class="timepicker-block">
<form class="nomargin input-append">
<label><small>The last</small></label>
<button class="btn btn" ng-repeat='timespan in panel.time_options' ng-class="{'btn-success': (panel.timespan == timespan)}" ng-click="set_timespan(timespan)">{{timespan}}</button>
<!--<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select>-->
</form>
......
<div class="row-fluid container" style="margin-top:10px">
<style>
.row-panel-filler {
opacity: 0;
}
.row-panel-filler:hover {
opacity: 0.3;
}
.row-name {
}
</style>
<div class="row-fluid container" style="margin-top:10px; width:98%">
<!-- Rows -->
<div class="row-fluid kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboard.current.rows" ng-style="row_style(row)">
<div class="row-control">
<div class="row-fluid" style="padding:0px;margin:0px;position:relative;">
<div class="row-close" ng-show="row.collapse">
<span bs-tooltip="'Show row'" data-placement="right" ng-class='{pointer:row.collapsable}' class="row-name label label-inverse" ng-click="toggle_row(row)">{{row.title || 'Row '+$index}}</span>
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer editlink" bs-modal="'app/partials/roweditor.html'"></i>
<div class="clear"></div>
<div class="row-close span12" ng-show="row.collapse" data-placement="bottom" >
<span class="row-button" ng-click="toggle_row(row)" ng-show="row.collapsable}">
<i bs-tooltip="'Expand row'" data-placement="right" ng-show="row.editable" class="icon-expand pointer" ></i>
</span>
<span class="row-button" bs-modal="'app/partials/roweditor.html'" class="pointer">
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
</span>
<span class="row-button row-text">{{row.title || 'Row '+$index}}</span>
</div>
<div class="row-open" ng-show="!row.collapse">
<i bs-tooltip="'Hide row'" data-placement="right" ng-class='{pointer:row.collapsable}' class="icon-chevron-up" ng-click="toggle_row(row)"></i><br>
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer editlink" bs-modal="'app/partials/roweditor.html'"></i>
<div style="text-align:left" class="row-open" ng-show="!row.collapse">
<span>
<i bs-tooltip="'Hide row'" data-placement="right" ng-show="row.collapsable" class="icon-collapse-top" ng-click="toggle_row(row)"></i>
</span><br>
<span bs-modal="'app/partials/roweditor.html'">
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
</span><br>
<span bs-modal="'app/partials/roweditor.html'">
<i ng-click="editor.index = 2" bs-tooltip="'Add panel'" data-placement="right" ng-show="row.editable" class="icon-plus pointer"></i>
</span>
</div>
</div>
<div class="row-fluid" style="padding-top:0px" ng-hide="row.collapse">
<!-- Panels -->
<div ng-repeat="(name, panel) in row.panels" ng-hide="panel.span == 0 || panel.hide" class="span{{panel.span}} panel" style="min-height:{{row.height}}; position:relative">
<div ng-repeat="(name, panel) in row.panels|filter:isPanel" ng-hide="panel.span == 0 || panel.hide" class="span{{panel.span}} panel nospace" style="min-height:{{row.height}}; position:relative" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:$index,onDrop:'panelMoveDrop',onOver:'panelMoveOver(true)',onOut:'panelMoveOut'}">
<!-- Error Panel -->
<div class="row-fluid">
<div class="span12 alert alert-error panel-error" ng-hide="!panel.error">
......@@ -39,16 +40,13 @@
</div>
</div>
<!-- Content Panel -->
<div class="row-fluid">
<div class="row-fluid" style="position:relative" ng-class="{'dragInProgress':dashboard.panelDragging}" >
<kibana-panel type="panel.type" ng-cloak></kibana-panel>
</div>
</div>
<div ng-hide="(12-rowSpan(row)) < 1 || !dashboard.current.panel_hints" ng-class="'span'+(12-rowSpan(row))" class="bordered row-panel-filler" style="height:{{row.height}}; position:relative; border: 1px dashed; border-radius: 10px;text-align:center;vertical-align:middle;">
<span class="pointer addLink" ng-click="editor.index=2" bs-modal="'app/partials/roweditor.html'">
Add a panel here<br>
<i style="font-size:20px" class="icon-plus-sign" ></i>
</span>
</div>
<div ng-hide="(12-rowSpan(row)) < 1 || !dashboard.current.panel_hints" class="panel span{{(12-rowSpan(row))}}" ng-class="{'dragInProgress':dashboard.panelDragging}" style="height:{{row.height}};" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:row.panels.length,onDrop:'panelMoveDrop({{(12-rowSpan(row))}})',onOver:'panelMoveOver(false)',onOut:'panelMoveOut'}"></div>
</div>
</div>
</div>
......
......@@ -35,6 +35,7 @@ function (angular, _) {
self.list = _.without(self.list,_a);
}, timeout);
}
return(_a);
};
this.clear = function(alert) {
......
......@@ -5,6 +5,7 @@ define([
'./filterSrv',
'./kbnIndex',
'./querySrv',
'./timer'
'./timer',
'./panelMove'
],
function () {});
\ No newline at end of file
......@@ -406,7 +406,6 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
return false;
});
};
});
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -26,7 +26,7 @@
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="css/font-awesome.min.css">
<div ng-repeat='alert in dashAlerts.list' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
<div ng-repeat='alert in dashAlerts.list' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last" style="position:fixed">
<button type="button" class="close" ng-click="dashAlerts.clear(alert)" style="padding-right:50px">&times;</button>
<strong>{{alert.title}}</strong> <span ng-bind-html-unsafe='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
</div>
......
......@@ -10,8 +10,6 @@
color: @black;
}
.editor-title {
margin-right: 10px;
font-size: 1.7em;
......@@ -42,23 +40,35 @@
}
.kibana-row {
margin-left: 15px;
margin-bottom: 10px;
}
.row-button {
border-left: 1px solid lighten(@bodyBackground, 10%);
border-right: 1px solid darken(@bodyBackground, 10%);
padding: 2px 7px 0px 7px;
float: left;
}
.row-text {
text-transform: uppercase;
font-weight: bold;
font-size: 0.8em;
}
.row-close {
color: #bbb;
margin-left: -35px;
font-size: 9pt;
font-weight: 200;
padding-left: 35px;
padding-top:0px;
outline: 1px solid darken(@bodyBackground, 10%);
border-top: 1px solid lighten(@bodyBackground, 10%);
padding: 0px;
margin: 0px;
min-height: 24px !important;
line-height: 24px;
background: darken(@bodyBackground, 3%);
}
.row-open {
text-align: right;
color: #bbb;
left:-30px;
left:-18px;
position: absolute;
font-size: 13pt;
font-weight: 200;
......@@ -81,7 +91,7 @@
display: none !important;
}
.table tbody + tbody{
.table tbody + tbody {
border-top: 0px;
}
......@@ -98,26 +108,43 @@
z-index: 800;
}
.panel span.panelextra {
position: absolute;
z-index: 800;
display: none;
opacity: 0.7;
top:-13px;
width: 98%;
text-align:right;
.ui-draggable-dragging {
display: block;
visibility: visible;
opacity: 1;
z-index: 9999;
}
.panel span.panelextra .link {
margin-right: 5px;
.panelCont {
outline: 1px solid darken(@bodyBackground, 10%);
border-top: 1px solid lighten(@bodyBackground, 10%);
padding: 0px 10px 10px 10px;
background: darken(@bodyBackground, 3%);
margin: 0px;
}
.panel:hover span.panelextra {
display: block;
.panel-title {
border: 0px;
margin-left: -11px;
}
.panel span.panelextra .editlink:hover {
opacity: 1;
.panel div.panel-extra div.panel-extra-container {
margin-right: -11px;
}
.panel div.panel-extra {
font-size: 0.9em;
margin-bottom: 10px;
}
.panel div.panel-extra .extra {
float:right !important;
border-bottom: 1px solid lighten(@bodyBackground, 5%);
}
.dragInProgress {
background-color: darken(@bodyBackground,1%);
border: 1px solid @tableBorder;
}
.link {
......
......@@ -272,29 +272,32 @@
// -------------------------
@gridColumns: 12;
@gridColumnWidth: 60px;
@gridGutterWidth: 20px;
@gridGutterWidth: 10px;
@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
// 1200px min
@gridColumnWidth1200: 70px;
@gridGutterWidth1200: 30px;
@gridGutterWidth1200: 10px;
@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1));
// 768px-979px
@gridColumnWidth768: 42px;
@gridGutterWidth768: 20px;
@gridGutterWidth768: 10px;
@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1));
// Fluid grid
// -------------------------
@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth);
@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth);
@gridGutterWidth: 10px;
//@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth);
// 1200px min
@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200);
@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200);
@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200);
@gridGutterWidth: 10px;
//@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200);
// 768px-979px
@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768);
@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768);
@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768);
@gridGutterWidth: 10px;
//@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768);
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