Merge branch 'master' into feature/ingest
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.aws-config.json
|
||||
.ackrc
|
||||
.DS_Store
|
||||
.node_binaries
|
||||
node_modules
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"dashboarding"
|
||||
],
|
||||
"private": false,
|
||||
"version": "5.0.0-snapshot",
|
||||
"version": "5.0.0-reskin-snapshot",
|
||||
"build": {
|
||||
"number": 8467,
|
||||
"sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9"
|
||||
|
@ -82,10 +82,10 @@
|
|||
"ansicolors": "0.3.2",
|
||||
"autoprefixer": "5.1.1",
|
||||
"autoprefixer-loader": "2.0.0",
|
||||
"babel": "5.8.23",
|
||||
"babel-core": "5.8.23",
|
||||
"babel": "5.8.38",
|
||||
"babel-core": "5.8.38",
|
||||
"babel-loader": "5.3.2",
|
||||
"babel-runtime": "5.8.20",
|
||||
"babel-runtime": "5.8.38",
|
||||
"bluebird": "2.9.34",
|
||||
"boom": "2.8.0",
|
||||
"bootstrap": "3.3.6",
|
||||
|
|
|
@ -63,6 +63,7 @@ class BaseOptimizer {
|
|||
|
||||
getConfig() {
|
||||
let mapQ = this.sourceMaps ? '?sourceMap' : '';
|
||||
let mapQPre = mapQ ? mapQ + '&' : '?';
|
||||
|
||||
return {
|
||||
context: fromRoot('.'),
|
||||
|
@ -101,7 +102,7 @@ class BaseOptimizer {
|
|||
test: /\.less$/,
|
||||
loader: ExtractTextPlugin.extract(
|
||||
'style',
|
||||
`css${mapQ}!autoprefixer${mapQ ? mapQ + '&' : '?'}{ "browsers": ["last 2 versions","> 5%"] }!less${mapQ}`
|
||||
`css${mapQ}!autoprefixer${mapQPre}{ "browsers": ["last 2 versions","> 5%"] }!less${mapQPre}dumpLineNumbers=comments`
|
||||
)
|
||||
},
|
||||
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', `css${mapQ}`) },
|
||||
|
|
|
@ -3,7 +3,7 @@ import search from './server/routes/api/search';
|
|||
|
||||
module.exports = function (kibana) {
|
||||
return new kibana.Plugin({
|
||||
|
||||
id: 'kibana',
|
||||
config: function (Joi) {
|
||||
return Joi.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
|
@ -14,7 +14,9 @@ module.exports = function (kibana) {
|
|||
|
||||
uiExports: {
|
||||
app: {
|
||||
id: 'kibana',
|
||||
title: 'Kibana',
|
||||
listed: false,
|
||||
description: 'the kibana you know and love',
|
||||
//icon: 'plugins/kibana/settings/sections/about/barcode.svg',
|
||||
main: 'plugins/kibana/kibana',
|
||||
|
@ -33,9 +35,39 @@ module.exports = function (kibana) {
|
|||
return {
|
||||
kbnDefaultAppId: config.get('kibana.defaultAppId')
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
links: [
|
||||
{
|
||||
title: 'Discover',
|
||||
order: -1003,
|
||||
url: '/app/kibana#/discover',
|
||||
description: 'interactively explore your data',
|
||||
icon: 'plugins/kibana/assets/discover.svg',
|
||||
},
|
||||
{
|
||||
title: 'Visualize',
|
||||
order: -1002,
|
||||
url: '/app/kibana#/visualize',
|
||||
description: 'design data visualizations',
|
||||
icon: 'plugins/kibana/assets/visualize.svg',
|
||||
},
|
||||
{
|
||||
title: 'Dashboard',
|
||||
order: -1001,
|
||||
url: '/app/kibana#/dashboard',
|
||||
description: 'compose visualizations for much win',
|
||||
icon: 'plugins/kibana/assets/dashboard.svg',
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
order: 1000,
|
||||
url: '/app/kibana#/settings',
|
||||
description: 'define index patterns, change config, and more',
|
||||
icon: 'plugins/kibana/assets/settings.svg',
|
||||
}
|
||||
],
|
||||
injectDefaultVars(server, options) {
|
||||
return {
|
||||
kbnIndex: options.index
|
||||
|
|
4
src/plugins/kibana/public/assets/dashboard.svg
Executable file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M4 0c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm0 1c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 1c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-1.66 1a.5.5 0 0 0-.19.84l.91.91c-.02.08-.06.16-.06.25 0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1c-.09 0-.17.04-.25.06l-.91-.91a.5.5 0 0 0-.44-.16.5.5 0 0 0-.06 0zm3.16 0c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 486 B |
3
src/plugins/kibana/public/assets/discover.svg
Executable file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M4 0c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm0 1c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm2 1l-3 1-1 3 3-1 1-3zm-2 1.5c.28 0 .5.22.5.5s-.22.5-.5.5-.5-.22-.5-.5.22-.5.5-.5z" />
|
||||
</svg>
|
After Width: | Height: | Size: 293 B |
3
src/plugins/kibana/public/assets/logout.svg
Executable file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M3 0v1h4v5h-4v1h5v-7h-5zm-1 2l-2 1.5 2 1.5v-1h4v-1h-4v-1z" />
|
||||
</svg>
|
After Width: | Height: | Size: 159 B |
4
src/plugins/kibana/public/assets/search.svg
Executable file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M3.5 0c-1.93 0-3.5 1.57-3.5 3.5s1.57 3.5 3.5 3.5c.59 0 1.17-.14 1.66-.41a1 1 0 0 0 .13.13l1 1a1.02 1.02 0 1 0 1.44-1.44l-1-1a1 1 0 0 0-.16-.13c.27-.49.44-1.06.44-1.66 0-1.93-1.57-3.5-3.5-3.5zm0 1c1.39 0 2.5 1.11 2.5 2.5 0 .66-.24 1.27-.66 1.72-.01.01-.02.02-.03.03a1 1 0 0 0-.13.13c-.44.4-1.04.63-1.69.63-1.39 0-2.5-1.11-2.5-2.5s1.11-2.5 2.5-2.5z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 450 B |
4
src/plugins/kibana/public/assets/settings.svg
Executable file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M3.5 0l-.5 1.19c-.1.03-.19.08-.28.13l-1.19-.5-.72.72.5 1.19c-.05.1-.09.18-.13.28l-1.19.5v1l1.19.5c.04.1.08.18.13.28l-.5 1.19.72.72 1.19-.5c.09.04.18.09.28.13l.5 1.19h1l.5-1.19c.09-.04.19-.08.28-.13l1.19.5.72-.72-.5-1.19c.04-.09.09-.19.13-.28l1.19-.5v-1l-1.19-.5c-.03-.09-.08-.19-.13-.28l.5-1.19-.72-.72-1.19.5c-.09-.04-.19-.09-.28-.13l-.5-1.19h-1zm.5 2.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5-1.5-.67-1.5-1.5.67-1.5 1.5-1.5z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 528 B |
3
src/plugins/kibana/public/assets/visualize.svg
Executable file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
|
||||
<path d="M0 0v7h8v-1h-7v-6h-1zm5 0v5h2v-5h-2zm-3 2v3h2v-3h-2z" />
|
||||
</svg>
|
After Width: | Height: | Size: 154 B |
|
@ -1,18 +1,15 @@
|
|||
<div class="panel panel-default" ng-switch on="panel.type" ng-if="savedObj || error">
|
||||
<div class="panel-heading">
|
||||
<span class="panel-title" title="{{::savedObj.title}}">
|
||||
<i
|
||||
class="fa"
|
||||
ng-class="savedObj.vis.type.icon"
|
||||
aria-label="{{::savedObj.vis.type.title}} Icon"
|
||||
title="{{::savedObj.vis.type.title}}">
|
||||
</i>
|
||||
{{::savedObj.title}}
|
||||
</span>
|
||||
<div class="btn-group">
|
||||
<a aria-label="Edit" ng-show="chrome.getVisible() && editUrl" ng-href="{{::editUrl}}">
|
||||
<i aria-hidden="true" class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a aria-label="Move" ng-show="chrome.getVisible()" class="panel-move">
|
||||
<i aria-hidden="true" class="fa fa-arrows"></i>
|
||||
</a>
|
||||
<a aria-label="Remove" ng-show="chrome.getVisible()" ng-click="remove()">
|
||||
<i aria-hidden="true" class="fa fa-times"></i>
|
||||
</a>
|
||||
|
|
|
@ -27,7 +27,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) {
|
|||
// number of columns to render
|
||||
const COLS = 12;
|
||||
// number of pixed between each column/row
|
||||
const SPACER = 10;
|
||||
const SPACER = 0;
|
||||
// pixels used by all of the spacers (gridster puts have a spacer on the ends)
|
||||
const spacerSize = SPACER * COLS;
|
||||
|
||||
|
@ -46,7 +46,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) {
|
|||
stop: readGridsterChangeHandler
|
||||
},
|
||||
draggable: {
|
||||
handle: '.panel-heading, .panel-title',
|
||||
handle: '.panel-move, .fa-arrows',
|
||||
stop: readGridsterChangeHandler
|
||||
}
|
||||
}).data('gridster');
|
||||
|
@ -232,4 +232,3 @@ app.directive('dashboardGrid', function ($compile, Notifier) {
|
|||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,62 @@
|
|||
<div dashboard-app class="app-container dashboard-container">
|
||||
<navbar ng-show="chrome.getVisible()" name="dashboard">
|
||||
<span class="name" ng-if="dash.id" ng-bind="::dash.title" tooltip="{{::dash.title}}" tooltip-append-to-body="true"></span>
|
||||
<navbar name="dashboard-options" class="kibana-nav-options">
|
||||
<div class="kibana-nav-info">
|
||||
<span ng-show="dash.id" class="kibana-nav-info-title">
|
||||
<span ng-bind="::dash.title"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="button-group kibana-nav-actions" role="toolbar">
|
||||
<button ng-click="newDashboard()"
|
||||
aria-label="New Dashboard">
|
||||
<span>New</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Save Dashboard"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
ng-click="configTemplate.toggle('save');">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Load Saved Dashboard"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
ng-click="configTemplate.toggle('load');">
|
||||
<span>Open</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Share Dashboard"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share');">
|
||||
<span>Share</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Add Visualization"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('pickVis') }}"
|
||||
ng-class="{active: configTemplate.is('pickVis')}"
|
||||
ng-click="configTemplate.toggle('pickVis');">
|
||||
<span>Add visualization</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Options"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('options') }}"
|
||||
ng-class="{active: configTemplate.is('options')}"
|
||||
ng-click="configTemplate.toggle('options');">
|
||||
<span>Options</span>
|
||||
</button>
|
||||
<div class="chrome-actions"kbn-chrome-append-nav-controls></div>
|
||||
</div>
|
||||
</navbar>
|
||||
<config config-template="configTemplate" config-object="opts"></config>
|
||||
|
||||
<navbar ng-show="chrome.getVisible()" name="dashboard-search">
|
||||
<form name="queryInput"
|
||||
class="fill inline-form"
|
||||
ng-submit="filterResults()"
|
||||
|
@ -29,66 +84,9 @@
|
|||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div class="button-group" role="toolbar">
|
||||
<kbn-tooltip text="New Dashboard" placement="bottom" append-to-body="1">
|
||||
<button ng-click="newDashboard()" aria-label="New Dashboard"><i aria-hidden="true" class="fa fa-file-new-o"></i></button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Save Dashboard" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Save Dashboard"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
ng-click="configTemplate.toggle('save');">
|
||||
<i aria-hidden="true" class="fa fa-save"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Load Saved Dashboard" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Load Saved Dashboard"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
ng-click="configTemplate.toggle('load');">
|
||||
<i aria-hidden="true" class="fa fa-folder-open-o"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Share" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Share Dashboard"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share');">
|
||||
<i aria-hidden="true" class="fa fa-external-link"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Add Visualization" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Add Visualization"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('pickVis') }}"
|
||||
ng-class="{active: configTemplate.is('pickVis')}"
|
||||
ng-click="configTemplate.toggle('pickVis');">
|
||||
<i aria-hidden="true" class="fa fa-plus-circle"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Options" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Options"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('options') }}"
|
||||
ng-class="{active: configTemplate.is('options')}"
|
||||
ng-click="configTemplate.toggle('options');">
|
||||
<i aria-hidden="true" class="fa fa-gear"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
</div>
|
||||
<div class="button-group"></div>
|
||||
</navbar>
|
||||
|
||||
<config config-template="configTemplate" config-object="opts"></config>
|
||||
|
||||
<filter-bar state="state"></filter-bar>
|
||||
|
||||
<div ng-show="!state.panels.length" class="text-center start-screen">
|
||||
|
|
|
@ -105,7 +105,9 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
|
|||
load: require('plugins/kibana/dashboard/partials/load_dashboard.html'),
|
||||
share: require('plugins/kibana/dashboard/partials/share.html'),
|
||||
pickVis: require('plugins/kibana/dashboard/partials/pick_visualization.html'),
|
||||
options: require('plugins/kibana/dashboard/partials/options.html')
|
||||
options: require('plugins/kibana/dashboard/partials/options.html'),
|
||||
filter: require('ui/chrome/config/filter.html'),
|
||||
interval: require('ui/chrome/config/interval.html')
|
||||
});
|
||||
|
||||
$scope.refresh = _.bindKey(courier, 'fetch');
|
||||
|
@ -239,7 +241,8 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
|
|||
ui: $state.options,
|
||||
save: $scope.save,
|
||||
addVis: $scope.addVis,
|
||||
addSearch: $scope.addSearch
|
||||
addSearch: $scope.addSearch,
|
||||
timefilter: $scope.timefilter
|
||||
};
|
||||
|
||||
init();
|
||||
|
|
|
@ -33,6 +33,24 @@ dashboard-grid {
|
|||
width: 25px;
|
||||
}
|
||||
|
||||
.gs-w {
|
||||
border: 2px dashed transparent;
|
||||
|
||||
&:hover {
|
||||
border-color: @kibanaGray4;
|
||||
|
||||
dashboard-panel {
|
||||
.visualize-show-spy {
|
||||
visibility: visible;
|
||||
}
|
||||
.panel .panel-heading .btn-group {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
i.remove {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -55,15 +73,23 @@ dashboard-grid {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
border: 0 solid transparent;
|
||||
|
||||
.panel-heading {
|
||||
padding: 0px 0px 0px 5px;
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
background-color: @white;
|
||||
border: none;
|
||||
|
||||
div.btn-group {
|
||||
.btn-group {
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
@ -85,6 +111,10 @@ dashboard-grid {
|
|||
}
|
||||
}
|
||||
|
||||
.panel-move:hover {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @dashboard-panel-heading-link-color;
|
||||
border: none;
|
||||
|
@ -96,6 +126,10 @@ dashboard-grid {
|
|||
}
|
||||
}
|
||||
|
||||
.visualize-show-spy {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.load-error {
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
|
@ -119,10 +153,6 @@ dashboard-grid {
|
|||
}
|
||||
}
|
||||
|
||||
.dashboard-panel-picker > li.list-group-item {
|
||||
border-top: 0px;
|
||||
}
|
||||
|
||||
.dashboard-load {
|
||||
margin: 10px;
|
||||
.dashboard-panel-picker > .list-group-item {
|
||||
border-top: 0;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,6 @@ app.directive('discoverField', function ($compile) {
|
|||
$scope.toggle(field.name);
|
||||
if (field.display) $scope.increaseFieldCounter(field);
|
||||
|
||||
// we are now displaying the field, kill its details
|
||||
if (field.details) {
|
||||
$scope.toggleDetails(field);
|
||||
}
|
||||
|
@ -80,10 +79,11 @@ app.directive('discoverField', function ($compile) {
|
|||
|
||||
detailsElem = $(detailsHtml);
|
||||
$compile(detailsElem)(detailScope);
|
||||
$elem.append(detailsElem);
|
||||
$elem.append(detailsElem).addClass('active');
|
||||
} else {
|
||||
delete field.details;
|
||||
detailsElem.remove();
|
||||
$elem.removeClass('active');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<div class="sidebar-list">
|
||||
<div ng-show="indexPatternList.length > 1">
|
||||
<div class="index-pattern" ng-click="showIndexPatternSelection = !showIndexPatternSelection">
|
||||
<div class="index-pattern" ng-click="showIndexPatternSelection = !showIndexPatternSelection"
|
||||
ng-class="{active: showIndexPatternSelection === true}">
|
||||
<div css-truncate title="{{indexPattern.id}}">{{indexPattern.id}}</div>
|
||||
<i ng-hide="showIndexPatternSelection" class="fa fa-caret-down"></i>
|
||||
<i ng-show="showIndexPatternSelection" class="fa fa-caret-up"></i>
|
||||
|
|
|
@ -96,16 +96,17 @@ app.controller('discover', function ($scope, config, courier, $route, $window, N
|
|||
$scope.toggleInterval = function () {
|
||||
$scope.showInterval = !$scope.showInterval;
|
||||
};
|
||||
|
||||
// config panel templates
|
||||
$scope.configTemplate = new ConfigTemplate({
|
||||
load: require('plugins/kibana/discover/partials/load_search.html'),
|
||||
save: require('plugins/kibana/discover/partials/save_search.html'),
|
||||
share: require('plugins/kibana/discover/partials/share_search.html')
|
||||
share: require('plugins/kibana/discover/partials/share_search.html'),
|
||||
filter: require('ui/chrome/config/filter.html'),
|
||||
interval: require('ui/chrome/config/interval.html')
|
||||
});
|
||||
|
||||
$scope.timefilter = timefilter;
|
||||
|
||||
|
||||
// the saved savedSearch
|
||||
const savedSearch = $route.current.locals.savedSearch;
|
||||
$scope.$on('$destroy', savedSearch.destroy);
|
||||
|
@ -147,7 +148,8 @@ app.controller('discover', function ($scope, config, courier, $route, $window, N
|
|||
index: $scope.indexPattern.id,
|
||||
timefield: $scope.indexPattern.timeFieldName,
|
||||
savedSearch: savedSearch,
|
||||
indexPatternList: $route.current.locals.ip.list
|
||||
indexPatternList: $route.current.locals.ip.list,
|
||||
timefilter: $scope.timefilter
|
||||
};
|
||||
|
||||
const init = _.once(function () {
|
||||
|
|
|
@ -17,7 +17,7 @@ uiModules
|
|||
const init = function () {
|
||||
// This elem should already have a height/width
|
||||
const myChart = new vislib.Chart(elem[0], {
|
||||
|
||||
addLegend: false
|
||||
});
|
||||
|
||||
$scope.$watch('data', function (data) {
|
||||
|
|
|
@ -1,5 +1,53 @@
|
|||
<div ng-controller="discover" class="app-container">
|
||||
<navbar name="discover">
|
||||
<navbar name="discover-options" class="kibana-nav-options">
|
||||
<div class="kibana-nav-info">
|
||||
<span ng-show="opts.savedSearch.id" class="kibana-nav-info-title">
|
||||
<span ng-bind="::opts.savedSearch.title"></span>
|
||||
<i aria-label="Reload Saved Search" tooltip="Reload Saved Search" ng-click="resetQuery();" class="fa fa-undo small"></i>
|
||||
</span>
|
||||
|
||||
<strong class="discover-info-hits">{{(hits || 0) | number:0}}</strong>
|
||||
<ng-pluralize count="hits" when="{'1':'hit', 'other':'hits'}"></ng-pluralize>
|
||||
</div>
|
||||
<div class="kibana-nav-actions button-group" role="toolbar">
|
||||
<button
|
||||
ng-click="newQuery()"
|
||||
aria-label="New Search">
|
||||
<span>New</span>
|
||||
</button>
|
||||
<button
|
||||
ng-click="configTemplate.toggle('save');"
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
aria-label="Save Search">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
<button
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
ng-click="configTemplate.toggle('load');"
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
aria-label="Load Saved Search">
|
||||
<span>Open</span>
|
||||
</button>
|
||||
<button
|
||||
aria-label="Share Search"
|
||||
aria-haspopup="false"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share');">
|
||||
<span>Share</span>
|
||||
</button>
|
||||
<div class="chrome-actions" kbn-chrome-append-nav-controls></div>
|
||||
</div>
|
||||
</navbar>
|
||||
<config
|
||||
config-template="configTemplate"
|
||||
config-object="opts"
|
||||
config-close="configClose"
|
||||
></config>
|
||||
<navbar name="discover-search">
|
||||
<form role="form" class="fill inline-form" ng-submit="fetch()" name="discoverSearch">
|
||||
<div class="typeahead" kbn-typeahead="discover">
|
||||
<div class="input-group"
|
||||
|
@ -21,49 +69,9 @@
|
|||
<kbn-typeahead-items></kbn-typeahead-items>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="button-group" role="toolbar">
|
||||
<kbn-tooltip text="New Search" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
ng-click="newQuery()"
|
||||
aria-label="New Search">
|
||||
<i aria-hidden="true" class="fa fa-file-new-o"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Save Search" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
ng-click="configTemplate.toggle('save');"
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
aria-label="Save Search">
|
||||
<i aria-hidden="true" class="fa fa-save"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Load Saved Search" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
ng-click="configTemplate.toggle('load');"
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
aria-label="Load Saved Search">
|
||||
<i aria-hidden="true" class="fa fa-folder-open-o"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Share" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
aria-label="Share Search"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share');">
|
||||
<i aria-hidden="true" class="fa fa-external-link"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
</div>
|
||||
<div class="button-group" role="toolbar"></div>
|
||||
</navbar>
|
||||
|
||||
<config config-template="configTemplate" config-object="opts" config-close="configClose"></config>
|
||||
|
||||
<div class="container-fluid" role="main">
|
||||
<div class="row">
|
||||
|
@ -84,17 +92,6 @@
|
|||
</div>
|
||||
|
||||
<div class="discover-wrapper col-md-10">
|
||||
|
||||
<div class="discover-info">
|
||||
<span ng-show="opts.savedSearch.id" class="discover-info-title">
|
||||
<span ng-bind="::opts.savedSearch.title"></span>
|
||||
<i aria-label="Reload Saved Search" tooltip="Reload Saved Search" ng-click="resetQuery();" class="fa fa-undo small"></i>
|
||||
</span>
|
||||
|
||||
<strong class="discover-info-hits">{{(hits || 0) | number:0}}</strong>
|
||||
<ng-pluralize count="hits" when="{'1':'hit', 'other':'hits'}"></ng-pluralize>
|
||||
</div>
|
||||
|
||||
<div class="discover-content">
|
||||
<!-- no results -->
|
||||
<div ng-show="resultState === 'none'">
|
||||
|
@ -153,7 +150,6 @@
|
|||
<div ng-show="resultState === 'loading'">
|
||||
<div class="discover-overlay">
|
||||
<h2>Searching</h2>
|
||||
<div class="spinner large"></div>
|
||||
<div ng-show="fetchStatus">{{fetchStatus.complete}}/{{fetchStatus.total}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
height: 200px;
|
||||
max-height: 600px;
|
||||
|
||||
.loading {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
&.only-spy {
|
||||
height: auto;
|
||||
|
||||
|
@ -71,12 +75,10 @@
|
|||
}
|
||||
|
||||
&-info {
|
||||
background-color: @discover-info-bg;
|
||||
float: right;
|
||||
padding: 5px 10px;
|
||||
line-height: 30px;
|
||||
padding: 0px 10px;
|
||||
border-bottom-left-radius: @border-radius-base;
|
||||
|
||||
text-align: right;
|
||||
|
||||
&-title {
|
||||
font-weight: bold;
|
||||
|
@ -245,6 +247,10 @@ disc-field-chooser {
|
|||
}
|
||||
}
|
||||
|
||||
.sidebar-item.active .sidebar-item-title {
|
||||
background-color: @sidebar-active-bg;
|
||||
color: @sidebar-active-color;
|
||||
}
|
||||
.sidebar-item-title {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -28,36 +28,14 @@ routes
|
|||
|
||||
chrome
|
||||
.setBrand({
|
||||
'logo': 'url(' + kibanaLogoUrl + ') left no-repeat',
|
||||
'smallLogo': 'url(' + kibanaLogoUrl + ') left no-repeat'
|
||||
'logo': 'url(' + kibanaLogoUrl + ') 6px 10px / 140px 50px no-repeat #e8488b',
|
||||
'smallLogo': 'url(' + kibanaLogoUrl + ') 6px 10px / 140px 50px no-repeat #e8488b'
|
||||
})
|
||||
.setNavBackground('#222222')
|
||||
.setTabDefaults({
|
||||
resetWhenActive: true,
|
||||
lastUrlStore: window.sessionStore,
|
||||
lastUrlStore: window.sessionStorage,
|
||||
activeIndicatorColor: '#656a76'
|
||||
})
|
||||
.setTabs([
|
||||
{
|
||||
id: 'discover',
|
||||
title: 'Discover'
|
||||
},
|
||||
{
|
||||
id: 'visualize',
|
||||
title: 'Visualize',
|
||||
activeIndicatorColor: function () {
|
||||
return (String(this.lastUrl).indexOf('/visualize/step/') === 0) ? 'white' : '#656a76';
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'dashboard',
|
||||
title: 'Dashboard'
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
title: 'Settings'
|
||||
}
|
||||
])
|
||||
.setRootController('kibana', function ($scope, $rootScope, courier, config) {
|
||||
function setDefaultTimezone() {
|
||||
moment.tz.setDefault(config.get('dateFormat:tz'));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<div class="app-container">
|
||||
<nav class="navbar navbar-default navbar-static-top subnav" data-test-subj="settingsNav">
|
||||
<div class="container-fluid">
|
||||
<bread-crumbs></bread-crumbs>
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-repeat="section in sections" ng-class="section.class">
|
||||
<a class="navbar-link" kbn-href="{{section.url}}" data-test-subj="{{section.name}}">{{section.display}}</a>
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'ui/filters/start_from';
|
|||
import 'ui/field_editor';
|
||||
import 'plugins/kibana/settings/sections/indices/_indexed_fields';
|
||||
import 'plugins/kibana/settings/sections/indices/_scripted_fields';
|
||||
import 'ui/directives/bread_crumbs';
|
||||
import registry from 'ui/registry/settings_sections';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
|
|
|
@ -11,6 +11,10 @@ kbn-settings-objects-view {
|
|||
display: block;
|
||||
}
|
||||
|
||||
nav.navbar {
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.settings-nav {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
@ -19,6 +23,15 @@ li.kbn-settings-tab:first-letter {
|
|||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
kbn-settings-app {
|
||||
div.app-container {
|
||||
div.container-fluid {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kbn-settings-objects {
|
||||
form {
|
||||
margin-bottom: @line-height-computed;
|
||||
|
@ -93,6 +106,8 @@ kbn-settings-objects-view {
|
|||
}
|
||||
|
||||
.advanced-settings {
|
||||
overflow-x: scroll;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
aria-label="{{ editorOpen ? 'Close Editor' : 'Open Editor' }}"
|
||||
ng-click="editorOpen = !editorOpen"
|
||||
type="button"
|
||||
class="btn btn-default btn-xs vis-editor-agg-header-toggle">
|
||||
class="btn btn-primary btn-xs vis-editor-agg-header-toggle">
|
||||
<i aria-hidden="true" ng-class="{ 'fa-caret-down': editorOpen, 'fa-caret-right': !editorOpen }" class="fa"></i>
|
||||
</button>
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
|||
tooltip="Increase Priority"
|
||||
tooltip-append-to-body="true"
|
||||
type="button"
|
||||
class="btn btn-xs btn-default">
|
||||
class="btn btn-xs btn-primary">
|
||||
<i aria-hidden="true" class="fa fa-caret-up"></i>
|
||||
</button>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
tooltip="Decrease Priority"
|
||||
tooltip-append-to-body="true"
|
||||
type="button"
|
||||
class="btn btn-xs btn-default">
|
||||
class="btn btn-xs btn-primary">
|
||||
<i aria-hidden="true" class="fa fa-caret-down"></i>
|
||||
</button>
|
||||
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
class="vis-editor-agg-wide-btn">
|
||||
|
||||
<div ng-if="!add.form">
|
||||
<div class="vis-editor-agg-wide-btn-add" ng-if="groupName !== 'buckets' || !stats.count">
|
||||
<i aria-hidden="true" class="fa fa-plus"></i> Add {{ groupName }}
|
||||
<div class="btn btn-sm btn-primary" ng-if="groupName !== 'buckets' || !stats.count">
|
||||
Add {{ groupName }}
|
||||
</div>
|
||||
<div class="vis-editor-agg-wide-btn-add" ng-if="groupName === 'buckets' && stats.count > 0">
|
||||
<i aria-hidden="true" class="fa fa-code-fork"></i> Add sub-{{ groupName }}
|
||||
<div class="btn btn-sm btn-primary" ng-if="groupName === 'buckets' && stats.count > 0">
|
||||
Add sub-{{ groupName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="vis-editor-agg-wide-btn-add" ng-if="add.form">
|
||||
<div class="btn btn-sm btn-primary" ng-if="add.form">
|
||||
Cancel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,13 +6,6 @@
|
|||
<div class="vis-editor-agg-group" ng-class="groupName">
|
||||
<!-- wrapper needed for nesting-indicator -->
|
||||
<div ng-repeat="agg in group" class="vis-editor-agg-wrapper">
|
||||
<nesting-indicator
|
||||
ng-if="groupName === 'buckets'"
|
||||
item="agg"
|
||||
index="$index"
|
||||
list="group">
|
||||
</nesting-indicator>
|
||||
|
||||
<!-- agg.html - controls for aggregation -->
|
||||
<ng-form vis-editor-agg name="aggForm" class="vis-editor-agg"></ng-form>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,60 @@
|
|||
<div ng-controller="VisEditor" class="vis-editor vis-type-{{ vis.type.name }}">
|
||||
<navbar ng-if="chrome.getVisible()" name="visualize">
|
||||
<div ng-controller="VisEditor" class="app-container vis-editor vis-type-{{ vis.type.name }}">
|
||||
<navbar name="visualize-options" class="kibana-nav-options" ng-if="chrome.getVisible()">
|
||||
<div class="vis-editor-info">
|
||||
<span ng-show="savedVis.id" class="vis-editor-info-title">
|
||||
<span ng-bind="::savedVis.title"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="button-group kibana-nav-actions">
|
||||
<button ng-click="startOver()" aria-label="New Visualization">
|
||||
<span>New</span>
|
||||
</button>
|
||||
<!-- normal save -->
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
ng-click="configTemplate.toggle('save')"
|
||||
ng-if="!editableVis.dirty"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
aria-label="Save Visualization">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
|
||||
<!-- save stub with tooltip -->
|
||||
<button disabled ng-if="editableVis.dirty" tooltip="Apply or Discard your changes before saving" aria-label="Apply or Discard your changes before saving">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
ng-click="configTemplate.toggle('load')"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
aria-label="Load Saved Visualization">
|
||||
<span>Load</span>
|
||||
</button>
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share')"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
aria-label="Share Visualization">
|
||||
<span>Share</span>
|
||||
</button>
|
||||
<button
|
||||
ng-click="fetch()"
|
||||
aria-label="Refresh">
|
||||
<span>Refresh</span>
|
||||
</button>
|
||||
<div class="chrome-actions"kbn-chrome-append-nav-controls></div>
|
||||
</div>
|
||||
</navbar>
|
||||
<config
|
||||
ng-if="chrome.getVisible()"
|
||||
config-template="configTemplate"
|
||||
config-object="opts">
|
||||
</config>
|
||||
|
||||
<navbar ng-if="chrome.getVisible()" name="visualize-search">
|
||||
<div class="fill bitty-modal-container">
|
||||
<div ng-if="vis.type.requiresSearch && $state.linked && !unlinking"
|
||||
ng-dblclick="unlink()"
|
||||
|
@ -62,65 +117,9 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<kbn-tooltip text="New Visualization" placement="bottom" append-to-body="1">
|
||||
<button ng-click="startOver()" aria-label="New Visualization"><i aria-hidden="true" class="fa fa-file-new-o"></i></button>
|
||||
</kbn-tooltip>
|
||||
|
||||
<kbn-tooltip text="Save Visualization" placement="bottom" append-to-body="1">
|
||||
<!-- normal save -->
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('save')}"
|
||||
ng-click="configTemplate.toggle('save')"
|
||||
ng-if="!editableVis.dirty"
|
||||
aria-expanded="{{ configTemplate.is('save') }}"
|
||||
aria-label="Save Visualization">
|
||||
<i aria-hidden="true" class="fa fa-save"></i>
|
||||
</button>
|
||||
|
||||
<!-- save stub with tooltip -->
|
||||
<button disabled ng-if="editableVis.dirty" tooltip="Apply or Discard your changes before saving" aria-label="Apply or Discard your changes before saving">
|
||||
<i aria-hidden="true" class="fa fa-save"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
|
||||
<kbn-tooltip text="Load Saved Visualization" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('load')}"
|
||||
ng-click="configTemplate.toggle('load')"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('load') }}"
|
||||
aria-label="Load Saved Visualization">
|
||||
<i aria-hidden="true" class="fa fa-folder-open-o"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Share Visualization" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
ng-class="{active: configTemplate.is('share')}"
|
||||
ng-click="configTemplate.toggle('share')"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{ configTemplate.is('share') }}"
|
||||
aria-label="Share Visualization">
|
||||
<i aria-hidden="true" class="fa fa-external-link"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
<kbn-tooltip text="Refresh" placement="bottom" append-to-body="1">
|
||||
<button
|
||||
ng-click="fetch()"
|
||||
aria-label="Refresh">
|
||||
<i aria-hidden="true" class="fa fa-refresh"></i>
|
||||
</button>
|
||||
</kbn-tooltip>
|
||||
</div>
|
||||
<div class="button-group"></div>
|
||||
</navbar>
|
||||
|
||||
<config
|
||||
ng-if="chrome.getVisible()"
|
||||
config-template="configTemplate"
|
||||
config-object="conf">
|
||||
</config>
|
||||
|
||||
<filter-bar state="state"></filter-bar>
|
||||
|
||||
<div class="vis-editor-content">
|
||||
|
@ -130,13 +129,6 @@
|
|||
</div>
|
||||
|
||||
<div class="vis-editor-canvas" ng-class="{ embedded: !chrome.getVisible() }">
|
||||
<div class="visualize-info" ng-if="savedVis.id">
|
||||
<div class="visualize-info-tab" title="{{::savedVis.vis.type.title}}">
|
||||
<i class="fa" aria-label="{{::savedVis.vis.type.title}} Icon" ng-class="savedVis.vis.type.icon"></i>
|
||||
<span ng-bind="::savedVis.title"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<visualize
|
||||
vis="vis"
|
||||
ui-state="uiState"
|
||||
|
|
|
@ -85,6 +85,8 @@ uiModules
|
|||
save: require('plugins/kibana/visualize/editor/panels/save.html'),
|
||||
load: require('plugins/kibana/visualize/editor/panels/load.html'),
|
||||
share: require('plugins/kibana/visualize/editor/panels/share.html'),
|
||||
filter: require('ui/chrome/config/filter.html'),
|
||||
interval: require('ui/chrome/config/interval.html')
|
||||
});
|
||||
|
||||
if (savedVis.id) {
|
||||
|
@ -125,8 +127,8 @@ uiModules
|
|||
$scope.editableVis = editableVis;
|
||||
$scope.state = $state;
|
||||
$scope.uiState = $state.makeStateful('uiState');
|
||||
|
||||
$scope.conf = _.pick($scope, 'doSave', 'savedVis', 'shareData');
|
||||
$scope.timefilter = timefilter;
|
||||
$scope.opts = _.pick($scope, 'doSave', 'savedVis', 'shareData', 'timefilter');
|
||||
$scope.configTemplate = configTemplate;
|
||||
|
||||
editableVis.listeners.click = vis.listeners.click = filterBarClickHandler($state);
|
||||
|
|
|
@ -1 +1 @@
|
|||
<saved-object-finder type="visualizations"></saved-object-finder>
|
||||
<saved-object-finder type="visualizations"></saved-object-finder>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<form role="form" ng-submit="conf.doSave()">
|
||||
<form role="form" ng-submit="opts.doSave()">
|
||||
<div class="form-group">
|
||||
<label for="visTitle">Title</label>
|
||||
<input class="form-control" input-focus="select" type="text" name="visTitle" ng-model="conf.savedVis.title" required>
|
||||
<input class="form-control" input-focus="select" type="text" name="visTitle" ng-model="opts.savedVis.title" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<share
|
||||
object-type="visualization"
|
||||
object-id="{{conf.savedVis.id}}">
|
||||
object-id="{{opts.savedVis.id}}">
|
||||
</share>
|
||||
|
|
|
@ -6,11 +6,40 @@
|
|||
@vis-editor-nesting-width: 8px;
|
||||
@vis-editor-agg-editor-spacing: 5px;
|
||||
|
||||
&-info {
|
||||
line-height: 30px;
|
||||
padding: 0px 10px;
|
||||
border-bottom-left-radius: @border-radius-base;
|
||||
|
||||
|
||||
&-title {
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// For the vis-editor sidebar nav
|
||||
.navbar-default .navbar-nav {
|
||||
&> .active > a:before {
|
||||
border: 7px solid transparent;
|
||||
border-bottom-color: @vis-editor-navbar-current-tab-color;
|
||||
&> .active > a {
|
||||
border-bottom: 2px solid @kibanaGray2;
|
||||
color: @kibanaGray1;
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
> li {
|
||||
> a {
|
||||
padding: 4px 0;
|
||||
margin: 0 10px;
|
||||
color: @kibanaGray2;
|
||||
}
|
||||
> a:hover {
|
||||
border-bottom: 2px solid @kibanaGray2;
|
||||
}
|
||||
}
|
||||
|
||||
.danger {
|
||||
|
@ -55,6 +84,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
&-content {
|
||||
.flex-parent();
|
||||
z-index: 0;
|
||||
|
@ -79,7 +109,9 @@
|
|||
max-width: @vis-editor-sidebar-min-width;
|
||||
}
|
||||
|
||||
.index-pattern,
|
||||
nav {
|
||||
min-height: @app-icon-height;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
|
@ -115,19 +147,13 @@
|
|||
}
|
||||
|
||||
.sidebar-item-title {
|
||||
font-size: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
border: inherit !important;
|
||||
background-color: @vis-editor-sidebar-title-bg;
|
||||
margin-bottom: @vis-editor-agg-editor-spacing;
|
||||
padding: 2px 5px !important;
|
||||
}
|
||||
|
||||
.sidebar-item-title:hover {
|
||||
color: @vis-editor-sidebar-title-hover-color !important;
|
||||
background-color: @vis-editor-sidebar-title-hover-bg !important;
|
||||
}
|
||||
|
||||
.hintbox {
|
||||
padding: @vis-editor-agg-editor-spacing;
|
||||
margin-bottom: @vis-editor-agg-editor-spacing;
|
||||
|
@ -178,7 +204,7 @@
|
|||
|
||||
&-group {
|
||||
.flex-parent(0, 1, auto);
|
||||
color: @vis-editor-agg-group-color;
|
||||
color: @kibanaGray2;
|
||||
}
|
||||
|
||||
&-header {
|
||||
|
@ -275,9 +301,7 @@
|
|||
}
|
||||
|
||||
&-wide-btn {
|
||||
border-radius: 0;
|
||||
border-top: 2px solid;
|
||||
border-top-color: @vis-editor-agg-wide-btn-border;
|
||||
text-align: center;
|
||||
|
||||
&-add {
|
||||
width: 140px;
|
||||
|
|
|
@ -3,57 +3,99 @@
|
|||
@import (reference) "~ui/styles/list-group-menu";
|
||||
|
||||
.vis-wizard {
|
||||
h1 {
|
||||
margin-top: 45px;
|
||||
}
|
||||
}
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
.wizard-vis-type {
|
||||
.list-group-item();
|
||||
.list-group-menu .list-group-menu-item();
|
||||
@media (min-width: @screen-lg) {
|
||||
.wizard {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
|
||||
// overrided for tablet and desktop
|
||||
@media (min-width: @screen-md-min) {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.wizard-column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0px 2.5px;
|
||||
|
||||
&-heading {
|
||||
flex: 0 0 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.2em;
|
||||
|
||||
.fa {
|
||||
flex: 0 0 auto;
|
||||
margin-right: @padding-base-horizontal;
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h4 {
|
||||
flex: 1 0 auto;
|
||||
.wizard-row {
|
||||
flex: 1;
|
||||
background-color: @kibanaGray6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
flex: 1 1 auto;
|
||||
color: @wizard-vis-type-description-color;
|
||||
}
|
||||
}
|
||||
|
||||
.visualize-info {
|
||||
align-self: flex-end;
|
||||
|
||||
&-tab {
|
||||
background-color: @visualize-info-bg;
|
||||
padding: 5px 10px;
|
||||
margin-left: @padding-base-horizontal;
|
||||
border-bottom-left-radius: @border-radius-base;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
h3 {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 8px;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
.wizard-row {
|
||||
.panel {
|
||||
margin-bottom: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading {
|
||||
background-color: @kibanaGray6;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
margin-bottom: 0;
|
||||
|
||||
.list-group-item {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.striped {
|
||||
li:nth-child(odd) {
|
||||
background-color: @white;
|
||||
}
|
||||
|
||||
li:nth-child(even) {
|
||||
background-color: @kibanaGray6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wizard-type {
|
||||
flex: 1;
|
||||
.list-group-item();
|
||||
.list-group-menu .list-group-menu-item();
|
||||
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: @kibanaGray6;
|
||||
|
||||
&-heading {
|
||||
flex: 0 0 200px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.2em;
|
||||
|
||||
.fa {
|
||||
flex: 0 0 auto;
|
||||
margin-right: @padding-base-horizontal;
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
color: @saved-object-finder-icon-color;
|
||||
}
|
||||
|
||||
h4 {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
flex: 1 1 auto;
|
||||
color: @wizard-vis-type-description-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import "../editor/styles/_editor.less";
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
<h1>
|
||||
Create a new visualization <br class="visible-xs">
|
||||
<span class="pull-right label label-default hidden-xs">Step 1</span>
|
||||
<span class="label label-default visible-xs">Step 1</span>
|
||||
</h1>
|
||||
|
||||
<div class="wizard-vis-types">
|
||||
<a class="wizard-vis-type"
|
||||
ng-repeat="type in visTypes.inTitleOrder"
|
||||
ng-href="{{ visTypeUrl(type) }}">
|
||||
<div class="wizard-vis-type-heading">
|
||||
<i aria-hidden="true" class="fa fa-fw" ng-class="type.icon"></i>
|
||||
<h4>{{type.title}}</h4>
|
||||
<bread-crumbs></bread-crumbs>
|
||||
<div class="wizard">
|
||||
<div class="wizard-column">
|
||||
<h3>Create New Visualization</h3>
|
||||
<div class="wizard-row">
|
||||
<a class="wizard-type" ng-repeat="type in visTypes.inTitleOrder" ng-href="{{ visTypeUrl(type) }}">
|
||||
<div class="wizard-type-heading">
|
||||
<i aria-hidden="true" class="fa fa-fw" ng-class="type.icon"></i>
|
||||
<h4>{{type.title}}</h4>
|
||||
</div>
|
||||
<p class="wizard-type-description">{{type.description}}</p>
|
||||
</a>
|
||||
</div>
|
||||
<p class="wizard-vis-type-description">{{type.description}}</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="wizard-column">
|
||||
<h3>Or, Open a Saved Visualization</h3>
|
||||
<saved-object-finder
|
||||
title="Saved Visualizations"
|
||||
type="visualizations"
|
||||
class="wizard-row">
|
||||
</saved-object-finder>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Or, open a saved visualization</h1>
|
||||
|
||||
<saved-object-finder
|
||||
title="Saved Visualizations"
|
||||
type="visualizations">
|
||||
</saved-object-finder>
|
||||
|
|
|
@ -1,37 +1,27 @@
|
|||
<h1>
|
||||
Select a search source
|
||||
<span class="pull-right label label-default hidden-xs">Step 2</span>
|
||||
<span class="label label-default visible-xs">Step 2</span>
|
||||
</h1>
|
||||
<ul class="list-group list-group-menu" ng-switch on="stepTwoMode">
|
||||
<li ng-click="stepTwoMode='new'"
|
||||
ng-class="{'active': stepTwoMode=='new'}"
|
||||
class="list-group-item list-group-menu-item">
|
||||
From a new search
|
||||
</li>
|
||||
<li class="list-group-item" ng-switch-when="new">
|
||||
<bread-crumbs></bread-crumbs>
|
||||
<div class="wizard">
|
||||
<div class="wizard-column">
|
||||
<h3>From a New Search</h3>
|
||||
<!-- Index patterns -->
|
||||
Select an index pattern
|
||||
<div class="form-group">
|
||||
<select
|
||||
class="form-control"
|
||||
ng-model="indexPattern.selection"
|
||||
ng-options="pattern as pattern for pattern in indexPattern.list | orderBy:'toString()'">
|
||||
</select>
|
||||
<div class="wizard-row">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Index Patterns</div>
|
||||
</div>
|
||||
<ul class="striped list-group">
|
||||
<li class="list-group-item" ng-repeat="pattern in indexPattern.list | orderBy: 'toString()'">
|
||||
<a class="index-link" kbn-href="{{ makeUrl(pattern) }}">{{pattern}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li ng-click="stepTwoMode='saved'"
|
||||
ng-class="{'active': stepTwoMode=='saved'}"
|
||||
class="list-group-item list-group-menu-item">
|
||||
From a saved search
|
||||
</li>
|
||||
<li class="list-group-item" ng-switch-when="saved">
|
||||
</div>
|
||||
<div class="wizard-column">
|
||||
<h3>Or, From a Saved Search</h3>
|
||||
<!-- Saved searches -->
|
||||
<saved-object-finder
|
||||
title="Saved Searches"
|
||||
type="searches"
|
||||
make-url="step2WithSearchUrl">
|
||||
title="Saved Searches"
|
||||
type="searches"
|
||||
class="wizard-row"
|
||||
make-url="step2WithSearchUrl">
|
||||
</saved-object-finder>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@ import uiModules from 'ui/modules';
|
|||
|
||||
|
||||
const templateStep = function (num, txt) {
|
||||
return '<div ng-controller="VisualizeWizardStep' + num + '" class="container vis-wizard">' + txt + '</div>';
|
||||
return '<div ng-controller="VisualizeWizardStep' + num + '" class="container-fluid vis-wizard">' + txt + '</div>';
|
||||
};
|
||||
|
||||
const module = uiModules.get('app/visualize', ['kibana/courier']);
|
||||
|
@ -56,16 +56,8 @@ module.controller('VisualizeWizardStep2', function ($route, $scope, $location, t
|
|||
list: $route.current.locals.indexPatternIds
|
||||
};
|
||||
|
||||
$scope.$watch('stepTwoMode', function (mode) {
|
||||
if (mode === 'new') {
|
||||
if ($scope.indexPattern.list && $scope.indexPattern.list.length === 1) {
|
||||
$scope.indexPattern.selection = $scope.indexPattern.list[0];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('indexPattern.selection', function (pattern) {
|
||||
$scope.makeUrl = function (pattern) {
|
||||
if (!pattern) return;
|
||||
kbnUrl.change('/visualize/create?type={{type}}&indexPattern={{pattern}}', {type: type, pattern: pattern});
|
||||
});
|
||||
return `#/visualize/create?type=${type}&indexPattern=${pattern}`;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -16,6 +16,5 @@
|
|||
|
||||
.metric-container {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,6 @@ import 'plugins/status_page/status_page.less';
|
|||
|
||||
|
||||
const chrome = require('ui/chrome')
|
||||
.setTabs([
|
||||
{
|
||||
id: '',
|
||||
title: 'Server Status',
|
||||
activeIndicatorColor: '#EFF0F2'
|
||||
}
|
||||
])
|
||||
.setRootTemplate(require('plugins/status_page/status_page.html'))
|
||||
.setRootController('ui', function ($http, $scope) {
|
||||
const ui = this;
|
||||
|
@ -54,3 +47,8 @@ const chrome = require('ui/chrome')
|
|||
|
||||
ui.refresh();
|
||||
});
|
||||
|
||||
require('ui/modules').get('kibana')
|
||||
.config(function (appSwitcherEnsureNavigationProvider) {
|
||||
appSwitcherEnsureNavigationProvider.forceNavigation(true);
|
||||
});
|
||||
|
|
|
@ -43,13 +43,36 @@ describe('lib/config/config', function () {
|
|||
|
||||
describe('constructor', function () {
|
||||
|
||||
it('should not allow any config if the schema is not passed', function (done) {
|
||||
it('should not allow any config if the schema is not passed', function () {
|
||||
var config = new Config();
|
||||
var run = function () {
|
||||
config.set('something.enable', true);
|
||||
};
|
||||
expect(run).to.throwException();
|
||||
done();
|
||||
});
|
||||
|
||||
it('should allow keys in the schema', function () {
|
||||
var config = new Config(schema);
|
||||
var run = function () {
|
||||
config.set('test.client.host', 'http://0.0.0.0');
|
||||
};
|
||||
expect(run).to.not.throwException();
|
||||
});
|
||||
|
||||
it('should not allow keys not in the schema', function () {
|
||||
var config = new Config(schema);
|
||||
var run = function () {
|
||||
config.set('paramNotDefinedInTheSchema', true);
|
||||
};
|
||||
expect(run).to.throwException();
|
||||
});
|
||||
|
||||
it('should not allow child keys not in the schema', function () {
|
||||
var config = new Config(schema);
|
||||
var run = function () {
|
||||
config.set('test.client.paramNotDefinedInTheSchema', true);
|
||||
};
|
||||
expect(run).to.throwException();
|
||||
});
|
||||
|
||||
it('should set defaults', function () {
|
||||
|
@ -198,6 +221,14 @@ describe('lib/config/config', function () {
|
|||
expect(config.get('myTest.test')).to.be(true);
|
||||
});
|
||||
|
||||
it('should allow you to extend the schema with a prefix', function () {
|
||||
var newSchema = Joi.object({ test: Joi.boolean().default(true) }).default();
|
||||
config.extendSchema('prefix.myTest', newSchema);
|
||||
expect(config.get('prefix')).to.eql({ myTest: { test: true }});
|
||||
expect(config.get('prefix.myTest')).to.eql({ test: true });
|
||||
expect(config.get('prefix.myTest.test')).to.be(true);
|
||||
});
|
||||
|
||||
it('should NOT allow you to extend the schema if somethign else is there', function () {
|
||||
var newSchema = Joi.object({ test: Joi.boolean().default(true) }).default();
|
||||
var run = function () {
|
||||
|
|
83
src/server/config/__tests__/unset.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
import unset from '../unset';
|
||||
import expect from 'expect.js';
|
||||
|
||||
describe('unset(obj, key)', function () {
|
||||
describe('invalid input', function () {
|
||||
it('should do nothing if not given an object', function () {
|
||||
const obj = 'hello';
|
||||
unset(obj, 'e');
|
||||
expect(obj).to.equal('hello');
|
||||
});
|
||||
|
||||
it('should do nothing if not given a key', function () {
|
||||
const obj = { one: 1 };
|
||||
unset(obj);
|
||||
expect(obj).to.eql({ one: 1 });
|
||||
});
|
||||
|
||||
it('should do nothing if given an empty string as a key', function () {
|
||||
const obj = { one: 1 };
|
||||
unset(obj, '');
|
||||
expect(obj).to.eql({ one: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('shallow removal', function () {
|
||||
let obj;
|
||||
|
||||
beforeEach(function () {
|
||||
obj = { one: 1, two: 2, deep: { three: 3, four: 4 } };
|
||||
});
|
||||
|
||||
it('should remove the param using a string key', function () {
|
||||
unset(obj, 'two');
|
||||
expect(obj).to.eql({ one: 1, deep: { three: 3, four: 4 } });
|
||||
});
|
||||
|
||||
it('should remove the param using an array key', function () {
|
||||
unset(obj, ['two']);
|
||||
expect(obj).to.eql({ one: 1, deep: { three: 3, four: 4 } });
|
||||
});
|
||||
});
|
||||
|
||||
describe('deep removal', function () {
|
||||
let obj;
|
||||
|
||||
beforeEach(function () {
|
||||
obj = { one: 1, two: 2, deep: { three: 3, four: 4 } };
|
||||
});
|
||||
|
||||
it('should remove the param using a string key', function () {
|
||||
unset(obj, 'deep.three');
|
||||
expect(obj).to.eql({ one: 1, two: 2, deep: { four: 4 } });
|
||||
});
|
||||
|
||||
it('should remove the param using an array key', function () {
|
||||
unset(obj, ['deep', 'three']);
|
||||
expect(obj).to.eql({ one: 1, two: 2, deep: { four: 4 } });
|
||||
});
|
||||
});
|
||||
|
||||
describe('recursive removal', function () {
|
||||
it('should clear object if only value is removed', function () {
|
||||
const obj = { one: { two: { three: 3 } } };
|
||||
unset(obj, 'one.two.three');
|
||||
expect(obj).to.eql({});
|
||||
});
|
||||
|
||||
it('should clear object if no props are left', function () {
|
||||
const obj = { one: { two: { three: 3 } } };
|
||||
unset(obj, 'one.two');
|
||||
expect(obj).to.eql({});
|
||||
});
|
||||
|
||||
it('should remove deep property, then clear the object', function () {
|
||||
const obj = { one: { two: { three: 3, four: 4 } } };
|
||||
unset(obj, 'one.two.three');
|
||||
expect(obj).to.eql({ one: { two: { four: 4 } } });
|
||||
|
||||
unset(obj, 'one.two.four');
|
||||
expect(obj).to.eql({});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -2,13 +2,13 @@ import Promise from 'bluebird';
|
|||
import Joi from 'joi';
|
||||
import _ from 'lodash';
|
||||
import override from './override';
|
||||
import unset from './unset';
|
||||
import createDefaultSchema from './schema';
|
||||
import pkg from '../../utils/package_json';
|
||||
import clone from './deep_clone_with_buffers';
|
||||
import { zipObject } from 'lodash';
|
||||
|
||||
const schema = Symbol('Joi Schema');
|
||||
const schemaKeys = Symbol('Schema Extensions');
|
||||
const schemaExts = Symbol('Schema Extensions');
|
||||
const vals = Symbol('config values');
|
||||
const pendingSets = Symbol('Pending Settings');
|
||||
|
||||
|
@ -18,16 +18,15 @@ module.exports = class Config {
|
|||
}
|
||||
|
||||
constructor(initialSchema, initialSettings) {
|
||||
this[schemaKeys] = new Map();
|
||||
|
||||
this[schemaExts] = Object.create(null);
|
||||
this[vals] = Object.create(null);
|
||||
this[pendingSets] = new Map(_.pairs(clone(initialSettings || {})));
|
||||
this[pendingSets] = _.merge(Object.create(null), initialSettings || {});
|
||||
|
||||
if (initialSchema) this.extendSchema(initialSchema);
|
||||
}
|
||||
|
||||
getPendingSets() {
|
||||
return this[pendingSets];
|
||||
return new Map(_.pairs(this[pendingSets]));
|
||||
}
|
||||
|
||||
extendSchema(key, extension) {
|
||||
|
@ -41,27 +40,27 @@ module.exports = class Config {
|
|||
throw new Error(`Config schema already has key: ${key}`);
|
||||
}
|
||||
|
||||
this[schemaKeys].set(key, extension);
|
||||
_.set(this[schemaExts], key, extension);
|
||||
this[schema] = null;
|
||||
|
||||
let initialVals = this[pendingSets].get(key);
|
||||
let initialVals = _.get(this[pendingSets], key);
|
||||
if (initialVals) {
|
||||
this.set(key, initialVals);
|
||||
this[pendingSets].delete(key);
|
||||
unset(this[pendingSets], key);
|
||||
} else {
|
||||
this._commit(this[vals]);
|
||||
}
|
||||
}
|
||||
|
||||
removeSchema(key) {
|
||||
if (!this[schemaKeys].has(key)) {
|
||||
if (!_.has(this[schemaExts], key)) {
|
||||
throw new TypeError(`Unknown schema key: ${key}`);
|
||||
}
|
||||
|
||||
this[schema] = null;
|
||||
this[schemaKeys].delete(key);
|
||||
this[pendingSets].delete(key);
|
||||
delete this[vals][key];
|
||||
unset(this[schemaExts], key);
|
||||
unset(this[pendingSets], key);
|
||||
unset(this[vals], key);
|
||||
}
|
||||
|
||||
resetTo(obj) {
|
||||
|
@ -138,7 +137,7 @@ module.exports = class Config {
|
|||
// Catch the partial paths
|
||||
if (path.join('.') === key) return true;
|
||||
// Only go deep on inner objects with children
|
||||
if (schema._inner.children.length) {
|
||||
if (_.size(schema._inner.children)) {
|
||||
for (let i = 0; i < schema._inner.children.length; i++) {
|
||||
let child = schema._inner.children[i];
|
||||
// If the child is an object recurse through it's children and return
|
||||
|
@ -163,8 +162,22 @@ module.exports = class Config {
|
|||
|
||||
getSchema() {
|
||||
if (!this[schema]) {
|
||||
let objKeys = zipObject([...this[schemaKeys]]);
|
||||
this[schema] = Joi.object().keys(objKeys).default();
|
||||
this[schema] = (function convertToSchema(children) {
|
||||
let schema = Joi.object().keys({}).default();
|
||||
|
||||
for (const key of Object.keys(children)) {
|
||||
const child = children[key];
|
||||
const childSchema = _.isPlainObject(child) ? convertToSchema(child) : child;
|
||||
|
||||
if (!childSchema || !childSchema.isJoi) {
|
||||
throw new TypeError('Unable to convert configuration definition value to Joi schema: ' + childSchema);
|
||||
}
|
||||
|
||||
schema = schema.keys({ [key]: childSchema });
|
||||
}
|
||||
|
||||
return schema;
|
||||
}(this[schemaExts]));
|
||||
}
|
||||
|
||||
return this[schema];
|
||||
|
|
26
src/server/config/unset.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import _ from 'lodash';
|
||||
import toPath from 'lodash/internal/toPath';
|
||||
|
||||
module.exports = function unset(object, rawPath) {
|
||||
if (!object) return;
|
||||
const path = toPath(rawPath);
|
||||
|
||||
switch (path.length) {
|
||||
case 0:
|
||||
return;
|
||||
|
||||
case 1:
|
||||
delete object[rawPath];
|
||||
break;
|
||||
|
||||
default:
|
||||
const leaf = path.pop();
|
||||
const parentPath = path.slice();
|
||||
const parent = _.get(object, parentPath);
|
||||
unset(parent, leaf);
|
||||
if (!_.size(parent)) {
|
||||
unset(object, parentPath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
|
@ -1,41 +1,87 @@
|
|||
import expect from 'expect.js';
|
||||
import * as kbnTestServer from '../../../../test/utils/kbn_server';
|
||||
import fromRoot from '../../../utils/from_root';
|
||||
|
||||
describe('routes', function () {
|
||||
this.slow(10000);
|
||||
this.timeout(60000);
|
||||
|
||||
describe('cookie validation', function () {
|
||||
let kbnServer;
|
||||
beforeEach(function () {
|
||||
kbnServer = kbnTestServer.createServer();
|
||||
kbnServer = kbnTestServer.createServer({
|
||||
plugins: {
|
||||
scanDirs: [
|
||||
fromRoot('src/plugins')
|
||||
]
|
||||
}
|
||||
});
|
||||
return kbnServer.ready();
|
||||
});
|
||||
afterEach(function () {
|
||||
return kbnServer.close();
|
||||
});
|
||||
|
||||
it('allows non-strict cookies', function (done) {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'test:80=value;test_80=value'
|
||||
}
|
||||
};
|
||||
kbnTestServer.makeRequest(kbnServer, options, (res) => {
|
||||
expect(res.payload).not.to.contain('Invalid cookie header');
|
||||
done();
|
||||
describe('cookie validation', function () {
|
||||
it('allows non-strict cookies', function (done) {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'test:80=value;test_80=value'
|
||||
}
|
||||
};
|
||||
kbnTestServer.makeRequest(kbnServer, options, (res) => {
|
||||
expect(res.payload).not.to.contain('Invalid cookie header');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an error if the cookie can\'t be parsed', function (done) {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'a'
|
||||
}
|
||||
};
|
||||
kbnTestServer.makeRequest(kbnServer, options, (res) => {
|
||||
expect(res.payload).to.contain('Invalid cookie header');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an error if the cookie can\'t be parsed', function (done) {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'a'
|
||||
describe('url shortener', () => {
|
||||
const shortenOptions = {
|
||||
method: 'POST',
|
||||
url: '/shorten',
|
||||
payload: {
|
||||
url: '/app/kibana#/visualize/create'
|
||||
}
|
||||
};
|
||||
kbnTestServer.makeRequest(kbnServer, options, (res) => {
|
||||
expect(res.payload).to.contain('Invalid cookie header');
|
||||
done();
|
||||
|
||||
it('generates shortened urls', (done) => {
|
||||
kbnTestServer.makeRequest(kbnServer, shortenOptions, (res) => {
|
||||
expect(typeof res.payload).to.be('string');
|
||||
expect(res.payload.length > 0).to.be(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('redirects shortened urls', (done) => {
|
||||
kbnTestServer.makeRequest(kbnServer, shortenOptions, (res) => {
|
||||
const gotoOptions = {
|
||||
method: 'GET',
|
||||
url: '/goto/' + res.payload
|
||||
};
|
||||
kbnTestServer.makeRequest(kbnServer, gotoOptions, (res) => {
|
||||
expect(res.statusCode).to.be(302);
|
||||
expect(res.headers.location).to.be(shortenOptions.payload.url);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -20,6 +20,9 @@ module.exports = class KbnServer {
|
|||
require('./logging'),
|
||||
require('./status'),
|
||||
|
||||
// writes pid file
|
||||
require('./pid'),
|
||||
|
||||
// find plugins and set this.plugins
|
||||
require('./plugins/scan'),
|
||||
|
||||
|
@ -74,9 +77,8 @@ module.exports = class KbnServer {
|
|||
|
||||
await this.ready();
|
||||
await fromNode(cb => server.start(cb));
|
||||
await require('./pid')(this, server, config);
|
||||
|
||||
server.log(['listening', 'info'], 'Server running at ' + server.info.uri);
|
||||
server.log(['listening', 'info'], `Server running at ${server.info.uri}`);
|
||||
return server;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
import toPath from 'lodash/internal/toPath';
|
||||
import Joi from 'joi';
|
||||
import Bluebird, { attempt, fromNode } from 'bluebird';
|
||||
import { basename, resolve } from 'path';
|
||||
|
@ -37,6 +38,8 @@ const defaultConfigSchema = Joi.object({
|
|||
* @param {String} [opts.version=pkg.version] - the version of this plugin
|
||||
* @param {Function} [opts.init] - A function that will be called to initialize
|
||||
* this plugin at the appropriate time.
|
||||
* @param {Function} [opts.configPrefix=this.id] - The prefix to use for configuration
|
||||
* values in the main configuration service
|
||||
* @param {Function} [opts.config] - A function that produces a configuration
|
||||
* schema using Joi, which is passed as its
|
||||
* first argument.
|
||||
|
@ -57,6 +60,7 @@ module.exports = class Plugin {
|
|||
this.requiredIds = opts.require || [];
|
||||
this.version = opts.version || pkg.version;
|
||||
this.externalInit = opts.init || _.noop;
|
||||
this.configPrefix = opts.configPrefix || this.id;
|
||||
this.getConfigSchema = opts.config || _.noop;
|
||||
this.init = _.once(this.init);
|
||||
this[extendInitFns] = [];
|
||||
|
@ -86,18 +90,18 @@ module.exports = class Plugin {
|
|||
async readConfig() {
|
||||
let schema = await this.getConfigSchema(Joi);
|
||||
let { config } = this.kbnServer;
|
||||
config.extendSchema(this.id, schema || defaultConfigSchema);
|
||||
config.extendSchema(this.configPrefix, schema || defaultConfigSchema);
|
||||
|
||||
if (config.get([this.id, 'enabled'])) {
|
||||
if (config.get([...toPath(this.configPrefix), 'enabled'])) {
|
||||
return true;
|
||||
} else {
|
||||
config.removeSchema(this.id);
|
||||
config.removeSchema(this.configPrefix);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async init() {
|
||||
let { id, version, kbnServer } = this;
|
||||
let { id, version, kbnServer, configPrefix } = this;
|
||||
let { config } = kbnServer;
|
||||
|
||||
// setup the hapi register function and get on with it
|
||||
|
@ -132,7 +136,7 @@ module.exports = class Plugin {
|
|||
await fromNode(cb => {
|
||||
kbnServer.server.register({
|
||||
register: register,
|
||||
options: config.has(id) ? config.get(id) : null
|
||||
options: config.has(configPrefix) ? config.get(configPrefix) : null
|
||||
}, cb);
|
||||
});
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ module.exports = async (kbnServer, server, config) => {
|
|||
server.decorate('reply', 'renderApp', function (app) {
|
||||
const payload = {
|
||||
app: app,
|
||||
nav: uiExports.apps,
|
||||
nav: uiExports.navLinks.inOrder,
|
||||
version: kbnServer.version,
|
||||
buildNum: config.get('pkg.buildNum'),
|
||||
buildSha: config.get('pkg.buildSha'),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<table>
|
||||
<tbody>
|
||||
<tr ng-repeat="detail in details" >
|
||||
<td><b>{{detail.label}}</b></td>
|
||||
<td>{{detail.value}}</td>
|
||||
<td class="tooltip-label"><b>{{detail.label}}</b></td>
|
||||
<td class="tooltip-value">{{detail.value}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<tr class="tooltip-label">
|
||||
<th>field</th>
|
||||
<th>value</th>
|
||||
<th>{{metricCol.label}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="row in rows track by $index">
|
||||
<tr class="tooltip-value" ng-repeat="row in rows track by $index">
|
||||
<td><span ng-bind-html="row.spacer"></span>{{row.field}}</td>
|
||||
<td class="row-bucket">{{row.bucket}}</td>
|
||||
<td>{{row.metric}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<table>
|
||||
<tbody>
|
||||
<tr ng-repeat="detail in details" >
|
||||
<td><b>{{detail.label}}</b></td>
|
||||
<td>
|
||||
<td class="tooltip-label"><b>{{detail.label}}</b></td>
|
||||
<td class="tooltip-value">
|
||||
{{detail.value}}
|
||||
<span ng-if="detail.percent"> ({{detail.percent}})</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
|
|
@ -4,6 +4,7 @@ export default class TabFakeStore {
|
|||
constructor() { this[store] = new Map(); }
|
||||
getItem(k) { return this[store].get(k); }
|
||||
setItem(k, v) { return this[store].set(k, v); }
|
||||
removeItem(k) { return this[store].delete(k); }
|
||||
getKeys() { return [ ...this[store].keys() ]; }
|
||||
getValues() { return [ ...this[store].values() ]; }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import sinon from 'auto-release-sinon';
|
||||
import Tab from '../tab';
|
||||
import expect from 'expect.js';
|
||||
import TabFakeStore from './_tab_fake_store';
|
||||
|
@ -89,13 +90,24 @@ describe('Chrome Tab', function () {
|
|||
it('discovers the lastUrl', function () {
|
||||
const lastUrlStore = new TabFakeStore();
|
||||
const tab = new Tab({ id: 'foo', lastUrlStore });
|
||||
expect(tab.lastUrl).to.not.equal('bar');
|
||||
expect(tab.lastUrl).to.not.equal('/foo/bar');
|
||||
|
||||
tab.setLastUrl('bar');
|
||||
expect(tab.lastUrl).to.equal('bar');
|
||||
tab.setLastUrl('/foo/bar');
|
||||
expect(tab.lastUrl).to.equal('/foo/bar');
|
||||
|
||||
const tab2 = new Tab({ id: 'foo', lastUrlStore });
|
||||
expect(tab2.lastUrl).to.equal('bar');
|
||||
expect(tab2.lastUrl).to.equal('/foo/bar');
|
||||
});
|
||||
|
||||
it('logs a warning about last urls that do not match the rootUrl', function () {
|
||||
const lastUrlStore = new TabFakeStore();
|
||||
const tab = new Tab({ id: 'foo', baseUrl: '/bar', lastUrlStore });
|
||||
tab.setLastUrl('/bar/foo/1');
|
||||
|
||||
const stub = sinon.stub(console, 'log');
|
||||
const tab2 = new Tab({ id: 'foo', baseUrl: '/baz', lastUrlStore });
|
||||
sinon.assert.calledOnce(stub);
|
||||
expect(tab2.lastUrl).to.equal(null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -167,14 +179,14 @@ describe('Chrome Tab', function () {
|
|||
expect(tab.getLastPath()).to.equal('/index');
|
||||
});
|
||||
|
||||
it('throws an error if the lastUrl does not extend the root url', function () {
|
||||
expect(function () {
|
||||
const baseUrl = 'http://local:5601/app/visualize#';
|
||||
const tab = new Tab({ baseUrl });
|
||||
it('logs a warning if the lastUrl does not extend the root url', function () {
|
||||
const baseUrl = 'http://local:5601/app/visualize#';
|
||||
const tab = new Tab({ baseUrl });
|
||||
sinon.stub(console, 'log');
|
||||
|
||||
tab.setLastUrl('http://local:5601/');
|
||||
tab.getLastPath();
|
||||
}).to.throwError(/invalid.*root/);
|
||||
tab.setLastUrl('http://local:5601/');
|
||||
tab.getLastPath();
|
||||
sinon.assert.calledOnce(console.log);// eslint-disable-line no-console
|
||||
});
|
||||
});
|
||||
|
||||
|
|
19
src/ui/public/chrome/api/__tests__/angular.js
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
import kbnAngular from '../angular';
|
||||
import TabFakeStore from '../../__tests__/_tab_fake_store';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
describe('Chrome API :: Angular', () => {
|
||||
describe('location helper methods', () => {
|
||||
it('should return the sub app based on the url', () => {
|
||||
const chrome = {
|
||||
getInjected: noop,
|
||||
addBasePath: noop
|
||||
};
|
||||
kbnAngular(chrome, {});
|
||||
});
|
||||
it('should return breadcrumbs based on the url', () => {
|
||||
});
|
||||
});
|
||||
});
|
|
@ -86,11 +86,11 @@ describe('Chrome API :: apps', function () {
|
|||
describe('#getAppUrl()', function () {
|
||||
it('returns the resolved url of the current app', function () {
|
||||
const chrome = {};
|
||||
const app = { url: '/foo' };
|
||||
const app = { navLink: { url: '/foo' } };
|
||||
setup(chrome, { app });
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.setAttribute('href', app.url);
|
||||
a.setAttribute('href', app.navLink.url);
|
||||
expect(chrome.getAppUrl()).to.equal(a.href);
|
||||
});
|
||||
|
||||
|
|
15
src/ui/public/chrome/api/angular.js
vendored
|
@ -3,6 +3,9 @@ import modules from 'ui/modules';
|
|||
|
||||
module.exports = function (chrome, internals) {
|
||||
|
||||
chrome.getFirstPathSegment = _.noop;
|
||||
chrome.getBreadcrumbs = _.noop;
|
||||
|
||||
chrome.setupAngular = function () {
|
||||
var kibana = modules.get('kibana');
|
||||
|
||||
|
@ -15,12 +18,22 @@ module.exports = function (chrome, internals) {
|
|||
.value('buildNum', internals.buildNum)
|
||||
.value('buildSha', internals.buildSha)
|
||||
.value('sessionId', Date.now())
|
||||
.value('chrome', chrome)
|
||||
.value('esUrl', (function () {
|
||||
var a = document.createElement('a');
|
||||
a.href = chrome.addBasePath('/elasticsearch');
|
||||
return a.href;
|
||||
}()))
|
||||
.config(chrome.$setupXsrfRequestInterceptor);
|
||||
.config(chrome.$setupXsrfRequestInterceptor)
|
||||
.run(($location) => {
|
||||
chrome.getFirstPathSegment = () => {
|
||||
return $location.path().split('/')[1];
|
||||
};
|
||||
|
||||
chrome.getBreadcrumbs = () => {
|
||||
return $location.path().split('/').slice(1);
|
||||
};
|
||||
});
|
||||
|
||||
require('../directives')(chrome, internals);
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import { resolve } from 'url';
|
|||
|
||||
module.exports = function (chrome, internals) {
|
||||
|
||||
if (internals.app) {
|
||||
internals.app.url = resolve(window.location.href, internals.app.url);
|
||||
if (get(internals, 'app.navLink.url')) {
|
||||
internals.app.navLink.url = resolve(window.location.href, internals.app.navLink.url);
|
||||
}
|
||||
|
||||
internals.appUrlStore = internals.appUrlStore || window.sessionStorage;
|
||||
|
@ -35,7 +35,7 @@ module.exports = function (chrome, internals) {
|
|||
};
|
||||
|
||||
chrome.getAppUrl = function () {
|
||||
return get(internals, ['app', 'url']);
|
||||
return get(internals, ['app', 'navLink', 'url']);
|
||||
};
|
||||
|
||||
chrome.getInjected = function (name, def) {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
import { parse, format } from 'url';
|
||||
import { startsWith, isString } from 'lodash';
|
||||
import { startsWith, isString, find } from 'lodash';
|
||||
|
||||
export default function (chrome, internals) {
|
||||
chrome.getNavLinks = function () {
|
||||
return internals.nav;
|
||||
};
|
||||
|
||||
chrome.getLastSubUrlFor = function (url) {
|
||||
return internals.appUrlStore.getItem(`lastSubUrl:${url}`);
|
||||
};
|
||||
|
||||
chrome.getBasePath = function () {
|
||||
return internals.basePath || '';
|
||||
};
|
||||
|
@ -34,26 +30,46 @@ export default function (chrome, internals) {
|
|||
});
|
||||
};
|
||||
|
||||
function lastSubUrlKey(link) {
|
||||
return `lastSubUrl:${link.url}`;
|
||||
}
|
||||
|
||||
function setLastUrl(link, url) {
|
||||
link.lastSubUrl = url;
|
||||
internals.appUrlStore.setItem(lastSubUrlKey(link), url);
|
||||
}
|
||||
|
||||
function refreshLastUrl(link) {
|
||||
link.lastSubUrl = internals.appUrlStore.getItem(lastSubUrlKey(link));
|
||||
}
|
||||
|
||||
internals.trackPossibleSubUrl = function (url) {
|
||||
for (const link of internals.nav) {
|
||||
if (startsWith(url, link.url)) {
|
||||
link.lastSubUrl = url;
|
||||
internals.appUrlStore.setItem(`lastSubUrl:${link.url}`, url);
|
||||
link.active = startsWith(url, link.url);
|
||||
|
||||
if (link.active) {
|
||||
setLastUrl(link, url);
|
||||
continue;
|
||||
}
|
||||
|
||||
const matchingTab = find(internals.tabs, { rootUrl: link.url });
|
||||
if (matchingTab) {
|
||||
setLastUrl(link, matchingTab.getLastUrl());
|
||||
continue;
|
||||
}
|
||||
|
||||
refreshLastUrl(link);
|
||||
}
|
||||
};
|
||||
|
||||
internals.nav.forEach(link => {
|
||||
// convert all link urls to absolute urls
|
||||
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', link.url);
|
||||
link.url = a.href;
|
||||
link.lastSubUrl = chrome.getLastSubUrlFor(link.url);
|
||||
|
||||
if (link.url === chrome.getAppUrl()) {
|
||||
link.active = true;
|
||||
}
|
||||
});
|
||||
|
||||
// simulate a possible change in url to initialize the
|
||||
// link.active and link.lastUrl properties
|
||||
internals.trackPossibleSubUrl(document.location.href);
|
||||
};
|
||||
|
|
|
@ -76,12 +76,6 @@ module.exports = function (chrome, internals) {
|
|||
return internals.tabs.getActive();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {any} def - the default value if there isn't any active tab
|
||||
* @return {any}
|
||||
*/
|
||||
chrome.getActiveTabId = activeGetter('id');
|
||||
|
||||
/**
|
||||
* @param {any} def - the default value if there isn't any active tab
|
||||
* @return {any}
|
||||
|
|
|
@ -1,74 +1,86 @@
|
|||
<kbn-notifications list="notifList"></kbn-notifications>
|
||||
<div class="content" chrome-context >
|
||||
<nav
|
||||
ng-style="::{ background: chrome.getNavBackground() }"
|
||||
ng-class="{ show: chrome.getVisible() }"
|
||||
class="hide navbar navbar-inverse navbar-static-top">
|
||||
<!-- TODO: These config dropdowns shouldn't be hard coded -->
|
||||
<nav class="app-links-wrapper">
|
||||
<li
|
||||
ng-if="!chrome.getBrand('logo') && !chrome.getBrand('smallLogo')"
|
||||
aria-label="{{ chrome.getAppTitle() }} Logo"
|
||||
class="logo kibana hidden-sm"
|
||||
></li>
|
||||
<li
|
||||
ng-if="chrome.getBrand('logo')"
|
||||
ng-style="{ 'background': chrome.getBrand('logo') }"
|
||||
aria-label="{{ chrome.getAppTitle() }} Logo"
|
||||
class="logo hidden-sm"
|
||||
></li>
|
||||
<li
|
||||
ng-if="chrome.getBrand('smallLogo')"
|
||||
ng-style="{ 'background': chrome.getBrand('smallLogo') }"
|
||||
aria-label="{{ chrome.getAppTitle() }} Logo"
|
||||
class="logo-small visible-sm hidden-xs"
|
||||
></li>
|
||||
|
||||
<!-- Mobile navbar -->
|
||||
<div class="navbar-header">
|
||||
<button ng-click="showCollapsed = !showCollapsed" type="button" class="navbar-toggle">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="visible-xs">
|
||||
<span ng-if="chrome.getBrand('title')" class="navbar-brand">{{ chrome.getBrand('title') }}</span>
|
||||
<span ng-if="chrome.getActiveTabTitle()" class="navbar-brand">{{ chrome.getActiveTabTitle() }}</span>
|
||||
<span ng-show="chrome.httpActive.length" class="spinner"></span>
|
||||
</span>
|
||||
<app-switcher>
|
||||
</app-switcher>
|
||||
<div class="bottom-apps hide app-links">
|
||||
<div class="app-link">
|
||||
<a href="http://elastic.co">
|
||||
<div class="app-icon">
|
||||
<i class="fa fa-gear"></i>
|
||||
</div>
|
||||
<div class="app-title">settings</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="app-link">
|
||||
<a href="http://elastic.co">
|
||||
<div class="app-icon">
|
||||
<i class="fa fa-user"></i>
|
||||
</div>
|
||||
<div class="app-title">Jon Doe</div>
|
||||
<div class="app-title">Logout</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Mobile navbar -->
|
||||
|
||||
<!-- Full navbar -->
|
||||
<div collapse="!showCollapsed" class="navbar-collapse" kbn-chrome-append-nav-controls>
|
||||
<ul class="nav navbar-nav" role="navigation">
|
||||
<li
|
||||
ng-if="chrome.getBrand('logo')"
|
||||
ng-style="{ 'background': chrome.getBrand('logo') }"
|
||||
aria-label="{{ chrome.getAppTitle() }} Logo"
|
||||
class="logo hidden-sm"
|
||||
></li>
|
||||
|
||||
<li
|
||||
ng-if="chrome.getBrand('smallLogo')"
|
||||
ng-style="{ 'background': chrome.getBrand('smallLogo') }"
|
||||
aria-label="{{ chrome.getAppTitle() }} Logo"
|
||||
class="logo-small visible-sm hidden-xs"
|
||||
></li>
|
||||
|
||||
<li ng-if="chrome.getBrand('title')" class="navbar-brand">{{ chrome.getBrand('title') }}</li>
|
||||
|
||||
<li ng-repeat="tab in chrome.getTabs()" ng-class="{ active: tab.active }">
|
||||
<a ng-href="{{ tab.href() }}" ng-style="{ 'border-bottom-color': tab.activeIndicatorColor }">
|
||||
{{ tab.title }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="to-body" ng-class="{ active: appSwitcherTemplate.is('switcher') }" ng-if="chrome.getShowAppsLink()">
|
||||
<a ng-click="appSwitcherTemplate.toggle('switcher')">
|
||||
<i class="fa fa-th" alt="Show app switcher"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /Full navbar -->
|
||||
</nav>
|
||||
|
||||
<!-- TODO: These config dropdowns shouldn't be hard coded -->
|
||||
<config
|
||||
config-template="appSwitcherTemplate"
|
||||
config-object="chrome"
|
||||
config-close="appSwitcherTemplate.close">
|
||||
</config>
|
||||
<div class="app-wrapper">
|
||||
<div class="app-wrapper-panel">
|
||||
<kbn-notifications list="notifList"></kbn-notifications>
|
||||
<nav
|
||||
ng-style="::{ background: chrome.getNavBackground() }"
|
||||
ng-class="{ show: chrome.getTabs().length > 0 }"
|
||||
class="hide navbar navbar-inverse navbar-static-top">
|
||||
|
||||
<config
|
||||
ng-show="timefilter.enabled"
|
||||
config-template="pickerTemplate"
|
||||
config-object="timefilter"
|
||||
config-close="pickerTemplate.close">
|
||||
</config>
|
||||
<!-- Mobile navbar -->
|
||||
<div class="navbar-header">
|
||||
<button ng-click="showCollapsed = !showCollapsed" type="button" class="navbar-toggle">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="visible-xs">
|
||||
<span ng-if="chrome.getBrand('title')" class="navbar-brand">{{ chrome.getBrand('title') }}</span>
|
||||
<span ng-if="chrome.getActiveTabTitle()" class="navbar-brand">{{ chrome.getActiveTabTitle() }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- /Mobile navbar -->
|
||||
|
||||
<div class="application" ng-class="'tab-' + chrome.getActiveTabId('-none-') + ' ' + chrome.getApplicationClasses()" ng-view></div>
|
||||
<!-- Full navbar -->
|
||||
<div collapse="!showCollapsed" class="navbar-collapse" kbn-chrome-append-nav-controls>
|
||||
<div ng-if="chrome.getBrand('title')" class="navbar-brand">{{ chrome.getBrand('title') }}</div>
|
||||
<ul class="nav navbar-nav" role="navigation">
|
||||
|
||||
|
||||
<li ng-repeat="tab in chrome.getTabs()" ng-class="{ active: tab.active }">
|
||||
<a ng-href="{{ tab.href() }}" ng-style="{ 'border-bottom-color': tab.activeIndicatorColor }">
|
||||
{{ tab.title }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /Full navbar -->
|
||||
</nav>
|
||||
<div class="application" ng-class="'tab-' + chrome.getFirstPathSegment() + ' ' + chrome.getApplicationClasses()" ng-view></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import $ from 'jquery';
|
|||
import 'ui/timefilter';
|
||||
import 'ui/private';
|
||||
import 'ui/promises';
|
||||
import 'ui/directives/kbn_src';
|
||||
|
||||
var chrome = {};
|
||||
var internals = _.defaults(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<kbn-timepicker
|
||||
from="timefilter.time.from"
|
||||
to="timefilter.time.to"
|
||||
mode="timefilter.time.mode"
|
||||
from="opts.timefilter.time.from"
|
||||
to="opts.timefilter.time.to"
|
||||
mode="opts.timefilter.time.mode"
|
||||
active-tab="'filter'"
|
||||
interval="timefilter.refreshInterval">
|
||||
interval="opts.timefilter.refreshInterval">
|
||||
</kbn-timepicker>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<kbn-timepicker
|
||||
from="timefilter.time.from"
|
||||
to="timefilter.time.to"
|
||||
mode="timefilter.time.mode"
|
||||
from="opts.timefilter.time.from"
|
||||
to="opts.timefilter.time.to"
|
||||
mode="opts.timefilter.time.mode"
|
||||
active-tab="'interval'"
|
||||
interval="timefilter.refreshInterval">
|
||||
interval="opts.timefilter.refreshInterval">
|
||||
</kbn-timepicker>
|
||||
|
|
|
@ -21,11 +21,6 @@ uiModules
|
|||
|
||||
// chrome is responsible for timepicker ui and state transfer...
|
||||
$scope.timefilter = timefilter;
|
||||
$scope.pickerTemplate = new ConfigTemplate({
|
||||
filter: require('ui/chrome/config/filter.html'),
|
||||
interval: require('ui/chrome/config/interval.html')
|
||||
});
|
||||
|
||||
$scope.toggleRefresh = function () {
|
||||
timefilter.refreshInterval.pause = !timefilter.refreshInterval.pause;
|
||||
};
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
<ul class="nav navbar-nav navbar-right navbar-timepicker" >
|
||||
<li ng-show="chrome.httpActive.length" class="navbar-text hidden-xs">
|
||||
<div class="spinner"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="spinner" ng-show="chrome.httpActive.length"></div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="app-links">
|
||||
<div
|
||||
class="app-link"
|
||||
ng-repeat="link in switcher.getNavLinks() | orderBy:'title'"
|
||||
ng-repeat="link in switcher.getNavLinks()"
|
||||
ng-class="{ active: link.active }">
|
||||
|
||||
<a
|
||||
|
@ -9,8 +9,8 @@
|
|||
ng-href="{{ link.active ? link.url : (link.lastSubUrl || link.url) }}"
|
||||
data-test-subj="appLink">
|
||||
|
||||
<div ng-if="link.icon" ng-style="{ 'background-image': 'url(../' + link.icon + ')' }" class="app-icon"></div>
|
||||
<div ng-if="!link.icon" class="app-icon app-icon-missing">{{ link.title[0] }}</div>
|
||||
<div ng-if="link.icon" class="app-icon"><img kbn-src="{{'/' + link.icon}}"></div>
|
||||
<div ng-if="!link.icon" class="app-icon-missing">{{ link.title[0] }}</div>
|
||||
|
||||
<div class="app-title">{{ link.title }}</div>
|
||||
</a>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import DomLocationProvider from 'ui/dom_location';
|
||||
import { parse } from 'url';
|
||||
import { bindKey } from 'lodash';
|
||||
|
@ -8,14 +7,45 @@ import appSwitcherTemplate from './app_switcher.html';
|
|||
|
||||
uiModules
|
||||
.get('kibana')
|
||||
.provider('appSwitcherEnsureNavigation', function () {
|
||||
let forceNavigation = false;
|
||||
|
||||
this.forceNavigation = function (val) {
|
||||
forceNavigation = !!val;
|
||||
};
|
||||
|
||||
this.$get = ['Private', function (Private) {
|
||||
const domLocation = Private(DomLocationProvider);
|
||||
|
||||
return function (event) {
|
||||
if (!forceNavigation || event.isDefaultPrevented() || event.altKey || event.metaKey || event.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toParsed = parse(event.delegateTarget.href);
|
||||
const fromParsed = parse(domLocation.href);
|
||||
const sameProto = toParsed.protocol === fromParsed.protocol;
|
||||
const sameHost = toParsed.host === fromParsed.host;
|
||||
const samePath = toParsed.path === fromParsed.path;
|
||||
|
||||
if (sameProto && sameHost && samePath) {
|
||||
toParsed.hash && domLocation.reload();
|
||||
|
||||
// event.preventDefault() keeps the browser from seeing the new url as an update
|
||||
// and even setting window.location does not mimic that behavior, so instead
|
||||
// we use stopPropagation() to prevent angular from seeing the click and
|
||||
// starting a digest cycle/attempting to handle it in the router.
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
}];
|
||||
})
|
||||
.directive('appSwitcher', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: appSwitcherTemplate,
|
||||
controllerAs: 'switcher',
|
||||
controller: function ($scope, Private) {
|
||||
var domLocation = Private(DomLocationProvider);
|
||||
|
||||
controller($scope, appSwitcherEnsureNavigation) {
|
||||
// since we render this in an isolate scope we can't "require: ^chrome", but
|
||||
// rather than remove all helpfull checks we can just check here.
|
||||
if (!$scope.chrome || !$scope.chrome.getNavLinks) {
|
||||
|
@ -26,28 +56,7 @@ uiModules
|
|||
|
||||
// links don't cause full-navigation events in certain scenarios
|
||||
// so we force them when needed
|
||||
this.ensureNavigation = function (event, app) {
|
||||
if (event.isDefaultPrevented() || event.altKey || event.metaKey || event.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toParsed = parse(event.delegateTarget.href);
|
||||
var fromParsed = parse(domLocation.href);
|
||||
var sameProto = toParsed.protocol === fromParsed.protocol;
|
||||
var sameHost = toParsed.host === fromParsed.host;
|
||||
var samePath = toParsed.path === fromParsed.path;
|
||||
|
||||
if (sameProto && sameHost && samePath) {
|
||||
toParsed.hash && domLocation.reload();
|
||||
|
||||
// event.preventDefault() keeps the browser from seeing the new url as an update
|
||||
// and even setting window.location does not mimic that behavior, so instead
|
||||
// we use stopPropagation() to prevent angular from seeing the click and
|
||||
// starting a digest cycle/attempting to handle it in the router.
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
this.ensureNavigation = appSwitcherEnsureNavigation;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,55 +1,155 @@
|
|||
@import (reference) "~ui/styles/mixins";
|
||||
@import (reference) "~ui/styles/variables";
|
||||
|
||||
@app-icon-size: 48px;
|
||||
@app-icon-padding: 10px;
|
||||
body { overflow-x: hidden; }
|
||||
|
||||
.app-links-wrapper {
|
||||
width: @as-open-width;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
background-color: @app-links-wrapper-background;
|
||||
overflow: hidden;
|
||||
transition: width @transition-time;
|
||||
transition-delay: @transition-delay;
|
||||
|
||||
&:hover {
|
||||
.app-title {
|
||||
display: inline-block;
|
||||
}
|
||||
+ .app-wrapper {
|
||||
transform: translateX(@as-open-width - @as-closed-width);
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 70px;
|
||||
width: @as-open-width;
|
||||
list-style-type: none;
|
||||
&.kibana {
|
||||
background-image: url("~ui/images/kibana.svg");
|
||||
background-position: 6px 10px;
|
||||
background-size: 140px 50px;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #e8488b;
|
||||
}
|
||||
}
|
||||
.bottom-apps {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
.app-wrapper {
|
||||
.real-flex-parent();
|
||||
position: absolute;
|
||||
transition: transform @transition-time;
|
||||
transition-delay: @transition-delay;
|
||||
left: @as-closed-width;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
|
||||
&-panel {
|
||||
.flex-parent(@shrink: 0);
|
||||
box-shadow: -4px 0px 3px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.app-links {
|
||||
text-align: justify;
|
||||
|
||||
.app-link {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
width: @app-icon-size + (@app-icon-padding * 2);
|
||||
margin: 0px 10px;
|
||||
padding: @app-icon-padding;
|
||||
border-radius: @border-radius-base;
|
||||
width: @as-open-width;
|
||||
height: @app-icon-height;
|
||||
line-height: @app-line-height;
|
||||
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
height: 100%;
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: @app-links-active-background;
|
||||
}
|
||||
|
||||
.app-icon {
|
||||
display: block;
|
||||
height: @app-icon-size;
|
||||
width: @app-icon-size;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
border-radius: @border-radius-base;
|
||||
background-color: @gray-light;
|
||||
width: 100%;
|
||||
float: left;
|
||||
filter: invert(100%);
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
font-size: 1.7em;
|
||||
display: inline-block;
|
||||
height: @app-icon-height;
|
||||
width: @as-closed-width;
|
||||
|
||||
&-missing {
|
||||
text-align: center;
|
||||
font-size: 2.7em;
|
||||
font-weight: bold;
|
||||
font-family: @font-family-sans-serif;
|
||||
color: #fff;
|
||||
> img {
|
||||
height: 18px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.app-title {
|
||||
color: @text-color;
|
||||
font-size: 0.9em;
|
||||
width: 100%;
|
||||
.app-icon-missing {
|
||||
float: left;
|
||||
text-align: center;
|
||||
margin-top: 3px;
|
||||
font-size: 1.7em;
|
||||
display: inline-block;
|
||||
height: @app-icon-height;
|
||||
line-height: @app-icon-height;
|
||||
width: @as-closed-width;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
&:hover .app-title {
|
||||
text-decoration: underline;
|
||||
.app-title {
|
||||
width: calc(@as-open-width - @as-closed-width);
|
||||
display: inline-block;
|
||||
float: right;
|
||||
font-size: 0.9em;
|
||||
text-align: left;
|
||||
padding-left: 3px;
|
||||
line-height: @app-icon-height;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: @gray-lighter;
|
||||
.app-title {
|
||||
text-decoration: underline;
|
||||
background-color: @app-links-active-background;
|
||||
> a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
img {
|
||||
filter: invert(100%);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
background-color: @firstLinkColor;
|
||||
&:hover {
|
||||
background-color: lighten(@firstLinkColor, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
background-color: @secondLinkColor;
|
||||
&:hover {
|
||||
background-color: lighten(@secondLinkColor, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
background-color: @thirdLinkColor;
|
||||
&:hover {
|
||||
background-color: lighten(@thirdLinkColor, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ export default function (chrome, internals) {
|
|||
const onRouteChange = function () {
|
||||
let { href } = window.location;
|
||||
let persist = chrome.getVisible();
|
||||
internals.trackPossibleSubUrl(href);
|
||||
internals.tabs.consumeRouteUpdate(href, persist);
|
||||
internals.trackPossibleSubUrl(href);
|
||||
};
|
||||
|
||||
$rootScope.$on('$routeChangeSuccess', onRouteChange);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import notify from 'ui/notify';
|
||||
import _ from 'lodash';
|
||||
import { escapeRegExp as reEsc } from 'lodash';
|
||||
import { parse, format } from 'url';
|
||||
|
@ -28,7 +29,16 @@ export default class Tab {
|
|||
|
||||
this.lastUrlStoreKey = `lastUrl:${this.id}`;
|
||||
this.lastUrlStore = spec.lastUrlStore;
|
||||
this.lastUrl = this.lastUrlStore ? this.lastUrlStore.getItem(this.lastUrlStoreKey) : null;
|
||||
|
||||
this.lastUrl = null;
|
||||
if (this.lastUrlStore) {
|
||||
this.lastUrl = this.lastUrlStore.getItem(this.lastUrlStoreKey);
|
||||
if (this.lastUrl && !this.lastUrl.startsWith(this.rootUrl)) {
|
||||
notify.log(`Found invalid lastUrl for tab with root url ${this.rootUrl}: "${this.lastUrl}"`);
|
||||
this.lastUrl = null;
|
||||
this.lastUrlStore.removeItem(this.lastUrlStoreKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
href() {
|
||||
|
@ -54,7 +64,8 @@ export default class Tab {
|
|||
let lastUrl = this.getLastUrl();
|
||||
|
||||
if (!lastUrl.startsWith(rootUrl)) {
|
||||
throw new Error(`Tab "${id}" has invalid root "${rootUrl}" for last url "${lastUrl}"`);
|
||||
notify.log(`Tab "${id}" has invalid root "${rootUrl}" for last url "${lastUrl}"`);
|
||||
lastUrl = rootUrl;
|
||||
}
|
||||
|
||||
return lastUrl.slice(rootUrl.length);
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
z-index: 1;
|
||||
|
||||
.sidebar-collapser {
|
||||
background-color: @collapser-bg;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -(@collapser-width);
|
||||
|
@ -14,21 +12,15 @@
|
|||
cursor: pointer;
|
||||
z-index: -1;
|
||||
|
||||
&:hover {
|
||||
background-color: @collapser-hover-bg;
|
||||
border-color: @collapser-hover-bg;
|
||||
color: @collapser-hover-color;
|
||||
}
|
||||
|
||||
.chevron-cont{
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 8px;
|
||||
font-size: 10px;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
color: @kibanaGray4;
|
||||
|
||||
&:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\F053";
|
||||
content: "\F137";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +37,7 @@
|
|||
.sidebar-collapser {
|
||||
visibility: visible;
|
||||
.chevron-cont:before {
|
||||
content: "\F054";
|
||||
content: "\F138";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import moment from 'moment-timezone';
|
|||
import _ from 'lodash';
|
||||
|
||||
export default function configDefaultsProvider() {
|
||||
// wraped in provider so that a new instance is given to each app/test
|
||||
// wrapped in provider so that a new instance is given to each app/test
|
||||
|
||||
return {
|
||||
'buildNum': {
|
||||
|
@ -112,7 +112,7 @@ export default function configDefaultsProvider() {
|
|||
'visualization:colorMapping': {
|
||||
type: 'json',
|
||||
value: JSON.stringify({
|
||||
'Count': '#57c17b'
|
||||
'Count': '#6eadc1'
|
||||
}),
|
||||
description: 'Maps values to specified colors within visualizations'
|
||||
},
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import angular from 'angular';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import $ from 'jquery';
|
||||
import 'plugins/kibana/discover/index';
|
||||
|
||||
|
||||
var $parentScope;
|
||||
|
||||
var $scope;
|
||||
|
||||
var $elem;
|
||||
|
||||
var init = function () {
|
||||
// Load the application
|
||||
ngMock.module('kibana');
|
||||
|
||||
// Create the scope
|
||||
ngMock.inject(function ($rootScope, $compile) {
|
||||
|
||||
// Give us a scope
|
||||
$parentScope = $rootScope;
|
||||
|
||||
// Create the element
|
||||
$elem = angular.element(
|
||||
'<span class="spinner"></span>'
|
||||
);
|
||||
|
||||
// And compile it
|
||||
$compile($elem)($parentScope);
|
||||
|
||||
// Fire a digest cycle
|
||||
$elem.scope().$digest();
|
||||
|
||||
// Grab the isolate scope so we can test it
|
||||
$scope = $elem.isolateScope();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
describe('spinner directive', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
init();
|
||||
});
|
||||
|
||||
it('should contain 3 divs', function (done) {
|
||||
expect($elem.children('div').length).to.be(3);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
21
src/ui/public/directives/bread_crumbs.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import _ from 'lodash';
|
||||
import chrome from 'ui/chrome/chrome';
|
||||
import breadCrumbsTemplate from 'ui/partials/bread_crumbs.html';
|
||||
import uiModules from 'ui/modules';
|
||||
var module = uiModules.get('kibana');
|
||||
|
||||
module.directive('breadCrumbs', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: true,
|
||||
template: breadCrumbsTemplate,
|
||||
controller: function ($scope) {
|
||||
$scope.crumbs = chrome.getBreadcrumbs();
|
||||
|
||||
if (_.last($scope.crumbs) === '') {
|
||||
// Remove the empty string from the end of the array
|
||||
$scope.crumbs.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
|
@ -57,8 +57,8 @@ module.directive('config', function ($compile) {
|
|||
html = $compile('' +
|
||||
'<div class="config" ng-show="configTemplate">' +
|
||||
wrapTmpl(tmpl) +
|
||||
' <div class="config-close remove" ng-click="close()">' +
|
||||
' <i class="fa fa-chevron-up"></i>' +
|
||||
' <div class="config-close remove">' +
|
||||
' <i class="fa fa-chevron-circle-up" ng-click="close()"></i>' +
|
||||
' </div>' +
|
||||
'</div>' +
|
||||
''
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import UiModules from 'ui/modules';
|
||||
import chrome from 'ui/chrome';
|
||||
import { words, camelCase, kebabCase } from 'lodash';
|
||||
|
||||
export function kbnUrlDirective(name) {
|
||||
|
@ -8,7 +7,7 @@ export function kbnUrlDirective(name) {
|
|||
|
||||
UiModules
|
||||
.get('kibana')
|
||||
.directive(name, function (Private) {
|
||||
.directive(name, function (Private, chrome) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function ($scope, $el, $attr) {
|
||||
|
|
|
@ -48,6 +48,23 @@ module.directive('savedObjectFinder', function ($location, $injector, kbnUrl, Pr
|
|||
|
||||
filterResults();
|
||||
|
||||
/**
|
||||
* Boolean that keeps track of whether hits are sorted ascending (true)
|
||||
* or descending (false) by title
|
||||
* @type {Boolean}
|
||||
*/
|
||||
self.isAscending = true;
|
||||
|
||||
/**
|
||||
* Sorts saved object finder hits either ascending or descending
|
||||
* @param {Array} hits Array of saved finder object hits
|
||||
* @return {Array} Array sorted either ascending or descending
|
||||
*/
|
||||
self.sortHits = function (hits) {
|
||||
self.isAscending = !self.isAscending;
|
||||
self.hits = self.isAscending ? _.sortBy(hits, 'title') : _.sortBy(hits, 'title').reverse();
|
||||
};
|
||||
|
||||
/**
|
||||
* Passed the hit objects and will determine if the
|
||||
* hit should have a url in the UI, returns it if so
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import uiModules from 'ui/modules';
|
||||
var html = '<div class="bounce1"></div> <div class="bounce2"></div> <div class="bounce3"></div>';
|
||||
var module = uiModules.get('kibana');
|
||||
|
||||
module.directive('spinner', function () {
|
||||
return {
|
||||
restrict: 'C',
|
||||
template: html
|
||||
};
|
||||
});
|
||||
|
|
@ -47,13 +47,12 @@ filter-bar .confirm {
|
|||
}
|
||||
|
||||
filter-bar .bar {
|
||||
padding: 6px 6px 4px 6px;
|
||||
padding: 5px 6px 3px 6px;
|
||||
background: @filter-bar-bar-bg;
|
||||
border-bottom: 1px solid;
|
||||
border-bottom-color: @filter-bar-bar-border;
|
||||
border-bottom: 0;
|
||||
|
||||
&-condensed {
|
||||
padding: 2px 6px 0px 6px !important;
|
||||
padding: 6px 6px 2px 6px !important;
|
||||
font-size: 0.9em;
|
||||
background: @filter-bar-bar-condensed-bg;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
|
@ -9,132 +7,104 @@
|
|||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="252px"
|
||||
height="45px"
|
||||
viewBox="0 0 252 45"
|
||||
enable-background="new 0 0 252 45"
|
||||
xml:space="preserve"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 141.37 51"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="kibana.svg"><metadata
|
||||
id="metadata4270"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs4268" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
sodipodi:docname="kibana.svg">
|
||||
<metadata
|
||||
id="metadata31">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Kibana-Full-Logo</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#515151"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2046"
|
||||
inkscape:window-height="1132"
|
||||
id="namedview4266"
|
||||
inkscape:window-width="1796"
|
||||
inkscape:window-height="1079"
|
||||
id="namedview29"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.0416667"
|
||||
inkscape:cx="126"
|
||||
inkscape:cy="22.5"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:zoom="2.0725756"
|
||||
inkscape:cx="70.684998"
|
||||
inkscape:cy="25.5"
|
||||
inkscape:window-x="349"
|
||||
inkscape:window-y="210"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1" /><font
|
||||
horiz-adv-x="1000"
|
||||
id="font4232"><!-- "Helvetica Neue" is a trademark of Heidelberger Druckmaschinen AG, which may be registered in certain jurisdictions, exclusivly licensed through Linotype Library GmbH, a wholly owned subsidiary of Heidelberger Druckmaschinen AG. --><font-face
|
||||
font-family="HelveticaNeue-Bold"
|
||||
units-per-em="1000"
|
||||
underline-position="-100"
|
||||
underline-thickness="50"
|
||||
id="font-face4234" /><missing-glyph
|
||||
horiz-adv-x="500"
|
||||
d="M391,607l-280,0l0,-512l280,0M482,698l0,-695l-465,0l0,695z"
|
||||
id="missing-glyph4236" /><glyph
|
||||
unicode="a"
|
||||
horiz-adv-x="574"
|
||||
d="M48,358C50,391 58,419 73,441C88,463 106,481 129,494C152,507 177,517 206,523C234,528 262,531 291,531C317,531 343,529 370,526C397,522 421,515 443,504C465,493 483,479 497,460C511,441 518,415 518,384l0,-269C518,92 519,69 522,48C525,27 529,11 536,0l-144,0C389,8 387,16 386,25C384,33 383,41 382,50C359,27 333,10 302,1C271,-8 240,-13 208,-13C183,-13 160,-10 139,-4C118,2 99,11 83,24C67,37 55,53 46,72C37,91 32,114 32,141C32,170 37,195 48,214C58,233 71,248 88,259C104,270 123,279 144,285C165,290 186,295 207,298C228,301 249,304 270,306C291,308 309,311 325,315C341,319 354,325 363,333C372,340 377,351 376,366C376,381 374,394 369,403C364,412 357,419 349,424C340,429 331,432 320,434C309,435 297,436 284,436C256,436 234,430 218,418C202,406 193,386 190,358M376,253C370,248 363,244 354,241C345,238 335,235 325,233C314,231 303,229 292,228C281,227 269,225 258,223C247,221 237,218 227,215C216,212 207,207 200,202C192,196 186,189 181,180C176,171 174,160 174,147C174,134 176,124 181,115C186,106 192,100 200,95C208,90 217,86 228,84C239,82 250,81 261,81C289,81 311,86 326,95C341,104 353,116 360,129C367,142 372,155 374,168C375,181 376,192 376,200z"
|
||||
id="glyph4238" /><glyph
|
||||
unicode="b"
|
||||
horiz-adv-x="611"
|
||||
d="M433,258C433,237 431,216 426,196C421,176 414,158 404,143C394,128 382,116 367,107C352,98 333,93 312,93C291,93 273,98 258,107C243,116 230,128 220,143C210,158 203,176 198,196C193,216 191,237 191,258C191,280 193,301 198,321C203,341 210,359 220,374C230,389 243,402 258,411C273,420 291,424 312,424C333,424 352,420 367,411C382,402 394,389 404,374C414,359 421,341 426,321C431,301 433,280 433,258M54,714l0,-714l135,0l0,66l2,0C206,37 229,17 259,5C289,-7 323,-13 361,-13C387,-13 413,-8 438,3C463,14 486,30 507,52C527,74 543,102 556,137C569,171 575,212 575,259C575,306 569,347 556,382C543,416 527,444 507,466C486,488 463,504 438,515C413,526 387,531 361,531C329,531 298,525 269,513C239,500 215,481 198,454l-2,0l0,260z"
|
||||
id="glyph4240" /><glyph
|
||||
unicode="i"
|
||||
horiz-adv-x="258"
|
||||
d="M200,597l0,117l-142,0l0,-117M58,517l0,-517l142,0l0,517z"
|
||||
id="glyph4242" /><glyph
|
||||
unicode="k"
|
||||
horiz-adv-x="574"
|
||||
d="M67,714l0,-714l142,0l0,178l55,53l142,-231l172,0l-217,327l195,190l-168,0l-179,-186l0,383z"
|
||||
id="glyph4244" /><glyph
|
||||
unicode="n"
|
||||
horiz-adv-x="593"
|
||||
d="M54,517l0,-517l142,0l0,271C196,324 205,362 222,385C239,408 267,419 306,419C340,419 364,409 377,388C390,367 397,335 397,292l0,-292l142,0l0,318C539,350 536,379 531,406C525,432 515,454 501,473C487,491 468,505 444,516C419,526 388,531 350,531C320,531 291,524 262,511C233,497 210,475 192,445l-3,0l0,72z"
|
||||
id="glyph4246" /></font><rect
|
||||
fill="#3C3C3C"
|
||||
width="252"
|
||||
height="45"
|
||||
id="rect4248"
|
||||
style="opacity:1" /><rect
|
||||
fill="#85C441"
|
||||
width="6.094"
|
||||
height="45"
|
||||
id="rect4250"
|
||||
style="opacity:1" /><rect
|
||||
x="5.958"
|
||||
fill="#2C448E"
|
||||
width="6.094"
|
||||
height="45"
|
||||
id="rect4252"
|
||||
style="opacity:1" /><rect
|
||||
x="12.052"
|
||||
fill="#F2BB1A"
|
||||
width="9.847"
|
||||
height="45"
|
||||
id="rect4254"
|
||||
style="opacity:1" /><rect
|
||||
x="21.899"
|
||||
fill="#3BBEB1"
|
||||
width="6.068"
|
||||
height="45"
|
||||
id="rect4256"
|
||||
style="opacity:1" /><rect
|
||||
x="28.029"
|
||||
fill="#006656"
|
||||
width="2.84"
|
||||
height="45"
|
||||
id="rect4258"
|
||||
style="opacity:1" /><rect
|
||||
x="30.869"
|
||||
fill="#EA458B"
|
||||
width="15.006"
|
||||
height="45"
|
||||
id="rect4260"
|
||||
style="opacity:1" /><rect
|
||||
x="41.5"
|
||||
fill="none"
|
||||
width="207.5"
|
||||
height="74"
|
||||
id="rect4262" /><g
|
||||
style="font-size:64.99947357px;font-family:HelveticaNeue-Bold;letter-spacing:-2.99203849px;opacity:1;fill:#ffffff"
|
||||
id="text4264"><path
|
||||
d="m 45.721,-0.49421886 0,46.40962386 9.229925,0 0,-11.569906 3.574971,-3.444972 9.229926,15.014878 11.179909,0 -14.104886,-21.254828 12.674898,-12.3499 -10.919912,0 -11.634906,12.089903 0,-24.89479886 -9.229925,0 z"
|
||||
style="letter-spacing:-1.33094156px"
|
||||
id="path4912" /><path
|
||||
d="m 90.358907,7.1107196 0,-7.60493846 -9.229925,0 0,7.60493846 9.229925,0 z m -9.229925,5.1999574 0,33.604728 9.229925,0 0,-33.604728 -9.229925,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';letter-spacing:-2.87854815px"
|
||||
id="path4914" /><path
|
||||
d="m 119.38291,29.145541 q 0,2.079983 -0.45499,4.029967 -0.455,1.949985 -1.42999,3.444973 -0.97499,1.494987 -2.46998,2.40498 -1.42999,0.844993 -3.50997,0.844993 -2.01499,0 -3.50998,-0.844993 -1.49498,-0.909993 -2.46998,-2.40498 -0.97499,-1.494988 -1.42998,-3.444973 -0.455,-1.949984 -0.455,-4.029967 0,-2.144983 0.455,-4.094967 0.45499,-1.949984 1.42998,-3.444972 0.975,-1.494988 2.46998,-2.339981 1.49499,-0.909993 3.50998,-0.909993 2.07998,0 3.50997,0.909993 1.49499,0.844993 2.46998,2.339981 0.97499,1.494988 1.42999,3.444972 0.45499,1.949984 0.45499,4.094967 z m -24.634798,-29.63975986 0,46.40962386 8.774928,0 0,-4.289965 0.13,0 q 1.49499,2.794977 4.41996,3.964968 2.92498,1.16999 6.62995,1.16999 2.53498,0 5.00496,-1.039991 2.46998,-1.039992 4.41996,-3.184974 2.01499,-2.144983 3.24998,-5.459956 1.23499,-3.379973 1.23499,-7.994935 0,-4.614963 -1.23499,-7.929936 -1.23499,-3.379973 -3.24998,-5.524955 -1.94998,-2.144983 -4.41996,-3.184975 -2.46998,-1.039991 -5.00496,-1.039991 -3.11997,0 -6.04495,1.23499 -2.85998,1.16999 -4.54996,3.769969 l -0.13,0 0,-16.89986286 -9.229928,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';letter-spacing:-2.87854815px"
|
||||
id="path4916" /><path
|
||||
d="m 131.21557,22.645594 q 0.195,-3.249974 1.62499,-5.394957 1.42999,-2.144982 3.63997,-3.444972 2.20998,-1.299989 4.93996,-1.819985 2.79498,-0.584995 5.58995,-0.584995 2.53498,0 5.13496,0.389997 2.59998,0.324997 4.74496,1.364989 2.14499,1.039991 3.50997,2.924976 1.36499,1.819985 1.36499,4.87496 l 0,17.484859 q 0,2.274981 0.26,4.354965 0.26,2.079983 0.90999,3.119974 l -9.35992,0 q -0.26,-0.779993 -0.455,-1.559987 -0.13,-0.844993 -0.19499,-1.689986 -2.20999,2.274981 -5.19996,3.184974 -2.98998,0.909992 -6.10995,0.909992 -2.40498,0 -4.48497,-0.584995 -2.07998,-0.584995 -3.63997,-1.819985 -1.55998,-1.23499 -2.46998,-3.119975 -0.84499,-1.884985 -0.84499,-4.484964 0,-2.859976 0.97499,-4.679962 1.03999,-1.884984 2.59998,-2.989975 1.62499,-1.104991 3.63997,-1.624987 2.07998,-0.584995 4.15997,-0.909993 2.07998,-0.324997 4.09496,-0.519996 2.01499,-0.194998 3.57498,-0.584995 1.55998,-0.389997 2.46998,-1.104991 0.90999,-0.779994 0.84499,-2.209982 0,-1.494988 -0.52,-2.339981 -0.45499,-0.909993 -1.29999,-1.364989 -0.77999,-0.519996 -1.88498,-0.649995 -1.03999,-0.194998 -2.27498,-0.194998 -2.72998,0 -4.28997,1.16999 -1.55999,1.169991 -1.81998,3.899969 l -9.22993,0 z m 21.31983,6.824944 q -0.585,0.519996 -1.49499,0.844994 -0.84499,0.259998 -1.88498,0.454996 -0.975,0.194998 -2.07999,0.324997 -1.10499,0.129999 -2.20998,0.324998 -1.03999,0.194998 -2.07998,0.519995 -0.97499,0.324998 -1.75499,0.909993 -0.71499,0.519996 -1.16999,1.364989 -0.455,0.844993 -0.455,2.144983 0,1.23499 0.455,2.079983 0.455,0.844993 1.23499,1.364989 0.77999,0.454996 1.81999,0.649994 1.03999,0.194999 2.14498,0.194999 2.72998,0 4.22496,-0.909993 1.49499,-0.909992 2.20999,-2.144982 0.71499,-1.29999 0.84499,-2.599979 0.195,-1.29999 0.195,-2.079983 l 0,-3.444973 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';letter-spacing:-2.87854815px"
|
||||
id="path4918" /><path
|
||||
d="m 165.92399,12.310677 0,33.604728 9.22992,0 0,-17.614857 q 0,-5.134958 1.68999,-7.344941 1.68999,-2.274981 5.45996,-2.274981 3.31497,0 4.61496,2.079983 1.29999,2.014984 1.29999,6.17495 l 0,18.979846 9.22992,0 0,-20.669832 q 0,-3.119975 -0.58499,-5.654955 -0.52,-2.599978 -1.88499,-4.354964 -1.36499,-1.819986 -3.76997,-2.794978 -2.33998,-1.039991 -6.04495,-1.039991 -2.92497,0 -5.71995,1.364989 -2.79498,1.299989 -4.54996,4.224966 l -0.195,0 0,-4.679963 -8.77493,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';letter-spacing:-2.87854815px"
|
||||
id="path4920" /><path
|
||||
d="m 201.24887,22.645594 q 0.195,-3.249974 1.62499,-5.394957 1.42999,-2.144982 3.63997,-3.444972 2.20998,-1.299989 4.93996,-1.819985 2.79498,-0.584995 5.58996,-0.584995 2.53497,0 5.13495,0.389997 2.59998,0.324997 4.74497,1.364989 2.14498,1.039991 3.50997,2.924976 1.36499,1.819985 1.36499,4.87496 l 0,17.484859 q 0,2.274981 0.25999,4.354965 0.26,2.079983 0.91,3.119974 l -9.35993,0 q -0.26,-0.779993 -0.45499,-1.559987 -0.13,-0.844993 -0.195,-1.689986 -2.20998,2.274981 -5.19996,3.184974 -2.98998,0.909992 -6.10995,0.909992 -2.40498,0 -4.48496,-0.584995 -2.07999,-0.584995 -3.63998,-1.819985 -1.55998,-1.23499 -2.46998,-3.119975 -0.84499,-1.884985 -0.84499,-4.484964 0,-2.859976 0.97499,-4.679962 1.04,-1.884984 2.59998,-2.989975 1.62499,-1.104991 3.63997,-1.624987 2.07999,-0.584995 4.15997,-0.909993 2.07998,-0.324997 4.09497,-0.519996 2.01498,-0.194998 3.57497,-0.584995 1.55998,-0.389997 2.46998,-1.104991 0.90999,-0.779994 0.84499,-2.209982 0,-1.494988 -0.52,-2.339981 -0.45499,-0.909993 -1.29998,-1.364989 -0.78,-0.519996 -1.88499,-0.649995 -1.03999,-0.194998 -2.27498,-0.194998 -2.72998,0 -4.28997,1.16999 -1.55998,1.169991 -1.81998,3.899969 l -9.22993,0 z m 21.31983,6.824944 q -0.58499,0.519996 -1.49499,0.844994 -0.84499,0.259998 -1.88498,0.454996 -0.97499,0.194998 -2.07999,0.324997 -1.10499,0.129999 -2.20998,0.324998 -1.03999,0.194998 -2.07998,0.519995 -0.97499,0.324998 -1.75499,0.909993 -0.71499,0.519996 -1.16999,1.364989 -0.45499,0.844993 -0.45499,2.144983 0,1.23499 0.45499,2.079983 0.455,0.844993 1.23499,1.364989 0.78,0.454996 1.81999,0.649994 1.03999,0.194999 2.14498,0.194999 2.72998,0 4.22497,-0.909993 1.49498,-0.909992 2.20998,-2.144982 0.71499,-1.29999 0.84499,-2.599979 0.195,-1.29999 0.195,-2.079983 l 0,-3.444973 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Helvetica Neue';-inkscape-font-specification:'Helvetica Neue Bold';letter-spacing:-2.87854815px"
|
||||
id="path4922" /></g></svg>
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<style
|
||||
id="style5">.cls-1,.cls-2,.cls-3,.cls-4{fill:#fff;}.cls-1{opacity:0.6;}.cls-2{opacity:0.4;}.cls-3{opacity:0.9;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title7">Kibana-Full-Logo</title>
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M409.68,273.59a38.94,38.94,0,0,1,18.71,4.76L448.2,254.5H408.94v19.11Z"
|
||||
transform="translate(-408.94 -254.5)"
|
||||
id="path9" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M428.39,278.35l-19.45,23.42v3.73h39.2A39.2,39.2,0,0,0,428.39,278.35Z"
|
||||
transform="translate(-408.94 -254.5)"
|
||||
id="path11" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M428.39,278.35l-19.45,23.42v3.73h7l18.87-22.77s-1.25-1.06-3-2.3C430.41,279.46,428.39,278.35,428.39,278.35Z"
|
||||
transform="translate(-408.94 -254.5)"
|
||||
id="path13" />
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M409.68,273.59l-0.74,0v28.17l19.45-23.42A38.94,38.94,0,0,0,409.68,273.59Z"
|
||||
transform="translate(-408.94 -254.5)"
|
||||
id="path15" />
|
||||
<g
|
||||
style="font-style:normal;font-weight:normal;font-size:33.04906845px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:0.92528737;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4159"
|
||||
transform="translate(0,-13.509761)">
|
||||
<path
|
||||
d="m 53.346838,50.53812 0,-6.74201 2.14819,-0.231343 4.031986,6.973353 4.065036,0 -5.023459,-8.791052 4.759066,-7.733482 -4.031986,0 -3.89979,6.444568 -2.049043,0.198295 0,-13.517069 -3.602348,0 0,23.39874 3.602348,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4891"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 66.269024,50.53812 3.602349,0 0,-16.524534 -3.602349,0 0,16.524534 z m 0,-19.333705 3.602349,0 0,-3.800643 -3.602349,0 0,3.800643 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4893"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 81.973529,33.650046 c -1.850747,0 -4.131133,0.991472 -4.131133,0.991472 l 0,-7.502138 -3.5693,0 0,23.365691 c 0,0 4.296379,0.396589 6.04798,0.396589 5.915783,0 8.063973,-2.015993 8.063973,-8.85715 0,-6.180176 -1.916846,-8.394464 -6.41152,-8.394464 z M 80.321076,47.6959 c -0.660981,0 -2.47868,-0.132196 -2.47868,-0.132196 l 0,-10.046917 c 0,0 1.949895,-0.660981 3.701495,-0.660981 2.214288,0 3.172711,1.454159 3.172711,5.188704 0,4.031986 -0.727079,5.65139 -4.395526,5.65139 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4895"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 104.18766,39.103143 c 0,-3.767594 -1.65245,-5.453097 -5.684435,-5.453097 -3.040515,0 -6.642863,0.859276 -6.642863,0.859276 l 0.132196,2.544778 c 0,0 3.998938,-0.33049 6.213225,-0.33049 1.619405,0 2.412587,0.561834 2.412587,2.379533 l 0,1.189766 -4.263335,0.36354 c -3.53625,0.297441 -5.453096,1.487208 -5.453096,4.990409 0,3.437103 1.652453,5.254802 4.924311,5.254802 2.676975,0 5.3209,-1.222816 5.3209,-1.222816 1.22282,0.958423 2.37953,1.222816 4.39553,1.222816 l 0.0991,-2.743073 c -0.95842,-0.132196 -1.38806,-0.528785 -1.45416,-1.520257 l 0,-7.535187 z m -3.56929,3.734544 0,4.395526 c 0,0 -2.214292,0.72708 -4.098089,0.72708 -1.388061,0 -2.015993,-0.925374 -2.015993,-2.412582 0,-1.487208 0.760128,-2.214288 2.280385,-2.346484 l 3.833697,-0.36354 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4897"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 112.28004,50.53812 0,-12.823038 c 0,0 1.8177,-0.859276 3.73454,-0.859276 2.51173,0 2.94137,1.619404 2.94137,4.924311 l 0,8.758003 3.5693,0 0,-8.85715 c 0,-5.420047 -1.12367,-8.030924 -5.71749,-8.030924 -2.14819,0 -4.56077,1.388061 -4.56077,1.388061 l 0,-1.024521 -3.5693,0 0,16.524534 3.60235,0 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4899"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 138.91501,39.103143 c 0,-3.767594 -1.65246,-5.453097 -5.68444,-5.453097 -3.04052,0 -6.64287,0.859276 -6.64287,0.859276 l 0.1322,2.544778 c 0,0 3.99894,-0.33049 6.21322,-0.33049 1.61941,0 2.41259,0.561834 2.41259,2.379533 l 0,1.189766 -4.26333,0.36354 c -3.53625,0.297441 -5.4531,1.487208 -5.4531,4.990409 0,3.437103 1.65245,5.254802 4.92431,5.254802 2.67698,0 5.3209,-1.222816 5.3209,-1.222816 1.22282,0.958423 2.37953,1.222816 4.39553,1.222816 l 0.0991,-2.743073 c -0.95842,-0.132196 -1.38806,-0.528785 -1.45415,-1.520257 l 0,-7.535187 z m -3.5693,3.734544 0,4.395526 c 0,0 -2.21429,0.72708 -4.09809,0.72708 -1.38806,0 -2.01599,-0.925374 -2.01599,-2.412582 0,-1.487208 0.76013,-2.214288 2.28038,-2.346484 l 3.8337,-0.36354 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#ffffff;fill-opacity:0.92528737"
|
||||
id="path4901"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.9 KiB |
|
@ -33,5 +33,4 @@
|
|||
<!-- auto-inserted by the paginate directive... -->
|
||||
<!-- <paginate-controls></paginate-controls> -->
|
||||
<div class="pagination-container" ng-transclude></div>
|
||||
|
||||
</paginate>
|
||||
|
|
6
src/ui/public/partials/bread_crumbs.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<ul>
|
||||
<li ng-repeat="crumb in crumbs">
|
||||
<span>{{crumb}}</span>
|
||||
<span ng-hide="$last"> / </span>
|
||||
</li>
|
||||
</ul>
|
|
@ -2,7 +2,7 @@
|
|||
<form role="form" class="container-fluid" ng-submit="configSubmit()">
|
||||
<div ng-bind-template="{{configTemplate}}" />
|
||||
</form>
|
||||
<div class="config-close remove" ng-click="close()">
|
||||
<i class="fa fa-chevron-up" />
|
||||
<div class="config-close remove">
|
||||
<i class="fa fa-chevron-circle-up" ng-click="close()"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,26 +1,42 @@
|
|||
<form role="form">
|
||||
<div class="form-group finder-form">
|
||||
<div class="finder-form-options">
|
||||
<a class="small" ng-click="finder.manageObjects(finder.properties.name)">manage {{finder.properties.nouns}}</a>
|
||||
<form role="form" class="form-inline">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="input-group form-group finder-form col-md-7">
|
||||
<span class="input-group-addon">
|
||||
<i class="fa fa-search"></i>
|
||||
</span>
|
||||
<input
|
||||
input-focus
|
||||
ng-model="filter"
|
||||
ng-attr-placeholder="{{finder.properties.nouns}} Filter..."
|
||||
ng-keydown="finder.filterKeyDown($event)"
|
||||
class="form-control"
|
||||
name="filter"
|
||||
type="text"
|
||||
autocomplete="off" />
|
||||
</div>
|
||||
<div class="finder-hit-count col-md-2">
|
||||
<span>{{finder.hitCount}} of {{finder.hitCount}}</span>
|
||||
</div>
|
||||
<div class="finder-manage-object col-md-2">
|
||||
<a class="small" ng-click="finder.manageObjects(finder.properties.name)">Manage {{finder.properties.nouns}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix visible-xs-block"></div>
|
||||
<input
|
||||
input-focus
|
||||
ng-model="filter"
|
||||
ng-attr-placeholder="{{finder.properties.noun}} Filter"
|
||||
ng-keydown="finder.filterKeyDown($event)"
|
||||
class="form-control"
|
||||
name="filter"
|
||||
type="text"
|
||||
autocomplete="off" />
|
||||
|
||||
<span class="finder-hit-count"><strong>{{finder.hitCount}}</strong> {{finder.hitCountNoun()}}</span>
|
||||
</div>
|
||||
</form>
|
||||
<paginate list="finder.hits" per-page="{{perPage}}">
|
||||
<ul
|
||||
class="list-group list-group-menu"
|
||||
ng-class="{'select-mode': finder.selector.enabled}">
|
||||
<paginate list="finder.hits" per-page="20">
|
||||
<ul class="li-striped list-group list-group-menu" ng-class="{'select-mode': finder.selector.enabled}">
|
||||
|
||||
<li class="list-group-item list-group-menu-item">
|
||||
<span class="paginate-heading">
|
||||
Name
|
||||
<i
|
||||
class="fa"
|
||||
ng-click="finder.sortHits(finder.hits)"
|
||||
ng-class="finder.isAscending ? 'fa-caret-up' : 'fa-caret-down'">
|
||||
</i>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="list-group-item list-group-menu-item"
|
||||
|
@ -29,19 +45,20 @@
|
|||
ng-keydown="finder.hitKeyDown($event, page, paginate)"
|
||||
ng-click="finder.onChoose(hit, $event)">
|
||||
|
||||
<a
|
||||
ng-href="{{finder.makeUrl(hit)}}"
|
||||
ng-blur="finder.hitBlur($event)"
|
||||
ng-click="finder.preventClick($event)">
|
||||
|
||||
<i aria-hidden="true" class="fa" ng-if="hit.icon" ng-class="hit.icon"></i> {{hit.title}}
|
||||
<p ng-if="hit.description" ng-bind="hit.description"></p>
|
||||
<a ng-href="{{finder.makeUrl(hit)}}"
|
||||
ng-blur="finder.hitBlur($event)"
|
||||
ng-click="finder.preventClick($event)">
|
||||
<i aria-hidden="true" class="finder-type fa" ng-if="hit.icon" ng-class="hit.icon"></i>
|
||||
<span>{{hit.title}}</span>
|
||||
<p ng-if="hit.description" ng-bind="hit.description"></p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="list-group-item list-group-no-results"
|
||||
ng-if="finder.hits.length === 0">
|
||||
<p ng-bind="'No matching ' + finder.properties.nouns + ' found.'"></p>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</paginate>
|
||||
|
|
124
src/ui/public/share/__tests__/url_shortener.js
Normal file
|
@ -0,0 +1,124 @@
|
|||
import _ from 'lodash';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import chrome from 'ui/chrome';
|
||||
import LibUrlShortenerProvider from 'ui/share/lib/url_shortener';
|
||||
|
||||
describe('Url shortener', () => {
|
||||
let $rootScope;
|
||||
let $location;
|
||||
let $http;
|
||||
let urlShortener;
|
||||
let $httpBackend;
|
||||
const shareId = 'id123';
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (_$rootScope_, _$location_, _$httpBackend_, Private) {
|
||||
$location = _$location_;
|
||||
$rootScope = _$rootScope_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
urlShortener = Private(LibUrlShortenerProvider);
|
||||
}));
|
||||
|
||||
describe('Shorten without base path', () => {
|
||||
it('should shorten urls with a port', function (done) {
|
||||
$httpBackend.when('POST', '/shorten').respond(function (type, route, data) {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana#123');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl('http://localhost:5601/app/kibana#123').then(function (url) {
|
||||
expect(url).to.be(`http://localhost:5601/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should shorten urls without a port', function (done) {
|
||||
$httpBackend.when('POST', '/shorten').respond(function (type, route, data) {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana#123');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl('http://localhost/app/kibana#123').then(function (url) {
|
||||
expect(url).to.be(`http://localhost/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shorten with base path', () => {
|
||||
const basePath = '/foo';
|
||||
|
||||
let getBasePath;
|
||||
beforeEach(ngMock.inject((Private) => {
|
||||
getBasePath = sinon.stub(chrome, 'getBasePath', () => basePath);
|
||||
urlShortener = Private(LibUrlShortenerProvider);
|
||||
}));
|
||||
|
||||
it('should shorten urls with a port', (done) => {
|
||||
$httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana#123');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl(`http://localhost:5601${basePath}/app/kibana#123`).then((url) => {
|
||||
expect(url).to.be(`http://localhost:5601${basePath}/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should shorten urls without a port', (done) => {
|
||||
$httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana#123');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana#123`).then((url) => {
|
||||
expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should shorten urls with a query string', (done) => {
|
||||
$httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana?foo#123');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana?foo#123`).then((url) => {
|
||||
expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should shorten urls without a hash', (done) => {
|
||||
$httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
|
||||
expect(JSON.parse(data).url).to.be('/app/kibana');
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana`).then((url) => {
|
||||
expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
it('should shorten urls with a query string in the hash', (done) => {
|
||||
const relativeUrl = "/app/kibana#/discover?_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-15m,mode:quick,to:now))&_a=(columns:!(_source),index:%27logstash-*%27,interval:auto,query:(query_string:(analyze_wildcard:!t,query:%27*%27)),sort:!(%27@timestamp%27,desc))"; //eslint-disable-line max-len, quotes
|
||||
$httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
|
||||
expect(JSON.parse(data).url).to.be(relativeUrl);
|
||||
return [200, shareId];
|
||||
});
|
||||
urlShortener.shortenUrl(`http://localhost${basePath}${relativeUrl}`).then((url) => {
|
||||
expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
|
||||
done();
|
||||
});
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
getBasePath.restore();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,24 +1,30 @@
|
|||
import chrome from 'ui/chrome';
|
||||
import url from 'url';
|
||||
|
||||
export default function createUrlShortener(Notifier, $http, $location) {
|
||||
const notify = new Notifier({
|
||||
location: 'Url Shortener'
|
||||
});
|
||||
const basePath = chrome.getBasePath();
|
||||
const baseUrl = `${$location.protocol()}://${$location.host()}:${$location.port()}${basePath}`;
|
||||
|
||||
async function shortenUrl(url) {
|
||||
const relativeUrl = url.replace(baseUrl, '');
|
||||
function shortenUrl(absoluteUrl) {
|
||||
const basePath = chrome.getBasePath();
|
||||
|
||||
const parsedUrl = url.parse(absoluteUrl);
|
||||
const path = parsedUrl.path.replace(basePath, '');
|
||||
const hash = parsedUrl.hash ? parsedUrl.hash : '';
|
||||
const relativeUrl = path + hash;
|
||||
|
||||
const formData = { url: relativeUrl };
|
||||
|
||||
try {
|
||||
const result = await $http.post(`${basePath}/shorten`, formData);
|
||||
|
||||
return `${baseUrl}/goto/${result.data}`;
|
||||
} catch (err) {
|
||||
notify.error(err);
|
||||
throw err;
|
||||
}
|
||||
return $http.post(`${basePath}/shorten`, formData).then((result) => {
|
||||
return url.format({
|
||||
protocol: parsedUrl.protocol,
|
||||
host: parsedUrl.host,
|
||||
pathname: `${basePath}/goto/${result.data}`
|
||||
});
|
||||
}).catch((response) => {
|
||||
notify.error(response);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -7,7 +7,7 @@ html,
|
|||
body {
|
||||
.flex-parent();
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
label > small {
|
||||
|
@ -76,16 +76,16 @@ ul.navbar-inline li {
|
|||
}
|
||||
|
||||
.content {
|
||||
.flex-parent();
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
.real-flex-parent(@flow: row nowrap);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
> nav {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.navbar-right {
|
||||
margin-right: 0;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ ul.navbar-inline li {
|
|||
.flex-parent(@shrink: 0);
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
background-color: @white;
|
||||
}
|
||||
|
||||
.top-fixed {
|
||||
|
@ -139,9 +140,31 @@ a {
|
|||
z-index: 0;
|
||||
}
|
||||
|
||||
.kibana-nav-options {
|
||||
padding-bottom: 0;
|
||||
padding-right: 0px;
|
||||
|
||||
.kibana-nav-actions {
|
||||
margin-left: auto;
|
||||
|
||||
.button-group > :last-child {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
.kibana-nav-info {
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
&-title {
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> config {
|
||||
z-index: 1;
|
||||
}
|
||||
> navbar { padding-bottom: 4px; }
|
||||
|
||||
> nav,
|
||||
> navbar {
|
||||
|
@ -161,6 +184,7 @@ a {
|
|||
&:not(.pull-right):first-child {
|
||||
// This is how .navbar-brand accomplishes it's solid placement
|
||||
margin-left: -15px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +221,11 @@ a {
|
|||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
kbn-info i {
|
||||
|
@ -264,30 +293,136 @@ table {
|
|||
}
|
||||
}
|
||||
|
||||
//== breadCrumbsTemplate
|
||||
bread-crumbs {
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 8px 10px;
|
||||
list-style-type: none;
|
||||
text-transform: capitalize;
|
||||
|
||||
>li {
|
||||
display: inline;
|
||||
>span {
|
||||
color: @kibanaGray2;
|
||||
}
|
||||
>span:hover {
|
||||
color: @kibanaGray1;
|
||||
}
|
||||
}
|
||||
|
||||
>li:last-child {
|
||||
>span {
|
||||
color: @kibanaGray1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//== SavedObjectFinder
|
||||
saved-object-finder {
|
||||
.row {
|
||||
background-color: @kibanaGray6;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 0;
|
||||
float: left;
|
||||
flex: 8;
|
||||
|
||||
input {
|
||||
.border-bottom-radius(0);
|
||||
border: none;
|
||||
padding: 5px 0px;
|
||||
border-radius: @border-radius-base;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 5px 0px;
|
||||
background-color: @white;
|
||||
border: none;
|
||||
|
||||
i {
|
||||
color: @kibanaGray3;
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.finder-hit-count, .finder-manage-object {
|
||||
min-width: 80px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.finder-hit-count {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
color: @kibanaGray3;
|
||||
}
|
||||
}
|
||||
|
||||
.finder-manage-object {
|
||||
flex: 3;
|
||||
text-align: left;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
a {
|
||||
i {
|
||||
color: @saved-object-finder-icon-color !important;
|
||||
.list-group-item-menu:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
ul.li-striped {
|
||||
li {
|
||||
border: none;
|
||||
}
|
||||
|
||||
li:nth-child(odd) {
|
||||
background-color: @kibanaGray6;
|
||||
}
|
||||
|
||||
li:nth-child(even) {
|
||||
background-color: @white;
|
||||
}
|
||||
|
||||
.paginate-heading {
|
||||
font-weight: normal;
|
||||
color: @kibanaGray1;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 8px 15px;
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.finder-type {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
color: @saved-object-finder-link-color !important;
|
||||
}
|
||||
a {
|
||||
i {
|
||||
color: @saved-object-finder-icon-color !important;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.border-top-radius(0) !important;
|
||||
}
|
||||
color: @saved-object-finder-link-color !important;
|
||||
}
|
||||
|
||||
&.list-group-no-results p {
|
||||
margin-bottom: 0 !important;
|
||||
&:first-child {
|
||||
.border-top-radius(0) !important;
|
||||
}
|
||||
|
||||
&.list-group-no-results p {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,13 +436,6 @@ saved-object-finder {
|
|||
}
|
||||
}
|
||||
|
||||
span.finder-hit-count {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 25px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
.finder-options {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
width: 100%;
|
||||
background-color: @config-close-bg;
|
||||
border-radius: 0;
|
||||
@shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);
|
||||
.box-shadow(@shadow);
|
||||
text-align: center;
|
||||
text-align: right;
|
||||
padding: 10px;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
padding: 10px 10px;
|
||||
background-color: @config-bg;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,37 +23,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
button {
|
||||
padding: @padding-base-vertical @padding-base-horizontal;
|
||||
font-size: @font-size-base;
|
||||
color: @control-group-link-color;
|
||||
background-color: @control-group-bg;
|
||||
|
||||
&:hover {
|
||||
color: @control-group-link-hover-color;
|
||||
background-color: @control-group-link-hover-bg;
|
||||
}
|
||||
|
||||
.active, &:active, &:focus {
|
||||
color: @control-group-link-active-color;
|
||||
background-color: @control-group-link-active-bg;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
color: @control-group-link-disabled-color;
|
||||
background-color: @control-group-link-disabled-bg;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
// because some buttons are all side-to-side, the browser's outline
|
||||
// is cut off by the next button. This causes the outline to be
|
||||
// drawn inside the button. Appplied to all buttons so that it's
|
||||
// uniform within this widget
|
||||
outline-offset: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// horizontal group of buttons/form elements
|
||||
.button-group,
|
||||
.inline-form .input-group {
|
||||
|
|
|
@ -581,4 +581,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import (reference) "~ui/styles/theme";
|
||||
|
||||
.list-group-menu {
|
||||
&.select-mode a{
|
||||
&.select-mode a {
|
||||
outline: none;
|
||||
color: @list-group-menu-item-select-color;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
@import "~ui/styles/variables";
|
||||
@import (reference) "~bootstrap/less/mixins";
|
||||
|
||||
.flex-parent(@grow: 1, @shrink: 1, @basis: auto) {
|
||||
.flex-parent(@grow: 1, @shrink: 1, @basis: auto, @direction: column) {
|
||||
flex: @grow @shrink @basis;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: @direction;
|
||||
|
||||
> * {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
.real-flex-parent(@flow: column nowrap) {
|
||||
display: flex;
|
||||
flex-flow: @flow;
|
||||
}
|
||||
|
||||
|
||||
.ellipsis() {
|
||||
white-space: nowrap;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
@import "./control_group";
|
||||
|
||||
@navbar-margin: @padding-small-vertical;
|
||||
|
||||
navbar {
|
||||
.control-group();
|
||||
|
||||
max-height: @navbar-collapse-max-height;
|
||||
margin-bottom: @navbar-margin-bottom;
|
||||
// top and bottom padding are normally calcuated and stored in @navbar-padding-vertical, but flexbox
|
||||
padding: @padding-base-vertical @navbar-padding-horizontal;
|
||||
padding: 0 @navbar-padding-horizontal 6px @navbar-padding-horizontal;
|
||||
color: @navbar-default-color;
|
||||
background-color: @navbar-default-bg;
|
||||
border-style: solid;
|
||||
border-color: @navbar-default-border;
|
||||
border-width: 0 0 1px;
|
||||
border: none;
|
||||
z-index: @zindex-navbar;
|
||||
|
||||
/***
|
||||
|
@ -22,6 +22,11 @@ navbar {
|
|||
padding-right: @navbar-padding-horizontal;
|
||||
}
|
||||
|
||||
.navbar-text {
|
||||
margin-top: @navbar-margin;
|
||||
margin-bottom: @navbar-margin;
|
||||
}
|
||||
|
||||
// the "brand" that is displayed, usually on the left of the navbar
|
||||
> .name {
|
||||
align-self: center;
|
||||
|
@ -47,6 +52,10 @@ navbar {
|
|||
&:active, &.active {
|
||||
color: @navbar-default-link-active-color;
|
||||
background-color: @navbar-default-link-active-bg;
|
||||
box-shadow: none;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
|
@ -59,9 +68,7 @@ navbar {
|
|||
button {
|
||||
color: @navbar-button-color;
|
||||
background-color: @navbar-button-bg;
|
||||
border: 2px solid;
|
||||
border-left: 0;
|
||||
border-color: @navbar-button-border;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ paginate {
|
|||
|
||||
a {
|
||||
text-decoration: none;
|
||||
background-color: @white;
|
||||
margin-left: 2px;
|
||||
padding: 8px 11px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
|
|
|
@ -11,8 +11,26 @@
|
|||
.sidebar-well {
|
||||
background-color: @sidebar-well-bg;
|
||||
}
|
||||
.vis-editor-agg-header-controls {
|
||||
.btn-primary {
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
background-color: @kibanaGray4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-list {
|
||||
.navbar-nav.navbar-right {
|
||||
border-radius: 4px;
|
||||
overflow:hidden;
|
||||
margin-right: -13px;
|
||||
margin-top: 2px;
|
||||
.navbar-btn-link {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
margin-bottom: 0px;
|
||||
|
@ -58,12 +76,6 @@
|
|||
&.full-title {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:hover .text-muted {
|
||||
color: @sidebar-hover-color;
|
||||
background-color: @sidebar-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&-text {
|
||||
|
@ -81,7 +93,7 @@
|
|||
|
||||
&.primary {
|
||||
background-color: @btn-primary-bg;
|
||||
color: @btn-primary-color
|
||||
color: @btn-primary-color;
|
||||
}
|
||||
|
||||
&.info {
|
||||
|
@ -123,19 +135,27 @@
|
|||
}
|
||||
|
||||
.index-pattern {
|
||||
background-color: @sidebar-active-bg;
|
||||
font-weight: bold;
|
||||
padding: 5px 10px;
|
||||
color: @sidebar-active-color;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: @kibanaGray4;
|
||||
line-height: 28px;
|
||||
|
||||
> * {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
&.active {
|
||||
background-color: @sidebar-active-bg;
|
||||
color: @sidebar-active-color;
|
||||
}
|
||||
}
|
||||
|
||||
.index-pattern-selection .sidebar-item-title {
|
||||
background-color: @sidebar-index-pattern-selection-bg;
|
||||
&:hover {
|
||||
background-color: @sidebar-index-pattern-selection-bg-hover;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,55 +1,40 @@
|
|||
@import "~ui/styles/variables";
|
||||
|
||||
@size: 400px;
|
||||
@color1: @kibanaPink1;
|
||||
@color2: @kibanaPink2;
|
||||
|
||||
.spinner.ng-hide {
|
||||
visibility: hidden;
|
||||
display: block !important;
|
||||
opacity: 0;
|
||||
transition-delay: 0.25s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
margin: 0px auto 0;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
display: inline;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
visibility: visible;
|
||||
display: block;
|
||||
animation: move 2s linear infinite;
|
||||
background-color: @kibanaPink2;
|
||||
background-image: linear-gradient(to right,
|
||||
@color1 0%,
|
||||
@color1 50%,
|
||||
@color2 50%,
|
||||
@color2 100%
|
||||
);
|
||||
background-size: @size @size;
|
||||
}
|
||||
|
||||
.spinner > div {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: @spinner-bg;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: bouncedelay 1s infinite ease-in-out;
|
||||
animation: bouncedelay 1s infinite ease-in-out;
|
||||
/* Prevent first frame from flickering when animation starts */
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.navbar .spinner > div {
|
||||
background-color: @navbar-default-link-color;
|
||||
}
|
||||
|
||||
.spinner.large > div {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.spinner .bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
.spinner .bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes bouncedelay {
|
||||
0%, 80%, 100% { -webkit-transform: scale(0.0) }
|
||||
40% { -webkit-transform: scale(1.0) }
|
||||
}
|
||||
|
||||
@keyframes bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
transform: scale(0.0);
|
||||
-webkit-transform: scale(0.0);
|
||||
} 40% {
|
||||
transform: scale(1.0);
|
||||
-webkit-transform: scale(1.0);
|
||||
@keyframes move {
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
100% {
|
||||
background-position: @size @size;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,39 @@
|
|||
.navbar {
|
||||
border-width: 0;
|
||||
|
||||
box-shadow: inset 0 -10px 10px -12px #333;
|
||||
-moz-box-shadow: inset 0 -10px 10px -12px #333;
|
||||
-webkit-box-shadow: inset 0 -10px 10px -12px #333;
|
||||
&-static-top {
|
||||
background-color: @kibanaGray5;
|
||||
color: @kibanaGray2;
|
||||
.navbar-brand:hover,
|
||||
.navbar-brand {
|
||||
float: none;
|
||||
color: @kibanaGray2;
|
||||
font-size: 1em;
|
||||
background-color: transparent;
|
||||
padding-top: 8px;
|
||||
height: 35px;
|
||||
}
|
||||
.navbar-nav {
|
||||
|
||||
> li > a {
|
||||
color: @kibanaGray2;
|
||||
font-size: 1.5em;
|
||||
padding: 5px 0 6px 0;
|
||||
margin: 0 10px;
|
||||
}
|
||||
// Active, hover state for the getTabs
|
||||
> .active > a,
|
||||
> .active > a:hover,
|
||||
> .active > a:active,
|
||||
> li > a:active,
|
||||
> li > a:hover {
|
||||
color: @kibanaGray1;
|
||||
background-color: transparent;
|
||||
border-bottom: 2px solid @kibanaGray1;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-btn-link {
|
||||
height: @navbar-height;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
|
||||
|
@ -58,34 +85,13 @@
|
|||
}
|
||||
|
||||
.navbar-nav > .active > a {
|
||||
border-bottom-color: @navbar-nav-active-link-border;
|
||||
|
||||
// navbar active arrow base styles
|
||||
&:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
border: @navbar-arrow-size solid transparent;
|
||||
border-bottom-color: inherit;
|
||||
top: (@navbar-height - @navbar-arrow-size*2);
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@media (max-width: @screen-sm-min) {
|
||||
&:before {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
border-bottom-color: @kibanaGray2;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&-brand {
|
||||
cursor: default;
|
||||
font-size: 1.8em;
|
||||
background-color: @navbar-inverse-brand-bg;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
//** Background color for `<body>`.
|
||||
@body-bg: @white;
|
||||
//** Global text color on `<body>`.
|
||||
@text-color: @brand-primary;
|
||||
@text-color: @kibanaGray1;
|
||||
|
||||
|
||||
//** Global textual link color.
|
||||
@link-color: @brand-info;
|
||||
@link-hover-color: lighten(@link-color, 10%);
|
||||
@link-color: @kibanaBlue2;
|
||||
@link-hover-color: @kibanaBlue1;
|
||||
@link-hover-decoration: none;
|
||||
|
||||
//** Disabled cursor for form controls and buttons.
|
||||
|
@ -26,7 +26,7 @@
|
|||
@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
@font-family-base: @font-family-sans-serif;
|
||||
|
||||
@font-size-base: 13px;
|
||||
@font-size-base: 14px;
|
||||
@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
|
||||
@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
|
||||
|
||||
|
@ -120,13 +120,13 @@
|
|||
@btn-default-bg: @gray;
|
||||
@btn-default-border: @btn-default-bg;
|
||||
|
||||
@btn-primary-color: @btn-default-color;
|
||||
@btn-primary-bg: @brand-primary;
|
||||
@btn-primary-border: @btn-primary-bg;
|
||||
@btn-primary-color: @kibanaGray6;
|
||||
@btn-primary-bg: @kibanaBlue3;
|
||||
@btn-primary-border: transparent;
|
||||
|
||||
@btn-success-color: @btn-default-color;
|
||||
@btn-success-bg: @brand-success;
|
||||
@btn-success-border: @btn-success-bg;
|
||||
@btn-success-bg: @kibanaBlue3;
|
||||
@btn-success-border: @kibanaBlue3;
|
||||
|
||||
@btn-info-color: @btn-default-color;
|
||||
@btn-info-bg: @brand-info;
|
||||
|
@ -332,22 +332,22 @@
|
|||
@navbar-height: 45px;
|
||||
@navbar-margin-bottom: 0px;
|
||||
@navbar-border-radius: @border-radius-base;
|
||||
@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
|
||||
@navbar-padding-horizontal: 10px;
|
||||
@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
|
||||
@navbar-collapse-max-height: 340px;
|
||||
|
||||
@navbar-arrow-size: 7px;
|
||||
|
||||
// Default theme
|
||||
@navbar-default-bg: #656A76;
|
||||
@navbar-default-color: @white;
|
||||
@navbar-default-border: darken(@navbar-default-bg, 10%);
|
||||
@navbar-default-link-color: @gray-lighter;
|
||||
@navbar-default-link-hover-color: @white;
|
||||
@navbar-default-bg: @kibanaGray5;
|
||||
@navbar-default-color: @kibanaGray2;
|
||||
@navbar-default-border: transparent;
|
||||
@navbar-default-link-color: @kibanaGray2;
|
||||
@navbar-default-link-hover-color: @kibanaGray2;
|
||||
@navbar-default-link-hover-bg: transparent;
|
||||
@navbar-default-link-active-color: @white;
|
||||
@navbar-default-link-active-bg: darken(@navbar-default-bg, 10%);
|
||||
@navbar-default-link-disabled-color: @gray12;
|
||||
@navbar-default-link-active-color: @kibanaGray1;
|
||||
@navbar-default-link-active-bg: @kibanaGray6;
|
||||
@navbar-default-link-disabled-color: @kibanaGray3;
|
||||
@navbar-default-link-disabled-bg: transparent;
|
||||
|
||||
// Navbar brand label
|
||||
|
@ -411,8 +411,8 @@
|
|||
|
||||
|
||||
//== Pills
|
||||
@nav-pills-active-link-hover-bg: @component-active-bg;
|
||||
@nav-pills-active-link-hover-color: @component-active-color;
|
||||
@nav-pills-active-link-hover-bg: @kibanaYellow1;
|
||||
@nav-pills-active-link-hover-color: @kibanaGray1;
|
||||
@nav-pills-border-radius: @border-radius-base;
|
||||
|
||||
//== Pagination
|
||||
|
@ -486,8 +486,8 @@
|
|||
//** Tooltip text color
|
||||
@tooltip-color: @white;
|
||||
//** Tooltip background color
|
||||
@tooltip-bg: rgba(0,0,0,.9);
|
||||
@tooltip-opacity: .9;
|
||||
@tooltip-bg: rgba(0,0,0,.8);
|
||||
@tooltip-opacity: .8;
|
||||
//** Tooltip arrow color
|
||||
@tooltip-arrow-color: @tooltip-bg;
|
||||
|
||||
|
@ -607,11 +607,11 @@
|
|||
@progress-border-radius: @border-radius-base;
|
||||
|
||||
//** Background color of the whole progress component
|
||||
@progress-bg: @gray-lighter;
|
||||
@progress-bg: @kibanaGray4;
|
||||
//** Progress bar text color
|
||||
@progress-bar-color: @white;
|
||||
//** Default progress bar color
|
||||
@progress-bar-bg: @brand-primary;
|
||||
@progress-bar-bg: @kibanaPink1;
|
||||
//** Success progress bar color
|
||||
@progress-bar-success-bg: @brand-success;
|
||||
//** Warning progress bar color
|
||||
|
@ -708,7 +708,7 @@
|
|||
//
|
||||
//##
|
||||
|
||||
@well-bg: @gray-lighter;
|
||||
@well-bg: @kibanaGray6;
|
||||
@well-border: transparent;
|
||||
|
||||
|
||||
|
@ -791,7 +791,7 @@
|
|||
//** Abbreviations and acronyms border color
|
||||
@abbr-border-color: @gray-light;
|
||||
//** Headings small color
|
||||
@headings-small-color: @gray-light;
|
||||
@headings-small-color: @kibanaGray1;
|
||||
//** Blockquote small color
|
||||
@blockquote-small-color: @gray-light;
|
||||
//** Blockquote border color
|
||||
|
|
|
@ -34,3 +34,31 @@
|
|||
@brand-info: #1F6B7A;
|
||||
@brand-warning: #F39C12;
|
||||
@brand-danger: #E74C3C;
|
||||
|
||||
@kibanaGray1: #2D2D2D;
|
||||
@kibanaGray2: #5A5A5A;
|
||||
@kibanaGray3: #9C9C9C;
|
||||
@kibanaGray4: #BEBEBE;
|
||||
@kibanaGray5: #E4E4E4;
|
||||
@kibanaGray6: #F6F6F6;
|
||||
@kibanaGray7: #FFFFFF;
|
||||
|
||||
@kibanaBlue1: #105A73;
|
||||
@kibanaBlue2: #328CAA;
|
||||
@kibanaBlue3: #6EADC1;
|
||||
@kibanaBlue4: #9DD0E0;
|
||||
|
||||
@kibanaGreen1: #80C383;
|
||||
@kibanaGreen2: #AEE8B0;
|
||||
|
||||
@kibanaYellow1: #FBCE47;
|
||||
@kibanaYellow2: #F5DD94;
|
||||
|
||||
@kibanaRed1: #D76051;
|
||||
@kibanaRed2: #FF9183;
|
||||
|
||||
@kibanaPurple1: #9980B2;
|
||||
@kibanaPurple2: #CDB5E4;
|
||||
|
||||
@kibanaPink1: #E8488B;
|
||||
@kibanaPink2: #FF95C1;
|
||||
|
|
|
@ -26,17 +26,16 @@
|
|||
@sidebar-hover-color: @sidebar-color;
|
||||
@sidebar-hover-bg: darken(@sidebar-bg, 10%);
|
||||
|
||||
@sidebar-active-color: @component-active-color;
|
||||
@sidebar-active-bg: @component-active-bg;
|
||||
@sidebar-active-hover-bg: @component-active-bg;
|
||||
@sidebar-active-hover-color: @component-active-color;
|
||||
@sidebar-active-color: @kibanaGray1;
|
||||
@sidebar-active-bg: @kibanaGray4;
|
||||
@sidebar-active-hover-bg: @kibanaGray4;
|
||||
@sidebar-active-hover-color: @kibanaGray1;
|
||||
|
||||
@sidebar-index-pattern-selection-bg: @white;
|
||||
@sidebar-index-pattern-selection-bg: @kibanaGray5;
|
||||
@sidebar-index-pattern-selection-bg-hover: @kibanaGray4;
|
||||
|
||||
|
||||
// Discover ====================================================================
|
||||
@discover-info-bg: @well-bg;
|
||||
|
||||
@discover-link-color: @link-color;
|
||||
@discover-link-btn-color: @text-color;
|
||||
|
||||
|
@ -48,9 +47,9 @@
|
|||
@discover-shard-failures-border: @brand-danger;
|
||||
|
||||
@discover-field-toggle-color: @btn-success-color;
|
||||
@discover-field-details-border: @well-border;
|
||||
@discover-field-details-color: @text-color;
|
||||
@discover-field-details-bg: @body-bg;
|
||||
@discover-field-details-border: @kibanaGray4;
|
||||
@discover-field-details-color: @kibanaGray2;
|
||||
@discover-field-details-bg: @kibanaGray5;
|
||||
@discover-field-details-close-border: @well-border;
|
||||
@discover-field-details-close-bg: @well-bg;
|
||||
@discover-field-details-close-hover-bg: @sidebar-hover-bg;
|
||||
|
@ -59,25 +58,25 @@
|
|||
|
||||
|
||||
// Field name ==================================================================
|
||||
@field-name-color: @text-muted;
|
||||
@field-name-no-results-color: @text-muted;
|
||||
@field-name-color: @kibanaGray3;
|
||||
@field-name-no-results-color: @kibanaGray3;
|
||||
|
||||
|
||||
// Collapser ===================================================================
|
||||
@collapser-bg: @gray-lighter;
|
||||
@collapser-border: @collapser-bg;
|
||||
@collapser-color: @gray3;
|
||||
@collapser-bg: @kibanaGray7;
|
||||
@collapser-border: @kibanaGray7;
|
||||
@collapser-color: @kibanaGray2;
|
||||
|
||||
@collapser-hover-bg: @gray-light;
|
||||
@collapser-hover-bg: @kibanaGray5;
|
||||
@collapser-hover-border: @collapser-hover-bg;
|
||||
@collapser-hover-color: @white;
|
||||
@collapser-hover-color: @kibanaGray7;
|
||||
|
||||
@collapser-width: 12px;
|
||||
|
||||
|
||||
// Dashboard ===================================================================
|
||||
@dashboard-bg: @gray-lighter;
|
||||
@dashboard-panel-bg: @panel-bg;
|
||||
@dashboard-bg: #fff;
|
||||
@dashboard-panel-bg: #fff;
|
||||
@dashboard-panel-color: @text-color;
|
||||
@dashboard-panel-heading-link-color: @text-color;
|
||||
@dashboard-panel-heading-link-hover-color: @link-hover-color;
|
||||
|
@ -101,8 +100,8 @@
|
|||
|
||||
// NavBar ======================================================================
|
||||
@navbar-button-border: @input-border;
|
||||
@navbar-button-color: @brand-primary;
|
||||
@navbar-button-bg: @input-group-addon-bg;
|
||||
@navbar-button-color: @kibanaGray7;
|
||||
@navbar-button-bg: @kibanaGray3;
|
||||
|
||||
|
||||
// AppSwitcher =================================================================
|
||||
|
@ -149,8 +148,8 @@
|
|||
@vis-editor-navbar-error-state-color: @btn-danger-color;
|
||||
|
||||
@vis-editor-navbar-modal-bg: @navbar-default-bg;
|
||||
@vis-editor-navbar-modal-color: @white;
|
||||
@vis-editor-navbar-modal-link-color: @white;
|
||||
@vis-editor-navbar-modal-color: @kibanaGray1;
|
||||
@vis-editor-navbar-modal-link-color: @kibanaGray1;
|
||||
|
||||
@vis-editor-sidebar-bg: @body-bg;
|
||||
@vis-editor-sidebar-border: @sidebar-bg;
|
||||
|
@ -208,7 +207,7 @@
|
|||
|
||||
// Config ======================================================================
|
||||
@config-border: darken(@body-bg, 10%);
|
||||
@config-bg: @body-bg;
|
||||
@config-bg: @kibanaGray6;
|
||||
|
||||
@config-close-bg: @well-bg;
|
||||
|
||||
|
@ -226,7 +225,7 @@
|
|||
|
||||
|
||||
// Paginate ====================================================================
|
||||
@paginate-page-link-active-color: @text-color;
|
||||
@paginate-page-link-active-color: @kibanaGray2;
|
||||
|
||||
|
||||
// Spinner =====================================================================
|
||||
|
@ -311,6 +310,8 @@
|
|||
@tooltip-color: @gray-lighter;
|
||||
|
||||
@tooltip-table-border: @gray;
|
||||
@tooltip-bold: 600;
|
||||
|
||||
|
||||
|
||||
// Svg =========================================================================
|
||||
|
@ -326,3 +327,17 @@
|
|||
// Saved Object Finder =========================================================
|
||||
@saved-object-finder-link-color: @link-color;
|
||||
@saved-object-finder-icon-color: darken(@saved-object-finder-link-color, 10%);
|
||||
|
||||
// App-switcher ================================================================
|
||||
@as-open-width: 160px;
|
||||
@as-closed-width: 53px;
|
||||
@app-icon-height: 38px;
|
||||
@app-line-height: 24px;
|
||||
@transition-time: .35s;
|
||||
@transition-delay: .25s;
|
||||
@app-links-wrapper-background: #3caed2;
|
||||
@app-links-active-background: lighten(@app-links-wrapper-background, 7.5%);
|
||||
|
||||
@firstLinkColor: #E4BB51;
|
||||
@secondLinkColor: #8AC336;
|
||||
@thirdLinkColor: #59C6C5;
|
||||
|
|