{isModalVisible ? this._elementAdd() : null}
+ {isPanelVisible ? this._embeddableAdd() : null}
+
+ Embed object
+
{
}
};
-const handleMouseDown = (commit, e, canvasOrigin, zoomScale) => {
+const handleMouseDown = (commit, e, canvasOrigin, zoomScale, allowDrag = true) => {
e.stopPropagation();
const { clientX, clientY, buttons, altKey, metaKey, shiftKey, ctrlKey } = e;
if (buttons !== 1 || !commit) {
resetHandler();
return; // left-click only
}
- setupHandler(commit, canvasOrigin, zoomScale);
+
+ if (allowDrag) {
+ setupHandler(commit, canvasOrigin, zoomScale);
+ }
+
const { x, y } = localMousePosition(canvasOrigin, clientX, clientY, zoomScale);
commit('mouseEvent', { event: 'mouseDown', x, y, altKey, metaKey, shiftKey, ctrlKey });
+
+ if (!allowDrag) {
+ commit('mouseEvent', { event: 'mouseUp', x, y, altKey, metaKey, shiftKey, ctrlKey });
+ }
};
export const eventHandlers = {
- onMouseDown: props => e => handleMouseDown(props.commit, e, props.canvasOrigin, props.zoomScale),
+ onMouseDown: props => e =>
+ handleMouseDown(
+ props.commit,
+ e,
+ props.canvasOrigin,
+ props.zoomScale,
+ props.canDragElement(e.target)
+ ),
onMouseMove: props => e => handleMouseMove(props.commit, e, props.canvasOrigin, props.zoomScale),
onMouseLeave: props => e => handleMouseLeave(props.commit, e),
onWheel: props => e => handleMouseMove(props.commit, e, props.canvasOrigin),
diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js
index d3150902fefa7..56ea35a6887ec 100644
--- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js
+++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js
@@ -195,6 +195,11 @@ export const InteractivePage = compose(
withProps(({ commit, forceRerender }) => ({
commit: (...args) => forceRerender(commit(...args)),
})),
+ withProps((...props) => ({
+ ...props,
+ canDragElement: element =>
+ !element.closest('.embeddable') || element.closest('.embPanel__header'),
+ })),
withHandlers(eventHandlers), // Captures user intent, needs to have reconciled state
() => InteractiveComponent
);
diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/interactive_workpad_page.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/interactive_workpad_page.js
index 448e94163d9f8..68f47f35c6fa1 100644
--- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/interactive_workpad_page.js
+++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/interactive_workpad_page.js
@@ -89,6 +89,7 @@ export class InteractiveWorkpadPage extends PureComponent {
onAnimationEnd={onAnimationEnd}
onWheel={onWheel}
>
+
{shortcuts}
{elements
.map(node => {
@@ -127,7 +128,6 @@ export class InteractiveWorkpadPage extends PureComponent {
}
})
.filter(element => !!element)}
-
);
}
diff --git a/x-pack/legacy/plugins/canvas/public/interpreter_expression_types.ts b/x-pack/legacy/plugins/canvas/public/interpreter_expression_types.ts
new file mode 100644
index 0000000000000..e443f7e40879f
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/public/interpreter_expression_types.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { typesRegistry } from '../../../../../src/legacy/core_plugins/interpreter/public/registries';
+import { typeFunctions } from '../canvas_plugin_src/expression_types';
+
+typeFunctions.forEach(r => {
+ typesRegistry.register(r);
+});
diff --git a/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.test.ts b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.test.ts
new file mode 100644
index 0000000000000..d1632fc3eef28
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.test.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { buildEmbeddableFilters } from './build_embeddable_filters';
+import { Filter } from '../../types';
+
+const columnFilter: Filter = {
+ and: [],
+ value: 'filter-value',
+ column: 'filter-column',
+ type: 'exactly',
+};
+
+const timeFilter: Filter = {
+ and: [],
+ column: 'time-column',
+ type: 'time',
+ from: '2019-06-04T04:00:00.000Z',
+ to: '2019-06-05T04:00:00.000Z',
+};
+
+describe('buildEmbeddableFilters', () => {
+ it('converts non time Canvas Filters to ES Filters ', () => {
+ const filters = buildEmbeddableFilters([timeFilter, columnFilter, columnFilter]);
+
+ expect(filters.filters).toHaveLength(2);
+ });
+
+ it('converts time filter to time range', () => {
+ const filters = buildEmbeddableFilters([timeFilter]);
+
+ expect(filters.timeRange!.from).toBe(timeFilter.from);
+ expect(filters.timeRange!.to).toBe(timeFilter.to);
+ });
+});
diff --git a/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts
new file mode 100644
index 0000000000000..b97d520de5c5a
--- /dev/null
+++ b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { buildQueryFilter, Filter as ESFilterType } from '@kbn/es-query';
+import { TimeRange } from 'ui/timefilter/time_history';
+import { Filter } from '../../types';
+// @ts-ignore Untyped Local
+import { buildBoolArray } from './build_bool_array';
+
+export interface EmbeddableFilterInput {
+ filters: ESFilterType[];
+ timeRange?: TimeRange;
+}
+
+const TimeFilterType = 'time';
+
+function getTimeRangeFromFilters(filters: Filter[]): TimeRange | undefined {
+ const timeFilter = filters.find(
+ filter => filter.type !== undefined && filter.type === TimeFilterType
+ );
+
+ return timeFilter !== undefined && timeFilter.from !== undefined && timeFilter.to !== undefined
+ ? {
+ from: timeFilter.from,
+ to: timeFilter.to,
+ }
+ : undefined;
+}
+
+function getQueryFilters(filters: Filter[]): ESFilterType[] {
+ return buildBoolArray(filters.filter(filter => filter.type !== 'time')).map(buildQueryFilter);
+}
+
+export function buildEmbeddableFilters(filters: Filter[]): EmbeddableFilterInput {
+ return {
+ timeRange: getTimeRangeFromFilters(filters),
+ filters: getQueryFilters(filters),
+ };
+}