Skip to content

Commit

Permalink
provide static container context on embeddable panel
Browse files Browse the repository at this point in the history
  • Loading branch information
Dosant authored and cqliu1 committed Nov 23, 2021
1 parent dae4625 commit c20a6f3
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/plugins/embeddable/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export {
EmbeddableStateTransfer,
EmbeddableRenderer,
useEmbeddableFactory,
EmbeddableContainerContext,
} from './lib';

export { AttributeService, ATTRIBUTE_SERVICE_KEY } from './lib/attribute_service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,6 @@ class EditableEmbeddable extends Embeddable {
public reload() {}
}

let originalLocation: Window['location'];
const testPath = '#/path/to/current/app';

beforeAll(async () => {
originalLocation = window.location;
window.location.hash = testPath;
});

afterAll(async () => {
window.location = originalLocation;
});

test('is compatible when edit url is available, in edit mode and editable', async () => {
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
expect(
Expand All @@ -56,7 +44,13 @@ test('is compatible when edit url is available, in edit mode and editable', asyn

test('redirects to app using state transfer with by value mode', async () => {
applicationMock.currentAppId$ = of('superCoolCurrentApp');
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
const testPath = '/test-path';
const action = new EditPanelAction(
getFactory,
applicationMock,
stateTransferMock,
() => testPath
);
const embeddable = new EditableEmbeddable(
{
id: '123',
Expand Down Expand Up @@ -86,7 +80,13 @@ test('redirects to app using state transfer with by value mode', async () => {

test('redirects to app using state transfer without by value mode', async () => {
applicationMock.currentAppId$ = of('superCoolCurrentApp');
const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock);
const testPath = '/test-path';
const action = new EditPanelAction(
getFactory,
applicationMock,
stateTransferMock,
() => testPath
);
const embeddable = new EditableEmbeddable(
{ id: '123', viewMode: ViewMode.EDIT, savedObjectId: '1234' } as SavedObjectEmbeddableInput,
true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export class EditPanelAction implements Action<ActionContext> {
constructor(
private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'],
private readonly application: ApplicationStart,
private readonly stateTransfer?: EmbeddableStateTransfer
private readonly stateTransfer?: EmbeddableStateTransfer,
private readonly getOriginatingPath?: () => string
) {
if (this.application?.currentAppId$) {
this.application.currentAppId$
Expand Down Expand Up @@ -109,10 +110,7 @@ export class EditPanelAction implements Action<ActionContext> {
if (this.currentAppId) {
const byValueMode = !(embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId;

const originatingPath = window.location.href.replace(
`${window.location.origin}${window.location.pathname}`,
''
);
const originatingPath = this.getOriginatingPath?.();

const state: EmbeddableEditorState = {
originatingApp: this.currentAppId,
Expand Down
16 changes: 15 additions & 1 deletion src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ const removeById =
({ id }: { id: string }) =>
disabledActions.indexOf(id) === -1;

/**
* Embeddable container may provide information about its environment,
* Use it for drilling down data that is static or doesn't have to be reactive,
* otherwise prefer passing data with input$
* */
export interface EmbeddableContainerContext {
/**
* Current app's path including query and hash starting from {appId}
*/
getCurrentPath?: () => string;
}

interface Props {
embeddable: IEmbeddable<EmbeddableInput, EmbeddableOutput>;
getActions: UiActionsService['getTriggerCompatibleActions'];
Expand All @@ -70,6 +82,7 @@ interface Props {
showShadow?: boolean;
showBadges?: boolean;
showNotifications?: boolean;
containerContext?: EmbeddableContainerContext;
}

interface State {
Expand Down Expand Up @@ -373,7 +386,8 @@ export class EmbeddablePanel extends React.Component<Props, State> {
editPanel: new EditPanelAction(
this.props.getEmbeddableFactory,
this.props.application,
this.props.stateTransfer
this.props.stateTransfer,
this.props.containerContext?.getCurrentPath
),
};
};
Expand Down
18 changes: 16 additions & 2 deletions src/plugins/embeddable/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
IEmbeddable,
EmbeddablePanel,
SavedObjectEmbeddableInput,
EmbeddableContainerContext,
} from './lib';
import { EmbeddableFactoryDefinition } from './lib/embeddables/embeddable_factory_definition';
import { EmbeddableStateTransfer } from './lib/state_transfer';
Expand Down Expand Up @@ -97,7 +98,11 @@ export interface EmbeddableStart extends PersistableStateService<EmbeddableState
) => AttributeService<A, V, R>;
}

export type EmbeddablePanelHOC = React.FC<{ embeddable: IEmbeddable; hideHeader?: boolean }>;
export type EmbeddablePanelHOC = React.FC<{
embeddable: IEmbeddable;
hideHeader?: boolean;
containerContext?: EmbeddableContainerContext;
}>;

export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, EmbeddableStart> {
private readonly embeddableFactoryDefinitions: Map<string, EmbeddableFactoryDefinition> =
Expand Down Expand Up @@ -155,7 +160,15 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl

const getEmbeddablePanelHoc =
() =>
({ embeddable, hideHeader }: { embeddable: IEmbeddable; hideHeader?: boolean }) =>
({
embeddable,
hideHeader,
containerContext,
}: {
embeddable: IEmbeddable;
hideHeader?: boolean;
containerContext?: EmbeddableContainerContext;
}) =>
(
<EmbeddablePanel
hideHeader={hideHeader}
Expand All @@ -169,6 +182,7 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
application={core.application}
inspector={inspector}
SavedObjectFinder={getSavedObjectFinder(core.savedObjects, core.uiSettings)}
containerContext={containerContext}
/>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { RendererStrings } from '../../../i18n';
import { embeddableInputToExpression } from './embeddable_input_to_expression';
import { RendererFactory, EmbeddableInput } from '../../../types';
import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib';
import type { EmbeddableContainerContext } from '../../../../../../src/plugins/embeddable/public/';

const { embeddable: strings } = RendererStrings;

Expand All @@ -31,14 +32,21 @@ const embeddablesRegistry: {
const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => {
const I18nContext = core.i18n.Context;

const embeddableContainerContext: EmbeddableContainerContext = {
getCurrentPath: () => window.location.hash,
};

return (embeddableObject: IEmbeddable) => {
return (
<div
className={CANVAS_EMBEDDABLE_CLASSNAME}
style={{ width: '100%', height: '100%', cursor: 'auto' }}
>
<I18nContext>
<plugins.embeddable.EmbeddablePanel embeddable={embeddableObject} />
<plugins.embeddable.EmbeddablePanel
embeddable={embeddableObject}
containerContext={embeddableContainerContext}
/>
</I18nContext>
</div>
);
Expand Down

0 comments on commit c20a6f3

Please sign in to comment.