diff --git a/src/legacy/core_plugins/kibana/public/discover/helpers/build_services.ts b/src/legacy/core_plugins/kibana/public/discover/helpers/build_services.ts index 14ea4e99b0de46..27c7c00fb729c6 100644 --- a/src/legacy/core_plugins/kibana/public/discover/helpers/build_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/helpers/build_services.ts @@ -27,7 +27,7 @@ import { import * as docViewsRegistry from 'ui/registry/doc_views'; import { FilterManager, TimefilterContract, IndexPatternsContract } from 'src/plugins/data/public'; // @ts-ignore -import { createSavedSearchesService } from '../saved_searches/saved_searches'; +import { createSavedSearchesService } from '../saved_searches'; // @ts-ignore import { DiscoverStartPlugins } from '../plugin'; import { DataStart } from '../../../../data/public'; diff --git a/src/legacy/core_plugins/kibana/public/discover/index.ts b/src/legacy/core_plugins/kibana/public/discover/index.ts index 6ea658682c89da..e85408dc9bf6b9 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/index.ts @@ -36,3 +36,5 @@ export const pluginInstance = plugin({} as PluginInitializerContext); SavedObjectRegistryProvider.register((savedSearches: any) => { return savedSearches; }); + +export { createSavedSearchesService } from './saved_searches/saved_searches'; diff --git a/src/legacy/core_plugins/kibana/public/discover/saved_searches/index.ts b/src/legacy/core_plugins/kibana/public/discover/saved_searches/index.ts index b9601e2fd257ad..1dd99025b4b70e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/saved_searches/index.ts +++ b/src/legacy/core_plugins/kibana/public/discover/saved_searches/index.ts @@ -17,4 +17,5 @@ * under the License. */ -import './saved_searches'; +export * from './saved_searches'; +import './saved_searches_register'; diff --git a/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches.ts b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches.ts index 46fdd3a7baedc2..abd3d46820c185 100644 --- a/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches.ts +++ b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches.ts @@ -16,22 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { npStart } from 'ui/new_platform'; -// @ts-ignore -import { uiModules } from 'ui/modules'; import { SavedObjectLoader } from 'ui/saved_objects'; import { SavedObjectKibanaServices } from 'ui/saved_objects/types'; -// @ts-ignore -import { savedObjectManagementRegistry } from '../../management/saved_object_registry'; import { createSavedSearchClass } from './_saved_search'; -// Register this service with the saved object registry so it can be -// edited by the object editor. -savedObjectManagementRegistry.register({ - service: 'savedSearches', - title: 'searches', -}); - export function createSavedSearchesService(services: SavedObjectKibanaServices) { const SavedSearchClass = createSavedSearchClass(services); const savedSearchLoader = new SavedObjectLoader( @@ -50,14 +38,3 @@ export function createSavedSearchesService(services: SavedObjectKibanaServices) return savedSearchLoader; } -// this is needed for saved object management -const module = uiModules.get('discover/saved_searches'); -module.service('savedSearches', () => { - const services = { - savedObjectsClient: npStart.core.savedObjects.client, - indexPatterns: npStart.plugins.data.indexPatterns, - chrome: npStart.core.chrome, - overlays: npStart.core.overlays, - }; - return createSavedSearchesService(services); -}); diff --git a/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches_register.ts b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches_register.ts new file mode 100644 index 00000000000000..bdb1495a33925f --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/saved_searches/saved_searches_register.ts @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { npStart } from 'ui/new_platform'; +// @ts-ignore +import { uiModules } from 'ui/modules'; +// @ts-ignore +import { savedObjectManagementRegistry } from '../../management/saved_object_registry'; + +import { createSavedSearchesService } from './saved_searches'; + +// this is needed for saved object management +// Register this service with the saved object registry so it can be +// edited by the object editor. +savedObjectManagementRegistry.register({ + service: 'savedSearches', + title: 'searches', +}); +const module = uiModules.get('discover/saved_searches'); +module.service('savedSearches', () => { + const services = { + savedObjectsClient: npStart.core.savedObjects.client, + indexPatterns: npStart.plugins.data.indexPatterns, + chrome: npStart.core.chrome, + overlays: npStart.core.overlays, + }; + return createSavedSearchesService(services); +}); diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts index 8e414984a0c08d..45cc1dc5fb9ddd 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts @@ -29,7 +29,7 @@ import { getTableAggs } from 'ui/visualize/loader/pipeline_helpers/utilities'; import { AppState } from 'ui/state_management/app_state'; import { npStart } from 'ui/new_platform'; import { IExpressionLoaderParams } from 'src/plugins/expressions/public'; -import { SearchSourceContract } from '../../../../../ui/public/courier'; +import { SearchSourceContract } from 'ui/courier'; import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; import { IIndexPattern, @@ -47,6 +47,7 @@ import { APPLY_FILTER_TRIGGER, } from '../../../../../../plugins/embeddable/public'; import { dispatchRenderComplete } from '../../../../../../plugins/kibana_utils/public'; +import { SavedSearch } from '../../discover/types'; const getKeys = (o: T): Array => Object.keys(o) as Array; @@ -57,6 +58,10 @@ export interface VisSavedObject extends SavedObject { title: string; uiStateJSON?: string; destroy: () => void; + savedSearchRefName?: string; + savedSearchId?: string; + savedSearch?: SavedSearch; + visState: any; } export interface VisualizeEmbeddableConfiguration { diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js deleted file mode 100644 index fd643115e90840..00000000000000 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * @name SavedVis - * - * @extends SavedObject. - * - * NOTE: It's a type of SavedObject, but specific to visualizations. - */ - -import { Vis } from 'ui/vis'; -import { uiModules } from 'ui/modules'; -import { updateOldState } from '../../../../visualizations/public'; -import { VisualizeConstants } from '../visualize_constants'; -import { createLegacyClass } from 'ui/utils/legacy_class'; -import { SavedObjectProvider } from 'ui/saved_objects/saved_object'; -import { extractReferences, injectReferences } from './saved_visualization_references'; - -uiModules.get('app/visualize').factory('SavedVis', function(savedSearches, Private) { - const SavedObject = Private(SavedObjectProvider); - createLegacyClass(SavedVis).inherits(SavedObject); - function SavedVis(opts) { - const self = this; - opts = opts || {}; - if (typeof opts !== 'object') opts = { id: opts }; - - SavedVis.Super.call(self, { - type: SavedVis.type, - mapping: SavedVis.mapping, - searchSource: SavedVis.searchSource, - extractReferences: extractReferences, - injectReferences: injectReferences, - - id: opts.id, - indexPattern: opts.indexPattern, - defaults: { - title: '', - visState: (function() { - if (!opts.type) return null; - const def = {}; - def.type = opts.type; - return def; - })(), - uiStateJSON: '{}', - description: '', - savedSearchId: opts.savedSearchId, - version: 1, - }, - - afterESResp: this._afterEsResp, - }); - - this.showInRecentlyAccessed = true; - } - - SavedVis.type = 'visualization'; - - SavedVis.mapping = { - title: 'text', - visState: 'json', - uiStateJSON: 'text', - description: 'text', - savedSearchId: 'keyword', - version: 'integer', - }; - - // Order these fields to the top, the rest are alphabetical - SavedVis.fieldOrder = ['title', 'description']; - - SavedVis.searchSource = true; - - SavedVis.prototype.getFullPath = function() { - return `/app/kibana#${VisualizeConstants.EDIT_PATH}/${this.id}`; - }; - - SavedVis.prototype._afterEsResp = async function() { - const self = this; - - await self._getLinkedSavedSearch(); - self.searchSource.setField('size', 0); - return self.vis ? self._updateVis() : self._createVis(); - }; - - SavedVis.prototype._getLinkedSavedSearch = async function() { - const self = this; - const linkedSearch = !!self.savedSearchId; - const current = self.savedSearch; - - if (linkedSearch && current && current.id === self.savedSearchId) { - return; - } - - if (self.savedSearch) { - self.searchSource.setParent(self.savedSearch.searchSource.getParent()); - self.savedSearch.destroy(); - self.savedSearch = null; - } - - if (linkedSearch) { - self.savedSearch = await savedSearches.get(self.savedSearchId); - self.searchSource.setParent(self.savedSearch.searchSource); - } - }; - - SavedVis.prototype._createVis = function() { - const self = this; - - self.visState = updateOldState(self.visState); - - // visState doesn't yet exist when importing a visualization, so we can't - // assume that exists at this point. If it does exist, then we're not - // importing a visualization, so we want to sync the title. - if (self.visState) { - self.visState.title = self.title; - } - self.vis = new Vis(self.searchSource.getField('index'), self.visState); - - self.vis.savedSearchId = self.savedSearchId; - - return self.vis; - }; - - SavedVis.prototype._updateVis = function() { - const self = this; - - self.vis.indexPattern = self.searchSource.getField('index'); - self.visState.title = self.title; - self.vis.setState(self.visState); - self.vis.savedSearchId = self.savedSearchId; - }; - - return SavedVis; -}); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts new file mode 100644 index 00000000000000..3490e0ab127edc --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.ts @@ -0,0 +1,146 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @name SavedVis + * + * @extends SavedObject. + * + * NOTE: It's a type of SavedObject, but specific to visualizations. + */ +// @ts-ignore +import { Vis } from 'ui/vis'; +import { SavedObject, SavedObjectKibanaServices } from 'ui/saved_objects/types'; +import { createSavedObjectClass } from 'ui/saved_objects/saved_object'; +import { updateOldState } from '../../../../visualizations/public'; +import { VisualizeConstants } from '../visualize_constants'; +import { extractReferences, injectReferences } from './saved_visualization_references'; +import { IIndexPattern } from '../../../../../../plugins/data/public'; +import { VisSavedObject } from '../legacy_imports'; + +import { createSavedSearchesService } from '../../discover'; + +async function _afterEsResp(savedVis: VisSavedObject, services: any) { + await _getLinkedSavedSearch(savedVis, services); + savedVis.searchSource!.setField('size', 0); + savedVis.vis = savedVis.vis ? _updateVis(savedVis) : await _createVis(savedVis); + return savedVis; +} + +async function _getLinkedSavedSearch(savedVis: VisSavedObject, services: any) { + const linkedSearch = !!savedVis.savedSearchId; + const current = savedVis.savedSearch; + + if (linkedSearch && current && current.id === savedVis.savedSearchId) { + return; + } + + if (savedVis.savedSearch) { + savedVis.searchSource!.setParent(savedVis.savedSearch.searchSource.getParent()); + savedVis.savedSearch.destroy(); + delete savedVis.savedSearch; + } + const savedSearches = createSavedSearchesService(services); + + if (linkedSearch) { + savedVis.savedSearch = await savedSearches.get(savedVis.savedSearchId!); + savedVis.searchSource!.setParent(savedVis.savedSearch!.searchSource); + } +} + +async function _createVis(savedVis: VisSavedObject) { + savedVis.visState = updateOldState(savedVis.visState); + + // visState doesn't yet exist when importing a visualization, so we can't + // assume that exists at this point. If it does exist, then we're not + // importing a visualization, so we want to sync the title. + if (savedVis.visState) { + savedVis.visState.title = savedVis.title; + } + // the typescript compiler is wrong here, will be right when vis.js -> vis.ts + // @ts-ignore + savedVis.vis = new Vis(savedVis.searchSource!.getField('index'), savedVis.visState); + + savedVis.vis!.savedSearchId = savedVis.savedSearchId; + + return savedVis.vis; +} + +function _updateVis(savedVis: VisSavedObject) { + if (savedVis.vis && savedVis.searchSource) { + savedVis.vis.indexPattern = savedVis.searchSource.getField('index'); + savedVis.visState.title = savedVis.title; + savedVis.vis.setState(savedVis.visState); + savedVis.vis.savedSearchId = savedVis.savedSearchId; + } + return savedVis.vis; +} + +export function createSavedVisClass(services: SavedObjectKibanaServices) { + const SavedObjectClass = createSavedObjectClass(services); + + class SavedVis extends SavedObjectClass { + public static type: string = 'visualization'; + public static mapping: Record = { + title: 'text', + visState: 'json', + uiStateJSON: 'text', + description: 'text', + savedSearchId: 'keyword', + version: 'integer', + }; + // Order these fields to the top, the rest are alphabetical + public static fieldOrder = ['title', 'description']; + public static searchSource = true; + + constructor(opts: Record | string = {}) { + if (typeof opts !== 'object') { + opts = { id: opts }; + } + const visState = !opts.type ? null : { type: opts.type }; + // Gives our SavedWorkspace the properties of a SavedObject + super({ + type: SavedVis.type, + mapping: SavedVis.mapping, + searchSource: SavedVis.searchSource, + extractReferences, + injectReferences, + id: (opts.id as string) || '', + indexPattern: opts.indexPattern as IIndexPattern, + defaults: { + title: '', + visState, + uiStateJSON: '{}', + description: '', + savedSearchId: opts.savedSearchId, + version: 1, + }, + afterESResp: (savedObject: SavedObject) => { + return _afterEsResp(savedObject as VisSavedObject, services) as Promise; + }, + }); + this.showInRecentlyAccessed = true; + this.getFullPath = () => { + return `/app/kibana#${VisualizeConstants.EDIT_PATH}/${this.id}`; + }; + } + } + + return SavedVis; +} diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/index.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/index.js rename to src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/index.ts diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts similarity index 92% rename from src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js rename to src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts index cdc232b06cf51a..6549b317d16346 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.ts @@ -18,6 +18,7 @@ */ import { extractReferences, injectReferences } from './saved_visualization_references'; +import { VisSavedObject } from '../embeddable/visualize_embeddable'; describe('extractReferences', () => { test('extracts nothing if savedSearchId is empty', () => { @@ -26,6 +27,7 @@ describe('extractReferences', () => { attributes: { foo: true, }, + references: [], }; const updatedDoc = extractReferences(doc); expect(updatedDoc).toMatchInlineSnapshot(` @@ -45,6 +47,7 @@ Object { foo: true, savedSearchId: '123', }, + references: [], }; const updatedDoc = extractReferences(doc); expect(updatedDoc).toMatchInlineSnapshot(` @@ -83,6 +86,7 @@ Object { }, }), }, + references: [], }; const updatedDoc = extractReferences(doc); @@ -108,13 +112,13 @@ describe('injectReferences', () => { test('injects nothing when savedSearchRefName is null', () => { const context = { id: '1', - foo: true, - }; + title: 'test', + } as VisSavedObject; injectReferences(context, []); expect(context).toMatchInlineSnapshot(` Object { - "foo": true, "id": "1", + "title": "test", } `); }); @@ -122,7 +126,7 @@ Object { test('injects references into context', () => { const context = { id: '1', - foo: true, + title: 'test', savedSearchRefName: 'search_0', visState: { params: { @@ -137,7 +141,7 @@ Object { ], }, }, - }; + } as VisSavedObject; const references = [ { name: 'search_0', @@ -153,9 +157,9 @@ Object { injectReferences(context, references); expect(context).toMatchInlineSnapshot(` Object { - "foo": true, "id": "1", "savedSearchId": "123", + "title": "test", "visState": Object { "params": Object { "controls": Array [ @@ -176,9 +180,9 @@ Object { test(`fails when it can't find the saved search reference in the array`, () => { const context = { id: '1', - foo: true, savedSearchRefName: 'search_0', - }; + title: 'test', + } as VisSavedObject; expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( `"Could not find saved search reference \\"search_0\\""` ); @@ -187,6 +191,7 @@ Object { test(`fails when it can't find the index pattern reference in the array`, () => { const context = { id: '1', + title: 'test', visState: { params: { controls: [ @@ -197,7 +202,7 @@ Object { ], }, }, - }; + } as VisSavedObject; expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( `"Could not find index pattern reference \\"control_0_index_pattern\\""` ); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts similarity index 77% rename from src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.js rename to src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts index 7f451076e239c7..dd8c2e9d2b74fa 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.js +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.ts @@ -16,8 +16,16 @@ * specific language governing permissions and limitations * under the License. */ +import { SavedObjectAttributes, SavedObjectReference } from 'kibana/server'; +import { VisSavedObject } from '../embeddable/visualize_embeddable'; -export function extractReferences({ attributes, references = [] }) { +export function extractReferences({ + attributes, + references = [], +}: { + attributes: SavedObjectAttributes; + references: SavedObjectReference[]; +}) { const updatedAttributes = { ...attributes }; const updatedReferences = [...references]; @@ -26,7 +34,7 @@ export function extractReferences({ attributes, references = [] }) { updatedReferences.push({ name: 'search_0', type: 'search', - id: updatedAttributes.savedSearchId, + id: String(updatedAttributes.savedSearchId), }); delete updatedAttributes.savedSearchId; updatedAttributes.savedSearchRefName = 'search_0'; @@ -34,9 +42,9 @@ export function extractReferences({ attributes, references = [] }) { // Extract index patterns from controls if (updatedAttributes.visState) { - const visState = JSON.parse(updatedAttributes.visState); + const visState = JSON.parse(String(updatedAttributes.visState)); const controls = (visState.params && visState.params.controls) || []; - controls.forEach((control, i) => { + controls.forEach((control: Record, i: number) => { if (!control.indexPattern) { return; } @@ -57,7 +65,7 @@ export function extractReferences({ attributes, references = [] }) { }; } -export function injectReferences(savedObject, references) { +export function injectReferences(savedObject: VisSavedObject, references: SavedObjectReference[]) { if (savedObject.savedSearchRefName) { const savedSearchReference = references.find( reference => reference.name === savedObject.savedSearchRefName @@ -70,13 +78,11 @@ export function injectReferences(savedObject, references) { } if (savedObject.visState) { const controls = (savedObject.visState.params && savedObject.visState.params.controls) || []; - controls.forEach(control => { + controls.forEach((control: Record) => { if (!control.indexPatternRefName) { return; } - const reference = references.find( - reference => reference.name === control.indexPatternRefName - ); + const reference = references.find(ref => ref.name === control.indexPatternRefName); if (!reference) { throw new Error(`Could not find index pattern reference "${control.indexPatternRefName}"`); } diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts similarity index 71% rename from src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.js rename to src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts index c50cda56c7151c..803474b1f7b3f1 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.js +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_register.ts @@ -18,8 +18,17 @@ */ import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; +// @ts-ignore +import { savedObjectManagementRegistry } from '../../management/saved_object_registry'; import './saved_visualizations'; -SavedObjectRegistryProvider.register(savedVisualizations => { +SavedObjectRegistryProvider.register((savedVisualizations: any) => { return savedVisualizations; }); + +// Register this service with the saved object registry so it can be +// edited by the object editor. +savedObjectManagementRegistry.register({ + service: 'savedVisualizations', + title: 'visualizations', +}); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.js deleted file mode 100644 index 784f45436e3a3d..00000000000000 --- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import './_saved_vis'; -import { uiModules } from 'ui/modules'; -import { SavedObjectLoader, SavedObjectsClientProvider } from 'ui/saved_objects'; -import { savedObjectManagementRegistry } from '../../management/saved_object_registry'; -import { start as visualizations } from '../../../../visualizations/public/np_ready/public/legacy'; -import { createVisualizeEditUrl } from '../visualize_constants'; -import { findListItems } from './find_list_items'; -import { npStart } from '../../../../../ui/public/new_platform'; - -const app = uiModules.get('app/visualize'); - -// Register this service with the saved object registry so it can be -// edited by the object editor. -savedObjectManagementRegistry.register({ - service: 'savedVisualizations', - title: 'visualizations', -}); - -app.service('savedVisualizations', function(SavedVis, Private) { - const visTypes = visualizations.types; - const savedObjectClient = Private(SavedObjectsClientProvider); - const saveVisualizationLoader = new SavedObjectLoader( - SavedVis, - savedObjectClient, - npStart.core.chrome - ); - - saveVisualizationLoader.mapHitSource = function(source, id) { - source.id = id; - source.url = this.urlFor(id); - - let typeName = source.typeName; - if (source.visState) { - try { - typeName = JSON.parse(source.visState).type; - } catch (e) { - /* missing typename handled below */ - } // eslint-disable-line no-empty - } - - if (!typeName || !visTypes.get(typeName)) { - source.error = 'Unknown visualization type'; - return source; - } - - source.type = visTypes.get(typeName); - source.savedObjectType = 'visualization'; - source.icon = source.type.icon; - source.image = source.type.image; - source.typeTitle = source.type.title; - source.editUrl = `#${createVisualizeEditUrl(id)}`; - - return source; - }; - - saveVisualizationLoader.urlFor = function(id) { - return `#/visualize/edit/${encodeURIComponent(id)}`; - }; - - // This behaves similarly to find, except it returns visualizations that are - // defined as appExtensions and which may not conform to type: visualization - saveVisualizationLoader.findListItems = function(search = '', size = 100) { - return findListItems({ - search, - size, - mapSavedObjectApiHits: this.mapSavedObjectApiHits.bind(this), - savedObjectsClient: this.savedObjectsClient, - visTypes: visualizations.types.getAliases(), - }); - }; - - return saveVisualizationLoader; -}); diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts new file mode 100644 index 00000000000000..7425250bffe1ac --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualizations.ts @@ -0,0 +1,86 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { npStart } from 'ui/new_platform'; +// @ts-ignore +import { uiModules } from 'ui/modules'; +import { SavedObjectLoader } from 'ui/saved_objects'; + +import { start as visualizations } from '../../../../visualizations/public/np_ready/public/legacy'; +import { createVisualizeEditUrl } from '../visualize_constants'; +// @ts-ignore +import { findListItems } from './find_list_items'; +import { createSavedVisClass } from './_saved_vis'; +const app = uiModules.get('app/visualize'); + +app.service('savedVisualizations', function() { + const savedObjectsClient = npStart.core.savedObjects.client; + const services = { + savedObjectsClient, + indexPatterns: npStart.plugins.data.indexPatterns, + chrome: npStart.core.chrome, + overlays: npStart.core.overlays, + }; + class SavedObjectLoaderVisualize extends SavedObjectLoader { + mapHitSource = (source: Record, id: string) => { + const visTypes = visualizations.types; + source.id = id; + source.url = this.urlFor(id); + + let typeName = source.typeName; + if (source.visState) { + try { + typeName = JSON.parse(String(source.visState)).type; + } catch (e) { + /* missing typename handled below */ + } // eslint-disable-line no-empty + } + + if (!typeName || !visTypes.get(typeName)) { + source.error = 'Unknown visualization type'; + return source; + } + + source.type = visTypes.get(typeName); + source.savedObjectType = 'visualization'; + source.icon = source.type.icon; + source.image = source.type.image; + source.typeTitle = source.type.title; + source.editUrl = `#${createVisualizeEditUrl(id)}`; + + return source; + }; + urlFor(id: string) { + return `#/visualize/edit/${encodeURIComponent(id)}`; + } + // This behaves similarly to find, except it returns visualizations that are + // defined as appExtensions and which may not conform to type: visualization + findListItems(search: string = '', size: number = 100) { + return findListItems({ + search, + size, + mapSavedObjectApiHits: this.mapSavedObjectApiHits.bind(this), + savedObjectsClient, + visTypes: visualizations.types.getAliases(), + }); + } + } + const SavedVis = createSavedVisClass(services); + + return new SavedObjectLoaderVisualize(SavedVis, savedObjectsClient, npStart.core.chrome); +}); diff --git a/src/legacy/ui/public/saved_objects/helpers/apply_es_resp.ts b/src/legacy/ui/public/saved_objects/helpers/apply_es_resp.ts index 1d1707418efe6b..bec0a1d96ba92e 100644 --- a/src/legacy/ui/public/saved_objects/helpers/apply_es_resp.ts +++ b/src/legacy/ui/public/saved_objects/helpers/apply_es_resp.ts @@ -70,7 +70,7 @@ export async function applyESResp( injectReferences(savedObject, resp.references); } if (typeof config.afterESResp === 'function') { - await config.afterESResp.call(savedObject); + savedObject = await config.afterESResp(savedObject); } return savedObject; } diff --git a/src/legacy/ui/public/saved_objects/helpers/initialize_saved_object.ts b/src/legacy/ui/public/saved_objects/helpers/initialize_saved_object.ts index c5ea31e0784aad..a9d4b416add1ee 100644 --- a/src/legacy/ui/public/saved_objects/helpers/initialize_saved_object.ts +++ b/src/legacy/ui/public/saved_objects/helpers/initialize_saved_object.ts @@ -37,7 +37,7 @@ export async function intializeSavedObject( _.assign(savedObject, savedObject.defaults); await savedObject.hydrateIndexPattern!(); if (typeof config.afterESResp === 'function') { - await config.afterESResp.call(savedObject); + savedObject = await config.afterESResp(savedObject); } return savedObject; } diff --git a/src/legacy/ui/public/saved_objects/types.ts b/src/legacy/ui/public/saved_objects/types.ts index 7b587591fbe277..c4e6438424046f 100644 --- a/src/legacy/ui/public/saved_objects/types.ts +++ b/src/legacy/ui/public/saved_objects/types.ts @@ -16,11 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -import { ChromeStart, OverlayStart, SavedObjectsClientContract } from 'kibana/public'; +import { + ChromeStart, + OverlayStart, + SavedObjectsClientContract, + SavedObjectAttributes, + SavedObjectReference, +} from 'kibana/public'; import { SearchSource, SearchSourceContract } from 'ui/courier'; -import { SavedObjectAttributes, SavedObjectReference } from 'kibana/server'; -import { IndexPatternsContract } from '../../../../plugins/data/public'; -import { IndexPattern } from '../../../core_plugins/data/public'; +import { IIndexPattern, IndexPatternsContract } from '../../../../plugins/data/public'; export interface SavedObject { _serialize: () => { attributes: SavedObjectAttributes; references: SavedObjectReference[] }; @@ -34,7 +38,7 @@ export interface SavedObject { getDisplayName: () => string; getEsType: () => string; getFullPath: () => string; - hydrateIndexPattern?: (id?: string) => Promise; + hydrateIndexPattern?: (id?: string) => Promise; id?: string; init?: () => Promise; isSaving: boolean; @@ -66,7 +70,8 @@ export interface SavedObjectKibanaServices { } export interface SavedObjectConfig { - afterESResp?: () => any; + // is only used by visualize + afterESResp?: (savedObject: SavedObject) => Promise; clearSavedIndexPattern?: boolean; defaults?: any; extractReferences?: (opts: { @@ -78,7 +83,7 @@ export interface SavedObjectConfig { }; id?: string; init?: () => void; - indexPattern?: IndexPattern; + indexPattern?: IIndexPattern; injectReferences?: any; mapping?: any; migrationVersion?: Record;