Merge pull request #8679 from cjcenizal/experiment/ui-framework-css

Integrate UI Framework
This commit is contained in:
CJ Cenizal 2016-10-26 21:40:36 -07:00 committed by GitHub
commit 2e89ced6ef
53 changed files with 830 additions and 873 deletions

View file

@ -49,6 +49,7 @@
"test:server": "grunt test:server",
"test:coverage": "grunt test:coverage",
"test:visualRegression": "grunt test:visualRegression",
"checkLicenses": "grunt licenses",
"build": "grunt build",
"release": "grunt release",
"start": "sh ./bin/kibana --dev",
@ -71,6 +72,7 @@
"@bigfunger/decompress-zip": "0.2.0-stripfix3",
"@bigfunger/jsondiffpatch": "0.1.38-webpack",
"@elastic/datemath": "2.3.0",
"@elastic/kibana-ui-framework": "0.0.9",
"@spalger/filesaver": "1.1.2",
"@spalger/leaflet-draw": "0.2.3",
"@spalger/leaflet-heat": "0.1.3",

View file

@ -8,22 +8,26 @@ export function SenseTopNavController(Private) {
{
key: 'welcome',
hideButton: true,
template: `<sense-welcome></sense-welcome>`
template: `<sense-welcome></sense-welcome>`,
testId: 'consoleWelcomeButton',
},
{
key: 'history',
description: 'History',
template: `<sense-history></sense-history>`
template: `<sense-history></sense-history>`,
testId: 'consoleHistoryButton',
},
{
key: 'settings',
description: 'Settings',
template: `<sense-settings></sense-settings>`
template: `<sense-settings></sense-settings>`,
testId: 'consoleSettingsButton',
},
{
key: 'help',
description: 'Help',
template: `<sense-help></sense-help>`
template: `<sense-help></sense-help>`,
testId: 'consoleHelpButton',
},
]);

View file

@ -1,36 +1,40 @@
<h3>Help</h3>
<div class="localDropdownTitle">Help</div>
<tabset>
<tab heading="Request format">
You can type one or more requests in the white editor. Console understands requests in a compact format:
<sense-help-example></sense-help-example>
<div class="list-group-item list-group-item--noBorder">
You can type one or more requests in the white editor. Console understands requests in a compact format:
<sense-help-example></sense-help-example>
</div>
</tab>
<tab heading="Keyboard tips">
<dl class="dl-horizontal">
<dt></dt>
<dd><strong>General editing</strong></dd>
<dt>Ctrl/Cmd + I</dt>
<dd>Auto indent current request</dd>
<dt>Ctrl + Space</dt>
<dd>Open Auto complete (even if not typing)</dd>
<dt>Ctrl/Cmd + Enter</dt>
<dd>Submit request</dd>
<dt>Ctrl/Cmd + Up/Down</dt>
<dd>Jump to the previous/next request start or end.</dd>
<dt>Ctrl/Cmd + Alt + L</dt>
<dd>Collapse/expand current scope.</dd>
<dt>Ctrl/Cmd + Option + 0</dt>
<dd>Collapse all scopes but the current one. Expand by adding a shift.</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd><strong>When auto-complete is visible</strong></dd>
<dt>Down arrow</dt>
<dd>Switch focus to auto-complete menu. Use arrows to further select a term</dd>
<dt>Enter/Tab</dt>
<dd>Select the currently selected or the top most term in auto-complete menu</dd>
<dt>Esc</dt>
<dd>Close auto-complete menu</dd>
</dl>
<div class="list-group-item list-group-item--noBorder">
<dl class="dl-horizontal">
<dt></dt>
<dd><strong>General editing</strong></dd>
<dt>Ctrl/Cmd + I</dt>
<dd>Auto indent current request</dd>
<dt>Ctrl + Space</dt>
<dd>Open Auto complete (even if not typing)</dd>
<dt>Ctrl/Cmd + Enter</dt>
<dd>Submit request</dd>
<dt>Ctrl/Cmd + Up/Down</dt>
<dd>Jump to the previous/next request start or end.</dd>
<dt>Ctrl/Cmd + Alt + L</dt>
<dd>Collapse/expand current scope.</dd>
<dt>Ctrl/Cmd + Option + 0</dt>
<dd>Collapse all scopes but the current one. Expand by adding a shift.</dd>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd><strong>When auto-complete is visible</strong></dd>
<dt>Down arrow</dt>
<dd>Switch focus to auto-complete menu. Use arrows to further select a term</dd>
<dt>Enter/Tab</dt>
<dd>Select the currently selected or the top most term in auto-complete menu</dd>
<dt>Esc</dt>
<dd>Close auto-complete menu</dd>
</dl>
</div>
</tab>
</tabset>

View file

@ -1,4 +1,4 @@
<h3>History</h3>
<div class="localDropdownTitle">History</div>
<div class="history-body">
<ul class="list-group history-reqs">
@ -11,8 +11,7 @@
ng-dblclick="history.restore(req)"
title="{{ req.description }}"
class="list-group-item history-req"
>
>
{{ history.describeReq(req) }}
<span class="history-req-icon"><i class="fa fa-chevron-right"></i></span>
</li>

View file

@ -1,22 +1,21 @@
<h3>Settings</h3>
<div class="localDropdownTitle">Settings</div>
<form class="form" name="settingsForm" ng-submit="settingsForm.$valid && settings.apply()">
<div class="form-group">
<h4>Editor &amp; Output pane settings</h4>
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">Font Size</div>
</div>
<div class="form-group">
<label>Font Size</label>
<div>
<input
input-focus
ng-model="settings.vals.fontSize"
name="fontSize"
type="number"
required
class="form-control"
data-test-subj="setting-font-size-input"
>
</div>
<div>
<input
input-focus
ng-model="settings.vals.fontSize"
name="fontSize"
type="number"
required
class="form-control"
data-test-subj="setting-font-size-input"
>
</div>
<div class="checkbox">
@ -28,7 +27,9 @@
</div>
<div class="form-group">
<h4>Autocomplete</h4>
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">Autocomplete</div>
</div>
<div class="checkbox">
<label>

View file

@ -1,6 +1,6 @@
<h3>Welcome to Console</h3>
<div class="localDropdownTitle">Welcome to Console</div>
<h4>Quick intro to the UI</h4>
<p><strong>Quick intro to the UI</strong></p>
<p>The Console UI is split into two panes: an editor pane (left) and a response pane (right).
Use the editor to type requests and submit them to Elasticsearch. The results will be displayed in
@ -14,8 +14,7 @@
These suggestions are made based on the request structure <i>as well as</i> your indices and types.
</p>
<h4>A few quick tips, while I have your attention</h4>
<p><strong>A few quick tips, while I have your attention</strong></p>
<ul>
<li>Submit requests to ES using the green triangle button.</li>
<li>Use the wrench menu for other useful things.</li>

View file

@ -1,43 +1,57 @@
<dashboard-app class="app-container dashboard-container">
<!-- Local nav. -->
<kbn-top-nav name="dashboard" config="topNavMenu">
<div class="kibana-nav-info">
<span ng-show="dash.id" class="kibana-nav-info-title">
<span ng-bind="::dash.title"></span>
</span>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Title. -->
<div
data-transclude-slot="topLeftCorner"
class="localTitle"
>
<span
ng-show="dash.id"
ng-bind="::dash.title"
></span>
</div>
<!-- Search. -->
<form
data-transclude-slot="bottomRow"
class="fullWidth"
ng-show="chrome.getVisible()"
role="form"
name="queryInput"
ng-submit="filterResults()"
>
<div class="typeahead" kbn-typeahead="dashboard">
<div class="localSearch">
<input
parse-query
input-focus
kbn-typeahead-input
ng-model="state.query"
placeholder="Filter..."
aria-label="Filter input"
type="text"
class="localSearchInput"
ng-class="{'localSearchInput-isInvalid': queryInput.$invalid}"
>
<button
type="submit"
aria-label="Filter Dashboards"
class="localSearchButton"
ng-disabled="queryInput.$invalid"
>
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
</div>
</kbn-top-nav>
<navbar ng-show="chrome.getVisible()" name="dashboard-search">
<form name="queryInput"
class="fill inline-form"
ng-submit="filterResults()"
role="form">
<div class="typeahead" kbn-typeahead="dashboard">
<div class="input-group"
ng-class="queryInput.$invalid ? 'has-error' : ''">
<input
type="text"
placeholder="Filter..."
aria-label="Filter input"
class="form-control"
ng-model="state.query"
input-focus
kbn-typeahead-input
parse-query>
<button type="submit" class="btn btn-default" ng-disabled="queryInput.$invalid" aria-label="Filter dashboards">
<span aria-hidden="true" class="fa fa-search"></span>
</button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
<div class="button-group"></div>
</navbar>
<!-- Filters. -->
<filter-bar state="state"></filter-bar>
<div ng-show="!state.panels.length" class="text-center start-screen">

View file

@ -119,7 +119,7 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter,
template: require('plugins/kibana/dashboard/partials/save_dashboard.html')
}, {
key: 'open',
description: 'Load Saved Dashboard',
description: 'Open Saved Dashboard',
template: require('plugins/kibana/dashboard/partials/load_dashboard.html')
}, {
key: 'share',

View file

@ -1 +1,2 @@
<saved-object-finder type="dashboards"></saved-object-finder>
<div class="localDropdownTitle">Open Dashboard</div>
<saved-object-finder type="dashboards"></saved-object-finder>

View file

@ -1,10 +1,9 @@
<form role="form" class="options">
<p>
<div class="input-group">
<label>
<input type="checkbox" ng-model="opts.ui.darkTheme" ng-checked="opts.ui.darkTheme">
Use dark theme
</label>
</div>
</p>
<form role="form">
<div class="localDropdownTitle">Options</div>
<div class="input-group">
<label>
<input type="checkbox" ng-model="opts.ui.darkTheme" ng-checked="opts.ui.darkTheme">
Use dark theme
</label>
</div>
</form>

View file

@ -1,14 +1,27 @@
<div ng-switch on="mode" ng-init="mode = 'visualization'" class="dashboard-panel-picker">
<div
ng-switch="mode"
ng-init="mode = 'visualization'"
>
<div class="localDropdownTitle">Add Panels</div>
<ul class="nav nav-tabs">
<li ng-class="{active: mode == 'visualization'}"><a ng-click="mode='visualization'" title="Visualizations">Visualizations</a></li>
<li ng-class="{active: mode == 'search'}"><a ng-click="mode='search'" title="Searches">Searches</a></li>
<li ng-class="{active: mode == 'visualization'}">
<a ng-click="mode='visualization'" title="Visualizations">
Visualization
</a>
</li>
<li ng-class="{active: mode == 'search'}">
<a ng-click="mode='search'" title="Searches">
Saved Search
</a>
</li>
</ul>
<div class="list-group-item" ng-switch-when="visualization">
<div class="list-group-item list-group-item--noBorder" ng-switch-when="visualization">
<saved-object-finder title="Choose a visualization" type="visualizations" on-choose="opts.addVis"></saved-object-finder>
</div>
<div class="list-group-item" ng-switch-when="search">
<div class="list-group-item list-group-item--noBorder" ng-switch-when="search">
<saved-object-finder title="Choose a search" type="searches" on-choose="opts.addSearch"></saved-object-finder>
</div>
</div>

View file

@ -1,8 +1,16 @@
<form ng-submit="opts.save()" role="form">
<div class="form-group">
<label for="dashboardTitle">Save As</label>
<input id="dashboardTitle" type="text" ng-model="opts.dashboard.title" class="form-control" placeholder="Dashboard title" input-focus="select">
</div>
<form
role="form"
ng-submit="opts.save()"
>
<div class="localDropdownTitle">Save Dashboard</div>
<input
class="localDropdownInput"
id="dashboardTitle"
type="text"
ng-model="opts.dashboard.title"
placeholder="Dashboard title"
input-focus="select"
>
<div class="form-group">
<label>
<input type="checkbox" ng-model="opts.dashboard.timeRestore" ng-checked="opts.dashboard.timeRestore">

View file

@ -152,7 +152,3 @@ dashboard-grid {
}
}
}
.dashboard-panel-picker > .list-group-item {
border-top: 0;
}

View file

@ -1,15 +1,24 @@
<div class="dev-tools__app-container app-container">
<bread-crumbs class="bread-crumbs--navbar" omit-current-page="true"></bread-crumbs>
<kbn-top-nav name="devtools" config="kbnDevToolsApp.topNavConfig">
<div class="localTabs">
<a
ng-repeat="item in kbnDevToolsApp.devTools"
class="localTab"
ng-class="{'localTab-isSelected': kbnDevToolsApp.currentPath === item.url}"
kbn-href="{{::item.url}}"
>
{{::item.display}}
</a>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Breadcrumbs. -->
<bread-crumbs
data-transclude-slot="topLeftCorner"
omit-current-page="true"
></bread-crumbs>
<!-- Tabs. -->
<div data-transclude-slot="bottomRow" class="localTabs">
<a
ng-repeat="item in kbnDevToolsApp.devTools"
class="localTab"
ng-class="{'localTab-isSelected': kbnDevToolsApp.currentPath === item.url}"
kbn-href="{{::item.url}}"
>
{{::item.display}}
</a>
</div>
</div>
</kbn-top-nav>
<div role="main" class="dev-tools__container" ng-transclude></div>

View file

@ -1,40 +1,55 @@
<discover-app class="app-container">
<!-- Local nav. -->
<kbn-top-nav name="discover" config="topNavMenu">
<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>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Breadcrumbs. -->
<div data-transclude-slot="topLeftCorner" class="localBreadcrumbs">
<div class="localBreadcrumb">
<span ng-show="opts.savedSearch.id" class="localBreadcrumb__emphasis">
<span data-test-subj="discoverCurrentQuery" 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>&nbsp;
</span>
<span data-test-subj="discoverQueryHits" class="localBreadcrumb__emphasis">{{(hits || 0) | number:0}}</span>
<ng-pluralize count="hits" when="{'1':'hit', 'other':'hits'}"></ng-pluralize>
</div>
</div>
<strong class="discover-info-hits">{{(hits || 0) | number:0}}</strong>
<ng-pluralize count="hits" when="{'1':'hit', 'other':'hits'}"></ng-pluralize>
<!-- Search. -->
<form
data-transclude-slot="bottomRow"
class="fullWidth"
role="form"
name="discoverSearch"
ng-submit="fetch()"
>
<div class="typeahead" kbn-typeahead="discover">
<div class="localSearch">
<input
parse-query
input-focus
kbn-typeahead-input
ng-model="state.query"
placeholder="Search..."
aria-label="Search input"
type="text"
class="localSearchInput"
ng-class="{'localSearchInput-isInvalid': discoverSearch.$invalid}"
>
<button
type="submit"
aria-label="Search"
class="localSearchButton"
ng-disabled="discoverSearch.$invalid"
>
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
</div>
</kbn-top-nav>
<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"
ng-class="discoverSearch.$invalid ? 'has-error' : ''">
<input
parse-query
input-focus
kbn-typeahead-input
ng-model="state.query"
placeholder="Search..."
aria-label="Search input"
type="text"
class="form-control">
<button type="submit"
ng-disabled="discoverSearch.$invalid"
aria-label="Search">
<span aria-hidden="true" class="fa fa-search"></span></button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
<div class="button-group" role="toolbar"></div>
</navbar>
<div class="container-fluid" role="main">
<div class="row">

View file

@ -1,3 +1,4 @@
<form role="form" class="container-fluid" ng-submit="fetch()">
<form role="form" ng-submit="fetch()">
<div class="localDropdownTitle">Open Search</div>
<saved-object-finder type="searches"></saved-object-finder>
</form>

View file

@ -1,17 +1,16 @@
<form role="form" class="container-fluid" ng-submit="opts.saveDataSource()">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="SaveSearch" class="control-label">Save Search</label>
<input id="SaveSearch" ng-model="opts.savedSearch.title" input-focus="select" class="form-control" placeholder="Name this search...">
</div>
<div class="form-group">
<button ng-disabled="!opts.savedSearch.title" data-test-subj="discover-save-search-btn" type="submit" class="btn btn-primary">
Save
</button>
</div>
</div>
</div>
</div>
<form
role="form"
ng-submit="opts.saveDataSource()"
>
<div class="localDropdownTitle">Save Search</div>
<input
class="localDropdownInput"
id="SaveSearch"
ng-model="opts.savedSearch.title"
input-focus="select"
placeholder="Name this search..."
>
<button ng-disabled="!opts.savedSearch.title" data-test-subj="discover-save-search-btn" type="submit" class="btn btn-primary">
Save
</button>
</form>

View file

@ -1,26 +1,36 @@
<div class="app-container">
<bread-crumbs class="bread-crumbs--navbar" omit-current-page="true"></bread-crumbs>
<!-- Local nav. -->
<kbn-top-nav name="management-subnav" data-test-subj="managementNav">
<div class="localTabs">
<span ng-if="!sectionName" class="localTab">
{{::section.display}}
</span>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Breadcrumbs. -->
<bread-crumbs
data-transclude-slot="topLeftCorner"
omit-current-page="true"
></bread-crumbs>
<a
ng-if="sectionName"
ng-repeat="item in section.items.inOrder"
class="localTab"
ng-class="{ 'localTab-isSelected': item.active, 'localTab-disabled': !item.url }"
kbn-href="{{::item.url}}"
data-test-subj="{{::item.name}}"
tooltip="{{::item.tooltip}}"
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
>
{{::item.display}}
</a>
<!-- Tabs. -->
<div data-transclude-slot="bottomRow" class="localTabs">
<span ng-if="!sectionName" class="localTab">
{{::section.display}}
</span>
<a
ng-if="sectionName"
ng-repeat="item in section.items.inOrder"
class="localTab"
ng-class="{ 'localTab-isSelected': item.active, 'localTab-disabled': !item.url }"
kbn-href="{{::item.url}}"
data-test-subj="{{::item.name}}"
tooltip="{{::item.tooltip}}"
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
>
{{::item.display}}
</a>
</div>
</div>
</kbn-top-nav>
<div role="main" class="management-container" ng-transclude></div>
</div>

View file

@ -1,4 +1,4 @@
<tr ng-class="conf.value === undefined ? 'default' : 'custom'" data-test-subj="advancedSetting {{conf.name}}" >
<tr ng-class="conf.value === undefined ? 'default' : 'custom'">
<td class="name">
<b>{{conf.name}}</b>
<span class="smaller" ng-show="!conf.isCustom && conf.value !== undefined">
@ -18,7 +18,8 @@
name="forms.configEdit"
ng-if="conf.editing"
ng-submit="save(conf)"
role="form">
role="form"
>
<input
ng-if="conf.normal"
@ -26,7 +27,8 @@
ng-keyup="maybeCancel($event, conf)"
placeholder="{{conf.value || conf.defVal}}"
type="text"
class="form-control">
class="form-control"
>
<textarea
ng-if="conf.markdown"
@ -35,7 +37,7 @@
ng-model="conf.unsavedValue"
ng-keyup="maybeCancel($event, conf)"
elastic-textarea
></textarea>
></textarea>
<textarea
ng-if="conf.json"
@ -45,7 +47,7 @@
ng-keyup="maybeCancel($event, conf)"
elastic-textarea
validate-json
></textarea>
></textarea>
<small ng-show="forms.configEdit.$error.jsonInput">Invalid JSON syntax</small>
<input
@ -55,13 +57,15 @@
ng-keyup="maybeCancel($event, conf)"
placeholder="{{(conf.value || conf.defVal).join(', ')}}"
type="text"
class="form-control">
class="form-control"
>
<input
ng-if="conf.bool"
ng-model="conf.unsavedValue"
type="checkbox"
class="form-control">
class="form-control"
>
<select
ng-if="conf.select"
@ -69,12 +73,12 @@
ng-model="conf.unsavedValue"
ng-options="option as option for option in conf.options"
class="form-control"
data-test-subj="selectInput">
>
</select>
</form>
<!-- Setting display formats -->
<span ng-if="!conf.editing" data-test-subj="currentValue">
<span ng-if="!conf.editing" data-test-subj="advancedSetting-{{conf.name}}-currentValue">
<span ng-if="(conf.normal || conf.json || conf.select)">{{conf.value || conf.defVal}}</span>
<span ng-if="conf.array">{{(conf.value || conf.defVal).join(', ')}}</span>
<span ng-if="conf.bool">{{conf.value === undefined ? conf.defVal : conf.value}}</span>
@ -89,7 +93,8 @@
class="btn btn-default"
ng-disabled="conf.tooComplex"
aria-label="Edit"
data-test-subj="editButton">
data-test-subj="advancedSetting-{{conf.name}}-editButton"
>
<span class="sr-only">Edit</span>
<i aria-hidden="true" class="fa fa-pencil"></i>
</button>
@ -100,7 +105,8 @@
class="btn btn-success"
ng-disabled="conf.loading || conf.tooComplex || forms.configEdit.$invalid"
aria-label="Save"
data-test-subj="saveButton">
data-test-subj="advancedSetting-{{conf.name}}-saveButton"
>
<span class="sr-only">Save</span>
<i aria-hidden="true" ng-if="!conf.loading" class="fa fa-save"></i>
<i aria-hidden="true" ng-if="conf.loading" class="fa fa-spinner"></i>
@ -112,7 +118,7 @@
ng-hide="conf.value === undefined"
class="btn btn-danger"
aria-label="Clear"
data-test-subj="clearButton">
>
<span class="sr-only">Clear</span>
<i aria-hidden="true" class="fa fa-trash-o"></i>
</button>
@ -122,7 +128,7 @@
ng-click="cancelEdit(conf)"
class="btn btn-default"
aria-label="Cancel edit"
data-test-subj="cancelButton">
>
<span class="sr-only">Cancel Edit</span>
<i aria-hidden="true" class="fa fa-times"></i>
</button>

View file

@ -32,10 +32,6 @@ li.kbn-management-tab:first-letter {
}
kbn-management-app {
bread-crumbs ul {
height: 36px;
}
li.current-page {
font-size: 1.5em;
margin: 0 10px;

View file

@ -1,78 +1,74 @@
<visualize-app class="app-container vis-editor vis-type-{{ vis.type.name }}">
<!-- Local nav. -->
<kbn-top-nav name="visualize" config="topNavMenu">
<div class="vis-editor-info">
<span ng-show="savedVis.id" class="vis-editor-info-title">
<span ng-bind="::savedVis.title"></span>
</span>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Title. -->
<div
data-transclude-slot="topLeftCorner"
class="localTitle"
>
<span
ng-show="savedVis.id"
ng-bind="::savedVis.title"
></span>
</div>
<!-- Search. -->
<div
data-transclude-slot="bottomRow"
ng-show="chrome.getVisible()"
class="fullWidth"
>
<!-- Block searching if the Visualization is linked to a Saved Search. -->
<div ng-if="vis.type.requiresSearch && $state.linked">
Linked to Saved Search &ldquo;{{ savedVis.savedSearch.title }}&rdquo;
&nbsp;
<a
href=""
ng-dblclick="unlink()"
tooltip="Double click to unlink from Saved Search"
>
<i aria-hidden="true" class="fa fa-chain-broken"></i>
</a>
</div>
<!-- Allow searching if there is no linked Saved Searc. -->
<form
ng-if="vis.type.requiresSearch && !$state.linked"
name="queryInput"
ng-submit="fetch()"
class="fullWidth"
>
<div class="typeahead" kbn-typeahead="visualize">
<div class="localSearch">
<input
ng-model="state.query"
parse-query
input-focus
kbn-typeahead-input
placeholder="Search..."
type="text"
class="localSearchInput"
ng-class="{'localSearchInput-isInvalid': queryInput.$invalid}"
>
<button
type="submit"
aria-label="Search"
class="localSearchButton"
ng-disabled="queryInput.$invalid"
>
<span aria-hidden="true" class="fa fa-search"></span>
</button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
</div>
</div>
</kbn-top-nav>
<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()"
tooltip="Double click to unlink this visualization from the saved search"
class="bitty-modal visualize-linked">
<i aria-hidden="true" class="fa fa-link"></i>
&nbsp;
This visualization is linked to a saved search:
<b>{{ savedVis.savedSearch.title }}</b>
</div>
<div
ng-if="vis.type.requiresSearch && unlinking"
ng-click="clearUnlinking()"
class="bitty-modal">
<i aria-hidden="true" class="fa fa-chain-broken"></i> Unlinked!
</div>
<form ng-if="vis.type.requiresSearch && $state.linked" class="inline-form fill" name="queryInput">
<div class="typeahead">
<div class="input-group">
<input
disabled
type="text"
class="form-control">
<button
class="btn btn-default" type="submit"
ng-disabled="true" aria-label="Search">
<span aria-hidden="true" class="fa fa-search"></span>
</button>
</div>
</div>
</form>
<form
ng-if="vis.type.requiresSearch && !$state.linked"
ng-submit="fetch()"
class="inline-form fill"
name="queryInput">
<div class="typeahead" kbn-typeahead="visualize">
<div class="input-group"
ng-class="queryInput.$invalid ? 'has-error' : ''">
<input
ng-model="state.query"
parse-query
input-focus
kbn-typeahead-input
placeholder="Search..."
type="text"
class="form-control">
<button
class="btn btn-default" type="submit"
ng-disabled="queryInput.$invalid" aria-label="Search">
<span aria-hidden="true" class="fa fa-search"></span>
</button>
</div>
<kbn-typeahead-items></kbn-typeahead-items>
</div>
</form>
</div>
<div class="button-group"></div>
</navbar>
<!-- Filters. -->
<filter-bar state="state"></filter-bar>
<div class="vis-editor-content">

View file

@ -110,9 +110,9 @@ function VisEditor($scope, $route, timefilter, AppState, $location, kbnUrl, $tim
template: require('plugins/kibana/visualize/editor/panels/save.html'),
description: 'Save Visualization'
}, {
key: 'load',
key: 'open',
template: require('plugins/kibana/visualize/editor/panels/load.html'),
description: 'Load Saved Visualization',
description: 'Open Saved Visualization',
}, {
key: 'share',
template: require('plugins/kibana/visualize/editor/panels/share.html'),
@ -309,13 +309,12 @@ function VisEditor($scope, $route, timefilter, AppState, $location, kbnUrl, $tim
$scope.unlink = function () {
if (!$state.linked) return;
notify.info(`Unlinked Visualization "${savedVis.title}" from Saved Search "${savedVis.savedSearch.title}"`);
$state.linked = false;
const parent = searchSource.getParent(true);
const parentsParent = parent.getParent(true);
// display unlinking for 2 seconds, unless it is double clicked
$scope.unlinking = $timeout($scope.clearUnlinking, 2000);
delete savedVis.savedSearchId;
parent.set('filter', _.union(searchSource.getOwn('filter'), parent.getOwn('filter')));
@ -332,13 +331,6 @@ function VisEditor($scope, $route, timefilter, AppState, $location, kbnUrl, $tim
searchSource.inherits(parentsParent);
};
$scope.clearUnlinking = function () {
if ($scope.unlinking) {
$timeout.cancel($scope.unlinking);
$scope.unlinking = null;
}
};
function transferVisState(fromVis, toVis, stage) {
return function () {

View file

@ -1 +1,2 @@
<div class="localDropdownTitle">Open Visualization</div>
<saved-object-finder type="visualizations"></saved-object-finder>

View file

@ -1,7 +1,21 @@
<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="opts.savedVis.title" required>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<form
role="form"
ng-submit="opts.doSave()"
>
<div class="localDropdownTitle">Save Visualization</div>
<input
class="localDropdownInput"
input-focus="select"
type="text"
name="visTitle"
ng-model="opts.savedVis.title"
required
>
<button
data-test-subj="saveVisualizationButton"
type="submit"
class="btn btn-primary"
>
Save
</button>
</form>

View file

@ -17,38 +17,6 @@
line-height: 1.3;
}
navbar {
.bitty-modal-container {
position: relative;
.bitty-modal {
position: absolute;
cursor: pointer;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 10;
background: fadeout(@vis-editor-navbar-modal-bg, 10%);
color: @vis-editor-navbar-modal-color;
text-align: center;
padding-top: 6px;
// Don't overflow container
padding-left: 20px;
padding-right: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
user-select: none;
}
a {
color: @vis-editor-navbar-modal-link-color;
}
}
}
.collapsible-sidebar {
.flex-parent(0, 0, auto);
margin-right: 10px;
@ -80,17 +48,6 @@
}
}
.vis-editor-info {
line-height: 30px;
padding: 0px 10px;
border-bottom-left-radius: @border-radius-base;
}
.vis-editor-info-title {
font-weight: bold;
margin-right: 10px;
}
.vis-editor-content {
.flex-parent();
z-index: 0;

View file

@ -2,11 +2,12 @@
@import (reference) "~ui/styles/bootstrap/list-group";
@import (reference) "~ui/styles/list-group-menu";
/**
* 1. Push down the breadcrumbs a bit.
*/
.vis-wizard {
margin-right: 0;
margin-left: 0;
padding-left: 0;
padding-right: 0;
margin: 0;
padding: 12px 0 0; // 1
}
.wizard-sub-title {

View file

@ -20,10 +20,6 @@
&-container {
margin: 20px;
&-fixed {
margin: 25px;
}
}
&-container-drawer {
@ -88,111 +84,87 @@
}
}
navbar.timelion-navbar {
&-fixed {
border-top: 5px solid @navbar-default-bg;
top: 0;
left: @as-closed-width;
right: 0px;
position: fixed;
}
input, select {
height: 34px;
}
.form-control:focus {
border-color: @gray-lighter;
}
}
.timelion-nav-wrapper {
z-index: 20;
}
.timelion-scroll-class {
}
.chart-container.running {
opacity: 0.50;
}
select.timelion-interval {
.timelion-interval {
width: 70px !important;
height: auto;
-webkit-appearance: none;
-moz-appearance: none;
padding: .5em;
padding-right: 1.5em;
line-height: 1;
border-top: 0;
border-right: 0;
border-bottom: 0;
border-radius: 0;
text-align: center;
&:focus {
border-color: #ecf0f1;
}
}
.timelion-interval--select {
background-position: right 50%;
background-repeat: no-repeat;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDZFNDEwNjlGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDZFNDEwNkFGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0NkU0MTA2N0Y3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0NkU0MTA2OEY3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuGsgwQAAAA5SURBVHjaYvz//z8DOYCJgUxAf42MQIzTk0D/M+KzkRGPoQSdykiKJrBGpOhgJFYTWNEIiEeAAAMAzNENEOH+do8AAAAASUVORK5CYII=);
padding: .5em;
padding-right: 1.5em;
border-left: 0px;
height: auto;
border-radius: 0;
}
&-other {
width: 10px !important;
}
.timelion-interval-other {
width: 10px !important;
}
timelion-interval {
display: flex;
}
input.timelion-interval {
border-radius: 0;
height: auto;
width: 40px !important;
padding: .5em;
border-right: 0px;
border-left: 0px;
text-align: center;
.timelionFunctionsDropdown {
height: 310px;
overflow-y: auto;
}
div.doc-container {
&-functions {
height: 310px;
overflow-y: auto;
background-color: @body-bg;
position: relative;
padding: 0px;
.timelionFunctionsTable {
background-color: white;
}
h3 {
margin-top: 0px;
}
.timelionFunctionsTableRow {
&:hover {
background-color: #f9f9f9;
}
}
tr.function:hover {
background-color: @gray-lighter;
}
/**
* 1. Override bootstrap .table styles.
*/
.timelionFunctionDetailsTable {
background-color: #f9f9f9 !important; // 1
}
.doc-container-content {
padding: 0 20px 20px 20px;
height: 310px;
overflow-y: auto;
background-color: @body-bg;
position: relative;
}
.doc-container-buttons {
position: relative;
text-align: center;
background-color: @body-bg;
height: 40px;
.btn-doc-prev {
position: absolute;
left: 20px;
}
&-content {
padding: 0 20px 20px 20px;
height: 310px;
overflow-y: auto;
background-color: @body-bg;
position: relative;
}
&-buttons {
text-align: center;
background-color: @body-bg;
height: 40px;
.btn-doc {
&-prev {
position: absolute;
left: 20px;
}
&-next {
position: absolute;
right: 20px;
}
}
.btn-doc-next {
position: absolute;
right: 20px;
}
}
@ -247,3 +219,10 @@ div.doc-container {
margin-right: 5px;
font-weight: bold;
}
/**
* 1. Needs to be relative to contain absolutely-positioned typeahead suggestions.
*/
.timelionLocalSearch {
position: relative; /* 1 */
}

View file

@ -2,7 +2,7 @@
class="form-control timelion-interval"
ng-model="otherInterval">
<select class="form-control timelion-interval"
<select class="form-control timelion-interval timelion-interval--select"
ng-options="i for i in intervalOptions"
ng-class="{'timelion-interval-other': interval == 'other'}"
ng-model="interval"></select>

View file

@ -1,65 +1,73 @@
<div class="timelion app-container" ng-controller="timelion" fixed-element-root>
<div class="timelion app-container" ng-controller="timelion">
<!-- Local nav. -->
<kbn-top-nav name="timelion" config="topNavMenu">
<div class="kibana-nav-info ng-scope">
<span class="kibana-nav-info-title">
<span ng-show="opts.savedSheet.id">
{{opts.savedSheet.title}}
<i class="fa fa-bolt" ng-click="showStats = !showStats"></i>
<!-- Transcluded elements. -->
<div data-transclude-slots>
<div data-transclude-slot="topLeftCorner" class="kibana-nav-info">
<span class="kibana-nav-info-title">
<span ng-show="opts.savedSheet.id">
{{opts.savedSheet.title}}
<i class="fa fa-bolt" ng-click="showStats = !showStats"></i>
</span>
<small class="timelion-stats" ng-show="showStats">
Query Time {{stats.queryTime - stats.invokeTime}}ms /
Processing Time {{stats.sheetTime - stats.queryTime}}ms
</small>
</span>
<small class="timelion-stats" ng-show="showStats">
Query Time {{stats.queryTime - stats.invokeTime}}ms /
Processing Time {{stats.sheetTime - stats.queryTime}}ms
</small>
</span>
</div>
<!-- Search. -->
<form
data-transclude-slot="bottomRow"
class="fullWidth"
role="form"
ng-submit="search()"
>
<div class="localSearch timelionLocalSearch">
<input
input-focus
ng-model="state.sheet[state.selected]"
timelion-expression="{{state.sheet[state.selected]}}"
placeholder="Expression..."
aria-label="Expression input"
type="text"
class="localSearchInput timelion-expression"
>
<timelion-interval model="state.interval"></timelion-interval>
<button
type="submit"
aria-label="Search"
class="localSearchButton"
>
<span class="fa fa-play"></span>
</button>
</div>
</form>
</div>
</kbn-top-nav>
<navbar class="timelion-navbar" fixed-element="timelion-navbar-fixed">
<form role="form" class="fill inline-form" ng-submit="search()" name="discoverSearch">
<div class="input-group">
<input input-focus
ng-model="state.sheet[state.selected]"
timelion-expression="{{state.sheet[state.selected]}}"
placeholder="Expression ..."
aria-label="Expression input"
type="text"
class="form-control timelion-expression">
<timelion-interval model="state.interval"></timelion-interval>
<button aria-label="Search" type="submit">
<span class="fa fa-play"></span>
</button>
</div>
</form>
</navbar>
<div class="timelion-container" fixed-element-body="timelion-container-fixed">
<div class="timelion-container">
<div class="timelion-container-sheet">
<div class="timelion-container-sheet-margin">
<timelion-fullscreen
ng-show="transient.fullscreen"
transient="transient"
state="state"
series="sheet[state.selected]"
expression="state.sheet[state.selected]"
on-search="search"
></timelion-fullscreen>
<timelion-fullscreen
ng-show="transient.fullscreen"
transient="transient"
state="state"
series="sheet[state.selected]"
expression="state.sheet[state.selected]"
on-search="search"
>
</timelion-fullscreen>
<timelion-cells
ng-show="!transient.fullscreen"
transient="transient"
state="state"
sheet="sheet"
on-search="search"
on-select="setActiveCell"
>
</timelion-cells>
<timelion-cells
ng-show="!transient.fullscreen"
transient="transient"
state="state"
sheet="sheet"
on-search="search"
on-select="setActiveCell"
></timelion-cells>
</div>
</div>
</div>

View file

@ -145,25 +145,27 @@
</div>
</div>
<div ng-show="section === 'functions'" class="doc-container-functions">
<h3>
<div ng-show="section === 'functions'" class="localDropdown timelionFunctionsDropdown">
<div class="localDropdownTitle">
Function reference
<small>
Click a function for details and arguments or <a ng-click="section = 'tutorial'">return to the tutorial.</a>
</small>
</h3>
<table class="table table-condensed table-striped table-bordered">
<tr class="function"
</div>
<div class="localDropdownHelpText">
Click a function for details and arguments or <a ng-click="section = 'tutorial'">return to the tutorial.</a>
</div>
<table class="table table-condensed table-bordered timelionFunctionsTable">
<tr class="timelionFunctionsTableRow"
ng-repeat-start="function in functions.list"
ng-class="{active: functions.details === function.name}"
ng-click="functions.details = (functions.details === function.name ? null : function.name)">
<td><strong>.{{function.name}}()</strong></td>
<td>{{function.help}}</td>
</tr>
<!-- Function details -->
<tr ng-if="functions.details === function.name" ng-repeat-end>
<td colspan=2>
<div class="suggestion-details" >
<table class="table table-striped table-condensed table-bordered"
<table class="table table-condensed table-bordered timelionFunctionDetailsTable"
ng-show="function.args.length > (function.chainable ? 1: 0)">
<thead>
<th>Argument Name</th>

View file

@ -1,3 +1,4 @@
<form role="form" class="container-fluid" ng-submit="fetch()">
<form role="form" ng-submit="fetch()">
<div class="localDropdownTitle">Open Sheet</div>
<saved-object-finder type="timelion-sheet" use-local-management="true"></saved-object-finder>
</form>

View file

@ -1,58 +1,52 @@
<div class="container-fluid">
<div class="row">
<div class="list-group">
<a class="list-group-item" ng-click="section = 'sheet'">
<h4 class="list-group-item-heading">Save entire Timelion sheet</h4>
<p class="list-group-item-text">
You want this option if you mostly use Timelion expressions from within the Timelion app and don't need to
add Timelion charts to Kibana dashboards. You may also want this if you make use of references to other
panels.
</p>
</a>
<div class="list-group-item" ng-show="section == 'sheet'">
<form role="form" class="container-fluid" ng-submit="opts.saveSheet()">
<div class="form-group">
<label for="savedSheet" class="control-label">Save sheet as</label>
<input id="savedSheet" ng-model="opts.savedSheet.title" input-focus="select" class="form-control" placeholder="Name this sheet...">
</div>
<div class="form-group">
<button ng-disabled="!opts.savedSheet.title" type="submit" class="btn btn-primary">
Save
</button>
</div>
</form>
</div>
<a class="list-group-item" ng-click="section = 'expression'">
<h4 class="list-group-item-heading">Save current expression as Kibana dashboard panel</h4>
<p class="list-group-item-text">
Need to add a chart to a Kibana dashboard? We can do that! This option will save your currently selected
expression as a panel that can be added to Kibana dashboards as you would add anything else. Note, if you
use references to other panels you will need to remove the refences by copying the referenced expression
directly into the expression you are saving. Click a chart to select a different expression to save.
</p>
</a>
<div class="list-group-item" ng-show="section == 'expression'">
<form role="form" class="container-fluid" ng-submit="opts.saveExpression(panelTitle)">
<div class="form-group">
<label class="control-label">Currently selected expression</label>
<code>{{opts.state.sheet[opts.state.selected]}}</code>
</div>
<div class="form-group">
<label for="savedExpression" class="control-label">Save expression as</label>
<input id="savedExpression" ng-model="panelTitle" input-focus="select" class="form-control" placeholder="Name this panel">
</div>
<div class="form-group">
<button ng-disabled="!panelTitle" type="submit" class="btn btn-primary">
Save
</button>
</div>
</form>
</div>
</div>
<div class="list-group">
<a class="list-group-item" ng-click="section = 'sheet'">
<h4 class="list-group-item-heading">Save entire Timelion sheet</h4>
<p class="list-group-item-text">
You want this option if you mostly use Timelion expressions from within the Timelion app and don't need to
add Timelion charts to Kibana dashboards. You may also want this if you make use of references to other
panels.
</p>
</a>
<div class="list-group-item" ng-show="section == 'sheet'">
<form role="form" class="container-fluid" ng-submit="opts.saveSheet()">
<div class="form-group">
<label for="savedSheet" class="control-label">Save sheet as</label>
<input id="savedSheet" ng-model="opts.savedSheet.title" input-focus="select" class="form-control" placeholder="Name this sheet...">
</div>
<div class="form-group">
<button ng-disabled="!opts.savedSheet.title" type="submit" class="btn btn-primary">
Save
</button>
</div>
</form>
</div>
<a class="list-group-item" ng-click="section = 'expression'">
<h4 class="list-group-item-heading">Save current expression as Kibana dashboard panel</h4>
<p class="list-group-item-text">
Need to add a chart to a Kibana dashboard? We can do that! This option will save your currently selected
expression as a panel that can be added to Kibana dashboards as you would add anything else. Note, if you
use references to other panels you will need to remove the refences by copying the referenced expression
directly into the expression you are saving. Click a chart to select a different expression to save.
</p>
</a>
<div class="list-group-item" ng-show="section == 'expression'">
<form role="form" class="container-fluid" ng-submit="opts.saveExpression(panelTitle)">
<div class="form-group">
<label class="control-label">Currently selected expression</label>
<code>{{opts.state.sheet[opts.state.selected]}}</code>
</div>
<div class="form-group">
<label for="savedExpression" class="control-label">Save expression as</label>
<input id="savedExpression" ng-model="panelTitle" input-focus="select" class="form-control" placeholder="Name this panel">
</div>
<div class="form-group">
<button ng-disabled="!panelTitle" type="submit" class="btn btn-primary">
Save
</button>
</div>
</form>
</div>
</div>

View file

@ -1,4 +1,6 @@
<form role="form" class="container-fluid">
<form role="form">
<div class="localDropdownTitle">Sheet options</div>
<div>
<div class="form-group col-md-6">
<label>Columns <small>Column count must divide evenly into 12</small></label>
<select class="form-control"
@ -15,4 +17,5 @@
ng-model="opts.state.rows">
</select>
</div>
</div>
</form>

View file

@ -12,10 +12,11 @@ module.directive('breadCrumbs', function () {
},
template: breadCrumbsTemplate,
controller: function ($scope) {
$scope.crumbs = chrome.getBreadcrumbs();
// Capitalize the first letter of each bread crumb.
$scope.breadcrumbs = chrome.getBreadcrumbs().map(breadcrumb => _.startCase(breadcrumb));
if ($scope.omitCurrentPage === true) {
$scope.crumbs.pop();
$scope.breadcrumbs.pop();
}
}
};

View file

@ -1,27 +1,52 @@
<navbar ng-show="kbnTopNav.isVisible()" class="kibana-nav-options" data-test-subj="top-nav">
<div ng-transclude></div>
<div class="button-group kibana-nav-actions" role="toolbar">
<button
ng-repeat="menuItem in kbnTopNav.menuItems"
aria-label="{{::menuItem.description}}"
aria-haspopup="{{!menuItem.hasFunction}}"
aria-expanded="{{kbnTopNav.isCurrent(menuItem.key)}}"
ng-class="{active: kbnTopNav.isCurrent(menuItem.key), 'is-kbn-top-nav-button-disabled': menuItem.disableButton()}"
ng-click="kbnTopNav.handleClick(menuItem)"
ng-bind="menuItem.label"
tooltip="{{menuItem.tooltip()}}"
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
data-test-subj="menu-item-{{menuItem.key}}"
>
</button>
<div
class="localNav"
ng-show="kbnTopNav.isVisible()"
data-test-subj="top-nav"
>
<!-- Top row -->
<div class="localNavRow">
<!-- Top left corner slot, e.g. breadcrumbs, title. -->
<div
class="localNavRow__section"
data-transclude-slot="topLeftCorner"
></div>
<!-- Right-side: menu -->
<div class="localNavRow__section">
<div class="localMenu">
<div
class="localMenuItem"
ng-repeat="menuItem in kbnTopNav.menuItems"
aria-label="{{::menuItem.description}}"
aria-haspopup="{{!menuItem.hasFunction}}"
aria-expanded="{{kbnTopNav.isCurrent(menuItem.key)}}"
ng-class="{'localMenuItem-isSelected': kbnTopNav.isCurrent(menuItem.key), 'localMenuItem-isDisabled': menuItem.disableButton()}"
ng-click="kbnTopNav.handleClick(menuItem)"
ng-bind="menuItem.label"
tooltip="{{menuItem.tooltip()}}"
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
data-test-subj="{{menuItem.testId}}"
></div>
<!-- Time-picker "menu item" -->
<kbn-global-timepicker></kbn-global-timepicker>
</div>
</div>
</div>
<kbn-global-timepicker></kbn-global-timepicker>
</navbar>
<div class="config" ng-show="kbnTopNav.rendered">
<div id="template_wrapper" class="container-fluid"></div>
<div class="config-close remove" ng-click="kbnTopNav.close()">
<i class="fa fa-chevron-circle-up"></i>
<!-- Dropdown content, e.g. time-picker. -->
<div
class="localDropdown"
id="template_wrapper"
ng-show="kbnTopNav.rendered"
>
<!-- Content gets dynamically inserted here. -->
</div>
<div class="localNavRow localNavRow--secondary">
<!-- Bottom row slot, e.g. tabs. -->
<div data-transclude-slot="bottomRow"></div>
</div>
</div>

View file

@ -1,13 +1,3 @@
import _ from 'lodash';
import 'ui/watch_multi';
import 'ui/directives/input_focus';
import uiModules from 'ui/modules';
import template from './kbn_top_nav.html';
import KbnTopNavControllerProvider from './kbn_top_nav_controller';
import RegistryNavbarExtensionsProvider from 'ui/registry/navbar_extensions';
const module = uiModules.get('kibana');
/**
* kbnTopNav directive
*
@ -41,6 +31,18 @@ const module = uiModules.get('kibana');
*
* Programatic control of the navbar can be acheived one of two ways
*/
import _ from 'lodash';
import angular from 'angular';
import 'ui/watch_multi';
import 'ui/directives/input_focus';
import uiModules from 'ui/modules';
import template from './kbn_top_nav.html';
import KbnTopNavControllerProvider from './kbn_top_nav_controller';
import RegistryNavbarExtensionsProvider from 'ui/registry/navbar_extensions';
const module = uiModules.get('kibana');
module.directive('kbnTopNav', function (Private) {
const KbnTopNavController = Private(KbnTopNavControllerProvider);
const navbarExtensions = Private(RegistryNavbarExtensionsProvider);
@ -55,7 +57,7 @@ module.directive('kbnTopNav', function (Private) {
template,
// TODO: The kbnTopNav currently requires that it share a scope with
// it's parent directive. This allows it to export the kbnTopNav controller
// its parent directive. This allows it to export the kbnTopNav controller
// and allows the config templates to use values from the parent scope.
//
// Moving this to an isolate scope will require modifying the config
@ -63,9 +65,38 @@ module.directive('kbnTopNav', function (Private) {
// parent controllers can be imported/required rather than simply referenced
// directly in the template.
//
// TODO: Our fake multi-slot transclusion solution also depends on an inherited
// scope. Moving this to an isolate scope will cause this to break.
//
// scope: {}
controller($scope, $attrs, $element) {
controller($scope, $attrs, $element, $transclude) {
// This is a semi-hacky solution to missing slot-transclusion support in Angular 1.4.7
// (it was added as a core feature in 1.5). Borrowed from http://stackoverflow.com/a/22080765.
$scope.transcludes = {};
// Extract transcluded elements for use in the link function.
$transclude(clone => {
// We expect the transcluded elements to be wrapped in a single div.
const transcludedContentContainer = _.find(clone, item => {
if (item.attributes) {
return _.find(item.attributes, attr => {
return attr.name.indexOf('data-transclude-slots') !== -1;
});
}
});
if (!transcludedContentContainer) {
return;
};
const transcludedContent = transcludedContentContainer.children;
_.forEach(transcludedContent, transcludedItem => {
const transclusionSlot = transcludedItem.getAttribute('data-transclude-slot');
$scope.transcludes[transclusionSlot] = transcludedItem;
});
});
const extensions = getNavbarExtensions($attrs.name);
let controls = _.get($scope, $attrs.config, []);
if (controls instanceof KbnTopNavController) {
@ -78,6 +109,20 @@ module.directive('kbnTopNav', function (Private) {
$scope.kbnTopNav._link($scope, $element);
return $scope.kbnTopNav;
},
link(scope, element) {
// These are the slots where transcluded elements can go.
const transclusionSlotNames = ['topLeftCorner', 'bottomRow'];
// Transclude elements into specified "slots" in the top nav.
transclusionSlotNames.forEach(name => {
const transcludedItem = scope.transcludes[name];
if (transcludedItem) {
const transclusionSlot = document.querySelector(`[data-transclude-slot="${name}"]`);
angular.element(transclusionSlot).replaceWith(transcludedItem);
}
});
}
};
});

View file

@ -1,6 +1,5 @@
<ul>
<li ng-repeat="crumb in crumbs">
<span>{{crumb}}</span>
<span ng-hide="$last"> / </span>
</li>
</ul>
<div class="localBreadcrumbs">
<div class="localBreadcrumb" ng-repeat="breadcrumb in breadcrumbs">
{{breadcrumb}}
</div>
</div>

View file

@ -1,2 +1 @@
import './styles/index.less';
import './directives/share';

View file

@ -1,79 +0,0 @@
.share-dropdown {
display: flex;
padding: 5px 15px;
}
.share-panel {
flex: 1 1 0%;
}
.share-panel--left {
margin-right: 30px;
}
.share-panel--right {
margin-left: 30px;
}
.share-panel__title {
margin-bottom: 12px;
padding-bottom: 4px;
font-size: 18px;
color: #000000;
}
.share-panel-section {
margin-bottom: 16px;
}
.share-panel-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
}
.share-panel-header__label {
font-size: 14px;
font-weight: 700;
color: #000000;
}
.share-panel-header__actions {
display: flex;
}
.share-panel-header__action {
font-size: 12px;
& + & {
margin-left: 10px;
}
}
.share-panel-input {
width: 100%;
padding: 4px 10px;
margin-bottom: 6px;
border: 0;
border-radius: 4px;
}
.share-panel-form-note {
font-size: 14px;
color: #5A5A5A;
}
.share-panel-help-text {
margin-bottom: 16px;
font-size: 14px;
color: #2D2D2D;
}
.share-panel-warning {
margin-bottom: 16px;
padding: 6px 10px;
font-size: 14px;
color: #2D2D2D;
background-color: #e4e4e4;
}

View file

@ -1,34 +1,34 @@
<div class="share-dropdown">
<div class="localDropdownPanels">
<!-- Left panel -->
<div class="share-panel share-panel--left">
<div class="localDropdownPanel localDropdownPanel--left">
<!-- Title -->
<div
data-test-subj="shareUiTitle"
class="share-panel__title"
class="localDropdownTitle"
>
Share saved {{share.objectType}}
</div>
<!-- Help text -->
<div ng-if="share.urls.original" class="share-panel-help-text">
<div ng-if="share.urls.original" class="localDropdownHelpText">
You can share this URL with people to let them load the most recent saved version of this {{share.objectType}}.
</div>
<div ng-if="!share.urls.original" class="share-panel-warning">
<div ng-if="!share.urls.original" class="localDropdownWarning">
Please save this {{share.objectType}} to enable this sharing option.
</div>
<div ng-if="share.urls.original">
<!-- iframe -->
<div class="share-panel-section" ng-if="share.allowEmbed">
<div class="localDropdownSection" ng-if="share.allowEmbed">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">
Embedded iframe
</div>
<div class="share-panel-header__actions">
<div class="localDropdownHeader__actions">
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-click="share.copyToClipboard('#originalIframeUrl')"
>
Copy
@ -39,28 +39,28 @@
<!-- Input -->
<input
id="originalIframeUrl"
class="share-panel-input"
class="localDropdownInput"
type="text"
readonly
value="{{share.makeIframeTag(share.urls.original)}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
<div class="localDropdownFormNote">
Add to your HTML source. Note that all clients must be able to access Kibana.
</div>
</div>
<!-- Link -->
<div class="share-panel-section">
<div class="localDropdownSection">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">
Link
</div>
<div class="share-panel-header__actions">
<div class="localDropdownHeader__actions">
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-click="share.copyToClipboard('#originalUrl')"
>
Copy
@ -71,7 +71,7 @@
<!-- Input -->
<input
id="originalUrl"
class="share-panel-input"
class="localDropdownInput"
type="text"
readonly
value="{{share.urls.original}}"
@ -81,27 +81,27 @@
</div>
<!-- Right panel -->
<div class="share-panel share-panel--right">
<div class="localDropdownPanel localDropdownPanel--right">
<!-- Title -->
<div class="share-panel__title">
<div class="localDropdownTitle">
Share Snapshot
</div>
<!-- Help text -->
<div class="share-panel-help-text">
<div class="localDropdownHelpText">
Snapshot URLs encode the current state of the {{share.objectType}} in the URL itself. Edits to the saved {{share.objectType}} won't be visible via this URL.
</div>
<!-- iframe -->
<div class="share-panel-section" ng-if="share.allowEmbed">
<div class="localDropdownSection" ng-if="share.allowEmbed">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">
Embedded iframe
</div>
<div class="share-panel-header__actions">
<div class="localDropdownHeader__actions">
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-if="!share.urlFlags.shortSnapshotIframe"
ng-click="share.toggleShortSnapshotIframeUrl()"
>
@ -109,7 +109,7 @@
</a>
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-if="share.urlFlags.shortSnapshotIframe"
ng-click="share.toggleShortSnapshotIframeUrl()"
>
@ -117,7 +117,7 @@
</a>
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-click="share.copyToClipboard('#snapshotIframeUrl')"
>
Copy
@ -128,29 +128,29 @@
<!-- Input -->
<input
id="snapshotIframeUrl"
class="share-panel-input"
class="localDropdownInput"
type="text"
readonly
value="{{share.urlFlags.shortSnapshotIframe ? share.makeIframeTag(share.urls.shortSnapshotIframe) : share.makeIframeTag(share.urls.snapshot)}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
<div class="localDropdownFormNote">
Add to your HTML source. Note that all clients must be able to access Kibana.
</div>
</div>
<!-- Link -->
<div class="share-panel-section">
<div class="localDropdownSection">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
<div class="localDropdownHeader">
<div class="localDropdownHeader__label">
Link
</div>
<div class="share-panel-header__actions">
<div class="localDropdownHeader__actions">
<a
data-test-subj="sharedSnapshotShortUrlButton"
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-if="!share.urlFlags.shortSnapshot"
ng-click="share.toggleShortSnapshotUrl()"
>
@ -158,7 +158,7 @@
</a>
<a
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-if="share.urlFlags.shortSnapshot"
ng-click="share.toggleShortSnapshotUrl()"
>
@ -167,7 +167,7 @@
<a
data-test-subj="sharedSnapshotCopyButton"
class="share-panel-header__action"
class="localDropdownHeader__action"
ng-click="share.copyToClipboard('#snapshotUrl')"
>
Copy
@ -179,14 +179,14 @@
<input
data-test-subj="sharedSnapshotUrl"
id="snapshotUrl"
class="share-panel-input"
class="localDropdownInput"
type="text"
readonly
value="{{share.urlFlags.shortSnapshot ? share.urls.shortSnapshot : share.urls.snapshot}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
<div class="localDropdownFormNote">
We recommend sharing shortened snapshot URLs for maximum compatibility. Internet Explorer has URL length restrictions, and some wiki and markup parsers don't do well with the full-length version of the snapshot URL, but the short URL should work great.
</div>
</div>

View file

@ -3,6 +3,9 @@
@import (reference) "./variables";
@import (reference) "~ui/styles/bootstrap/bootstrap";
// Kibana UI Framework
@import (less) "~@elastic/kibana-ui-framework/dist/framework.css";
html,
body {
.flex-parent();
@ -157,16 +160,6 @@ a {
.button-group > :last-child {
border-radius: 0;
}
button.is-kbn-top-nav-button-disabled {
opacity: 0.5;
cursor: default;
&:active {
color: @kibanaGray2;
background-color: transparent;
}
}
}
.kibana-nav-info {
@ -303,38 +296,6 @@ table {
}
}
//== breadCrumbsTemplate
bread-crumbs {
display: block;
&.bread-crumbs--navbar {
background-color: @navbar-default-bg;
}
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,
paginated-selectable-list {
@ -670,4 +631,24 @@ fieldset {
font-size: 14px;
}
/**
* Utility class.
* TODO: Move to UI Framework.
*/
.fullWidth {
width: 100%;
}
/**
* TODO: This is a generic pattern that should be replaced by specific components, e.g. inputGroup.
*/
.flexGroup {
display: flex;
width: 100%;
}
.flexGroup__filler {
flex: 1 1 auto;
}
@import "~dragula/dist/dragula.css";

View file

@ -37,6 +37,9 @@
}
}
.list-group-item--noBorder {
border-top: 0;
}
// Interactive list items
//

View file

@ -1,33 +0,0 @@
@import (reference) "./variables.less";
.localTabs {
display: flex;
align-items: center;
}
.localTab {
flex: 0 0 auto;
padding: 5px 0 6px;
font-size: 18px;
line-height: 20px;
color: @kibanaGray2;
border-bottom: 2px solid transparent;
background-color: transparent;
text-decoration: none;
&.localTab-disabled {
opacity: 0.5;
cursor: default;
}
&:only-child,
&:hover,
&.localTab-isSelected {
color: @kibanaGray1;
border-bottom-color: @kibanaGray1;
}
}
.localTab + .localTab {
margin-left: 20px;
}

View file

@ -18,6 +18,6 @@ describe('kbnGlobalTimepicker', function () {
});
it('injects the timepicker into the DOM', () => {
const $el = compile();
expect($el.find('button[ng-click]')).to.have.length(3);
expect($el.attr('data-test-subj')).to.be('globalTimepicker');
});
});

View file

@ -1,32 +1,38 @@
<ul ng-show="timefilter.enabled" class="nav navbar-nav navbar-right navbar-timepicker">
<li>
<button
ng-click="toggleRefresh()"
ng-show="timefilter.refreshInterval.value > 0">
<i class="fa" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
</button>
</li>
<div ng-show="timefilter.enabled" class="localMenu" data-test-subj="globalTimepicker">
<div
class="localMenuItem"
ng-click="toggleRefresh()"
ng-show="timefilter.refreshInterval.value > 0"
>
<i class="fa" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
</div>
<li
ng-show="timefilter.refreshInterval.value > 0 || kbnTopNav.isCurrent('interval') || kbnTopNav.isCurrent('filter')">
<div
class="localMenuItem navbar-timepicker-auto-refresh-desc"
ng-class="{'localMenuItem-isSelected': kbnTopNav.isCurrent('interval') }"
ng-show="timefilter.refreshInterval.value > 0 || kbnTopNav.isCurrent('interval') || kbnTopNav.isCurrent('filter')"
ng-click="kbnTopNav.toggle('interval')"
>
<span ng-show="timefilter.refreshInterval.value === 0">
<i class="fa fa-repeat"></i> Auto-refresh
</span>
<span ng-show="timefilter.refreshInterval.value > 0">
{{timefilter.refreshInterval.display}}
</span>
</div>
<button ng-click="kbnTopNav.toggle('interval')"
ng-class="{active: kbnTopNav.isCurrent('interval') }"
class="navbar-timepicker-auto-refresh-desc">
<span ng-show="timefilter.refreshInterval.value === 0"><i class="fa fa-repeat"></i> Auto-refresh</span>
<span ng-show="timefilter.refreshInterval.value > 0">{{timefilter.refreshInterval.display}}</span>
</button>
</li>
<li>
<button ng-class="{active: kbnTopNav.isCurrent('filter')}"
ng-click="kbnTopNav.toggle('filter')"
aria-haspopup="true"
aria-expanded="false"
class="navbar-timepicker-time-desc">
<i aria-hidden="true" class="fa fa-clock-o"></i>
<pretty-duration from="timefilter.time.from" to="timefilter.time.to"></pretty-duration>
</button>
</li>
</ul>
<div
data-test-subj="globalTimepickerButton"
class="localMenuItem navbar-timepicker-time-desc"
ng-class="{'localMenuItem-isSelected': kbnTopNav.isCurrent('filter')}"
ng-click="kbnTopNav.toggle('filter')"
aria-haspopup="true"
aria-expanded="false"
>
<i aria-hidden="true" class="fa fa-clock-o"></i>
<pretty-duration
from="timefilter.time.from" to="timefilter.time.to"
data-test-subj="globalTimepickerRange"
></pretty-duration>
</div>
</div>

View file

@ -18,6 +18,7 @@ UiModules
return {
template: toggleHtml,
replace: true,
link: ($scope, $el, attrs) => {
listenForUpdates($rootScope);

View file

@ -23,7 +23,7 @@
<!-- Filters -->
<div ng-show="activeTab === 'filter'" role="tabpanel" class="tab-pane active">
<br>
<div class="localDropdownTitle">Time Range</div>
<div class="row">
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked kbn-timepicker-modes">
@ -160,7 +160,7 @@
<!-- Refresh Intervals -->
<div ng-show="activeTab === 'interval'" role="tabpanel" class="tab-pane active">
<br>
<div class="localDropdownTitle">Refresh Interval</div>
<div ng-repeat="list in refreshLists" class="kbn-refresh-section">
<ul class="list-unstyled">
<li ng-repeat="inter in list">

View file

@ -17,7 +17,7 @@ export default class ConsolePage {
}
async getRequestEditor() {
return await PageObjects.common.findTestSubject('console request-editor');
return await PageObjects.common.findTestSubject('request-editor');
}
async getRequest() {
@ -26,22 +26,22 @@ export default class ConsolePage {
}
async getResponse() {
const responseEditor = await PageObjects.common.findTestSubject('console response-editor');
const responseEditor = await PageObjects.common.findTestSubject('response-editor');
return await getVisibleTextFromAceEditor(responseEditor);
}
async clickPlay() {
const sendRequestButton = await PageObjects.common.findTestSubject('console send-request-button');
const sendRequestButton = await PageObjects.common.findTestSubject('send-request-button');
await sendRequestButton.click();
}
async collapseHelp() {
const closeButton = await PageObjects.common.findTestSubject('console help-close-button');
const closeButton = await PageObjects.common.findTestSubject('help-close-button');
await closeButton.click();
}
async openSettings() {
const settingsButton = await PageObjects.common.findTestSubject('console top-nav menu-item-settings');
const settingsButton = await PageObjects.common.findTestSubject('consoleSettingsButton');
await settingsButton.click();
}
@ -50,13 +50,13 @@ export default class ConsolePage {
// while the settings form opens/loads this may fail, so retry for a while
await PageObjects.common.try(async () => {
const fontSizeInput = await PageObjects.common.findTestSubject('console setting-font-size-input');
const fontSizeInput = await PageObjects.common.findTestSubject('setting-font-size-input');
await fontSizeInput.clearValue();
await fontSizeInput.click();
await fontSizeInput.type(String(newSize));
});
const saveButton = await PageObjects.common.findTestSubject('console settings-save-button');
const saveButton = await PageObjects.common.findTestSubject('settings-save-button');
await saveButton.click();
}

View file

@ -14,13 +14,13 @@ export default class DashboardPage {
clickNewDashboard() {
return this.findTimeout
.findByCssSelector('button.ng-scope[aria-label="New Dashboard"]')
.findByCssSelector('[aria-label="New Dashboard"]')
.click();
}
clickAddVisualization() {
return this.findTimeout
.findByCssSelector('button.ng-scope[aria-label="Add a panel to the dashboard"]')
.findByCssSelector('[aria-label="Add a panel to the dashboard"]')
.click();
}
@ -71,7 +71,7 @@ export default class DashboardPage {
saveDashboard(dashName) {
return this.findTimeout
.findByCssSelector('button.ng-scope[aria-label="Save Dashboard"]')
.findByCssSelector('[aria-label="Save Dashboard"]')
.click()
.then(() => {
return PageObjects.header.getSpinnerDone();
@ -126,7 +126,7 @@ export default class DashboardPage {
loadSavedDashboard(dashName) {
var self = this;
return this.findTimeout
.findByCssSelector('button.ng-scope[aria-label="Load Saved Dashboard"]')
.findByCssSelector('[aria-label="Open Saved Dashboard"]')
.click()
.then(function filterDashboard() {
PageObjects.common.debug('Load Saved Dashboard button clicked');

View file

@ -23,8 +23,7 @@ export default class DiscoverPage {
}
getTimespanText() {
return this.findTimeout
.findByCssSelector('.kibana-nav-options .navbar-timepicker-time-desc pretty-duration')
return PageObjects.common.findTestSubject('globalTimepickerRange')
.getVisibleText();
}
@ -59,25 +58,24 @@ export default class DiscoverPage {
clickNewSearchButton() {
return this.findTimeout
.findByCssSelector('button[aria-label="New Search"]')
.findByCssSelector('[aria-label="New Search"]')
.click();
}
clickSaveSearchButton() {
return this.findTimeout
.findByCssSelector('button[aria-label="Save Search"]')
.findByCssSelector('[aria-label="Save Search"]')
.click();
}
clickLoadSavedSearchButton() {
return this.findTimeout
.findDisplayedByCssSelector('button[aria-label="Load Saved Search"]')
.findDisplayedByCssSelector('[aria-label="Load Saved Search"]')
.click();
}
getCurrentQueryName() {
return this.findTimeout
.findByCssSelector('span.kibana-nav-info-title span')
return PageObjects.common.findTestSubject('discoverCurrentQuery')
.getVisibleText();
}
@ -143,8 +141,7 @@ export default class DiscoverPage {
getHitCount() {
return PageObjects.header.getSpinnerDone()
.then(() => {
return this.findTimeout
.findByCssSelector('strong.discover-info-hits')
return PageObjects.common.findTestSubject('discoverQueryHits')
.getVisibleText();
});
}
@ -196,31 +193,27 @@ export default class DiscoverPage {
clickShare() {
return this.findTimeout
.findByCssSelector('button[aria-label="Share Search"]')
.findByCssSelector('[aria-label="Share Search"]')
.click();
}
clickShortenUrl() {
return this.findTimeout
.findByCssSelector('[data-test-subj="sharedSnapshotShortUrlButton"]')
return PageObjects.common.findTestSubject('sharedSnapshotShortUrlButton')
.click();
}
clickCopyToClipboard() {
return this.findTimeout
.findByCssSelector('[data-test-subj="sharedSnapshotCopyButton"]')
return PageObjects.common.findTestSubject('sharedSnapshotCopyButton')
.click();
}
getShareCaption() {
return this.findTimeout
.findByCssSelector('[data-test-subj="shareUiTitle"]')
return PageObjects.common.findTestSubject('shareUiTitle')
.getVisibleText();
}
getSharedUrl() {
return this.findTimeout
.findByCssSelector('[data-test-subj="sharedSnapshotUrl"]')
return PageObjects.common.findTestSubject('sharedSnapshotUrl')
.getProperty('value');
}

View file

@ -42,8 +42,8 @@ export default class HeaderPage {
}
clickTimepicker() {
return this.remote.setFindTimeout(defaultFindTimeout)
.findDisplayedByClassName('navbar-timepicker-time-desc').click();
return PageObjects.common.findTestSubject('globalTimepickerButton')
.click();
}
isTimepickerOpen() {
@ -104,16 +104,10 @@ export default class HeaderPage {
return this.getSpinnerDone();
})
.then(() => {
return this.collapseTimepicker();
return this.clickTimepicker();
});
}
collapseTimepicker() {
return this.remote.setFindTimeout(defaultFindTimeout)
.findByCssSelector('.fa.fa-chevron-circle-up')
.click();
}
getToastMessage() {
return this.remote.setFindTimeout(defaultFindTimeout)
.findDisplayedByCssSelector('kbn-truncated.toast-message.ng-isolate-scope')

View file

@ -32,14 +32,14 @@ export default class SettingsPage {
getAdvancedSettings(propertyName) {
PageObjects.common.debug('in setAdvancedSettings');
return PageObjects.common.findTestSubject('advancedSetting&' + propertyName + ' currentValue')
return PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-currentValue')
.getVisibleText();
}
setAdvancedSettings(propertyName, propertyValue) {
var self = this;
return PageObjects.common.findTestSubject('advancedSetting&' + propertyName + ' editButton')
return PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-editButton')
.click()
.then(() => {
return PageObjects.header.getSpinnerDone();
@ -56,7 +56,7 @@ export default class SettingsPage {
return PageObjects.header.getSpinnerDone();
})
.then(function setAdvancedSettingsClickSaveButton() {
return PageObjects.common.findTestSubject('advancedSetting&' + propertyName + ' saveButton')
return PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-saveButton')
.click();
})
.then(() => {
@ -67,7 +67,7 @@ export default class SettingsPage {
getAdvancedSettings(propertyName) {
var self = this;
PageObjects.common.debug('in setAdvancedSettings');
return PageObjects.common.findTestSubject('advancedSetting&' + propertyName + ' currentValue')
return PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-currentValue')
.getVisibleText();
}

View file

@ -296,7 +296,7 @@ export default class VisualizePage {
clickNewVisualization() {
return this.remote
.setFindTimeout(defaultFindTimeout)
.findByCssSelector('button[aria-label="New Visualization"]')
.findByCssSelector('[aria-label="New Visualization"]')
.click();
}
@ -304,7 +304,7 @@ export default class VisualizePage {
saveVisualization(vizName) {
return this.remote
.setFindTimeout(defaultFindTimeout)
.findByCssSelector('button[aria-label="Save Visualization"]')
.findByCssSelector('[aria-label="Save Visualization"]')
.click()
.then(() => {
return PageObjects.common.sleep(1000);
@ -319,9 +319,7 @@ export default class VisualizePage {
// // click save button
.then(() => {
PageObjects.common.debug('click submit button');
return this.remote
.setFindTimeout(defaultFindTimeout)
.findByCssSelector('.config button[type="submit"]')
return PageObjects.common.findTestSubject('saveVisualizationButton')
.click();
})
.then(function () {
@ -343,7 +341,7 @@ export default class VisualizePage {
clickLoadSavedVisButton() {
return this.remote
.setFindTimeout(defaultFindTimeout)
.findDisplayedByCssSelector('button[aria-label="Load Saved Visualization"]')
.findDisplayedByCssSelector('[aria-label="Open Saved Visualization"]')
.click();
}