Skip to content
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
cc77109
added location state to scopedHistory.ts - used this location state f…
ThomThomson May 18, 2020
07bbfc6
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 18, 2020
a0bad30
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 19, 2020
1d70c31
added the redirectTo scopedHistory system to visualize
ThomThomson May 19, 2020
df86dd7
API changes
ThomThomson May 19, 2020
8be92da
removed lens dashboard dependency
ThomThomson May 19, 2020
c527675
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 20, 2020
78e45af
short circuit for destructuring, changed jest test
ThomThomson May 20, 2020
072fe2e
Removed unnecessary scoped history changes
ThomThomson May 20, 2020
4911b46
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 26, 2020
1bbfbdc
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 27, 2020
77dfdf5
Created an embeddable state transfer API with generic and specific ty…
ThomThomson May 27, 2020
32de3b6
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 28, 2020
3bf46f5
Added embeddablePackage to state transfer API. Used the state transfe…
ThomThomson May 29, 2020
e461319
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson May 29, 2020
b5a0b29
Updated tests. Added mock for EmbeddablePanel
ThomThomson May 29, 2020
afe51e1
Updated tests. Added mock for EmbeddablePanel
ThomThomson May 29, 2020
a8129c8
Added tests for embeddable state transfer
ThomThomson May 29, 2020
7e8b25a
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 1, 2020
9d425f1
fixed type error, added embeddable to NP set_services.ts
ThomThomson Jun 1, 2020
c2feccc
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 1, 2020
1b2929c
Made state transfer optional in edit panel and new vis modal
ThomThomson Jun 2, 2020
81e6aa1
Removed all Embeddable panel changes in favor of #68006. Renamed stat…
ThomThomson Jun 2, 2020
65ddfe9
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 4, 2020
0263f3a
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 4, 2020
4fac70c
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 5, 2020
070f9b8
Used removeAfterFetch to make lens state on reload behavior match vis…
ThomThomson Jun 5, 2020
aecab9c
update embeddable state transfer tests to use scoped history mock
ThomThomson Jun 5, 2020
927a40c
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 8, 2020
289d458
Changed to a factory approach for embeddable state transfer
ThomThomson Jun 8, 2020
f615d9a
type changes
ThomThomson Jun 8, 2020
d98b8fe
Reinstated dashboard as a required plugin for visualize
ThomThomson Jun 9, 2020
75dda63
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 9, 2020
94730d1
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 11, 2020
524d1cb
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 12, 2020
2cec3f9
changed incoming state fetch to optionally remove a list of keys from…
ThomThomson Jun 15, 2020
8f0504f
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 15, 2020
4d68185
Added append mode option to embeddable state transfer outgoing methods
ThomThomson Jun 17, 2020
22e7974
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 17, 2020
7950a31
type fixes
ThomThomson Jun 17, 2020
1d5bd74
jest fixes
ThomThomson Jun 18, 2020
8fab749
Merge branch 'master' of github.com:elastic/kibana into arch/redirect…
ThomThomson Jun 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import { getDashboardTitle } from './dashboard_strings';
import { DashboardAppScope } from './dashboard_app';
import { convertSavedDashboardPanelToPanelState } from './lib/embeddable_saved_object_converters';
import { RenderDeps } from './application';
import { IKbnUrlStateStorage, removeQueryParam, unhashUrl } from '../../../kibana_utils/public';
import { IKbnUrlStateStorage, unhashUrl } from '../../../kibana_utils/public';
import {
addFatalError,
AngularHttpError,
Expand Down Expand Up @@ -132,6 +132,7 @@ export class DashboardAppController {
embeddable,
share,
dashboardCapabilities,
scopedHistory,
embeddableCapabilities: { visualizeCapabilities, mapsCapabilities },
data: { query: queryService },
core: {
Expand Down Expand Up @@ -425,15 +426,13 @@ export class DashboardAppController {
refreshDashboardContainer();
});

// This code needs to be replaced with a better mechanism for adding new embeddables of
// any type from the add panel. Likely this will happen via creating a visualization "inline",
// without navigating away from the UX.
if ($routeParams[DashboardConstants.ADD_EMBEDDABLE_TYPE]) {
const type = $routeParams[DashboardConstants.ADD_EMBEDDABLE_TYPE];
const id = $routeParams[DashboardConstants.ADD_EMBEDDABLE_ID];
container.addNewEmbeddable<SavedObjectEmbeddableInput>(type, { savedObjectId: id });
removeQueryParam(history, DashboardConstants.ADD_EMBEDDABLE_TYPE);
removeQueryParam(history, DashboardConstants.ADD_EMBEDDABLE_ID);
const incomingState = embeddable
.getStateTransfer(scopedHistory())
.getIncomingEmbeddablePackage();
if (incomingState) {
container.addNewEmbeddable<SavedObjectEmbeddableInput>(incomingState.type, {
savedObjectId: incomingState.id,
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
} from '../../../../kibana_react/public';
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
import { PanelPlacementMethod, IPanelPlacementArgs } from './panel/dashboard_panel_placement';
import { EmbeddableStateTransfer } from '../../../../embeddable/public';

export interface DashboardContainerInput extends ContainerInput {
viewMode: ViewMode;
Expand Down Expand Up @@ -98,9 +99,12 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard

public renderEmpty?: undefined | (() => React.ReactNode);

private embeddablePanel: EmbeddableStart['EmbeddablePanel'];

constructor(
initialInput: DashboardContainerInput,
private readonly options: DashboardContainerOptions,
stateTransfer?: EmbeddableStateTransfer,
parent?: Container
) {
super(
Expand All @@ -111,6 +115,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
options.embeddable.getEmbeddableFactory,
parent
);
this.embeddablePanel = options.embeddable.getEmbeddablePanel(stateTransfer);
}

protected createNewPanelState<
Expand Down Expand Up @@ -186,7 +191,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
<DashboardViewport
renderEmpty={this.renderEmpty}
container={this}
PanelComponent={this.options.embeddable.EmbeddablePanel}
PanelComponent={this.embeddablePanel}
/>
</KibanaContextProvider>
</I18nProvider>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import { i18n } from '@kbn/i18n';
import { UiActionsStart } from 'src/plugins/ui_actions/public';
import { CoreStart } from 'src/core/public';
import { CoreStart, ScopedHistory } from 'src/core/public';
import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { EmbeddableFactory, EmbeddableStart } from '../../../../embeddable/public';
import {
Expand Down Expand Up @@ -54,7 +54,10 @@ export class DashboardContainerFactoryDefinition
public readonly isContainerType = true;
public readonly type = DASHBOARD_CONTAINER_TYPE;

constructor(private readonly getStartServices: () => Promise<StartServices>) {}
constructor(
private readonly getStartServices: () => Promise<StartServices>,
private getHistory: () => ScopedHistory
) {}

public isEditable = async () => {
const { capabilities } = await this.getStartServices();
Expand All @@ -81,6 +84,7 @@ export class DashboardContainerFactoryDefinition
parent?: Container
): Promise<DashboardContainer | ErrorEmbeddable> => {
const services = await this.getStartServices();
return new DashboardContainer(initialInput, services, parent);
const stateTransfer = services.embeddable.getStateTransfer(this.getHistory());
return new DashboardContainer(initialInput, services, stateTransfer, parent);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function prepare(props?: Partial<DashboardGridProps>) {
embeddable: {
getTriggerCompatibleActions: (() => []) as any,
getEmbeddableFactories: start.getEmbeddableFactories,
getEmbeddablePanel: jest.fn(),
getEmbeddableFactory,
} as any,
notifications: {} as any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function getProps(
application: applicationServiceMock.createStartContract(),
embeddable: {
getTriggerCompatibleActions: (() => []) as any,
getEmbeddablePanel: jest.fn(),
getEmbeddableFactories: start.getEmbeddableFactories,
getEmbeddableFactory: start.getEmbeddableFactory,
} as any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { context } from '../../../../../kibana_react/public';

export interface DashboardViewportProps {
container: DashboardContainer;
renderEmpty?: () => React.ReactNode;
PanelComponent: EmbeddableStart['EmbeddablePanel'];
renderEmpty?: () => React.ReactNode;
}

interface State {
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/dashboard/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ export class DashboardPlugin
};
};

const factory = new DashboardContainerFactoryDefinition(getStartServices);
const factory = new DashboardContainerFactoryDefinition(
getStartServices,
() => this.currentHistory!
);
embeddable.registerEmbeddableFactory(factory.type, factory);

const placeholderFactory = new PlaceholderEmbeddableFactory();
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/embeddable/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import './index.scss';
import { PluginInitializerContext } from 'src/core/public';
import { EmbeddablePublicPlugin } from './plugin';

export { EMBEDDABLE_ORIGINATING_APP_PARAM } from './types';
export {
ACTION_ADD_PANEL,
ACTION_APPLY_FILTER,
Expand Down Expand Up @@ -69,6 +68,9 @@ export {
isSavedObjectEmbeddableInput,
isRangeSelectTriggerContext,
isValueClickTriggerContext,
EmbeddableStateTransfer,
EmbeddableOriginatingAppState,
EmbeddablePackageState,
EmbeddableRenderer,
EmbeddableRendererProps,
} from './lib';
Expand All @@ -82,4 +84,5 @@ export {
EmbeddableStart,
EmbeddableSetupDependencies,
EmbeddableStartDependencies,
EmbeddablePanelHOC,
} from './plugin';
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import { ViewMode } from '../types';
import { ContactCardEmbeddable } from '../test_samples';
import { embeddablePluginMock } from '../../mocks';
import { applicationServiceMock } from '../../../../../core/public/mocks';
import { of } from 'rxjs';

const { doStart } = embeddablePluginMock.createInstance();
const start = doStart();
const getFactory = start.getEmbeddableFactory;
const applicationMock = applicationServiceMock.createStartContract();
const stateTransferMock = embeddablePluginMock.createStartContract().getStateTransfer();

class EditableEmbeddable extends Embeddable {
public readonly type = 'EDITABLE_EMBEDDABLE';
Expand All @@ -43,16 +45,28 @@ class EditableEmbeddable extends Embeddable {
}

test('is compatible when edit url is available, in edit mode and editable', async () => {
const action = new EditPanelAction(getFactory, applicationMock);
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true),
})
).toBe(true);
});

test('redirects to app using state transfer', async () => {
applicationMock.currentAppId$ = of('superCoolCurrentApp');
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
const embeddable = new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true);
embeddable.getOutput = jest.fn(() => ({ editApp: 'ultraVisualize', editPath: '/123' }));
await action.execute({ embeddable });
expect(stateTransferMock.navigateToWithOriginatingApp).toHaveBeenCalledWith('ultraVisualize', {
path: '/123',
state: { originatingApp: 'superCoolCurrentApp' },
});
});

test('getHref returns the edit urls', async () => {
const action = new EditPanelAction(getFactory, applicationMock);
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
expect(action.getHref).toBeDefined();

if (action.getHref) {
Expand All @@ -66,7 +80,7 @@ test('getHref returns the edit urls', async () => {
});

test('is not compatible when edit url is not available', async () => {
const action = new EditPanelAction(getFactory, applicationMock);
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
const embeddable = new ContactCardEmbeddable(
{
id: '123',
Expand All @@ -85,7 +99,7 @@ test('is not compatible when edit url is not available', async () => {
});

test('is not visible when edit url is available but in view mode', async () => {
const action = new EditPanelAction(getFactory, applicationMock);
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable(
Expand All @@ -100,7 +114,7 @@ test('is not visible when edit url is available but in view mode', async () => {
});

test('is not compatible when edit url is available, in edit mode, but not editable', async () => {
const action = new EditPanelAction(getFactory, applicationMock);
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable(
Expand Down
36 changes: 22 additions & 14 deletions src/plugins/embeddable/public/lib/actions/edit_panel_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ import { take } from 'rxjs/operators';
import { ViewMode } from '../types';
import { EmbeddableFactoryNotFoundError } from '../errors';
import { EmbeddableStart } from '../../plugin';
import { EMBEDDABLE_ORIGINATING_APP_PARAM, IEmbeddable } from '../..';
import { IEmbeddable, EmbeddableOriginatingAppState, EmbeddableStateTransfer } from '../..';

export const ACTION_EDIT_PANEL = 'editPanel';

interface ActionContext {
embeddable: IEmbeddable;
}

interface NavigationContext {
app: string;
path: string;
state?: EmbeddableOriginatingAppState;
}

export class EditPanelAction implements Action<ActionContext> {
public readonly type = ACTION_EDIT_PANEL;
public readonly id = ACTION_EDIT_PANEL;
Expand All @@ -40,7 +46,8 @@ export class EditPanelAction implements Action<ActionContext> {

constructor(
private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'],
private readonly application: ApplicationStart
private readonly application: ApplicationStart,
private readonly stateTransfer?: EmbeddableStateTransfer
) {
if (this.application?.currentAppId$) {
this.application.currentAppId$
Expand Down Expand Up @@ -79,9 +86,15 @@ export class EditPanelAction implements Action<ActionContext> {

public async execute(context: ActionContext) {
const appTarget = this.getAppTarget(context);

if (appTarget) {
await this.application.navigateToApp(appTarget.app, { path: appTarget.path });
if (this.stateTransfer && appTarget.state) {
await this.stateTransfer.navigateToWithOriginatingApp(appTarget.app, {
path: appTarget.path,
state: appTarget.state,
});
} else {
await this.application.navigateToApp(appTarget.app, { path: appTarget.path });
}
return;
}

Expand All @@ -92,22 +105,17 @@ export class EditPanelAction implements Action<ActionContext> {
}
}

public getAppTarget({ embeddable }: ActionContext): { app: string; path: string } | undefined {
public getAppTarget({ embeddable }: ActionContext): NavigationContext | undefined {
const app = embeddable ? embeddable.getOutput().editApp : undefined;
let path = embeddable ? embeddable.getOutput().editPath : undefined;
const path = embeddable ? embeddable.getOutput().editPath : undefined;
if (app && path) {
if (this.currentAppId) {
path += `?${EMBEDDABLE_ORIGINATING_APP_PARAM}=${this.currentAppId}`;
}
return { app, path };
const state = this.currentAppId ? { originatingApp: this.currentAppId } : undefined;
return { app, path, state };
}
}

public async getHref({ embeddable }: ActionContext): Promise<string> {
let editUrl = embeddable ? embeddable.getOutput().editUrl : undefined;
if (editUrl && this.currentAppId) {
editUrl += `?${EMBEDDABLE_ORIGINATING_APP_PARAM}=${this.currentAppId}`;
}
const editUrl = embeddable ? embeddable.getOutput().editUrl : undefined;
return editUrl ? editUrl : '';
}
}
1 change: 1 addition & 0 deletions src/plugins/embeddable/public/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export * from './actions';
export * from './triggers';
export * from './containers';
export * from './panel';
export * from './state_transfer';
8 changes: 7 additions & 1 deletion src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { EditPanelAction } from '../actions';
import { CustomizePanelModal } from './panel_header/panel_actions/customize_title/customize_panel_modal';
import { EmbeddableStart } from '../../plugin';
import { EmbeddableErrorLabel } from './embeddable_error_label';
import { EmbeddableStateTransfer } from '..';

const sortByOrderField = (
{ order: orderA }: { order?: number },
Expand All @@ -62,6 +63,7 @@ interface Props {
application: CoreStart['application'];
inspector: InspectorStartContract;
SavedObjectFinder: React.ComponentType<any>;
stateTransfer?: EmbeddableStateTransfer;
hideHeader?: boolean;
}

Expand Down Expand Up @@ -299,7 +301,11 @@ export class EmbeddablePanel extends React.Component<Props, State> {
),
new InspectPanelAction(this.props.inspector),
new RemovePanelAction(),
new EditPanelAction(this.props.getEmbeddableFactory, this.props.application),
new EditPanelAction(
this.props.getEmbeddableFactory,
this.props.application,
this.props.stateTransfer
),
];

const sortedActions = [...regularActions, ...extraActions].sort(sortByOrderField);
Expand Down
Loading