Allow users to disable polling in Console (#38949) (#39231)

* Add ability to turn autocomplete suggestions polling on and off.
  - Add button for manually refreshing the suggestions.
  - Change buttons to use the EUI classes.
This commit is contained in:
CJ Cenizal 2019-06-19 06:32:51 -07:00 committed by GitHub
parent 1d28e068e1
commit da706ab1df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 128 additions and 36 deletions

View file

@ -24,7 +24,7 @@ import history from '../history';
import mappings from '../mappings';
import init from '../app';
describe('app initialization', () => {
describe('console app initialization', () => {
const sandbox = sinon.createSandbox();
let inputMock;
@ -34,7 +34,7 @@ describe('app initialization', () => {
ajaxDoneStub = sinon.stub();
sandbox.stub($, 'ajax').returns({ done: ajaxDoneStub });
sandbox.stub(history, 'getSavedEditorState');
sandbox.stub(mappings, 'startPolling');
sandbox.stub(mappings, 'retrieveAutoCompleteInfo');
inputMock = {
update: sinon.stub(),

View file

@ -129,7 +129,8 @@ export default function init(input, output, sourceLocation = 'stored') {
input.moveCursorTo(pos.row + prefix.length, 0);
input.focus();
};
setupAutosave();
loadSavedState();
mappings.startPolling();
mappings.retrieveAutoCompleteInfo();
}

View file

@ -20,7 +20,8 @@
require('ui/directives/input_focus');
import template from './settings.html';
const mappings = require('../mappings');
import { getAutocomplete, getCurrentSettings, updateSettings, getPolling } from '../settings';
import mappings from '../mappings';
require('ui/modules')
.get('app/sense')
@ -30,22 +31,37 @@ require('ui/modules')
template,
controllerAs: 'settings',
controller: function ($scope, $element) {
const settings = require('../settings');
this.vals = getCurrentSettings();
this.vals = settings.getCurrentSettings();
this.apply = () => {
const prevSettings = settings.getAutocomplete();
this.vals = settings.updateSettings(this.vals);
// Find which, if any, autocomplete settings have changed
this.isPollingVisible = () => {
const selectedAutoCompleteOptions =
Object.keys(this.vals.autocomplete).filter(key => this.vals.autocomplete[key]);
return selectedAutoCompleteOptions.length > 0;
};
this.refresh = () => {
mappings.retrieveAutoCompleteInfo();
};
this.saveSettings = () => {
const prevSettings = getAutocomplete();
this.vals = updateSettings(this.vals);
// Find which, if any, autocomplete settings have changed.
const settingsDiff = Object.keys(prevSettings).filter(key => prevSettings[key] !== this.vals.autocomplete[key]);
if (settingsDiff.length > 0) {
// Retrieve autocomplete info if the user has changed one of the autocomplete settings or
// has turned on polling.
if (settingsDiff.length > 0 || getPolling()) {
const changedSettings = settingsDiff.reduce((changedSettingsAccum, setting) => {
changedSettingsAccum[setting] = this.vals.autocomplete[setting];
return changedSettingsAccum;
}, {});
// Update autocomplete info based on changes so new settings takes effect immediately.
mappings.retrieveAutoCompleteInfo(changedSettings);
}
$scope.kbnTopNav.close();
};
@ -53,7 +69,7 @@ require('ui/modules')
function onEnter(event) {
if (event.which === 13) {
self.apply();
self.saveSettings();
}
}

View file

@ -4,7 +4,7 @@
i18n-default-message="Settings"
></h2>
<form class="form" name="settingsForm" ng-submit="settingsForm.$valid && settings.apply()">
<form class="form" name="settingsForm" ng-submit="settingsForm.$valid && settings.saveSettings()">
<fieldset
class="kuiVerticalRhythm"
role="group"
@ -14,7 +14,7 @@
id="consoleFontSize"
class="kuiLocalDropdownHeader__label"
i18n-id="console.settingsPage.fontSizeLabel"
i18n-default-message="Font Size"
i18n-default-message="Font size"
></legend>
</div>
@ -103,21 +103,84 @@
</label>
</fieldset>
<fieldset
class="kuiVerticalRhythm"
role="group"
ng-show="settings.isPollingVisible()"
>
<div class="kuiLocalDropdownHeader">
<legend
class="kuiLocalDropdownHeader__label"
i18n-id="console.settingsPage.refreshingDataLabel"
i18n-default-message="Refreshing autocomplete suggestions"
></legend>
</div>
<p
class="kuiVerticalRhythmSmall"
id="consoleRefreshingData"
i18n-id="console.settingsPage.refreshingDataDescription"
i18n-default-message="Console refreshes autocomplete suggestions by querying Elasticsearch.
Automatic refreshes may be an issue if you have a large cluster or if you have network limitations."
></p>
<label class="kuiCheckBoxLabel kuiVerticalRhythmSmall">
<input
class="kuiCheckBox"
name="polling"
type="checkbox"
ng-model="settings.vals.polling"
aria-describedby="consoleRefreshingData"
>
<span
class="kuiCheckBoxLabel__text"
i18n-id="console.settingsPage.pollingLabelText"
i18n-default-message="Automatically refresh autocomplete suggestions"
></span>
</label>
<button
type="button"
ng-click="settings.refresh()"
class="euiButton euiButton--primary kuiVerticalRhythmSmall"
>
<span class="euiButton__content">
<span
class="euiButton__text"
i18n-id="console.settingsPage.refreshButtonLabel"
i18n-default-message="Refresh autocomplete suggestions"
></span>
</span>
</button>
</fieldset>
<div class="kuiVerticalRhythm">
<button
ng-click="kbnTopNav.close()"
class="kuiButton kuiButton--hollow"
i18n-id="console.settingsPage.cancelButtonLabel"
i18n-default-message="Cancel"
></button>
class="euiButton euiButton--primary"
>
<span class="euiButton__content">
<span
class="euiButton__text"
i18n-id="console.settingsPage.cancelButtonLabel"
i18n-default-message="Cancel"
></span>
</span>
</button>
<button
type="submit"
ng-disabled="settingsForm.$invalid"
class="kuiButton kuiButton--primary"
class="euiButton euiButton--primary euiButton--fill"
data-test-subj="settings-save-button"
i18n-id="console.settingsPage.saveButtonLabel"
i18n-default-message="Save"
></button>
>
<span class="euiButton__content">
<span
class="euiButton__text"
i18n-id="console.settingsPage.saveButtonLabel"
i18n-default-message="Save"
></span>
</span>
</button>
</div>
</form>

View file

@ -129,9 +129,11 @@ export function initializeInput($el, $actionsEl, $copyAsCurlEl, output, openDocu
((xhr.status >= 200 && xhr.status < 300) || xhr.status === 404);
if (isSuccess) {
if (xhr.status !== 404) {
if (xhr.status !== 404 && settings.getPolling()) {
// If the user has submitted a request against ES, something in the fields, indices, aliases,
// or templates may have changed, so we'll need to update this data.
// or templates may have changed, so we'll need to update this data. Assume that if
// the user disables polling they're trying to optimize performance or otherwise
// preserve resources, so they won't want this request sent either.
mappings.retrieveAutoCompleteInfo();
}

View file

@ -324,18 +324,17 @@ function retrieveAutoCompleteInfo(settingsToRetrieve = settings.getAutocomplete(
}
// Schedule next request.
pollTimeoutId = setTimeout(retrieveAutoCompleteInfo, POLL_INTERVAL);
pollTimeoutId = setTimeout(() => {
// This looks strange/inefficient, but it ensures correct behavior because we don't want to send
// a scheduled request if the user turns off polling.
if (settings.getPolling()) {
retrieveAutoCompleteInfo();
}
}, POLL_INTERVAL);
});
}
function startPolling() {
// Technically, we don't need this method and we could just expose retrieveAutoCompleteInfo.
// However, we'll want to allow the user to turn polling on and off eventually so we'll leave this
// here to support this eventual functionality.
retrieveAutoCompleteInfo();
}
export default _.assign(mappingObj, {
export default {
getFields,
getTemplates,
getIndices,
@ -344,6 +343,5 @@ export default _.assign(mappingObj, {
loadAliases,
expandAliases,
clear,
startPolling,
retrieveAutoCompleteInfo,
});
};

View file

@ -51,6 +51,16 @@ function setAutocomplete(settings) {
return true;
}
export function getPolling() {
return storage.get('console_polling', true);
}
function setPolling(polling) {
storage.set('console_polling', polling);
applyCurrentSettings();
return true;
}
export function applyCurrentSettings(editor) {
if (typeof editor === 'undefined') {
applyCurrentSettings(getInput());
@ -67,13 +77,15 @@ export function getCurrentSettings() {
autocomplete: getAutocomplete(),
wrapMode: getWrapMode(),
fontSize: parseFloat(getFontSize()),
polling: Boolean(getPolling()),
};
}
export function updateSettings({ fontSize, wrapMode, autocomplete }) {
export function updateSettings({ fontSize, wrapMode, autocomplete, polling }) {
setFontSize(fontSize);
setWrapMode(wrapMode);
setAutocomplete(autocomplete);
setPolling(polling);
getInput().focus();
return getCurrentSettings();
}