"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.deleteSavedWorkspace = deleteSavedWorkspace; exports.findSavedWorkspace = findSavedWorkspace; exports.getEmptyWorkspace = getEmptyWorkspace; exports.getSavedWorkspace = getSavedWorkspace; exports.saveSavedWorkspace = saveSavedWorkspace; var _lodash = require("lodash"); var _i18n = require("@kbn/i18n"); var _public = require("@kbn/saved-objects-plugin/public"); var _public2 = require("@kbn/kibana-utils-plugin/public"); var _content_management = require("../../common/content_management"); var _saved_workspace_references = require("../services/persistence/saved_workspace_references"); var _saved_objects_utils = require("./saved_objects_utils"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ const savedWorkspaceType = 'graph-workspace'; const mapping = { title: 'text', description: 'text', numLinks: 'integer', numVertices: 'integer', version: 'integer', wsState: 'json' }; const defaultsProps = { title: _i18n.i18n.translate('xpack.graph.savedWorkspace.workspaceNameTitle', { defaultMessage: 'New Graph Workspace' }), numLinks: 0, numVertices: 0, wsState: '{}', version: 1 }; const urlFor = (basePath, id) => basePath.prepend(`/app/graph#/workspace/${encodeURIComponent(id)}`); function mapHits(hit, url) { const source = hit.attributes; source.id = hit.id; source.url = url; source.updatedAt = hit.updatedAt; source.icon = 'cluster'; // maybe there's a better choice here? return source; } function findSavedWorkspace({ contentClient, basePath }, searchString, size = 100) { return contentClient.search({ contentTypeId: _content_management.CONTENT_ID, query: { text: searchString ? `${searchString}*` : '' } }).then(resp => { return { total: resp.pagination.total, hits: resp.hits.map(hit => mapHits(hit, urlFor(basePath, hit.id))) }; }); } function getEmptyWorkspace() { return { savedObject: { displayName: 'graph workspace', getEsType: () => savedWorkspaceType, ...defaultsProps } }; } async function getSavedWorkspace(contentClient, id) { const resolveResult = await contentClient.get({ contentTypeId: _content_management.CONTENT_ID, id }); const resp = resolveResult.item; if (!resp.attributes) { throw new _public2.SavedObjectNotFound(savedWorkspaceType, id || ''); } const savedObject = { id, displayName: 'graph workspace', getEsType: () => savedWorkspaceType, _source: (0, _lodash.cloneDeep)({ ...resp.attributes }) }; // assign the defaults to the response (0, _lodash.defaults)(savedObject._source, defaultsProps); // transform the source using JSON.parse if (savedObject._source.wsState) { savedObject._source.wsState = JSON.parse(savedObject._source.wsState); } // Give obj all of the values in _source.fields (0, _lodash.assign)(savedObject, savedObject._source); savedObject.lastSavedTitle = savedObject.title; if (resp.references && resp.references.length > 0) { (0, _saved_workspace_references.injectReferences)(savedObject, resp.references); } const sharingSavedObjectProps = { outcome: resolveResult.meta.outcome, aliasTargetId: resolveResult.meta.aliasTargetId, aliasPurpose: resolveResult.meta.aliasPurpose }; return { savedObject, sharingSavedObjectProps }; } function deleteSavedWorkspace(contentClient, ids) { return Promise.all(ids.map(id => contentClient.delete({ contentTypeId: _content_management.CONTENT_ID, id }))); } async function saveSavedWorkspace(savedObject, { confirmOverwrite = false, isTitleDuplicateConfirmed = false, onTitleDuplicate } = {}, services) { let attributes = {}; (0, _lodash.forOwn)(mapping, (fieldType, fieldName) => { const savedObjectFieldVal = savedObject[fieldName]; if (savedObjectFieldVal != null) { attributes[fieldName] = fieldName === 'wsState' ? JSON.stringify(savedObjectFieldVal) : savedObjectFieldVal; } }); const extractedRefs = (0, _saved_workspace_references.extractReferences)({ attributes, references: [] }); const references = extractedRefs.references; attributes = extractedRefs.attributes; if (!references) { throw new Error('References not returned from extractReferences'); } // Save the original id in case the save fails. const originalId = savedObject.id; try { // Read https://github.com/elastic/kibana/issues/9056 and // https://github.com/elastic/kibana/issues/9012 for some background into why this copyOnSave variable // exists. // The goal is to move towards a better rename flow, but since our users have been conditioned // to expect a 'save as' flow during a rename, we are keeping the logic the same until a better // UI/UX can be worked out. if (savedObject.copyOnSave) { delete savedObject.id; } savedObject.isSaving = true; await (0, _saved_objects_utils.checkForDuplicateTitle)(savedObject, isTitleDuplicateConfirmed, onTitleDuplicate, services); const createOpt = { id: savedObject.id, migrationVersion: savedObject.migrationVersion, references }; const resp = confirmOverwrite ? await (0, _saved_objects_utils.saveWithConfirmation)(attributes, savedObject, createOpt, services) : savedObject.id ? await services.contentClient.update({ contentTypeId: _content_management.CONTENT_ID, id: savedObject.id, data: { ...extractedRefs.attributes }, options: { references: extractedRefs.references } }) : await services.contentClient.create({ contentTypeId: _content_management.CONTENT_ID, data: attributes, options: { references: createOpt.references, overwrite: true } }); savedObject.id = resp.item.id; savedObject.isSaving = false; savedObject.lastSavedTitle = savedObject.title; return savedObject.id; } catch (err) { savedObject.isSaving = false; savedObject.id = originalId; if ((0, _public.isErrorNonFatal)(err)) { return ''; } return Promise.reject(err); } }