Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate react control group embeddable into dashboard container #190273

Merged
merged 109 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
7936e9f
render empty control group
nreese Aug 6, 2024
a42343a
add time slider control
nreese Aug 7, 2024
c6116f8
Merge remote-tracking branch 'upstream/main' into dashboard_container…
nreese Aug 7, 2024
e4ce369
write timeslice
nreese Aug 7, 2024
d104f98
dashboard dataLoading
nreese Aug 7, 2024
b5dce18
clean up
nreese Aug 7, 2024
e59ef31
Merge remote-tracking branch 'upstream/main' into dashboard_container…
nreese Aug 9, 2024
8f4b7ad
clean up imports
nreese Aug 9, 2024
68bb622
clean up
nreese Aug 9, 2024
6a31b9b
add control button
nreese Aug 9, 2024
cdd2237
edit control group settings
nreese Aug 9, 2024
9b1ef21
unifiedSearchFilters$
nreese Aug 9, 2024
3974fc1
getSerializedStateForChild pass controlGroupInput
nreese Aug 10, 2024
1ad602f
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 12, 2024
4185328
update startSyncingDashboardDataViews for controlGroupApi
nreese Aug 12, 2024
c7dd0a6
update DashboardViewport to subscribe to hasControls
nreese Aug 12, 2024
bf89d4f
remove parsing panelsJSON
nreese Aug 12, 2024
5b4f99a
backup controlGroupApi unsaved changes
nreese Aug 12, 2024
d83834a
clean up
nreese Aug 12, 2024
57132a4
useStateFromPublishingSubject
nreese Aug 12, 2024
cfb96d5
fix loading error
nreese Aug 12, 2024
b5c37e1
async reset
nreese Aug 12, 2024
db9075a
remove controlGroup from DashboardContainer
nreese Aug 12, 2024
0368198
move startSyncingDashboardControlGroup to constructor
nreese Aug 13, 2024
106c0a2
save control group
nreese Aug 13, 2024
6ff481d
fix add timeslider
nreese Aug 13, 2024
30498d1
display timeslider default title
nreese Aug 13, 2024
2193b7a
remove unused imports
nreese Aug 13, 2024
4196b0e
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 13, 2024
8a50e5a
get runtime state working
nreese Aug 14, 2024
8478b96
eslint
nreese Aug 14, 2024
879f0d8
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 14, 2024
60a9edf
fix jest tests
nreese Aug 14, 2024
8abb70e
tslint
nreese Aug 14, 2024
bd55151
use override controlGroupInput
nreese Aug 14, 2024
0385627
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 14, 2024
81e409b
add data-test-subj controls-group-wrapper
nreese Aug 14, 2024
6aabbc8
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 15, 2024
42ce392
fix failing test
nreese Aug 15, 2024
43edd45
eslint
nreese Aug 15, 2024
cda1cdd
key from dashboard id, not saved object id
nreese Aug 15, 2024
101c493
fix dashboard_container jest test
nreese Aug 15, 2024
bfbb1a9
fix test test/functional/apps/dashboard_elements/controls/options_lis…
nreese Aug 15, 2024
eecc544
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 15, 2024
7b9b423
tslint
nreese Aug 15, 2024
1a1cc2e
revert small change
nreese Aug 15, 2024
3f15622
clean up
nreese Aug 15, 2024
f0a7f64
fix test x-pack/test/functional/apps/dashboard/group2/migration_smoke…
nreese Aug 16, 2024
f20a37f
fix test test/functional/apps/dashboard_elements/controls/options_lis…
nreese Aug 16, 2024
aec0041
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Aug 16, 2024
3d81d51
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 16, 2024
fa502fa
fix issue with restting and leaving orphaned controls
nreese Aug 16, 2024
44a6583
signal to parent that overlay is closed when delete all executes
nreese Aug 16, 2024
998e9f2
eslint
nreese Aug 16, 2024
944cef3
fix query$ subject changing after save
nreese Aug 19, 2024
f9e8c81
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 19, 2024
6e93f3d
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 20, 2024
2a9d109
serialize options list control properly
nreese Aug 20, 2024
fa775e0
merge with main
nreese Aug 22, 2024
9eb71a5
do not load embeddables until control group is initialized
nreese Aug 22, 2024
cbd923b
fix test and eslint
nreese Aug 22, 2024
800f42b
merge with main
nreese Aug 22, 2024
17c90a8
fix more tests
nreese Aug 22, 2024
a0f3cd5
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Aug 22, 2024
bdd1479
round min and max
nreese Aug 23, 2024
82c641f
fix options list test
nreese Aug 23, 2024
2eb588a
update initialChildControlState
nreese Aug 23, 2024
2f911ef
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 23, 2024
af53432
fix timeslider test
nreese Aug 23, 2024
25a075f
fix option list sort comparator
nreese Aug 23, 2024
d2cd031
fix unsaved changes
nreese Aug 23, 2024
01f87ef
clean up
nreese Aug 23, 2024
aeca77e
remove only in test
nreese Aug 23, 2024
f12f4bd
fix dashboard_grid jest test
nreese Aug 23, 2024
e7e58dc
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 23, 2024
723b718
fix test
nreese Aug 24, 2024
f16a57a
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 24, 2024
5d25151
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 25, 2024
505020e
remove console.logs
nreese Aug 25, 2024
6c3d163
fix issue where empty enhancments was keeping unsaved state
nreese Aug 25, 2024
13f7707
fix control_group_apply_button.ts
nreese Aug 26, 2024
9b49e33
fix options_list_validation.ts test
nreese Aug 26, 2024
9e374b7
move selections into saved test object
nreese Aug 26, 2024
19ce11d
add skip until feature is fixed
nreese Aug 26, 2024
7d6ea91
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Aug 26, 2024
7596ea1
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 26, 2024
9daaa80
fix test
nreese Aug 26, 2024
44b34a7
fix test/functional/apps/dashboard_elements/controls/common/replace_c…
nreese Aug 26, 2024
29605d9
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 27, 2024
5347c83
fix test/functional/apps/dashboard_elements/controls/common/multiple_…
nreese Aug 27, 2024
eab7edc
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 27, 2024
5c2e88d
remove skipped test now that issue is resolved in main
nreese Aug 27, 2024
af90f4f
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 28, 2024
58e6fdf
fix test/functional/apps/dashboard_elements/controls/options_list/opt…
nreese Aug 28, 2024
55be9ce
resolve issue where timeslider movement caused controls to left to up…
nreese Aug 28, 2024
0f36a16
Update src/plugins/dashboard/public/dashboard_container/embeddable/da…
nreese Aug 28, 2024
00054bb
fix restore deleted control on reset
nreese Aug 29, 2024
101d71d
apply selections on save
nreese Aug 29, 2024
f51fb5f
show ControlsToolbarButton while controlsGroupApi loads
nreese Aug 29, 2024
86b747b
fix missing comma
nreese Aug 29, 2024
84aae81
use dashboard input id instead of dashboard id
nreese Aug 29, 2024
ad2d7ba
keep reference names the same
nreese Aug 29, 2024
ea45ab9
fix test
nreese Aug 29, 2024
8c4265c
initialControlsState
nreese Aug 29, 2024
50e2ded
cleanup
nreese Aug 29, 2024
540569a
fix typo in name
nreese Aug 29, 2024
a6513f5
add id to explicit input on serialize
nreese Aug 29, 2024
158bc6e
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 29, 2024
3844856
Merge branch 'main' into dashboard_container_control_group
elasticmachine Aug 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ const initialSerializedControlGroupState = {
} as object,
references: [
{
name: `controlGroup_${rangeSliderControlId}:${RANGE_SLIDER_CONTROL}DataView`,
name: `controlGroup_${rangeSliderControlId}:rangeSliderDataView`,
type: 'index-pattern',
id: WEB_LOGS_DATA_VIEW_ID,
},
{
name: `controlGroup_${optionsListId}:${OPTIONS_LIST_CONTROL}DataView`,
name: `controlGroup_${optionsListId}:optionsListDataView`,
type: 'index-pattern',
id: WEB_LOGS_DATA_VIEW_ID,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import React, { useEffect, useState } from 'react';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { controlGroupInputBuilder } from '@kbn/controls-plugin/public';
import { getDefaultControlGroupInput } from '@kbn/controls-plugin/common';
import { controlGroupStateBuilder } from '@kbn/controls-plugin/public';
import {
AwaitingDashboardAPI,
DashboardRenderer,
Expand Down Expand Up @@ -63,16 +62,15 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView
<EuiPanel hasBorder={true}>
<DashboardRenderer
getCreationOptions={async (): Promise<DashboardCreationOptions> => {
const builder = controlGroupInputBuilder;
const controlGroupInput = getDefaultControlGroupInput();
await builder.addDataControlFromField(controlGroupInput, {
const controlGroupState = {};
await controlGroupStateBuilder.addDataControlFromField(controlGroupState, {
dataViewId: dataView.id ?? '',
title: 'Destintion country',
fieldName: 'geo.dest',
width: 'medium',
grow: false,
});
await builder.addDataControlFromField(controlGroupInput, {
await controlGroupStateBuilder.addDataControlFromField(controlGroupState, {
dataViewId: dataView.id ?? '',
fieldName: 'bytes',
width: 'medium',
Expand All @@ -85,7 +83,7 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView
getInitialInput: () => ({
timeRange: { from: 'now-30d', to: 'now' },
viewMode: ViewMode.VIEW,
controlGroupInput,
controlGroupState,
}),
};
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import deepEqual from 'fast-deep-equal';
import { SerializableRecord } from '@kbn/utility-types';

import { v4 } from 'uuid';
import { pick, omit, xor } from 'lodash';

import {
Expand All @@ -23,7 +22,6 @@ import {
} from './control_group_panel_diff_system';
import { ControlGroupInput } from '..';
import {
ControlsPanels,
PersistableControlGroupInput,
persistableControlGroupInputKeys,
RawControlGroupAttributes,
Expand Down Expand Up @@ -103,32 +101,6 @@ const getPanelsAreEqual = (
return true;
};

export const controlGroupInputToRawControlGroupAttributes = (
controlGroupInput: Omit<ControlGroupInput, 'id'>
): RawControlGroupAttributes => {
return {
controlStyle: controlGroupInput.controlStyle,
chainingSystem: controlGroupInput.chainingSystem,
showApplySelections: controlGroupInput.showApplySelections,
panelsJSON: JSON.stringify(controlGroupInput.panels),
ignoreParentSettingsJSON: JSON.stringify(controlGroupInput.ignoreParentSettings),
};
};

export const generateNewControlIds = (controlGroupInput?: PersistableControlGroupInput) => {
if (!controlGroupInput?.panels) return;

const newPanelsMap: ControlsPanels = {};
for (const panel of Object.values(controlGroupInput.panels)) {
const newId = v4();
newPanelsMap[newId] = {
...panel,
explicitInput: { ...panel.explicitInput, id: newId },
};
}
return { ...controlGroupInput, panels: newPanelsMap };
};

export const rawControlGroupAttributesToControlGroupInput = (
rawControlGroupAttributes: RawControlGroupAttributes
): PersistableControlGroupInput | undefined => {
Expand Down
2 changes: 0 additions & 2 deletions src/plugins/controls/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ export {
persistableControlGroupInputKeys,
} from './control_group/types';
export {
controlGroupInputToRawControlGroupAttributes,
rawControlGroupAttributesToControlGroupInput,
rawControlGroupAttributesToSerializable,
serializableToRawControlGroupAttributes,
getDefaultControlGroupPersistableInput,
persistableControlGroupInputIsEqual,
getDefaultControlGroupInput,
generateNewControlIds,
} from './control_group/control_group_persistence';

export {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function ControlGroup({
paddingSize="none"
color={draggingId ? 'success' : 'transparent'}
className="controlsWrapper"
data-test-subj="controls-group-wrapper"
>
<EuiFlexGroup
gutterSize="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ import { apiPublishesAsyncFilters } from '../controls/data_controls/publishes_as

export type ControlGroupComparatorState = Pick<
ControlGroupRuntimeState,
| 'autoApplySelections'
| 'chainingSystem'
| 'ignoreParentSettings'
| 'initialChildControlState'
| 'labelPosition'
'autoApplySelections' | 'chainingSystem' | 'ignoreParentSettings' | 'labelPosition'
> & {
controlsInOrder: ControlsInOrder;
};
Expand All @@ -38,6 +34,7 @@ export function initializeControlGroupUnsavedChanges(
children$: PresentationContainer['children$'],
comparators: StateComparators<ControlGroupComparatorState>,
snapshotControlsRuntimeState: () => ControlPanelsState,
resetControlsUnsavedChanges: () => void,
parentApi: unknown,
lastSavedRuntimeState: ControlGroupRuntimeState
) {
Expand All @@ -47,7 +44,6 @@ export function initializeControlGroupUnsavedChanges(
chainingSystem: lastSavedRuntimeState.chainingSystem,
controlsInOrder: getControlsInOrder(lastSavedRuntimeState.initialChildControlState),
ignoreParentSettings: lastSavedRuntimeState.ignoreParentSettings,
initialChildControlState: lastSavedRuntimeState.initialChildControlState,
labelPosition: lastSavedRuntimeState.labelPosition,
},
parentApi,
Expand All @@ -72,6 +68,7 @@ export function initializeControlGroupUnsavedChanges(
),
asyncResetUnsavedChanges: async () => {
controlGroupUnsavedChanges.api.resetUnsavedChanges();
resetControlsUnsavedChanges();

const filtersReadyPromises: Array<Promise<void>> = [];
Object.values(children$.value).forEach((controlApi) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,19 @@ 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 { ControlGroupApi, ControlGroupRuntimeState, ControlGroupSerializedState } from './types';
import {
ControlGroupApi,
ControlGroupRuntimeState,
ControlGroupSerializedState,
ControlPanelsState,
} from './types';
import { ControlGroup } from './components/control_group';
import { initSelectionsManager } from './selections_manager';
import { initializeControlGroupUnsavedChanges } from './control_group_unsaved_changes_api';
import { openDataControlEditor } from '../controls/data_controls/open_data_control_editor';

const DEFAULT_CHAINING_SYSTEM = 'HIERARCHICAL';

export const getControlGroupEmbeddableFactory = (services: {
core: CoreStart;
dataViews: DataViewsPublicPluginStart;
Expand All @@ -60,27 +67,29 @@ export const getControlGroupEmbeddableFactory = (services: {
lastSavedRuntimeState
) => {
const {
initialChildControlState,
labelPosition: initialLabelPosition,
chainingSystem,
autoApplySelections,
ignoreParentSettings,
} = initialRuntimeState;

const autoApplySelections$ = new BehaviorSubject<boolean>(autoApplySelections);
const parentDataViewId = apiPublishesDataViews(parentApi)
? parentApi.dataViews.value?.[0]?.id
: undefined;
const defaultDataViewId = await services.dataViews.getDefaultId();
const lastSavedControlsState$ = new BehaviorSubject<ControlPanelsState>(
lastSavedRuntimeState.initialChildControlState
);
const controlsManager = initControlsManager(
initialChildControlState,
parentDataViewId ?? (await services.dataViews.getDefaultId())
initialRuntimeState.initialChildControlState,
lastSavedControlsState$
);
const selectionsManager = initSelectionsManager({
...controlsManager.api,
autoApplySelections$,
});
const dataViews = new BehaviorSubject<DataView[] | undefined>(undefined);
const chainingSystem$ = new BehaviorSubject<ControlGroupChainingSystem>(chainingSystem);
const chainingSystem$ = new BehaviorSubject<ControlGroupChainingSystem>(
chainingSystem ?? DEFAULT_CHAINING_SYSTEM
);
nreese marked this conversation as resolved.
Show resolved Hide resolved
const ignoreParentSettings$ = new BehaviorSubject<ParentIgnoreSettings | undefined>(
ignoreParentSettings
);
Expand All @@ -104,6 +113,7 @@ export const getControlGroupEmbeddableFactory = (services: {
chainingSystem: [
chainingSystem$,
(next: ControlGroupChainingSystem) => chainingSystem$.next(next),
(a, b) => (a ?? DEFAULT_CHAINING_SYSTEM) === (b ?? DEFAULT_CHAINING_SYSTEM),
],
ignoreParentSettings: [
ignoreParentSettings$,
Expand All @@ -113,6 +123,7 @@ export const getControlGroupEmbeddableFactory = (services: {
labelPosition: [labelPosition$, (next: ControlStyle) => labelPosition$.next(next)],
},
controlsManager.snapshotControlsRuntimeState,
controlsManager.resetControlsUnsavedChanges,
parentApi,
lastSavedRuntimeState
);
Expand Down Expand Up @@ -159,20 +170,28 @@ export const getControlGroupEmbeddableFactory = (services: {
i18n.translate('controls.controlGroup.displayName', {
defaultMessage: 'Controls',
}),
openAddDataControlFlyout: (settings) => {
const { controlInputTransform } = settings ?? {
controlInputTransform: (state) => state,
};
openAddDataControlFlyout: (options) => {
const parentDataViewId = apiPublishesDataViews(parentApi)
? parentApi.dataViews.value?.[0]?.id
: undefined;
const newControlState = controlsManager.getNewControlState();
openDataControlEditor({
initialState: controlsManager.getNewControlState(),
initialState: {
...newControlState,
dataViewId:
newControlState.dataViewId ?? parentDataViewId ?? defaultDataViewId ?? undefined,
},
onSave: ({ type: controlType, state: initialState }) => {
controlsManager.api.addNewPanel({
panelType: controlType,
initialState: controlInputTransform!(
initialState as Partial<ControlGroupSerializedState>,
controlType
),
initialState: options?.controlInputTransform
? options.controlInputTransform(
initialState as Partial<ControlGroupSerializedState>,
controlType
)
: initialState,
});
options?.onSave?.();
},
controlGroupApi: api,
services,
Expand Down Expand Up @@ -207,6 +226,20 @@ export const getControlGroupEmbeddableFactory = (services: {
dataViews.next(newDataViews)
);

const saveNotificationSubscription = apiHasSaveNotification(parentApi)
? parentApi.saveNotification$.subscribe(() => {
lastSavedControlsState$.next(controlsManager.snapshotControlsRuntimeState());

if (
typeof autoApplySelections$.value === 'boolean' &&
!autoApplySelections$.value &&
selectionsManager.hasUnappliedSelections$.value
) {
selectionsManager.applySelections();
}
})
: undefined;

/** Fetch the allowExpensiveQuries setting for the children to use if necessary */
try {
const { allowExpensiveQueries } = await services.core.http.get<{
Expand Down Expand Up @@ -235,6 +268,7 @@ export const getControlGroupEmbeddableFactory = (services: {
return () => {
selectionsManager.cleanup();
childrenDataViewsSubscription.unsubscribe();
saveNotificationSubscription?.unsubscribe();
};
}, []);

Expand Down
Loading