Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add editApp and editPath to embeddable #64297

Merged
merged 4 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -275,6 +275,7 @@ class DashboardGridUi extends React.Component<DashboardGridProps, State> {
getEmbeddableFactory={this.props.kibana.services.embeddable.getEmbeddableFactory}
getAllEmbeddableFactories={this.props.kibana.services.embeddable.getEmbeddableFactories}
overlays={this.props.kibana.services.overlays}
application={this.props.kibana.services.application}
notifications={this.props.kibana.services.notifications}
inspector={this.props.kibana.services.inspector}
SavedObjectFinder={this.props.kibana.services.SavedObjectFinder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ test('DashboardContainer in edit mode shows edit mode actions', async () => {
getAllEmbeddableFactories={(() => []) as any}
getEmbeddableFactory={(() => null) as any}
notifications={{} as any}
application={{} as any}
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class EditableEmbeddable extends Embeddable {
}

test('is compatible when edit url is available, in edit mode and editable', async () => {
const action = new EditPanelAction(getFactory);
const action = new EditPanelAction(getFactory, {} as any);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true),
Expand All @@ -50,7 +50,7 @@ test('is compatible when edit url is available, in edit mode and editable', asyn
});

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

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

test('is not compatible when edit url is not available', async () => {
const action = new EditPanelAction(getFactory);
const action = new EditPanelAction(getFactory, {} as any);
const embeddable = new ContactCardEmbeddable(
{
id: '123',
Expand All @@ -83,7 +83,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);
const action = new EditPanelAction(getFactory, {} as any);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable(
Expand All @@ -98,7 +98,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);
const action = new EditPanelAction(getFactory, {} as any);
expect(
await action.isCompatible({
embeddable: new EditableEmbeddable(
Expand Down
29 changes: 25 additions & 4 deletions src/plugins/embeddable/public/lib/actions/edit_panel_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import { i18n } from '@kbn/i18n';
import { ApplicationStart } from 'kibana/public';
import { Action } from 'src/plugins/ui_actions/public';
import { ViewMode } from '../types';
import { EmbeddableFactoryNotFoundError } from '../errors';
Expand All @@ -35,7 +36,10 @@ export class EditPanelAction implements Action<ActionContext> {
public readonly id = ACTION_EDIT_PANEL;
public order = 15;

constructor(private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']) {}
constructor(
private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'],
private readonly application: ApplicationStart
) {}

public getDisplayName({ embeddable }: ActionContext) {
const factory = this.getEmbeddableFactory(embeddable.type);
Expand All @@ -56,18 +60,35 @@ export class EditPanelAction implements Action<ActionContext> {

public async isCompatible({ embeddable }: ActionContext) {
const canEditEmbeddable = Boolean(
embeddable && embeddable.getOutput().editable && embeddable.getOutput().editUrl
embeddable &&
embeddable.getOutput().editable &&
(embeddable.getOutput().editUrl ||
(embeddable.getOutput().editApp && embeddable.getOutput().editPath))
streamich marked this conversation as resolved.
Show resolved Hide resolved
);
const inDashboardEditMode = embeddable.getInput().viewMode === ViewMode.EDIT;
return Boolean(canEditEmbeddable && inDashboardEditMode);
}

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

if (appTarget) {
await this.application.navigateToApp(appTarget.app, { path: appTarget.path });
return;
}

const href = await this.getHref(context);
if (href) {
// TODO: when apps start using browser router instead of hash router this has to be fixed
// https://github.com/elastic/kibana/issues/58217
window.location.href = href;
return;
}
}

public getAppTarget({ embeddable }: ActionContext): { app: string; path: string } | undefined {
const app = embeddable ? embeddable.getOutput().editApp : undefined;
const path = embeddable ? embeddable.getOutput().editPath : undefined;
if (app && path) {
return { app, path };
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ test('EmbeddableChildPanel renders an embeddable when it is done loading', async
getAllEmbeddableFactories={start.getEmbeddableFactories}
getEmbeddableFactory={getEmbeddableFactory}
notifications={{} as any}
application={{} as any}
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
Expand Down Expand Up @@ -105,6 +106,7 @@ test(`EmbeddableChildPanel renders an error message if the factory doesn't exist
getEmbeddableFactory={(() => undefined) as any}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface EmbeddableChildPanelProps {
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: CoreStart['overlays'];
notifications: CoreStart['notifications'];
application: CoreStart['application'];
inspector: InspectorStartContract;
SavedObjectFinder: React.ComponentType<any>;
}
Expand Down Expand Up @@ -101,6 +102,7 @@ export class EmbeddableChildPanel extends React.Component<EmbeddableChildPanelPr
getEmbeddableFactory={this.props.getEmbeddableFactory}
getAllEmbeddableFactories={this.props.getAllEmbeddableFactories}
overlays={this.props.overlays}
application={this.props.application}
notifications={this.props.notifications}
inspector={this.props.inspector}
SavedObjectFinder={this.props.SavedObjectFinder}
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export interface EmbeddableInput {

export interface EmbeddableOutput {
editUrl?: string;
editApp?: string;
editPath?: string;
defaultTitle?: string;
title?: string;
editable?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ test('HelloWorldContainer in view mode hides edit mode actions', async () => {
getAllEmbeddableFactories={start.getEmbeddableFactories}
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
application={{} as any}
overlays={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
Expand Down Expand Up @@ -198,6 +199,7 @@ const renderInEditModeAndOpenContextMenu = async (
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
Expand Down Expand Up @@ -296,6 +298,7 @@ test('HelloWorldContainer in edit mode shows edit mode actions', async () => {
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
Expand Down Expand Up @@ -358,6 +361,7 @@ test('Updates when hidePanelTitles is toggled', async () => {
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
/>
Expand Down Expand Up @@ -410,6 +414,7 @@ test('Check when hide header option is false', async () => {
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
hideHeader={false}
Expand Down Expand Up @@ -447,6 +452,7 @@ test('Check when hide header option is true', async () => {
getEmbeddableFactory={start.getEmbeddableFactory}
notifications={{} as any}
overlays={{} as any}
application={{} as any}
inspector={inspector}
SavedObjectFinder={() => null}
hideHeader={true}
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface Props {
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: CoreStart['overlays'];
notifications: CoreStart['notifications'];
application: CoreStart['application'];
inspector: InspectorStartContract;
SavedObjectFinder: React.ComponentType<any>;
hideHeader?: boolean;
Expand Down Expand Up @@ -243,7 +244,7 @@ export class EmbeddablePanel extends React.Component<Props, State> {
),
new InspectPanelAction(this.props.inspector),
new RemovePanelAction(),
new EditPanelAction(this.props.getEmbeddableFactory),
new EditPanelAction(this.props.getEmbeddableFactory, this.props.application),
];

const sorted = actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface HelloWorldContainerOptions {
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: CoreStart['overlays'];
application: CoreStart['application'];
notifications: CoreStart['notifications'];
inspector: InspectorStartContract;
SavedObjectFinder: React.ComponentType<any>;
Expand Down Expand Up @@ -81,6 +82,7 @@ export class HelloWorldContainer extends Container<InheritedInput, HelloWorldCon
getAllEmbeddableFactories={this.options.getAllEmbeddableFactories}
getEmbeddableFactory={this.options.getEmbeddableFactory}
overlays={this.options.overlays}
application={this.options.application}
notifications={this.options.notifications}
inspector={this.options.inspector}
SavedObjectFinder={this.options.SavedObjectFinder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface Props {
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: CoreStart['overlays'];
application: CoreStart['application'];
notifications: CoreStart['notifications'];
inspector: InspectorStartContract;
SavedObjectFinder: React.ComponentType<any>;
Expand Down Expand Up @@ -112,6 +113,7 @@ export class HelloWorldContainerComponent extends Component<Props, State> {
getAllEmbeddableFactories={this.props.getAllEmbeddableFactories}
overlays={this.props.overlays}
notifications={this.props.notifications}
application={this.props.application}
inspector={this.props.inspector}
SavedObjectFinder={this.props.SavedObjectFinder}
/>
Expand Down
1 change: 1 addition & 0 deletions src/plugins/embeddable/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
getAllEmbeddableFactories={this.getEmbeddableFactories}
overlays={core.overlays}
notifications={core.notifications}
application={core.application}
inspector={inspector}
SavedObjectFinder={getSavedObjectFinder(core.savedObjects, core.uiSettings)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ test('ApplyFilterAction is incompatible if the root container does not accept a
getAllEmbeddableFactories: api.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -145,6 +146,7 @@ test('trying to execute on incompatible context throws an error ', async () => {
getAllEmbeddableFactories: api.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector,
SavedObjectFinder: () => null,
}
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/embeddable/public/tests/container.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ async function creatHelloWorldContainerAndEmbeddable(
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
});
Expand Down Expand Up @@ -147,6 +148,7 @@ test('Container.removeEmbeddable removes and cleans up', async done => {
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -327,6 +329,7 @@ test(`Container updates its state when a child's input is updated`, async done =
getEmbeddableFactory: start.getEmbeddableFactory,
notifications: coreStart.notifications,
overlays: coreStart.overlays,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
});
Expand Down Expand Up @@ -584,6 +587,7 @@ test('Container changes made directly after adding a new embeddable are propagat
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -708,6 +712,7 @@ test('untilEmbeddableLoaded() throws an error if there is no such child panel in
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -742,6 +747,7 @@ test('untilEmbeddableLoaded() resolves if child is loaded in the container', asy
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -781,6 +787,7 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -821,6 +828,7 @@ test('adding a panel then subsequently removing it before its loaded removes the
getAllEmbeddableFactories: start.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ beforeEach(async () => {
getAllEmbeddableFactories: api.getEmbeddableFactories,
overlays: coreStart.overlays,
notifications: coreStart.notifications,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/embeddable/public/tests/explicit_input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ test('Explicit embeddable input mapped to undefined with no inherited value will
getEmbeddableFactory: start.getEmbeddableFactory,
notifications: coreStart.notifications,
overlays: coreStart.overlays,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down Expand Up @@ -136,6 +137,7 @@ test('Explicit input tests in async situations', (done: () => void) => {
getEmbeddableFactory: start.getEmbeddableFactory,
notifications: coreStart.notifications,
overlays: coreStart.overlays,
application: coreStart.application,
inspector: {} as any,
SavedObjectFinder: () => null,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => {
getAllEmbeddableFactories={plugins.embeddable.getEmbeddableFactories}
notifications={core.notifications}
overlays={core.overlays}
application={core.application}
inspector={plugins.inspector}
SavedObjectFinder={getSavedObjectFinder(core.savedObjects, core.uiSettings)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export const EmbeddedMapComponent = ({
notifications={services.notifications}
overlays={services.overlays}
inspector={services.inspector}
application={services.application}
SavedObjectFinder={getSavedObjectFinder(services.savedObjects, services.uiSettings)}
/>
) : !isLoading && isIndexError ? (
Expand Down