mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[5.x] Refactor loading saved objects (Manual Backport) (#9556)
* [5.x] Refactor loading saved objects (Manual Backport) * Fix mistaken line deleted * Merge of #9562 to avoid delete bug
This commit is contained in:
parent
dfd16c6868
commit
e004a604b2
6 changed files with 145 additions and 275 deletions
|
@ -3,6 +3,7 @@ import Scanner from 'ui/utils/scanner';
|
|||
import 'plugins/kibana/dashboard/services/_saved_dashboard';
|
||||
import uiModules from 'ui/modules';
|
||||
const module = uiModules.get('app/dashboard');
|
||||
import { SavedObjectLoader } from 'ui/courier/saved_object/saved_object_loader';
|
||||
|
||||
// bring in the factory
|
||||
|
||||
|
@ -15,80 +16,6 @@ require('plugins/kibana/management/saved_object_registry').register({
|
|||
});
|
||||
|
||||
// This is the only thing that gets injected into controllers
|
||||
module.service('savedDashboards', function (Promise, SavedDashboard, kbnIndex, es, kbnUrl) {
|
||||
const scanner = new Scanner(es, {
|
||||
index: kbnIndex,
|
||||
type: 'dashboard'
|
||||
});
|
||||
|
||||
this.type = SavedDashboard.type;
|
||||
this.Class = SavedDashboard;
|
||||
|
||||
|
||||
this.loaderProperties = {
|
||||
name: 'dashboards',
|
||||
noun: 'Dashboard',
|
||||
nouns: 'dashboards'
|
||||
};
|
||||
|
||||
// Returns a single dashboard by ID, should be the name of the dashboard
|
||||
this.get = function (id) {
|
||||
// Returns a promise that contains a dashboard which is a subclass of docSource
|
||||
return (new SavedDashboard(id)).init();
|
||||
};
|
||||
|
||||
this.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/dashboard/{{id}}', {id: id});
|
||||
};
|
||||
|
||||
this.delete = function (ids) {
|
||||
ids = !_.isArray(ids) ? [ids] : ids;
|
||||
return Promise.map(ids, function (id) {
|
||||
return (new SavedDashboard(id)).delete();
|
||||
});
|
||||
};
|
||||
|
||||
this.scanAll = function (queryString, pageSize = 1000) {
|
||||
return scanner.scanAndMap(queryString, {
|
||||
pageSize,
|
||||
docCount: Infinity
|
||||
}, (hit) => this.mapHits(hit));
|
||||
};
|
||||
|
||||
this.mapHits = function (hit) {
|
||||
const source = hit._source;
|
||||
source.id = hit._id;
|
||||
source.url = this.urlFor(hit._id);
|
||||
return source;
|
||||
};
|
||||
|
||||
this.find = function (searchString, size = 100) {
|
||||
let body;
|
||||
if (searchString) {
|
||||
body = {
|
||||
query: {
|
||||
simple_query_string: {
|
||||
query: searchString + '*',
|
||||
fields: ['title^3', 'description'],
|
||||
default_operator: 'AND'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
body = { query: {match_all: {}}};
|
||||
}
|
||||
|
||||
return es.search({
|
||||
index: kbnIndex,
|
||||
type: 'dashboard',
|
||||
body: body,
|
||||
size: size
|
||||
})
|
||||
.then((resp) => {
|
||||
return {
|
||||
total: resp.hits.total,
|
||||
hits: resp.hits.hits.map((hit) => this.mapHits(hit))
|
||||
};
|
||||
});
|
||||
};
|
||||
module.service('savedDashboards', function (SavedDashboard, kbnIndex, es, kbnUrl) {
|
||||
return new SavedObjectLoader(SavedDashboard, kbnIndex, es, kbnUrl);
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import Scanner from 'ui/utils/scanner';
|
|||
import 'plugins/kibana/discover/saved_searches/_saved_search';
|
||||
import 'ui/notify';
|
||||
import uiModules from 'ui/modules';
|
||||
|
||||
import { SavedObjectLoader } from 'ui/courier/saved_object/saved_object_loader';
|
||||
|
||||
const module = uiModules.get('discover/saved_searches', [
|
||||
'kibana/notify'
|
||||
|
@ -17,82 +17,14 @@ require('plugins/kibana/management/saved_object_registry').register({
|
|||
});
|
||||
|
||||
module.service('savedSearches', function (Promise, config, kbnIndex, es, createNotifier, SavedSearch, kbnUrl) {
|
||||
const scanner = new Scanner(es, {
|
||||
index: kbnIndex,
|
||||
type: 'search'
|
||||
});
|
||||
|
||||
const notify = createNotifier({
|
||||
location: 'Saved Searches'
|
||||
});
|
||||
|
||||
this.type = SavedSearch.type;
|
||||
this.Class = SavedSearch;
|
||||
|
||||
this.loaderProperties = {
|
||||
const savedSearchLoader = new SavedObjectLoader(SavedSearch, kbnIndex, es, kbnUrl);
|
||||
savedSearchLoader.loaderProperties = {
|
||||
name: 'searches',
|
||||
noun: 'Saved Search',
|
||||
nouns: 'saved searches'
|
||||
};
|
||||
|
||||
|
||||
this.scanAll = function (queryString, pageSize = 1000) {
|
||||
return scanner.scanAndMap(queryString, {
|
||||
pageSize,
|
||||
docCount: Infinity
|
||||
}, (hit) => this.mapHits(hit));
|
||||
};
|
||||
|
||||
|
||||
this.get = function (id) {
|
||||
return (new SavedSearch(id)).init();
|
||||
};
|
||||
|
||||
this.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/discover/{{id}}', {id: id});
|
||||
};
|
||||
|
||||
this.delete = function (ids) {
|
||||
ids = !_.isArray(ids) ? [ids] : ids;
|
||||
return Promise.map(ids, function (id) {
|
||||
return (new SavedSearch(id)).delete();
|
||||
});
|
||||
};
|
||||
|
||||
this.mapHits = function (hit) {
|
||||
const source = hit._source;
|
||||
source.id = hit._id;
|
||||
source.url = this.urlFor(hit._id);
|
||||
return source;
|
||||
};
|
||||
|
||||
this.find = function (searchString, size = 100) {
|
||||
let body;
|
||||
if (searchString) {
|
||||
body = {
|
||||
query: {
|
||||
simple_query_string: {
|
||||
query: searchString + '*',
|
||||
fields: ['title^3', 'description'],
|
||||
default_operator: 'AND'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
body = { query: {match_all: {}}};
|
||||
}
|
||||
|
||||
return es.search({
|
||||
index: kbnIndex,
|
||||
type: 'search',
|
||||
body: body,
|
||||
size: size
|
||||
})
|
||||
.then((resp) => {
|
||||
return {
|
||||
total: resp.hits.total,
|
||||
hits: resp.hits.hits.map((hit) => this.mapHits(hit))
|
||||
};
|
||||
});
|
||||
savedSearchLoader.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/discover/{{id}}', { id: id });
|
||||
};
|
||||
return savedSearchLoader;
|
||||
});
|
||||
|
|
|
@ -3,6 +3,8 @@ import Scanner from 'ui/utils/scanner';
|
|||
import 'plugins/kibana/visualize/saved_visualizations/_saved_vis';
|
||||
import RegistryVisTypesProvider from 'ui/registry/vis_types';
|
||||
import uiModules from 'ui/modules';
|
||||
import { SavedObjectLoader } from 'ui/courier/saved_object/saved_object_loader';
|
||||
|
||||
const app = uiModules.get('app/visualize');
|
||||
|
||||
|
||||
|
@ -15,48 +17,12 @@ require('plugins/kibana/management/saved_object_registry').register({
|
|||
|
||||
app.service('savedVisualizations', function (Promise, es, kbnIndex, SavedVis, Private, Notifier, kbnUrl) {
|
||||
const visTypes = Private(RegistryVisTypesProvider);
|
||||
|
||||
const scanner = new Scanner(es, {
|
||||
index: kbnIndex,
|
||||
type: 'visualization'
|
||||
});
|
||||
|
||||
const notify = new Notifier({
|
||||
location: 'Saved Visualization Service'
|
||||
});
|
||||
|
||||
this.type = SavedVis.type;
|
||||
this.Class = SavedVis;
|
||||
|
||||
this.loaderProperties = {
|
||||
name: 'visualizations',
|
||||
noun: 'Visualization',
|
||||
nouns: 'visualizations'
|
||||
};
|
||||
|
||||
this.get = function (id) {
|
||||
return (new SavedVis(id)).init();
|
||||
};
|
||||
|
||||
this.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/visualize/edit/{{id}}', {id: id});
|
||||
};
|
||||
|
||||
this.delete = function (ids) {
|
||||
ids = !_.isArray(ids) ? [ids] : ids;
|
||||
return Promise.map(ids, function (id) {
|
||||
return (new SavedVis(id)).delete();
|
||||
});
|
||||
};
|
||||
|
||||
this.scanAll = function (queryString, pageSize = 1000) {
|
||||
return scanner.scanAndMap(queryString, {
|
||||
pageSize,
|
||||
docCount: Infinity
|
||||
}, (hit) => this.mapHits(hit));
|
||||
};
|
||||
|
||||
this.mapHits = function (hit) {
|
||||
const saveVisualizationLoader = new SavedObjectLoader(SavedVis, kbnIndex, es, kbnUrl);
|
||||
saveVisualizationLoader.mapHits = function (hit) {
|
||||
const source = hit._source;
|
||||
source.id = hit._id;
|
||||
source.url = this.urlFor(hit._id);
|
||||
|
@ -70,7 +36,7 @@ app.service('savedVisualizations', function (Promise, es, kbnIndex, SavedVis, Pr
|
|||
if (!typeName || !visTypes.byName[typeName]) {
|
||||
if (!typeName) notify.error('Visualization type is missing. Please add a type to this visualization.', hit);
|
||||
else notify.error('Visualization type of "' + typeName + '" is invalid. Please change to a valid type.', hit);
|
||||
return kbnUrl.redirect('/management/kibana/objects/savedVisualizations/{{id}}', {id: source.id});
|
||||
return kbnUrl.redirect('/management/kibana/objects/savedVisualizations/{{id}}', { id: source.id });
|
||||
}
|
||||
|
||||
source.type = visTypes.byName[typeName];
|
||||
|
@ -78,34 +44,9 @@ app.service('savedVisualizations', function (Promise, es, kbnIndex, SavedVis, Pr
|
|||
return source;
|
||||
};
|
||||
|
||||
this.find = function (searchString, size = 100) {
|
||||
let body;
|
||||
if (searchString) {
|
||||
body = {
|
||||
query: {
|
||||
simple_query_string: {
|
||||
query: searchString + '*',
|
||||
fields: ['title^3', 'description'],
|
||||
default_operator: 'AND',
|
||||
analyze_wildcard: true
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
body = { query: {match_all: {}}};
|
||||
}
|
||||
|
||||
return es.search({
|
||||
index: kbnIndex,
|
||||
type: 'visualization',
|
||||
body: body,
|
||||
size: size
|
||||
})
|
||||
.then((resp) => {
|
||||
return {
|
||||
total: resp.hits.total,
|
||||
hits: resp.hits.hits.map((hit) => this.mapHits(hit))
|
||||
};
|
||||
});
|
||||
saveVisualizationLoader.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/visualize/edit/{{id}}', { id: id });
|
||||
};
|
||||
|
||||
return saveVisualizationLoader;
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { SavedObjectLoader } from 'ui/courier/saved_object/saved_object_loader';
|
||||
|
||||
define(function (require) {
|
||||
var module = require('ui/modules').get('app/sheet');
|
||||
var _ = require('lodash');
|
||||
|
@ -14,66 +16,15 @@ define(function (require) {
|
|||
|
||||
// This is the only thing that gets injected into controllers
|
||||
module.service('savedSheets', function (Promise, SavedSheet, kbnIndex, es, kbnUrl) {
|
||||
this.type = SavedSheet.type;
|
||||
this.Class = SavedSheet;
|
||||
|
||||
this.loaderProperties = {
|
||||
const savedSheetLoader = new SavedObjectLoader(SavedSheet, kbnIndex, es, kbnUrl);
|
||||
savedSheetLoader.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/{{id}}', { id: id });
|
||||
};
|
||||
savedSheetLoader.loaderProperties = {
|
||||
name: 'timelion-sheet',
|
||||
noun: 'Saved Sheets',
|
||||
nouns: 'saved sheets'
|
||||
};
|
||||
|
||||
// Returns a single sheet by ID, should be the name of the sheet
|
||||
this.get = function (id) {
|
||||
// Returns a promise that contains a sheet which is a subclass of docSource
|
||||
return (new SavedSheet(id)).init();
|
||||
};
|
||||
|
||||
this.urlFor = function (id) {
|
||||
return kbnUrl.eval('#/{{id}}', {id: id});
|
||||
};
|
||||
|
||||
this.delete = function (ids) {
|
||||
ids = !_.isArray(ids) ? [ids] : ids;
|
||||
return Promise.map(ids, function (id) {
|
||||
return (new SavedSheet(id)).delete();
|
||||
});
|
||||
};
|
||||
|
||||
this.find = function (searchString) {
|
||||
var self = this;
|
||||
var body;
|
||||
if (searchString) {
|
||||
body = {
|
||||
query: {
|
||||
simple_query_string: {
|
||||
query: searchString + '*',
|
||||
fields: ['title^3', 'description'],
|
||||
default_operator: 'AND'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
body = { query: {match_all: {}}};
|
||||
}
|
||||
|
||||
return es.search({
|
||||
index: kbnIndex,
|
||||
type: 'timelion-sheet',
|
||||
body: body,
|
||||
size: 1000
|
||||
})
|
||||
.then(function (resp) {
|
||||
return {
|
||||
total: resp.hits.total,
|
||||
hits: resp.hits.hits.map(function (hit) {
|
||||
var source = hit._source;
|
||||
source.id = hit._id;
|
||||
source.url = self.urlFor(hit._id);
|
||||
return source;
|
||||
})
|
||||
};
|
||||
});
|
||||
};
|
||||
return savedSheetLoader;
|
||||
});
|
||||
});
|
||||
|
|
108
src/ui/public/courier/saved_object/saved_object_loader.js
Normal file
108
src/ui/public/courier/saved_object/saved_object_loader.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
import _ from 'lodash';
|
||||
import Scanner from 'ui/utils/scanner';
|
||||
import { StringUtils } from 'ui/utils/string_utils';
|
||||
|
||||
export class SavedObjectLoader {
|
||||
constructor(SavedObjectClass, kbnIndex, es, kbnUrl) {
|
||||
this.type = SavedObjectClass.type;
|
||||
this.Class = SavedObjectClass;
|
||||
this.lowercaseType = this.type.toLowerCase();
|
||||
this.kbnIndex = kbnIndex;
|
||||
this.kbnUrl = kbnUrl;
|
||||
this.es = es;
|
||||
|
||||
this.scanner = new Scanner(es, {
|
||||
index: kbnIndex,
|
||||
type: this.lowercaseType
|
||||
});
|
||||
|
||||
this.loaderProperties = {
|
||||
name: `${ this.lowercaseType }s`,
|
||||
noun: StringUtils.upperFirst(this.type),
|
||||
nouns: `${ this.lowercaseType }s`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a saved object by id. Returns a promise that completes when the object finishes
|
||||
* initializing.
|
||||
* @param id
|
||||
* @returns {Promise<SavedObject>}
|
||||
*/
|
||||
get(id) {
|
||||
return (new this.Class(id)).init();
|
||||
}
|
||||
|
||||
urlFor(id) {
|
||||
return this.kbnUrl.eval(`#/${ this.lowercaseType }/{{id}}`, { id: id });
|
||||
}
|
||||
|
||||
delete(ids) {
|
||||
ids = !_.isArray(ids) ? [ids] : ids;
|
||||
|
||||
const deletions = ids.map(id => {
|
||||
const savedObject = new this.Class(id);
|
||||
return savedObject.delete();
|
||||
});
|
||||
|
||||
return Promise.all(deletions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates hit._source to contain an id and url field, and returns the updated
|
||||
* source object.
|
||||
* @param hit
|
||||
* @returns {hit._source} The modified hit._source object, with an id and url field.
|
||||
*/
|
||||
mapHits(hit) {
|
||||
const source = hit._source;
|
||||
source.id = hit._id;
|
||||
source.url = this.urlFor(hit._id);
|
||||
return source;
|
||||
}
|
||||
|
||||
scanAll(queryString, pageSize = 1000) {
|
||||
return this.scanner.scanAndMap(queryString, {
|
||||
pageSize,
|
||||
docCount: Infinity
|
||||
}, (hit) => this.mapHits(hit));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Rather than use a hardcoded limit, implement pagination. See
|
||||
* https://github.com/elastic/kibana/issues/8044 for reference.
|
||||
*
|
||||
* @param searchString
|
||||
* @param size
|
||||
* @returns {Promise}
|
||||
*/
|
||||
find(searchString, size = 100) {
|
||||
let body;
|
||||
if (searchString) {
|
||||
body = {
|
||||
query: {
|
||||
simple_query_string: {
|
||||
query: searchString + '*',
|
||||
fields: ['title^3', 'description'],
|
||||
default_operator: 'AND'
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
body = { query: { match_all: {} } };
|
||||
}
|
||||
|
||||
return this.es.search({
|
||||
index: this.kbnIndex,
|
||||
type: this.type.toLowerCase(),
|
||||
body,
|
||||
size
|
||||
})
|
||||
.then((resp) => {
|
||||
return {
|
||||
total: resp.hits.total,
|
||||
hits: resp.hits.hits.map((hit) => this.mapHits(hit))
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
11
src/ui/public/utils/string_utils.js
Normal file
11
src/ui/public/utils/string_utils.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
export class StringUtils {
|
||||
|
||||
/**
|
||||
* Returns a version of the string with the first letter capitalized.
|
||||
* @param str {string}
|
||||
* @returns {string}
|
||||
*/
|
||||
static upperFirst(str) {
|
||||
return str ? str.charAt(0).toUpperCase() + str.slice(1) : '';
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue