Skip to content

Commit

Permalink
[Embeddable Rebuild] [Controls] Refactor control editing + creation (#…
Browse files Browse the repository at this point in the history
…187606)

Closes #187504

## Summary

This PR changes how control creation/editing is handled in the new
system by changing from a state manager to an explicit `initialState` +
`updateState` callback structure. Unfortunately, the `stateManager`
system really only works if we had inline creation for controls - since
we don't have that, the embeddable (and hence the `stateManager`)
doesn't exist until **after** the editor is saved. Therefore, especially
with respect to the custom options component, we had no way of knowing
what keys the `stateManager` should include when trying to create a new
control. The new system isn't quite as clean IMO, but it works better
for our current goals with this refactor. We can revisit the
`stateManager` idea once controls support inline editing 👍

This PR also fixes a few visual bugs, noted below.

### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
Heenawter and kibanamachine committed Jul 17, 2024
1 parent fcf2702 commit 23bb3c1
Show file tree
Hide file tree
Showing 17 changed files with 649 additions and 231 deletions.
37 changes: 36 additions & 1 deletion examples/controls_example/public/app/react_control_example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
EuiSuperDatePicker,
OnTimeChangeProps,
} from '@elastic/eui';
import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common';
import {
CONTROL_GROUP_TYPE,
DEFAULT_CONTROL_GROW,
DEFAULT_CONTROL_WIDTH,
} from '@kbn/controls-plugin/common';
import { CoreStart } from '@kbn/core/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { ReactEmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public';
Expand All @@ -39,6 +43,7 @@ import { ControlGroupApi } from '../react_controls/control_group/types';
import { RANGE_SLIDER_CONTROL_TYPE } from '../react_controls/data_controls/range_slider/types';
import { SEARCH_CONTROL_TYPE } from '../react_controls/data_controls/search_control/types';
import { TIMESLIDER_CONTROL_TYPE } from '../react_controls/timeslider_control/types';
import { openDataControlEditor } from '../react_controls/data_controls/open_data_control_editor';

const toggleViewButtons = [
{
Expand Down Expand Up @@ -167,6 +172,7 @@ export const ReactControlExample = ({
addNewPanel: () => {
return Promise.resolve(undefined);
},
lastUsedDataViewId: new BehaviorSubject<string>(WEB_LOGS_DATA_VIEW_ID),
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Expand Down Expand Up @@ -282,6 +288,35 @@ export const ReactControlExample = ({
Serialize control group
</EuiButton>
</EuiFlexItem>
{controlGroupApi && (
<EuiFlexItem grow={false}>
<EuiButton
onClick={() => {
openDataControlEditor({
initialState: {
grow: DEFAULT_CONTROL_GROW,
width: DEFAULT_CONTROL_WIDTH,
dataViewId: dashboardApi.lastUsedDataViewId.getValue(),
},
onSave: ({ type: controlType, state: initialState }) => {
controlGroupApi.addNewPanel({
panelType: controlType,
initialState,
});
},
controlGroupApi,
services: {
core,
dataViews: dataViewsService,
},
});
}}
size="s"
>
Add new data control
</EuiButton>
</EuiFlexItem>
)}
<EuiFlexItem grow={false}>
<EuiButtonGroup
legend="Change the view mode"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import React, { useEffect } from 'react';
import { BehaviorSubject } from 'rxjs';

import { EuiFlexGroup } from '@elastic/eui';
import {
ControlGroupChainingSystem,
ControlWidth,
Expand All @@ -34,8 +36,9 @@ import {
useStateFromPublishingSubject,
} from '@kbn/presentation-publishing';

import { EuiFlexGroup } from '@elastic/eui';
import { ControlRenderer } from '../control_renderer';
import { chaining$, controlFetch$, controlGroupFetch$ } from './control_fetch';
import { initControlsManager } from './init_controls_manager';
import { openEditControlGroupFlyout } from './open_edit_control_group_flyout';
import { deserializeControlGroup } from './serialization_utils';
import {
Expand All @@ -44,8 +47,6 @@ import {
ControlGroupSerializedState,
ControlGroupUnsavedChanges,
} from './types';
import { initControlsManager } from './init_controls_manager';
import { controlGroupFetch$, chaining$, controlFetch$ } from './control_fetch';

export const getControlGroupEmbeddableFactory = (services: {
core: CoreStart;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.controlPanel {
width: 100%;
max-inline-size: 100% !important;
height: calc($euiButtonHeight - 2px);
height: $euiButtonHeight;
box-shadow: none !important;
background-color: $euiFormBackgroundColor !important;

Expand All @@ -10,14 +10,16 @@
border-radius: $euiBorderRadius !important;
}

&--label {
@include euiTextTruncate;
&--labelWrapper {
max-width: 40%;
background-color: transparent;
border-radius: $euiBorderRadius;

margin-left: 0 !important;
padding-left: 0 !important;
.controlPanel--label {
@include euiTextTruncate;
background-color: transparent;
border-radius: $euiBorderRadius;
margin-left: 0 !important;
padding-left: 0 !important;
}
}

&--hideComponent {
Expand Down
21 changes: 17 additions & 4 deletions examples/controls_example/public/react_controls/control_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
import classNames from 'classnames';
import React, { useState } from 'react';

import { EuiFlexItem, EuiFormControlLayout, EuiFormLabel, EuiFormRow, EuiIcon } from '@elastic/eui';
import {
EuiFlexItem,
EuiFormControlLayout,
EuiFormLabel,
EuiFormRow,
EuiIcon,
EuiToolTip,
} from '@elastic/eui';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import {
Expand Down Expand Up @@ -135,12 +142,18 @@ export const ControlPanel = <ApiType extends DefaultControlApi = DefaultControlA
controlTitle={panelTitle || defaultPanelTitle}
hideEmptyDragHandle={usingTwoLineLayout || Boolean(api?.CustomPrependComponent)}
/>

{api?.CustomPrependComponent ? (
<api.CustomPrependComponent />
) : usingTwoLineLayout ? null : (
<EuiFormLabel className="controlPanel--label">
{panelTitle || defaultPanelTitle}
</EuiFormLabel>
<EuiToolTip
anchorClassName="controlPanel--labelWrapper"
content={panelTitle || defaultPanelTitle}
>
<EuiFormLabel className="controlPanel--label">
{panelTitle || defaultPanelTitle}
</EuiFormLabel>
</EuiToolTip>
)}
</>
}
Expand Down
Loading

0 comments on commit 23bb3c1

Please sign in to comment.