Skip to content

Commit

Permalink
Dashboard embeddable plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
stacey-gammon committed Jun 19, 2019
1 parent d75ec76 commit 7c69835
Show file tree
Hide file tree
Showing 42 changed files with 2,347 additions and 6 deletions.
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"inputControl": "src/legacy/core_plugins/input_control_vis",
"inspectorViews": "src/legacy/core_plugins/inspector_views",
"interpreter": "src/legacy/core_plugins/interpreter",
"dashboardEmbeddableContainer": "src/legacy/core_plugins/dashboard_embeddable_container",
"kbn": "src/legacy/core_plugins/kibana",
"kbnDocViews": "src/legacy/core_plugins/kbn_doc_views",
"embeddableApi": "src/legacy/core_plugins/embeddable_api",
Expand Down
33 changes: 33 additions & 0 deletions src/legacy/core_plugins/dashboard_embeddable_container/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { resolve } from 'path';

// eslint-disable-next-line import/no-default-export
export default function(kibana: any) {
return new kibana.Plugin({
uiExports: {
embeddableActions: ['plugins/dashboard_embeddable_container/actions/expand_panel_action'],
embeddableFactories: [
'plugins/dashboard_embeddable_container/embeddable/dashboard_container_factory',
],
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "dashboard_embeddable_container",
"version": "kibana"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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 '../np_core.test.mocks';

import {
isErrorEmbeddable,
createRegistry,
EmbeddableFactory,
} from '../../../embeddable_api/public';
import { ExpandPanelAction } from './expand_panel_action';
import {
ContactCardEmbeddable,
CONTACT_CARD_EMBEDDABLE,
ContactCardEmbeddableInput,
ContactCardEmbeddableOutput,
ContactCardEmbeddableFactory,
} from '../../../embeddable_api/public/test_samples/index';
import { DashboardContainer } from '../embeddable';
import { getSampleDashboardInput, getSampleDashboardPanel } from '../test_helpers';

const embeddableFactories = createRegistry<EmbeddableFactory>();
embeddableFactories.set(CONTACT_CARD_EMBEDDABLE, new ContactCardEmbeddableFactory());

let container: DashboardContainer;
let embeddable: ContactCardEmbeddable;

beforeEach(async () => {
container = new DashboardContainer(
getSampleDashboardInput({
panels: {
'123': getSampleDashboardPanel<ContactCardEmbeddableInput>({
explicitInput: { firstName: 'Sam', id: '123' },
type: CONTACT_CARD_EMBEDDABLE,
}),
},
}),
embeddableFactories
);

const contactCardEmbeddable = await container.addNewEmbeddable<
ContactCardEmbeddableInput,
ContactCardEmbeddableOutput,
ContactCardEmbeddable
>(CONTACT_CARD_EMBEDDABLE, {
firstName: 'Kibana',
});

if (isErrorEmbeddable(contactCardEmbeddable)) {
throw new Error('Failed to create embeddable');
} else {
embeddable = contactCardEmbeddable;
}
});

test('Sets the embeddable expanded panel id on the parent', async () => {
const expandPanelAction = new ExpandPanelAction();

expect(container.getInput().expandedPanelId).toBeUndefined();

expandPanelAction.execute({ embeddable });

expect(container.getInput().expandedPanelId).toBe(embeddable.id);
});

test('Is not compatible when embeddable is not in a dashboard container', async () => {
const action = new ExpandPanelAction();
expect(
await action.isCompatible({
embeddable: new ContactCardEmbeddable({ firstName: 'sue', id: '123' }),
})
).toBe(false);
});

test('Execute throws an error when called with an embeddable not in a parent', async () => {
const action = new ExpandPanelAction();
async function check() {
await action.execute({ embeddable: container });
}
await expect(check()).rejects.toThrow(Error);
});

test('Returns title', async () => {
const action = new ExpandPanelAction();
expect(action.getDisplayName({ embeddable })).toBeDefined();
});

test('Returns an icon', async () => {
const action = new ExpandPanelAction();
expect(action.getIcon({ embeddable })).toBeDefined();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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 { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import {
Action,
actionRegistry,
IEmbeddable,
CONTEXT_MENU_TRIGGER,
triggerRegistry,
ActionContext,
attachAction,
IncompatibleActionError,
} from '../../../embeddable_api/public';
import { DASHBOARD_CONTAINER_TYPE, DashboardContainer } from '../embeddable';

export const EXPAND_PANEL_ACTION = 'togglePanel';

function isDashboard(
embeddable: IEmbeddable | DashboardContainer
): embeddable is DashboardContainer {
return (embeddable as DashboardContainer).type === DASHBOARD_CONTAINER_TYPE;
}

function isExpanded(embeddable: IEmbeddable) {
if (!embeddable.parent || !isDashboard(embeddable.parent)) {
throw new IncompatibleActionError();
}

return embeddable.id === embeddable.parent.getInput().expandedPanelId;
}

export class ExpandPanelAction extends Action {
public readonly type = EXPAND_PANEL_ACTION;

constructor() {
super(EXPAND_PANEL_ACTION);
this.order = 7;
}

public getDisplayName({ embeddable }: ActionContext) {
if (!embeddable.parent || !isDashboard(embeddable.parent)) {
throw new IncompatibleActionError();
}

return isExpanded(embeddable)
? i18n.translate(
'dashboardEmbeddableContainer.actions.toggleExpandPanelMenuItem.expandedDisplayName',
{
defaultMessage: 'Minimize',
}
)
: i18n.translate(
'dashboardEmbeddableContainer.actions.toggleExpandPanelMenuItem.notExpandedDisplayName',
{
defaultMessage: 'Full screen',
}
);
}

public getIcon({ embeddable }: ActionContext) {
if (!embeddable.parent || !isDashboard(embeddable.parent)) {
throw new IncompatibleActionError();
}
// TODO: use 'minimize' when an eui-icon of such is available.
return <EuiIcon type={isExpanded(embeddable) ? 'expand' : 'expand'} />;
}

public async isCompatible({ embeddable }: ActionContext) {
return Boolean(embeddable.parent && isDashboard(embeddable.parent));
}

public execute({ embeddable }: ActionContext) {
if (!embeddable.parent || !isDashboard(embeddable.parent)) {
throw new IncompatibleActionError();
}
const newValue = isExpanded(embeddable) ? undefined : embeddable.id;
embeddable.parent.updateInput({
expandedPanelId: newValue,
});
}
}

actionRegistry.set(EXPAND_PANEL_ACTION, new ExpandPanelAction());

attachAction(triggerRegistry, {
triggerId: CONTEXT_MENU_TRIGGER,
actionId: EXPAND_PANEL_ACTION,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import './viewport/index';
@import './panel/index';
@import './grid/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.
*/

export const DASHBOARD_GRID_COLUMN_COUNT = 48;
export const DASHBOARD_GRID_HEIGHT = 20;
export const DEFAULT_PANEL_WIDTH = DASHBOARD_GRID_COLUMN_COUNT / 2;
export const DEFAULT_PANEL_HEIGHT = 15;
Loading

0 comments on commit 7c69835

Please sign in to comment.