Skip to content

Commit

Permalink
[Controls] Move Controls To Their Own Plugin (#121668)
Browse files Browse the repository at this point in the history
* Moved controls out of Presentation Util and into their own plugin
  • Loading branch information
ThomThomson committed Jan 6, 2022
1 parent 47c39a2 commit 825ea5b
Show file tree
Hide file tree
Showing 119 changed files with 1,203 additions and 544 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
/src/plugins/input_control_vis/ @elastic/kibana-presentation
/src/plugins/vis_type_markdown/ @elastic/kibana-presentation
/src/plugins/presentation_util/ @elastic/kibana-presentation
/src/plugins/controls/ @elastic/kibana-presentation
/test/functional/apps/dashboard/ @elastic/kibana-presentation
/test/functional/apps/dashboard_elements/ @elastic/kibana-presentation
/x-pack/plugins/canvas/ @elastic/kibana-presentation
Expand Down
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"discover": "src/plugins/discover",
"bfetch": "src/plugins/bfetch",
"dashboard": "src/plugins/dashboard",
"controls": "src/plugins/controls",
"data": "src/plugins/data",
"dataViews": "src/plugins/data_views",
"embeddableApi": "src/plugins/embeddable",
Expand Down
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ as uiSettings within the code.
|Console provides the user with tools for storing and executing requests against Elasticsearch.
|{kib-repo}blob/{branch}/src/plugins/controls/README.mdx[controls]
|The Controls plugin contains Embeddables which can be used to add user-friendly interactivity to apps.
|{kib-repo}blob/{branch}/src/plugins/custom_integrations/README.md[customIntegrations]
|Register add-data cards
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pageLoadAssetSize:
watcher: 43598
runtimeFields: 41752
stackAlerts: 29684
presentationUtil: 84606
presentationUtil: 58834
osquery: 107090
fileUpload: 25664
dataVisualizer: 27530
Expand Down Expand Up @@ -119,4 +119,5 @@ pageLoadAssetSize:
visTypeHeatmap: 25340
screenshotting: 17017
expressionGauge: 25000
controls: 34788
expressionPie: 26338
1 change: 1 addition & 0 deletions src/dev/storybook/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export const storybookAliases = {
ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/.storybook',
observability: 'x-pack/plugins/observability/.storybook',
presentation: 'src/plugins/presentation_util/storybook',
controls: 'src/plugins/controls/storybook',
lists: 'x-pack/plugins/lists/.storybook',
};
25 changes: 25 additions & 0 deletions src/plugins/controls/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
id: controls
slug: /kibana-dev-docs/controls
title: Controls Plugin
summary: Introduction to the Controls Plugin.
date: 2020-01-12
tags: ['kibana', 'controls', 'dashboard']
related: []
---

## Introduction

The Controls plugin contains Embeddables which can be used to add user-friendly interactivity to apps.

## The Control Group

The Control group is an embeddable container which provides the ability to add, remove, reorder, and edit multiple types of control embeddable. In any implementation, the control group embeddable should be the main point of contact between the application and the controls. The list of filters it sends to its output observable should be considered the final output of the current state of the controls, and can then be sent to other embeddables, or combined with filters from other sources.

## Control Types

Multiple types of controls can be registered to work with the Control Group. The current implementations are as follows:

### Options List

The options list is the most basic, and most used control type. It allows the dashboard author to specify a data view and field, and create a searchable dropdown.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import {
EmbeddableInput,
EmbeddablePersistableStateService,
EmbeddableStateWithType,
} from '../../../../embeddable/common/types';
} from '../../../embeddable/common/types';
import { ControlGroupInput, ControlPanelState } from './types';
import { SavedObjectReference } from '../../../../../core/types';
import { SavedObjectReference } from '../../../../core/types';

type ControlGroupInputWithType = Partial<ControlGroupInput> & { type: string };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { EmbeddableInput, PanelState } from '../../../../embeddable/common/types';
import { EmbeddableInput, PanelState } from '../../../embeddable/common/types';
import { ControlInput, ControlStyle, ControlWidth } from '../types';

export const CONTROL_GROUP_TYPE = 'control_group';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import {
EmbeddableStateWithType,
EmbeddablePersistableStateService,
} from '../../../../../embeddable/common/types';
} from '../../../../embeddable/common';
import { OptionsListEmbeddableInput } from './types';
import { SavedObjectReference } from '../../../../../../core/types';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '../../../../../data_views/common';
import { SavedObjectReference } from '../../../../../core/types';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '../../../../data_views/common';

type OptionsListInputWithType = Partial<OptionsListEmbeddableInput> & { type: string };
const dataViewReferenceName = 'optionsListDataView';
Expand Down
14 changes: 14 additions & 0 deletions src/plugins/controls/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export type { ControlPanelState, ControlsPanels, ControlGroupInput } from './control_group/types';
export type { OptionsListEmbeddableInput } from './control_types/options_list/types';
export type { ControlWidth } from './types';

export { OPTIONS_LIST_CONTROL } from './control_types/options_list/types';
export { CONTROL_GROUP_TYPE } from './control_group/types';
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
*/

import { Filter, Query } from '@kbn/es-query';
import { TimeRange } from '../../../data/common';
import { EmbeddableInput } from '../../../embeddable/common/types';
import { TimeRange } from '../../data/common';
import { EmbeddableInput } from '../../embeddable/common/types';

export type ControlWidth = 'auto' | 'small' | 'medium' | 'large';
export type ControlStyle = 'twoLine' | 'oneLine';
Expand Down
23 changes: 23 additions & 0 deletions src/plugins/controls/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "controls",
"owner": {
"name": "Kibana Presentation",
"githubTeam": "kibana-presentation"
},
"description": "The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls",
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": true,
"ui": true,
"extraPublicDirs": ["common"],
"requiredPlugins": [
"presentationUtil",
"savedObjects",
"kibanaReact",
"expressions",
"embeddable",
"dataViews",
"data"
],
"optionalPlugins": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,35 @@
import { EuiFlexGroup, EuiFlexItem, EuiSwitch, EuiTextAlign } from '@elastic/eui';
import React, { useEffect, useMemo, useState, useCallback, FC } from 'react';
import useEffectOnce from 'react-use/lib/useEffectOnce';

import uuid from 'uuid';

import {
getFlightOptionsAsync,
storybookFlightsDataView,
} from '../../../presentation_util/public/mocks';
import {
ControlGroupContainerFactory,
OptionsListEmbeddableInput,
OPTIONS_LIST_CONTROL,
} from '../';

import { ViewMode } from '../../../embeddable/public';
import { EmbeddablePersistableStateService } from '../../../embeddable/common';

import { decorators } from './decorators';
import { ControlsPanels } from '../control_group/types';
import { ViewMode } from '../../../../../embeddable/public';
import { getFlightOptionsAsync, storybookFlightsDataView } from './fixtures/flights';
import { pluginServices, registry } from '../../../services/storybook';
import { OptionsListEmbeddableInput, OPTIONS_LIST_CONTROL } from '../../..';
import { replaceValueSuggestionMethod } from '../../../services/storybook/data';
import { injectStorybookDataView } from '../../../services/storybook/data_views';
import { ControlGroupContainer } from '../control_group';
import { pluginServices, registry } from '../services/storybook';
import { replaceValueSuggestionMethod } from '../services/storybook/data';
import { injectStorybookDataView } from '../services/storybook/data_views';
import { populateStorybookControlFactories } from './storybook_control_factories';
import { EmbeddablePersistableStateService } from '../../../../../embeddable/common';
import { ControlGroupContainerFactory } from '../control_group/embeddable/control_group_container_factory';

export default {
title: 'Controls',
description: '',
decorators,
};

type EmbeddableType = Awaited<ReturnType<ControlGroupContainerFactory['create']>>;

injectStorybookDataView(storybookFlightsDataView);
replaceValueSuggestionMethod(getFlightOptionsAsync);

Expand All @@ -39,7 +46,7 @@ const ControlGroupStoryComponent: FC<{
edit?: boolean;
}> = ({ panels, edit }) => {
const embeddableRoot: React.RefObject<HTMLDivElement> = useMemo(() => React.createRef(), []);
const [embeddable, setEmbeddable] = useState<EmbeddableType>();
const [embeddable, setEmbeddable] = useState<ControlGroupContainer>();
const [viewMode, setViewMode] = useState<ViewMode>(
edit === undefined || edit ? ViewMode.EDIT : ViewMode.VIEW
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
*/

import { OptionsListEmbeddableFactory } from '../control_types/options_list';
import { PresentationControlsService } from '../../../services/controls';
import { ControlsService } from '../services/controls';
import { ControlFactory } from '..';

export const populateStorybookControlFactories = (
controlsServiceStub: PresentationControlsService
) => {
export const populateStorybookControlFactories = (controlsServiceStub: ControlsService) => {
const optionsListFactoryStub = new OptionsListEmbeddableFactory();

// cast to unknown because the stub cannot use the embeddable start contract to transform the EmbeddableFactoryDefinition into an EmbeddableFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import {
} from '@elastic/eui';

import { ControlGroupInput } from '../types';
import { pluginServices } from '../../services';
import { EditControlButton } from '../editor/edit_control';
import { useChildEmbeddable } from '../../hooks/use_child_embeddable';
import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context';
import { ControlGroupStrings } from '../control_group_strings';
import { pluginServices } from '../../../../services';
import { useChildEmbeddable } from '../../hooks/use_child_embeddable';
import { useReduxContainerContext } from '../../../../presentation_util/public';

export interface ControlFrameProps {
customPrepend?: JSX.Element;
Expand All @@ -38,7 +38,7 @@ export const ControlFrame = ({ customPrepend, enableActions, embeddableId }: Con
} = useReduxContainerContext<ControlGroupInput>();
const { controlStyle } = useEmbeddableSelector((state) => state);

// Presentation Services Context
// Controls Services Context
const { overlays } = pluginServices.getHooks();
const { openConfirm } = overlays.useService();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ import {
} from '@dnd-kit/core';

import { ControlGroupInput } from '../types';
import { pluginServices } from '../../../../services';
import { pluginServices } from '../../services';
import { ViewMode } from '../../../../embeddable/public';
import { ControlGroupStrings } from '../control_group_strings';
import { CreateControlButton } from '../editor/create_control';
import { ViewMode } from '../../../../../../embeddable/public';
import { EditControlGroup } from '../editor/edit_control_group';
import { forwardAllContext } from '../editor/forward_all_context';
import { controlGroupReducers } from '../state/control_group_reducers';
import { ControlClone, SortableControl } from './control_group_sortable_item';
import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context';
import { useReduxContainerContext } from '../../../../presentation_util/public';

export const ControlGroup = () => {
// Presentation Services Context
// Controls Services Context
const { overlays } = pluginServices.getHooks();
const { openFlyout } = overlays.useService();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import classNames from 'classnames';

import { ControlGroupInput } from '../types';
import { ControlFrame, ControlFrameProps } from './control_frame_component';
import { useReduxContainerContext } from '../../../redux_embeddables/redux_embeddable_context';
import { useReduxContainerContext } from '../../../../presentation_util/public';

interface DragInfo {
isOver?: boolean;
Expand Down

0 comments on commit 825ea5b

Please sign in to comment.