From c04d0f7b5f70911d0d30a76bcdfb455f3de1e561 Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Wed, 9 Sep 2020 12:40:38 +0100 Subject: [PATCH] Using custom save method on attribute service --- .../attribute_service.test.ts | 10 ++++ .../attribute_service/attribute_service.tsx | 15 ++++-- .../create_vis_embeddable_from_object.ts | 2 +- .../public/embeddable/visualize_embeddable.ts | 54 ++++++++++++------- .../visualize_embeddable_factory.tsx | 4 +- 5 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/plugins/dashboard/public/attribute_service/attribute_service.test.ts b/src/plugins/dashboard/public/attribute_service/attribute_service.test.ts index 06f380ca3862b6..91b86a4b0c8a3e 100644 --- a/src/plugins/dashboard/public/attribute_service/attribute_service.test.ts +++ b/src/plugins/dashboard/public/attribute_service/attribute_service.test.ts @@ -189,5 +189,15 @@ describe('attributeService', () => { }); expect(customSaveMethod).toHaveBeenCalledWith(defaultTestType, attributes, undefined); }); + + it('uses custom save method when passed through setOptions', async () => { + const customSaveMethod = jest.fn().mockReturnValue({ id: '678' }); + const attributeService = mockAttributeService(defaultTestType); + attributeService.setOptions({ customSaveMethod }); + expect(await attributeService.wrapAttributes(attributes, true)).toEqual({ + savedObjectId: '678', + }); + expect(customSaveMethod).toHaveBeenCalledWith(defaultTestType, attributes, undefined); + }); }); }); diff --git a/src/plugins/dashboard/public/attribute_service/attribute_service.tsx b/src/plugins/dashboard/public/attribute_service/attribute_service.tsx index 817f377719c7b1..e9a05485f82d1c 100644 --- a/src/plugins/dashboard/public/attribute_service/attribute_service.tsx +++ b/src/plugins/dashboard/public/attribute_service/attribute_service.tsx @@ -57,7 +57,7 @@ export interface AttributeServiceOptions { type: string, attributes: A, savedObjectId?: string - ) => Promise<{ id: string }>; + ) => Promise<{ id?: string } | { error: Error}>; customUnwrapMethod?: (savedObject: SimpleSavedObject) => A; } @@ -124,7 +124,10 @@ export class AttributeService< newAttributes, savedObjectId ); - return { ...originalInput, savedObjectId: savedItem.id } as RefType; + if ('id' in savedItem) { + return { ...originalInput, savedObjectId: savedItem.id } as RefType; + } + return { ...originalInput } as RefType; } if (savedObjectId) { @@ -176,7 +179,6 @@ export class AttributeService< getInputAsRefType = async ( input: ValType | RefType, saveOptions?: { showSaveModal: boolean; saveModalTitle?: string } | { title: string }, - customSaveMethod?: (props: OnSaveProps) => Promise ): Promise => { if (this.inputIsRefType(input)) { return input; @@ -209,11 +211,10 @@ export class AttributeService< return { error }; } }; - const onSaveMethod = customSaveMethod ? customSaveMethod : onSave; if (saveOptions && (saveOptions as { showSaveModal: boolean }).showSaveModal) { this.showSaveModal( reject()} title={get(saveOptions, 'saveModalTitle', input[ATTRIBUTE_SERVICE_KEY].title)} showCopyOnSave={false} @@ -225,4 +226,8 @@ export class AttributeService< } }); }; + + public setOptions = (options: AttributeServiceOptions) => { + this.options = options; + }; } diff --git a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts index b9fb36c18b1c18..01723bc4e0219a 100644 --- a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts +++ b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts @@ -42,12 +42,12 @@ import { SavedVisualizationsLoader } from '../saved_visualizations'; export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDeps) => async ( vis: Vis, input: Partial & { id: string }, + savedVisualizationsLoader?: SavedVisualizationsLoader, attributeService?: AttributeService< VisualizeSavedObjectAttributes, VisualizeByValueInput, VisualizeByReferenceInput >, - savedVisualizationsLoader?: SavedVisualizationsLoader, parent?: IContainer ): Promise => { const savedVisualizations = getSavedVisualizationsLoader(); diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index 723726fdfa9d40..0f4d28b57796a4 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -54,7 +54,6 @@ import { SavedObjectAttributes } from '../../../../core/types'; import { AttributeService } from '../../../dashboard/public'; import { SavedVisualizationsLoader } from '../saved_visualizations'; import { VisSavedObject } from '../types'; -import { OnSaveProps, SaveResult } from '../../../saved_objects/public'; const getKeys = (o: T): Array => Object.keys(o) as Array; @@ -83,7 +82,11 @@ export interface VisualizeOutput extends EmbeddableOutput { visTypeName: string; } -export type VisualizeSavedObjectAttributes = SavedObjectAttributes & { title: string }; +export type VisualizeSavedObjectAttributes = SavedObjectAttributes & { + title: string; + vis?: Vis; + savedVis?: VisSavedObject; +}; export type VisualizeByValueInput = { attributes: VisualizeSavedObjectAttributes } & VisualizeInput; export type VisualizeByReferenceInput = SavedObjectEmbeddableInput & VisualizeInput; @@ -426,33 +429,42 @@ export class VisualizeEmbeddable }; getInputAsRefType = async (): Promise => { + const savedVis: VisSavedObject = await this.savedVisualizationsLoader?.get({}); + if (!savedVis) { + throw new Error('No Saved Vis'); + } return new Promise((resolve, reject) => { - const onSave = async (props: OnSaveProps): Promise => { + const onSave = async ( + type: string, + attributes: VisualizeSavedObjectAttributes + ): Promise<{ id: string }> => { try { - const savedVis: VisSavedObject = await this.savedVisualizationsLoader?.get({}); + const { title, vis } = attributes; const saveOptions = { confirmOverwrite: false, returnToOrigin: true, }; - savedVis.title = props.newTitle; - savedVis.copyOnSave = props.newCopyOnSave || false; - savedVis.description = props.newDescription || ''; - savedVis.searchSourceFields = this.vis?.data.searchSource?.getSerializedFields(); - const serializedVis = this.vis.serialize(); - const { title, type, params, data } = serializedVis; + savedVis.title = title; + savedVis.copyOnSave = false; + savedVis.description = ''; + savedVis.searchSourceFields = vis?.data.searchSource?.getSerializedFields(); + const serializedVis = ((vis as unknown) as Vis).serialize(); + const { params, data } = serializedVis; savedVis.visState = { title, - type, + type: serializedVis.type, params, aggs: data.aggs, }; - savedVis.uiStateJSON = this.vis.uiState.toString(); + if (vis) { + savedVis.uiStateJSON = vis.uiState.toString(); + } const id = await savedVis.save(saveOptions); resolve({ savedObjectId: id, id: this.id }); return { id }; } catch (error) { reject(error); - return { error }; + return { id: '' }; } }; const saveModalTitle = this.getTitle() @@ -460,15 +472,21 @@ export class VisualizeEmbeddable : i18n.translate('visualize.embeddable.placeholderTitle', { defaultMessage: 'Placeholder Title', }); + // @ts-ignore + const attributes: VisualizeSavedObjectAttributes = { + savedVis, + vis: this.vis, + title: this.vis.title, + }; + this.attributeService.setOptions({ + customSaveMethod: onSave, + }); return this.attributeService.getInputAsRefType( { id: this.id, - attributes: { - title: this.vis.title, - }, + attributes, }, - { showSaveModal: true, saveModalTitle }, - onSave + { showSaveModal: true, saveModalTitle } ); }); }; diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index 8ac80b5c9e88ac..221fa5daafb113 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -149,8 +149,8 @@ export class VisualizeEmbeddableFactory return createVisEmbeddableFromObject(this.deps)( vis, input, - await this.getAttributeService(), savedVisualizations, + await this.getAttributeService(), parent ); } catch (e) { @@ -170,8 +170,8 @@ export class VisualizeEmbeddableFactory return createVisEmbeddableFromObject(this.deps)( vis, input, - await this.getAttributeService(), savedVisualizations, + await this.getAttributeService(), parent ); } else {