-
Notifications
You must be signed in to change notification settings - Fork 915
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Tyler Ohlsen <[email protected]>
- Loading branch information
Showing
17 changed files
with
484 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
src/plugins/vis_augmenter/public/saved_augment_vis/_saved_augment_vis.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @name SavedAugmentVis | ||
* | ||
* @extends SavedObject. | ||
*/ | ||
import { get } from 'lodash'; | ||
import { | ||
createSavedObjectClass, | ||
SavedObject, | ||
SavedObjectOpenSearchDashboardsServices, | ||
} from '../../../saved_objects/public'; | ||
import { IIndexPattern } from '../../../data/public'; | ||
import { extractReferences, injectReferences } from './saved_augment_vis_references'; | ||
|
||
export function createSavedAugmentVisClass(services: SavedObjectOpenSearchDashboardsServices) { | ||
const SavedObjectClass = createSavedObjectClass(services); | ||
|
||
class SavedAugmentVis extends SavedObjectClass { | ||
public static type: string = 'augment-vis'; | ||
public static mapping: Record<string, string> = { | ||
description: 'text', | ||
pluginResourceId: 'text', | ||
savedObjectType: 'keyword', | ||
savedObjectId: 'keyword', | ||
visLayerExpressionFn: 'object', | ||
version: 'integer', | ||
}; | ||
|
||
constructor(opts: Record<string, unknown> | string = {}) { | ||
if (typeof opts !== 'object') { | ||
opts = { id: opts }; | ||
} | ||
super({ | ||
type: SavedAugmentVis.type, | ||
mapping: SavedAugmentVis.mapping, | ||
extractReferences, | ||
injectReferences, | ||
id: (opts.id as string) || '', | ||
indexPattern: opts.indexPattern as IIndexPattern, | ||
defaults: { | ||
description: get(opts, 'description', ''), | ||
pluginResourceId: get(opts, 'pluginResourceId', ''), | ||
savedObjectType: get(opts, 'savedObjectType', ''), | ||
savedObjectId: get(opts, 'savedObjectId', ''), | ||
visLayerExpressionFn: get(opts, 'visLayerExpressionFn', {}), | ||
version: 1, | ||
}, | ||
}); | ||
// probably set to false since this saved obj should be hidden by default | ||
this.showInRecentlyAccessed = false; | ||
|
||
// we probably don't need this below field. we aren't going to need a full path | ||
// since we aren't going to allow editing by default | ||
// this.getFullPath = () => { | ||
// return `/app/visualize#/edit/${this.id}`; | ||
// }; | ||
} | ||
} | ||
|
||
return SavedAugmentVis as new (opts: Record<string, unknown> | string) => SavedObject; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
export * from './saved_augment_vis'; | ||
export * from './utils'; |
64 changes: 64 additions & 0 deletions
64
src/plugins/vis_augmenter/public/saved_augment_vis/saved_augment_vis.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { get } from 'lodash'; | ||
import { | ||
SavedObjectLoader, | ||
SavedObjectOpenSearchDashboardsServices, | ||
} from '../../../saved_objects/public'; | ||
import { createSavedAugmentVisClass } from './_saved_augment_vis'; | ||
|
||
// currently visualizations have a 'vis_types' plugin that maintains all of the | ||
// different vis types. in the saved vis loader, those types are then imported here, | ||
// such that if a type returned by the client isn't in the list, the request is | ||
// rejected. essentially just post-processing of the returned obj. We may do something | ||
// same for the vis integration augment fn types, since we will have a set list | ||
// of eligible augment fn types for plugins to choose from, when creating their saved objs. | ||
// | ||
// for now, and until it's determined where this code will live (separate plugin, within | ||
// dashboards, etc.), we will not enforce the fn types. | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface SavedObjectOpenSearchDashboardsServicesWithAugmentVis | ||
extends SavedObjectOpenSearchDashboardsServices {} | ||
export type SavedAugmentVisLoader = ReturnType<typeof createSavedAugmentVisLoader>; | ||
export function createSavedAugmentVisLoader( | ||
services: SavedObjectOpenSearchDashboardsServicesWithAugmentVis | ||
) { | ||
const { savedObjectsClient } = services; | ||
|
||
class SavedObjectLoaderAugmentVis extends SavedObjectLoader { | ||
// this is doing a lightweight version of injectReferences | ||
// essentially we want to inject the saved object id/type | ||
// by fetching the saved object reference and parsing out the id/type | ||
mapHitSource = (source: Record<string, any>, id: string) => { | ||
source.id = id; | ||
source.savedObjectId = get(source, 'savedObjectReference.id', ''); | ||
source.savedObjectType = get(source, 'savedObjectReference.type', ''); | ||
delete source.savedObjectReference; | ||
delete source.savedObjectName; | ||
return source; | ||
}; | ||
|
||
/** | ||
* Updates hit.attributes to contain an id and fields related to the referenced saved object | ||
* (savedObjectId, savedObjectType) and returns the updated attributes object. | ||
* @param hit | ||
* @returns {hit.attributes} The modified hit.attributes object, with an id and url field. | ||
*/ | ||
mapSavedObjectApiHits(hit: { | ||
references: any[]; | ||
attributes: Record<string, unknown>; | ||
id: string; | ||
}) { | ||
// For now we are assuming only one reference per saved object. | ||
// If we change to multiple, we will need to dynamically handle that | ||
const savedObjectReference = hit.references[0]; | ||
return this.mapHitSource({ ...hit.attributes, savedObjectReference }, hit.id); | ||
} | ||
} | ||
const SavedAugmentVis = createSavedAugmentVisClass(services); | ||
return new SavedObjectLoaderAugmentVis(SavedAugmentVis, savedObjectsClient) as SavedObjectLoader; | ||
} |
154 changes: 154 additions & 0 deletions
154
src/plugins/vis_augmenter/public/saved_augment_vis/saved_augment_vis_references.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { extractReferences, injectReferences } from './saved_augment_vis_references'; | ||
import { AugmentVisSavedObject } from '../../common'; | ||
|
||
describe('extractReferences()', () => { | ||
test('extracts nothing if savedObjectType is empty', () => { | ||
const doc = { | ||
id: '1', | ||
attributes: { | ||
foo: true, | ||
savedObjectId: 'test-id', | ||
}, | ||
references: [], | ||
}; | ||
const updatedDoc = extractReferences(doc); | ||
expect(updatedDoc).toMatchInlineSnapshot(` | ||
Object { | ||
"attributes": Object { | ||
"foo": true, | ||
"savedObjectId": "test-id", | ||
}, | ||
"references": Array [], | ||
} | ||
`); | ||
}); | ||
|
||
test('extracts nothing if savedObjectId is empty', () => { | ||
const doc = { | ||
id: '1', | ||
attributes: { | ||
foo: true, | ||
savedObjectType: 'test-type', | ||
}, | ||
references: [], | ||
}; | ||
const updatedDoc = extractReferences(doc); | ||
expect(updatedDoc).toMatchInlineSnapshot(` | ||
Object { | ||
"attributes": Object { | ||
"foo": true, | ||
"savedObjectType": "test-type", | ||
}, | ||
"references": Array [], | ||
} | ||
`); | ||
}); | ||
|
||
test('extracts nothing if savedObjectType & savedObjectId are empty', () => { | ||
const doc = { | ||
id: '1', | ||
attributes: { | ||
foo: true, | ||
}, | ||
references: [], | ||
}; | ||
const updatedDoc = extractReferences(doc); | ||
expect(updatedDoc).toMatchInlineSnapshot(` | ||
Object { | ||
"attributes": Object { | ||
"foo": true, | ||
}, | ||
"references": Array [], | ||
} | ||
`); | ||
}); | ||
|
||
test('extracts references from savedObjectType & savedObjectId', () => { | ||
const doc = { | ||
id: '1', | ||
attributes: { | ||
foo: true, | ||
savedObjectType: 'test-type', | ||
savedObjectId: 'test-id', | ||
}, | ||
references: [], | ||
}; | ||
const updatedDoc = extractReferences(doc); | ||
expect(updatedDoc).toMatchInlineSnapshot(` | ||
Object { | ||
"attributes": Object { | ||
"foo": true, | ||
"savedObjectName": "saved_object_0", | ||
}, | ||
"references": Array [ | ||
Object { | ||
"id": "test-id", | ||
"name": "saved_object_0", | ||
"type": "test-type", | ||
}, | ||
], | ||
} | ||
`); | ||
}); | ||
}); | ||
|
||
describe('injectReferences()', () => { | ||
test('injects nothing when savedObjectName is null', () => { | ||
const context = ({ | ||
id: '1', | ||
pluginResourceId: 'test-resource-id', | ||
visLayerExpressionFn: 'test-fn', | ||
} as unknown) as AugmentVisSavedObject; | ||
injectReferences(context, []); | ||
expect(context).toMatchInlineSnapshot(` | ||
Object { | ||
"id": "1", | ||
"pluginResourceId": "test-resource-id", | ||
"visLayerExpressionFn": "test-fn", | ||
} | ||
`); | ||
}); | ||
|
||
test('injects references into context', () => { | ||
const context = ({ | ||
id: '1', | ||
pluginResourceId: 'test-resource-id', | ||
visLayerExpressionFn: 'test-fn', | ||
savedObjectName: 'saved_object_0', | ||
} as unknown) as AugmentVisSavedObject; | ||
const references = [ | ||
{ | ||
name: 'saved_object_0', | ||
type: 'visualization', | ||
id: 'test-id', | ||
}, | ||
]; | ||
injectReferences(context, references); | ||
expect(context).toMatchInlineSnapshot(` | ||
Object { | ||
"id": "1", | ||
"pluginResourceId": "test-resource-id", | ||
"savedObjectId": "test-id", | ||
"savedObjectType": "visualization", | ||
"visLayerExpressionFn": "test-fn", | ||
} | ||
`); | ||
}); | ||
|
||
test(`fails when it can't find the saved object reference in the array`, () => { | ||
const context = ({ | ||
id: '1', | ||
pluginResourceId: 'test-resource-id', | ||
visLayerExpressionFn: 'test-fn', | ||
savedObjectName: 'saved_object_0', | ||
} as unknown) as AugmentVisSavedObject; | ||
expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( | ||
`"Could not find saved object reference \\"saved_object_0\\""` | ||
); | ||
}); | ||
}); |
Oops, something went wrong.