Skip to content

Commit

Permalink
[Graph] Deangularize saved object handling (workspace) (#52529)
Browse files Browse the repository at this point in the history
  • Loading branch information
kertal authored Dec 13, 2019
1 parent 96fb2d1 commit dbec0b1
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 170 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { SavedObject, SavedObjectKibanaServices } from 'ui/saved_objects/types';
import { createSavedObjectClass } from 'ui/saved_objects/saved_object';
import { i18n } from '@kbn/i18n';
import { extractReferences, injectReferences } from './saved_workspace_references';

export interface SavedWorkspace extends SavedObject {
wsState?: string;
}

export function createSavedWorkspaceClass(services: SavedObjectKibanaServices) {
// SavedWorkspace constructor. Usually you'd interact with an instance of this.
// ID is option, without it one will be generated on save.
const SavedObjectClass = createSavedObjectClass(services);
class SavedWorkspaceClass extends SavedObjectClass {
public static type: string = 'graph-workspace';
// if type:workspace has no mapping, we push this mapping into ES
public static mapping: Record<string, string> = {
title: 'text',
description: 'text',
numLinks: 'integer',
numVertices: 'integer',
version: 'integer',
wsState: 'json',
};
// Order these fields to the top, the rest are alphabetical
public static fieldOrder = ['title', 'description'];
public static searchSource = false;

public wsState?: string;

constructor(id: string) {
// Gives our SavedWorkspace the properties of a SavedObject
super({
type: SavedWorkspaceClass.type,
mapping: SavedWorkspaceClass.mapping,
searchSource: SavedWorkspaceClass.searchSource,
extractReferences,
injectReferences,
// if this is null/undefined then the SavedObject will be assigned the defaults
id,
// default values that will get assigned if the doc is new
defaults: {
title: i18n.translate('xpack.graph.savedWorkspace.workspaceNameTitle', {
defaultMessage: 'New Graph Workspace',
}),
numLinks: 0,
numVertices: 0,
wsState: '{}',
version: 1,
},
});
}
// Overwrite the default getDisplayName function which uses type and which is not very
// user friendly for this object.
getDisplayName = () => {
return 'graph workspace';
};
}
return SavedWorkspaceClass;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { extractReferences, injectReferences } from './saved_workspace_references';
import { SavedWorkspace } from './saved_workspace';

describe('extractReferences', () => {
test('extracts references from wsState', () => {
Expand All @@ -19,6 +20,7 @@ describe('extractReferences', () => {
})
),
},
references: [],
};
const updatedDoc = extractReferences(doc);
expect(updatedDoc).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -48,6 +50,7 @@ Object {
})
),
},
references: [],
};
expect(() => extractReferences(doc)).toThrowErrorMatchingInlineSnapshot(
`"indexPattern attribute is missing in \\"wsState\\""`
Expand All @@ -59,12 +62,12 @@ describe('injectReferences', () => {
test('injects references into context', () => {
const context = {
id: '1',
foo: true,
title: 'test',
wsState: JSON.stringify({
indexPatternRefName: 'indexPattern_0',
bar: true,
}),
};
} as SavedWorkspace;
const references = [
{
name: 'indexPattern_0',
Expand All @@ -75,8 +78,8 @@ describe('injectReferences', () => {
injectReferences(context, references);
expect(context).toMatchInlineSnapshot(`
Object {
"foo": true,
"id": "1",
"title": "test",
"wsState": "{\\"bar\\":true,\\"indexPattern\\":\\"pattern*\\"}",
}
`);
Expand All @@ -85,13 +88,13 @@ Object {
test('skips when wsState is not a string', () => {
const context = {
id: '1',
foo: true,
};
title: 'test',
} as SavedWorkspace;
injectReferences(context, []);
expect(context).toMatchInlineSnapshot(`
Object {
"foo": true,
"id": "1",
"title": "test",
}
`);
});
Expand All @@ -100,7 +103,7 @@ Object {
const context = {
id: '1',
wsState: JSON.stringify({ bar: true }),
};
} as SavedWorkspace;
injectReferences(context, []);
expect(context).toMatchInlineSnapshot(`
Object {
Expand All @@ -116,7 +119,7 @@ Object {
wsState: JSON.stringify({
indexPatternRefName: 'indexPattern_0',
}),
};
} as SavedWorkspace;
expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot(
`"Could not find reference \\"indexPattern_0\\""`
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/

export function extractReferences({ attributes, references = [] }) {
import { SavedObjectAttributes, SavedObjectReference } from 'kibana/public';
import { SavedWorkspace } from './saved_workspace';

export function extractReferences({
attributes,
references = [],
}: {
attributes: SavedObjectAttributes;
references: SavedObjectReference[];
}) {
// For some reason, wsState comes in stringified 2x
const state = JSON.parse(JSON.parse(attributes.wsState));
const state = JSON.parse(JSON.parse(String(attributes.wsState)));
const { indexPattern } = state;
if (!indexPattern) {
throw new Error('indexPattern attribute is missing in "wsState"');
Expand All @@ -20,7 +29,7 @@ export function extractReferences({ attributes, references = [] }) {
name: 'indexPattern_0',
type: 'index-pattern',
id: indexPattern,
}
},
],
attributes: {
...attributes,
Expand All @@ -29,7 +38,7 @@ export function extractReferences({ attributes, references = [] }) {
};
}

export function injectReferences(savedObject, references) {
export function injectReferences(savedObject: SavedWorkspace, references: SavedObjectReference[]) {
// Skip if wsState is missing, at the time of development of this, there is no guarantee each
// saved object has wsState.
if (typeof savedObject.wsState !== 'string') {
Expand All @@ -41,7 +50,9 @@ export function injectReferences(savedObject, references) {
if (!state.indexPatternRefName) {
return;
}
const indexPatternReference = references.find(reference => reference.name === state.indexPatternRefName);
const indexPatternReference = references.find(
reference => reference.name === state.indexPatternRefName
);
if (!indexPatternReference) {
// Throw an error as "indexPatternRefName" means the reference exists within
// "references" and in this scenario we have bad data.
Expand Down

This file was deleted.

Loading

0 comments on commit dbec0b1

Please sign in to comment.