Skip to content

Commit

Permalink
Add saved queries to maps (#44442)
Browse files Browse the repository at this point in the history
* initial attempt at adding saved-queries to maps

* Adds savedQuery methods to map_controller

* Adds saveQuery to Maps ui

* Fixes watcher on state

* Fixes adding filters, still debuggin why the timefilter automatically changes to last 15 min on saving a query with a time filter. The time filter saves correctly in the saved query

* Gets time filter working with saved queries

* Adds saved query management component functionality tests to maps for all privileges

* Adds a saved query to the mapping and data for maps security functional tests

* Updates test saved query doc

* Adds functional tests for saved queries as a maps read-only user

* Adds 'skip' back to maps security functional tests

* uses onRefreshChange in map_controller

* Removes redundant trigger of onQuerySubmit call in the search bar

* deletes redundant call to updateStateFromSavedQuery in state.savedQuery watcher

* Refactors savedQuery watchers in map controller
  • Loading branch information
TinaHeiligers authored Sep 9, 2019
1 parent 41d183d commit 2541850
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,6 @@ class SearchBarUI extends Component<SearchBarProps, State> {
if (this.props.onSaved) {
this.props.onSaved(response);
}

if (this.props.onQuerySubmit) {
this.props.onQuerySubmit({
query: this.state.query,
dateRange: {
from: this.state.dateRangeFrom,
to: this.state.dateRangeTo,
},
});
}
} catch (error) {
toastNotifications.addDanger(`An error occured while saving your query: ${error.message}`);
throw error;
Expand Down
6 changes: 3 additions & 3 deletions x-pack/legacy/plugins/maps/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ export function maps(kibana) {
privileges: {
all: {
savedObject: {
all: ['map'],
all: ['map', 'query'],
read: ['index-pattern']
},
ui: ['save', 'show'],
ui: ['save', 'show', 'saveQuery'],
},
read: {
savedObject: {
all: [],
read: ['map', 'index-pattern']
read: ['map', 'index-pattern', 'query']
},
ui: ['show'],
},
Expand Down
5 changes: 5 additions & 0 deletions x-pack/legacy/plugins/maps/public/angular/map.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
show-search-bar="chrome.getVisible()"
show-filter-bar="chrome.getVisible()"
show-date-picker="showDatePicker"
show-save-query="showSaveQuery"
query="query"
saved-query="savedQuery"
on-query-submit="updateQueryAndDispatch"
filters="filters"
on-filters-updated="updateFiltersAndDispatch"
Expand All @@ -18,6 +20,9 @@
is-refresh-paused="refreshConfig.isPaused"
refresh-interval="refreshConfig.interval"
on-refresh-change="onRefreshChange"
on-saved="onQuerySaved"
on-saved-query-updated="onSavedQueryUpdated"
on-clear-saved-query="onClearSavedQuery"
>
</kbn-top-nav>
</div>
Expand Down
72 changes: 72 additions & 0 deletions x-pack/legacy/plugins/maps/public/angular/map_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import {
import { FilterStateStore } from '@kbn/es-query';
import { setup as data } from '../../../../../../src/legacy/core_plugins/data/public/legacy';

const { savedQueryService } = data.search.services;

const REACT_ANCHOR_DOM_ELEMENT_ID = 'react-maps-root';

const app = uiModules.get(MAP_APP_PATH, []);
Expand Down Expand Up @@ -124,6 +126,76 @@ app.controller('GisMapController', ($scope, $route, kbnUrl, localStorage, AppSta
globalState: globalState,
});

/* Saved Queries */
$scope.showSaveQuery = capabilities.get().maps.saveQuery;

$scope.$watch(() => capabilities.get().maps.saveQuery, (newCapability) => {
$scope.showSaveQuery = newCapability;
});

$scope.onQuerySaved = savedQuery => {
$scope.savedQuery = savedQuery;
};

$scope.onSavedQueryUpdated = savedQuery => {
$scope.savedQuery = { ...savedQuery };
};

$scope.onClearSavedQuery = () => {
delete $scope.savedQuery;
delete $state.savedQuery;
onQueryChange({
filters: [],
query: {
query: '',
language: localStorage.get('kibana.userQueryLanguage')
},
});
};

function updateStateFromSavedQuery(savedQuery) {
if (savedQuery.attributes.timefilter) {
if (savedQuery.attributes.timefilter.refreshInterval) {
$scope.onRefreshChange({
isPaused: savedQuery.attributes.timefilter.refreshInterval.pause,
refreshInterval: savedQuery.attributes.timefilter.refreshInterval.value
});
}
onQueryChange({
filters: savedQuery.attributes.filters || [],
query: savedQuery.attributes.query,
time: savedQuery.attributes.timefilter
});
} else {
onQueryChange({
filters: savedQuery.attributes.filters || [],
query: savedQuery.attributes.query,
});
}
}

$scope.$watch('savedQuery', (newSavedQuery) => {
if (!newSavedQuery) return;

$state.savedQuery = newSavedQuery.id;
updateStateFromSavedQuery(newSavedQuery);
});

$scope.$watch(() => $state.savedQuery, newSavedQueryId => {
if (!newSavedQueryId) {
$scope.savedQuery = undefined;
return;
}
if ($scope.savedQuery && newSavedQueryId !== $scope.savedQuery.id) {
savedQueryService.getSavedQuery(newSavedQueryId).then((savedQuery) => {
$scope.$evalAsync(() => {
$scope.savedQuery = savedQuery;
updateStateFromSavedQuery(savedQuery);
});
});
}
});
/* End of Saved Queries */
async function onQueryChange({ filters, query, time }) {
if (filters) {
await data.filter.filterManager.setFilters(filters); // Maps and merges filters
Expand Down
58 changes: 58 additions & 0 deletions x-pack/test/functional/apps/maps/feature_controls/maps_security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
const appsMenu = getService('appsMenu');
const testSubjects = getService('testSubjects');
const globalNav = getService('globalNav');
const queryBar = getService('queryBar');
const savedQueryManagementComponent = getService('savedQueryManagementComponent');

// FLAKY: https://github.com/elastic/kibana/issues/38414
describe.skip('security feature controls', () => {
Expand Down Expand Up @@ -82,6 +84,37 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
it(`doesn't show read-only badge`, async () => {
await globalNav.badgeMissingOrFail();
});

it('allows saving via the saved query management component popover with no query loaded', async () => {
await PageObjects.maps.openNewMap();
await queryBar.setQuery('response:200');
await savedQueryManagementComponent.saveNewQuery('foo', 'bar', true, false);
await savedQueryManagementComponent.savedQueryExistOrFail('foo');
});

it('allows saving a currently loaded saved query as a new query via the saved query management component ', async () => {
await savedQueryManagementComponent.saveCurrentlyLoadedAsNewQuery(
'foo2',
'bar2',
true,
false
);
await savedQueryManagementComponent.savedQueryExistOrFail('foo2');
});

it('allow saving changes to a currently loaded query via the saved query management component', async () => {
await queryBar.setQuery('response:404');
await savedQueryManagementComponent.updateCurrentlyLoadedQuery('bar2', false, false);
await savedQueryManagementComponent.clearCurrentlyLoadedQuery();
await savedQueryManagementComponent.loadSavedQuery('foo2');
const queryString = await queryBar.getQueryString();
expect(queryString).to.eql('response:404');
});

it('allows deleting saved queries in the saved query management component ', async () => {
await savedQueryManagementComponent.deleteSavedQuery('foo2');
await savedQueryManagementComponent.savedQueryMissingOrFail('foo2');
});
});

describe('global maps read-only privileges', () => {
Expand Down Expand Up @@ -153,6 +186,31 @@ export default function({ getPageObjects, getService }: FtrProviderContext) {
it(`can't add layer`, async () => {
await PageObjects.maps.expectMissingAddLayerButton();
});

it('allows loading a saved query via the saved query management component', async () => {
await savedQueryManagementComponent.loadSavedQuery('OKJpgs');
const queryString = await queryBar.getQueryString();
expect(queryString).to.eql('response:200');
});

it('does not allow saving via the saved query management component popover with no query loaded', async () => {
await savedQueryManagementComponent.saveNewQueryMissingOrFail();
});

it('does not allow saving changes to saved query from the saved query management component', async () => {
await savedQueryManagementComponent.loadSavedQuery('OKJpgs');
await queryBar.setQuery('response:404');
await savedQueryManagementComponent.updateCurrentlyLoadedQueryMissingOrFail();
});

it('does not allow deleting a saved query from the saved query management component', async () => {
await savedQueryManagementComponent.deleteSavedQueryMissingOrFail('OKJpgs');
});

it('allows clearing the currently loaded saved query', async () => {
await savedQueryManagementComponent.loadSavedQuery('OKJpgs');
await savedQueryManagementComponent.clearCurrentlyLoadedQuery();
});
});
});

Expand Down
21 changes: 21 additions & 0 deletions x-pack/test/functional/es_archives/maps/kibana/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,3 +762,24 @@
}
}
}

{
"type": "doc",
"value": {
"index": ".kibana",
"id": "query:okjpgs",
"source": {
"query": {
"title": "OKJpgs",
"description": "Ok responses for jpg files",
"query": {
"query": "response:200",
"language": "kuery"
},
"filters": [{"meta":{"index":"b15b1d40-a8bb-11e9-98cf-2bb06ef63e0b","alias":null,"negate":false,"type":"phrase","key":"extension.raw","value":"jpg","params":{"query":"jpg"},"disabled":false},"query":{"match":{"extension.raw":{"query":"jpg","type":"phrase"}}},"$state":{"store":"appState"}}]
},
"type": "query",
"updated_at": "2019-07-17T17:54:26.378Z"
}
}
}
29 changes: 29 additions & 0 deletions x-pack/test/functional/es_archives/maps/kibana/mappings.json
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,35 @@
"type": "text"
}
}
},
"query": {
"properties": {
"title": {
"type": "text"
},
"description": {
"type": "text"
},
"query": {
"properties": {
"language": {
"type": "keyword"
},
"query": {
"type": "keyword",
"index": false
}
}
},
"filters": {
"type": "object",
"enabled": false
},
"timefilter": {
"type": "object",
"enabled": false
}
}
}
}
},
Expand Down

0 comments on commit 2541850

Please sign in to comment.