few enhancements to default sidebar editor (#15619) (#15700)

This commit is contained in:
Peter Pisljar 2017-12-19 21:32:37 +01:00 committed by GitHub
parent 3294a2ff8e
commit 20c9e3bf30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 200 additions and 14 deletions

View file

@ -17,6 +17,42 @@
.collapsible-sidebar {
.flex-parent(0, 0, auto);
margin-right: 10px;
flex-direction: row;
max-width: 75%;
min-width: @vis-editor-sidebar-min-width;
width: @vis-editor-sidebar-min-width;
}
.collapsible-sidebar--small {
width: 15%;
}
.collapsible-sidebar--medium {
width: 30%;
}
.collapsible-sidebar--large {
width: 50%;
}
.default-editor__resizer {
display: flex;
flex: 0 0 13px;
cursor: ew-resize;
background-color: @globalColorLightestGray;
align-items: center;
margin: 0;
user-select: none;
&:hover {
background-color: lighten(@globalColorBlue, 50%);
}
&.active {
background-color: @globalColorBlue;
color: white;
}
}
.visualization-options {
@ -81,8 +117,6 @@
// overrided for tablet and desktop
@media (min-width: @screen-md-min) {
flex-basis: @vis-editor-sidebar-basis;
min-width: @vis-editor-sidebar-min-width;
max-width: @vis-editor-sidebar-min-width;
}
.index-pattern,

View file

@ -6,6 +6,7 @@ import markdownVisTemplate from 'plugins/markdown_vis/markdown_vis.html';
import markdownVisParamsTemplate from 'plugins/markdown_vis/markdown_vis_params.html';
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
import image from './images/icon-markdown.svg';
import { DefaultEditorSize } from 'ui/vis/editor_size';
// we need to load the css ourselves
// we also need to load the controller and used by the template
@ -32,7 +33,9 @@ function MarkdownVisProvider(Private) {
}
},
editorConfig: {
optionsTemplate: markdownVisParamsTemplate
optionsTemplate: markdownVisParamsTemplate,
enableAutoApply: true,
defaultSize: DefaultEditorSize.LARGE,
},
options: {
showTimePicker: false,

View file

@ -3,6 +3,7 @@ import { CATEGORY } from 'ui/vis/vis_category';
import image from '../images/icon-timelion.svg';
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
import { TimelionRequestHandlerProvider } from './timelion_request_handler';
import { DefaultEditorSize } from 'ui/vis/editor_size';
// we also need to load the controller and directive used by the template
import 'plugins/timelion/vis/timelion_vis_controller';
@ -38,6 +39,7 @@ export default function TimelionVisProvider(Private) {
},
editorConfig: {
optionsTemplate: editorConfigTemplate,
defaultSize: DefaultEditorSize.MEDIUM,
},
requestHandler: timelionRequestHandler.handler,
responseHandler: 'none',

View file

@ -0,0 +1,5 @@
export const DefaultEditorSize = {
SMALL: 'small',
MEDIUM: 'medium',
LARGE: 'large'
};

View file

@ -1,5 +1,11 @@
<div class="collapsible-sidebar">
<div class="collapsible-sidebar" ng-class="::getSidebarClass()">
<vis-editor-sidebar class="vis-editor-sidebar" />
<vis-editor-resizer
class="default-editor__resizer"
tabindex="0"
aria-label="Press left/right to resize the editor"
data-test-subj="visualizeEditorResizer"
>&#xFE19;</vis-editor-resizer>
</div>
<div

View file

@ -1,10 +1,13 @@
import './sidebar';
import './vis_options';
import './vis_editor_resizer';
import $ from 'jquery';
import _ from 'lodash';
import angular from 'angular';
import defaultEditorTemplate from './default.html';
import { keyCodes } from '@elastic/eui';
import { DefaultEditorSize } from 'ui/vis/editor_size';
import { VisEditorTypesRegistryProvider } from 'ui/registry/vis_editor_types';
@ -60,6 +63,36 @@ const defaultEditor = function ($rootScope, $compile) {
$scope.vis.dirty = false;
};
$scope.autoApplyEnabled = false;
if ($scope.vis.type.editorConfig.enableAutoApply) {
$scope.toggleAutoApply = () => {
$scope.autoApplyEnabled = !$scope.autoApplyEnabled;
};
$scope.$watch('vis.dirty', _.debounce(() => {
if (!$scope.autoApplyEnabled || !$scope.vis.dirty) return;
$scope.stageEditableVis();
}, 800));
}
$scope.submitEditorWithKeyboard = (event) => {
if (event.ctrlKey && event.keyCode === keyCodes.ENTER) {
event.preventDefault();
event.stopPropagation();
$scope.stageEditableVis();
}
};
$scope.getSidebarClass = () => {
if ($scope.vis.type.editorConfig.defaultSize === DefaultEditorSize.SMALL) {
return 'collapsible-sidebar--small';
} else if ($scope.vis.type.editorConfig.defaultSize === DefaultEditorSize.MEDIUM) {
return 'collapsible-sidebar--medium';
} else if ($scope.vis.type.editorConfig.defaultSize === DefaultEditorSize.LARGE) {
return 'collapsible-sidebar--large';
}
};
$scope.$watch(function () {
return $scope.vis.getCurrentState(false);
}, function (newState) {

View file

@ -4,12 +4,13 @@
ng-submit="visualizeEditor.$invalid ? stageEditableVis(false) : stageEditableVis()"
name="visualizeEditor"
novalidate
ng-keydown="submitEditorWithKeyboard($event)"
><!-- see http://goo.gl/9kgz5w -->
<div
css-truncate
aria-label="{{:: 'Index pattern: ' + vis.indexPattern.title}}"
ng-if="vis.type.requiresSearch"
ng-if="vis.type.requiresSearch && vis.type.options.showIndexSelection"
class="index-pattern"
tabindex="0"
id="sidebarIndexPatternTitle"
@ -44,6 +45,7 @@
aria-selected="{{sidebar.section === tab.name}}"
ng-repeat="tab in vis.type.editorConfig.optionTabs"
ng-class="{active: sidebar.section == tab.name}"
ng-if="vis.type.editorConfig.optionTabs.length > 1 || sidebar.showData"
>
<a
class="vis-editor-subnav-link"
@ -75,16 +77,39 @@
</div>
</li>
<li
tooltip="Auto apply changes"
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
ng-if="vis.type.editorConfig.enableAutoApply"
>
<button
data-test-subj="visualizeEditorAutoButton"
class="kuiButton kuiButton--basic navbar-btn-link"
aria-label="Auto update the visualization on every change"
ng-click="toggleAutoApply()"
ng-class="{
'kuiButton--primary': autoApplyEnabled,
'kuiButton--basic': !autoApplyEnabled
}"
>
<span aria-hidden="true" class="kuiIcon fa-repeat"></span>
<span ng-show="autoApplyEnabled">Auto Apply</span>
</button>
</li>
<li
tooltip="Apply changes"
tooltip-placement="bottom"
tooltip-popup-delay="400" tooltip-append-to-body="1"
ng-hide="autoApplyEnabled"
>
<button
data-test-subj="visualizeEditorRenderButton"
class="kuiButton kuiButton--primary navbar-btn-link"
type="submit"
ng-disabled="!vis.dirty || visualizeEditor.errorCount() > 0"
ng-disabled="!vis.dirty || visualizeEditor.errorCount() > 0 || autoApplyEnabled"
aria-label="Update the visualization with your changes"
>
<span aria-hidden="true" class="kuiIcon fa-play"></span>
@ -96,6 +121,7 @@
tooltip-placement="bottom"
tooltip-popup-delay="400"
tooltip-append-to-body="1"
ng-hide="autoApplyEnabled"
>
<button
class="kuiButton kuiButton--basic navbar-btn-link"

View file

@ -0,0 +1,45 @@
import $ from 'jquery';
import { uiModules } from 'ui/modules';
import { keyCodes } from '@elastic/eui';
uiModules
.get('kibana')
.directive('visEditorResizer', function () {
return {
restrict: 'E',
link: function ($scope, $el) {
const $left = $el.parent();
$el.on('mousedown', function (event) {
$el.addClass('active');
const startWidth = $left.width();
const startX = event.pageX;
function onMove(event) {
const newWidth = startWidth + event.pageX - startX;
$left.width(newWidth);
}
$(document.body)
.on('mousemove', onMove)
.one('mouseup', () => {
$el.removeClass('active');
$(document.body).off('mousemove', onMove);
$scope.$broadcast('render');
});
});
$el.on('keydown', event => {
const { keyCode } = event;
if (keyCode === keyCodes.LEFT || keyCode === keyCodes.RIGHT) {
event.preventDefault();
const startWidth = $left.width();
const newWidth = startWidth + (keyCode === keyCodes.LEFT ? -15 : 15);
$left.width(newWidth);
$scope.$broadcast('render');
}
});
}
};
});

View file

@ -44,8 +44,8 @@ export default function ({ getService, getPageObjects }) {
});
});
it.skip('should show Split Gauges', function () {
const expectedTexts = [ 'win 8', 'win xp', 'win 7', 'ios', 'osx' ];
it('should show Split Gauges', function () {
const expectedTexts = [ 'win 8', 'win xp', 'win 7', 'ios' ];
return PageObjects.visualize.clickMetricEditor()
.then(function clickBucket() {
log.debug('Bucket = Split Group');
@ -59,6 +59,10 @@ export default function ({ getService, getPageObjects }) {
log.debug('Field = machine.os.raw');
return PageObjects.visualize.selectField('machine.os.raw');
})
.then(function setSize() {
log.debug('Size = 4');
return PageObjects.visualize.setSize('4');
})
.then(function clickGo() {
return PageObjects.visualize.clickGo();
})
@ -72,8 +76,8 @@ export default function ({ getService, getPageObjects }) {
});
});
it.skip('should show correct values for fields with fieldFormatters', async function () {
const expectedTexts = [ '2,904\nwin 8: Count', '5.528KB' ];
it('should show correct values for fields with fieldFormatters', async function () {
const expectedTexts = [ '2,904\nwin 8: Count', '0B\nwin 8: Min bytes' ];
await PageObjects.visualize.clickMetricEditor();
@ -83,17 +87,18 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.visualize.setSize('1');
await PageObjects.visualize.clickAddMetric();
await PageObjects.visualize.clickBucket('Metric');
await PageObjects.visualize.selectAggregation('Average', 'metrics');
await PageObjects.visualize.selectAggregation('Min', 'metrics');
await PageObjects.visualize.selectField('bytes', 'metrics');
await PageObjects.visualize.clickGo();
return retry.try(function tryingForTime() {
return PageObjects.visualize.getGaugeValue()
.then(function (metricValue) {
.then(async function (metricValue) {
expect(expectedTexts).to.eql(metricValue);
});
});
});
});
});
}

View file

@ -1,7 +1,8 @@
import expect from 'expect.js';
export default function ({ getPageObjects }) {
export default function ({ getPageObjects, getService }) {
const PageObjects = getPageObjects(['common', 'visualize', 'header']);
const find = getService('find');
const markdown = `
# Heading 1
@ -14,7 +15,6 @@ export default function ({ getPageObjects }) {
await PageObjects.visualize.clickMarkdownWidget();
await PageObjects.visualize.setMarkdownTxt(markdown);
await PageObjects.visualize.clickGo();
await PageObjects.header.waitUntilLoadingHasFinished();
});
describe('markdown vis', async () => {
@ -34,6 +34,23 @@ export default function ({ getPageObjects }) {
const actual = await PageObjects.visualize.getMarkdownText();
expect(actual).to.equal(expected);
});
it('should auto apply changes if auto mode is turned on', async function () {
const markdown2 = '## Heading 2';
await PageObjects.visualize.toggleAutoMode();
await PageObjects.visualize.setMarkdownTxt(markdown2);
await PageObjects.header.waitUntilLoadingHasFinished();
const h1Txt = await PageObjects.visualize.getMarkdownBodyDescendentText('h2');
expect(h1Txt).to.equal('Heading 2');
});
it('should resize the editor', async function () {
const editorSidebar = await find.byCssSelector('.vis-editor-sidebar');
const initialSize = await editorSidebar.getSize();
await PageObjects.visualize.sizeUpEditor();
const afterSize = await editorSidebar.getSize();
expect(afterSize.width).to.be.greaterThan(initialSize.width);
});
});
});
}

View file

@ -1,4 +1,5 @@
import { VisualizeConstants } from '../../../src/core_plugins/kibana/public/visualize/visualize_constants';
import Keys from 'leadfoot/keys';
export function VisualizePageProvider({ getService, getPageObjects }) {
const remote = getService('remote');
@ -389,6 +390,15 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
}
async toggleAutoMode() {
await testSubjects.click('visualizeEditorAutoButton');
}
async sizeUpEditor() {
await testSubjects.click('visualizeEditorResizer');
await remote.pressKeys(Keys.ARROW_RIGHT);
}
async clickOptions() {
await find.clickByPartialLinkText('Options');
}