Skip to content

Commit

Permalink
[Dashboard] Add visualization by value to dashboard (#69898)
Browse files Browse the repository at this point in the history
* Plugging in DashboardStart dependency

* Create embeddable by reference and navigate back to dashboard

* Trying to feature flag the new flow

* Feature flagging new visualize flow

* Removing unnecessary console statement

* Fixing typescript errors

* Adding a functional test for new functionality

* Adding a functional test for new functionality

* Fixing test name

* Changing test name

* Moving functional test to a separate folder

* Trying to fix the config file

* Adding an index file

* Remove falsly included file

* Adding aggs and params to vis input

* Serializing vis before passing it as an input

* Incorporating new state transfer logic

* Remove dashboardStart as a dependency

* Trying to get the test to run

* Remove unused import

* Readding spaces

* Fixing type errors

* Incorporating new changes
  • Loading branch information
Maja Grubic authored Jun 30, 2020
1 parent 351629f commit 7c352c0
Show file tree
Hide file tree
Showing 15 changed files with 870 additions and 16 deletions.
1 change: 1 addition & 0 deletions scripts/functional_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const alwaysImportedTests = [
require.resolve('../test/functional/config.js'),
require.resolve('../test/plugin_functional/config.js'),
require.resolve('../test/ui_capabilities/newsfeed_err/config.ts'),
require.resolve('../test/new_visualize_flow/config.js'),
];
// eslint-disable-next-line no-restricted-syntax
const onlyNotInCoverageTests = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import {
isErrorEmbeddable,
openAddPanelFlyout,
ViewMode,
SavedObjectEmbeddableInput,
ContainerOutput,
EmbeddableInput,
} from '../../../embeddable/public';
Expand Down Expand Up @@ -432,14 +431,16 @@ export class DashboardAppController {
.getIncomingEmbeddablePackage();
if (incomingState) {
if ('id' in incomingState) {
container.addNewEmbeddable<SavedObjectEmbeddableInput>(incomingState.type, {
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, {
savedObjectId: incomingState.id,
});
} else if ('input' in incomingState) {
container.addNewEmbeddable<EmbeddableInput>(
incomingState.type,
incomingState.input
);
const input = incomingState.input;
delete input.id;
const explicitInput = {
savedVis: input,
};
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, explicitInput);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
import { DisabledLabEmbeddable } from './disabled_lab_embeddable';
import { VisualizeEmbeddable, VisualizeInput, VisualizeOutput } from './visualize_embeddable';
import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
import { Vis } from '../vis';
import { SerializedVis, Vis } from '../vis';
import {
getCapabilities,
getTypes,
Expand Down Expand Up @@ -124,13 +124,20 @@ export class VisualizeEmbeddableFactory
}
}

public async create() {
public async create(input: VisualizeInput & { savedVis?: SerializedVis }, parent?: IContainer) {
// TODO: This is a bit of a hack to preserve the original functionality. Ideally we will clean this up
// to allow for in place creation of visualizations without having to navigate away to a new URL.
showNewVisModal({
originatingApp: await this.getCurrentAppId(),
outsideVisualizeApp: true,
});
return undefined;
if (input.savedVis) {
const visState = input.savedVis;
const vis = new Vis(visState.type, visState);
await vis.setState(visState);
return createVisEmbeddableFromObject(this.deps)(vis, input, parent);
} else {
showNewVisModal({
originatingApp: await this.getCurrentAppId(),
outsideVisualizeApp: true,
});
return undefined;
}
}
}
26 changes: 26 additions & 0 deletions src/plugins/visualize/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';

export const configSchema = schema.object({
showNewVisualizeFlow: schema.boolean({ defaultValue: false }),
});

export type ConfigSchema = TypeOf<typeof configSchema>;
2 changes: 2 additions & 0 deletions src/plugins/visualize/public/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { SharePluginStart } from 'src/plugins/share/public';
import { SavedObjectsStart, SavedObject } from 'src/plugins/saved_objects/public';
import { EmbeddableStart } from 'src/plugins/embeddable/public';
import { KibanaLegacyStart } from 'src/plugins/kibana_legacy/public';
import { ConfigSchema } from '../../config';

export type PureVisState = SavedVisState;

Expand Down Expand Up @@ -110,6 +111,7 @@ export interface VisualizeServices extends CoreStart {
createVisEmbeddableFromObject: VisualizationsStart['__LEGACY']['createVisEmbeddableFromObject'];
restorePreviousUrl: () => void;
scopedHistory: ScopedHistory;
featureFlagConfig: ConfigSchema;
}

export interface SavedVisInstance {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import React from 'react';
import { i18n } from '@kbn/i18n';

import { TopNavMenuData } from 'src/plugins/navigation/public';
import uuid from 'uuid';
import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../visualizations/public';
import {
showSaveModal,
Expand All @@ -33,7 +34,6 @@ import { unhashUrl } from '../../../../kibana_utils/public';
import { SavedVisInstance, VisualizeServices, VisualizeAppStateContainer } from '../types';
import { VisualizeConstants } from '../visualize_constants';
import { getEditBreadcrumbs } from './breadcrumbs';

interface TopNavConfigParams {
hasUnsavedChanges: boolean;
setHasUnsavedChanges: (value: boolean) => void;
Expand Down Expand Up @@ -66,6 +66,7 @@ export const getTopNavConfig = (
toastNotifications,
visualizeCapabilities,
i18n: { Context: I18nContext },
featureFlagConfig,
}: VisualizeServices
) => {
/**
Expand Down Expand Up @@ -234,6 +235,19 @@ export const getTopNavConfig = (
return response;
};

const createVisReference = () => {
if (!originatingApp) {
return;
}
const input = {
...vis.serialize(),
id: uuid.v4(),
};
embeddable.getStateTransfer().navigateToWithEmbeddablePackage(originatingApp, {
state: { input, type: VISUALIZE_EMBEDDABLE_TYPE },
});
};

const saveModal = (
<SavedObjectSaveModalOrigin
documentInfo={savedVis}
Expand All @@ -243,7 +257,11 @@ export const getTopNavConfig = (
originatingApp={originatingApp}
/>
);
showSaveModal(saveModal, I18nContext);
if (originatingApp === 'dashboards' && featureFlagConfig.showNewVisualizeFlow) {
createVisReference();
} else {
showSaveModal(saveModal, I18nContext);
}
},
},
]
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/visualize/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export interface VisualizePluginSetupDependencies {
data: DataPublicPluginSetup;
}

export interface FeatureFlagConfig {
showNewVisualizeFlow: boolean;
}

export class VisualizePlugin
implements
Plugin<void, void, VisualizePluginSetupDependencies, VisualizePluginStartDependencies> {
Expand Down Expand Up @@ -165,6 +169,7 @@ export class VisualizePlugin
savedObjectsPublic: pluginsStart.savedObjects,
scopedHistory: params.history,
restorePreviousUrl,
featureFlagConfig: this.initializerContext.config.get<FeatureFlagConfig>(),
};

params.element.classList.add('visAppWrapper');
Expand Down
11 changes: 10 additions & 1 deletion src/plugins/visualize/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,17 @@
* under the License.
*/

import { PluginInitializerContext } from 'kibana/server';
import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server';
import { VisualizeServerPlugin } from './plugin';

import { ConfigSchema, configSchema } from '../config';

export const config: PluginConfigDescriptor<ConfigSchema> = {
exposeToBrowser: {
showNewVisualizeFlow: true,
},
schema: configSchema,
};

export const plugin = (initContext: PluginInitializerContext) =>
new VisualizeServerPlugin(initContext);
2 changes: 2 additions & 0 deletions tasks/function_test_groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const getDefaultArgs = (tag) => {
// '--config', 'test/functional/config.firefox.js',
'--bail',
'--debug',
'--config',
'test/new_visualize_flow/config.js',
];
};

Expand Down
26 changes: 26 additions & 0 deletions test/functional/services/dashboard/visualizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,31 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }: F
redirectToOrigin: true,
});
}

async createAndEmbedMetric(name: string) {
log.debug(`createAndEmbedMetric(${name})`);
const inViewMode = await PageObjects.dashboard.getIsInViewMode();
if (inViewMode) {
await PageObjects.dashboard.switchToEditMode();
}
await this.ensureNewVisualizationDialogIsShowing();
await PageObjects.visualize.clickMetric();
await find.clickByCssSelector('li.euiListGroupItem:nth-of-type(2)');
await testSubjects.exists('visualizeSaveButton');
await testSubjects.click('visualizeSaveButton');
}

async createAndEmbedMarkdown({ name, markdown }: { name: string; markdown: string }) {
log.debug(`createAndEmbedMarkdown(${markdown})`);
const inViewMode = await PageObjects.dashboard.getIsInViewMode();
if (inViewMode) {
await PageObjects.dashboard.switchToEditMode();
}
await this.ensureNewVisualizationDialogIsShowing();
await PageObjects.visualize.clickMarkdownWidget();
await PageObjects.visEditor.setMarkdownTxt(markdown);
await PageObjects.visEditor.clickGo();
await testSubjects.click('visualizeSaveButton');
}
})();
}
Loading

0 comments on commit 7c352c0

Please sign in to comment.