Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
16426a2
initial set up of new embeddable factory types.
ThomThomson Mar 25, 2025
07c26d6
First pass of state manager. Messy version of state & unsaved changes…
ThomThomson Mar 27, 2025
ebd2e6e
[Embeddables][Serialized State Only] Use serialized state in state tr…
Heenawter Mar 27, 2025
a873bdd
Dashboard integration in progress.
ThomThomson Mar 28, 2025
d4c0a7d
Merge remote-tracking branch 'refs/remotes/upstream/embeddable-serial…
ThomThomson Mar 28, 2025
8e7cd88
SerializedStateOnly Dashboard integration
ThomThomson Apr 2, 2025
7b3505d
Use new state manager type for titles and markdown. set up unsaved ch…
ThomThomson Apr 3, 2025
df5191d
convert search example embeddable (#217246)
nreese Apr 4, 2025
237928c
Migrate Map embeddable to serialized state only (#217351)
nreese Apr 7, 2025
1c0574a
Migrate Visualize embeddable to serialized state only (#217736)
nreese Apr 9, 2025
0f155ec
Fix unlink from library (#217743)
nreese Apr 9, 2025
5b1dac2
[canvas] migrate canvas to serialized state only (#217874)
nreese Apr 10, 2025
3ecdbaf
convert Lens embeddable to serialized state only (#217911)
nreese Apr 11, 2025
5ab2cf5
Discover session serialized state (#218015)
nreese Apr 11, 2025
fa546d3
Tslint serialize state (#218026)
nreese Apr 11, 2025
777ee00
fix reading properties of undefined when currentChildState[uuid] is n…
nreese Apr 14, 2025
b060605
Merge remote-tracking branch 'upstream/main' into embeddable-serializ…
ThomThomson Apr 15, 2025
8b8c21b
update titleManger to implement PublishesTitle and PublishesWritableT…
nreese Apr 16, 2025
aad38e0
[Serialized State Only] Field list embeddable (#218174)
nickpeihl Apr 16, 2025
c3b1aca
[Embeddable] [Serialized State Only] Convert SLO embeddable to serial…
nickpeihl Apr 16, 2025
95c3453
[Embeddable] SLO Alerts embeddable to serialized state only (#218349)
nickpeihl Apr 16, 2025
245f010
[Serialized State Only] [SLO] Convert SLO Burn rate to serialized sta…
nickpeihl Apr 16, 2025
7533eea
[Serialized State Only] Data table embeddable (#218355)
Heenawter Apr 16, 2025
be7e55c
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 16, 2025
331f37d
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 17, 2025
1e2d7d6
Convert control group embeddable to serialized state only (#218370)
nreese Apr 18, 2025
d5e57af
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 18, 2025
6deb95d
convert traces embeddable to serialized state only (#218667)
nreese Apr 18, 2025
55a8c7f
[Serialized State Only] [SLO] Convert SLO Error Budget embeddable to …
nickpeihl Apr 18, 2025
236fb0c
[Serialized State Only] Alerts embeddable serialized state only (#218…
nickpeihl Apr 18, 2025
5dda37e
[Serialized State Only] Book embeddable (#218343)
cqliu1 Apr 19, 2025
9266efa
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 21, 2025
73914d0
[Embeddable] [Serialized State Only] Convert Synthetics stats embedda…
nickpeihl Apr 21, 2025
6c451aa
tslint lens and maps plugins (#218732)
nreese Apr 21, 2025
58c02f5
[Serialized state only] Convert synthetic monitors embeddable to seri…
nickpeihl Apr 21, 2025
0e93aac
copy to dashboard action (#218737)
nreese Apr 21, 2025
0f043cf
[Serialized State Only] Convert APM alerting embeddables to serialize…
nickpeihl Apr 21, 2025
077f0bd
[Serialized State Only] Convert pattern anslysis embeddable to serial…
nickpeihl Apr 22, 2025
f07fd6f
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 22, 2025
edef835
[Serialized State Only] Field Stats (#218751)
ThomThomson Apr 22, 2025
5a30250
[Serialized State Only] Button embeddable (#218658)
olapawlus Apr 22, 2025
012a8c6
Merge branch 'main' into embeddable-serialized-state
nreese Apr 22, 2025
132190d
Dashboard locator serialized state (#218832)
nreese Apr 23, 2025
3088a23
Merge branch 'main' into embeddable-serialized-state
nreese Apr 23, 2025
1c8ded2
[Serialized State Only] Convert log rate analysis embeddable to seria…
nickpeihl Apr 23, 2025
9f50157
tslint embeddable_examples plugin (#219009)
nreese Apr 23, 2025
522253d
convert links embeddable to serialized state only (#219023)
nreese Apr 23, 2025
a2bcb30
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 24, 2025
197d372
Convert change point embeddable to expose serialized state only (#219…
nreese Apr 24, 2025
de0db03
tslint discover plugin (#219151)
nreese Apr 24, 2025
872edfe
tslint portable dashboard examples (#219153)
nreese Apr 24, 2025
8fa3c4f
[Serialized state only] Convert log stream embeddable to serialized s…
nickpeihl Apr 24, 2025
63de363
tslint ml plugin (#219159)
nreese Apr 24, 2025
1935085
tslint image plugin (#219163)
nreese Apr 24, 2025
5b76387
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Apr 24, 2025
b33726e
[CI] Auto-commit changed files from 'node scripts/styled_components_m…
kibanamachine Apr 24, 2025
f575b45
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 24, 2025
859c85a
[Serialized State Only] Fix alerts table embeddable unit test (#219249)
nickpeihl Apr 25, 2025
dee9270
eslint and tslint fixes (#219165)
nreese Apr 25, 2025
1782be1
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 25, 2025
afcae50
Fix jest tests (#219312)
nickpeihl Apr 25, 2025
dc46068
Functional tests serialized state only (#219301)
nreese Apr 25, 2025
7d0a887
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 25, 2025
3ae89d7
[Serialized State Only] Fix control group mock (#219386)
nickpeihl Apr 28, 2025
b0c6cf5
Merge branch 'main' into embeddable-serialized-state
nreese Apr 28, 2025
e1e03b6
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 28, 2025
992196a
lint lens (#219396)
nreese Apr 28, 2025
1633607
Fix panel titles functional test (#219414)
nreese Apr 28, 2025
37243ce
More tests2 (#219444)
nreese Apr 28, 2025
f8eeedf
pass serializedState when adding ESQL control (#219455)
nreese Apr 28, 2025
1873a6e
Merge remote-tracking branch 'upstream/main' into embeddable-serializ…
ThomThomson Apr 28, 2025
438ec81
fix links test (#219468)
nreese Apr 28, 2025
3b9a6f4
revert useBatchedPublishingSubjects for vis embeddable (#219470)
nreese Apr 28, 2025
1d4e1ec
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 28, 2025
1c7c3cb
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 29, 2025
952c0c6
fix ESQL control test (#219551)
nreese Apr 29, 2025
ec9fc0d
[Serialized state only] Provide defaultTitle to execution context (#2…
nickpeihl Apr 29, 2025
2aecbce
Merge branch 'main' into embeddable-serialized-state
nreese Apr 29, 2025
ecd4829
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 29, 2025
d88f837
Merge branch 'main' into embeddable-serialized-state
nreese Apr 30, 2025
9edab85
fix merge with main issues (#219756)
nreese Apr 30, 2025
c130f9e
[Serialized state only] Fix lens functional test (#219574)
cqliu1 Apr 30, 2025
aa280d2
fix saved vis comparator (#219778)
nreese Apr 30, 2025
e178e09
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 30, 2025
2374da8
Merge branch 'main' into embeddable-serialized-state
elasticmachine Apr 30, 2025
d000baa
fix discover session issues found in testing swarm (#219800)
nreese Apr 30, 2025
01d1f75
Merge branch 'main' into embeddable-serialized-state
elasticmachine May 1, 2025
e49f95d
Add values for exclude and existsSelected in options list control def…
cqliu1 May 1, 2025
83762e9
fix image embeddable reset (#219882)
nreese May 1, 2025
6d9f4f3
fix-cypress-test (#219886)
nreese May 2, 2025
0b2a9b5
Fix Change point chart not reporting unsaved changes
nickpeihl May 2, 2025
e0ee4bc
Merge branch 'main' into embeddable-serialized-state
nreese May 4, 2025
02171a7
Merge branch 'main' into embeddable-serialized-state
elasticmachine May 5, 2025
8f6533d
fix Unsaved changes still appears after resetting layer change in map…
nreese May 5, 2025
0586bc8
clean up embeddable README (#220125)
nreese May 5, 2025
58ee10d
review feedback (#220179)
nreese May 6, 2025
879faeb
Merge branch 'main' into embeddable-serialized-state
elasticmachine May 6, 2025
c412a0b
Merge branch 'main' into embeddable-serialized-state
elasticmachine May 6, 2025
c528ca0
fix race condition where ML embeddables are used before they are regi…
nreese May 6, 2025
c224fe5
remove timeRange: undefined since its provided by ...timeRangeManager…
nreese May 6, 2025
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 @@ -68,7 +68,7 @@ export const EditExample = () => {
localStorage.setItem(
INPUT_KEY,
JSON.stringify({
...controlGroupAPI.snapshotRuntimeState(),
...controlGroupAPI.getInput(),
disabledActions: controlGroupAPI.disabledActionIds$.getValue(), // not part of runtime
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import React, { useEffect, useMemo, useState } from 'react';
Comment thread
nreese marked this conversation as resolved.
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
import { BehaviorSubject, combineLatest, of, Subject } from 'rxjs';
import useMountedState from 'react-use/lib/useMountedState';
import {
EuiBadge,
Expand All @@ -21,36 +21,25 @@ import {
EuiFlexItem,
EuiSpacer,
EuiSuperDatePicker,
EuiToolTip,
OnTimeChangeProps,
} from '@elastic/eui';
import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common';
import { CONTROL_GROUP_TYPE, ControlGroupSerializedState } from '@kbn/controls-plugin/common';
import { ControlGroupApi } from '@kbn/controls-plugin/public';
import { CoreStart } from '@kbn/core/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
import { combineCompatibleChildrenApis } from '@kbn/presentation-containers';
import {
apiPublishesDataLoading,
HasUniqueId,
PublishesDataLoading,
SerializedPanelState,
useBatchedPublishingSubjects,
ViewMode,
} from '@kbn/presentation-publishing';
import { toMountPoint } from '@kbn/react-kibana-mount';

import {
clearControlGroupSerializedState,
getControlGroupSerializedState,
setControlGroupSerializedState,
WEB_LOGS_DATA_VIEW_ID,
} from './serialized_control_group_state';
import {
clearControlGroupRuntimeState,
getControlGroupRuntimeState,
setControlGroupRuntimeState,
} from './runtime_control_group_state';
import { savedStateManager, unsavedStateManager, WEB_LOGS_DATA_VIEW_ID } from './session_storage';

const toggleViewButtons = [
{
Expand All @@ -65,6 +54,8 @@ const toggleViewButtons = [
},
];

const CONTROL_GROUP_EMBEDDABLE_ID = 'CONTROL_GROUP_EMBEDDABLE_ID';

export const ReactControlExample = ({
core,
dataViews: dataViewsService,
Expand Down Expand Up @@ -97,9 +88,6 @@ export const ReactControlExample = ({
const viewMode$ = useMemo(() => {
return new BehaviorSubject<ViewMode>('edit');
}, []);
const saveNotification$ = useMemo(() => {
return new Subject<void>();
}, []);
const reload$ = useMemo(() => {
return new Subject<void>();
}, []);
Expand All @@ -114,9 +102,11 @@ export const ReactControlExample = ({
const [dataViewNotFound, setDataViewNotFound] = useState(false);
const [isResetting, setIsResetting] = useState(false);

const dashboardApi = useMemo(() => {
const parentApi = useMemo(() => {
const query$ = new BehaviorSubject<Query | AggregateQuery | undefined>(undefined);
const children$ = new BehaviorSubject<{ [key: string]: unknown }>({});
const unsavedSavedControlGroupState = unsavedStateManager.get();
const lastSavedControlGroupState = savedStateManager.get();
const lastSavedControlGroupState$ = new BehaviorSubject(lastSavedControlGroupState);

return {
dataLoading$,
Expand All @@ -126,29 +116,44 @@ export const ReactControlExample = ({
query$,
timeRange$,
timeslice$,
children$,
publishFilters: (newFilters: Filter[] | undefined) => filters$.next(newFilters),
setChild: (child: HasUniqueId) =>
children$.next({ ...children$.getValue(), [child.uuid]: child }),
removePanel: () => {},
replacePanel: () => {
return Promise.resolve('');
reload$,
getSerializedStateForChild: (childId: string) => {
if (childId === CONTROL_GROUP_EMBEDDABLE_ID) {
return unsavedSavedControlGroupState
? unsavedSavedControlGroupState
: lastSavedControlGroupState;
}

return {
rawState: {},
references: [],
};
},
getPanelCount: () => {
return 2;
lastSavedStateForChild$: (childId: string) => {
return childId === CONTROL_GROUP_EMBEDDABLE_ID
? lastSavedControlGroupState$
: of(undefined);
},
addNewPanel: () => {
return Promise.resolve(undefined);
getLastSavedStateForChild: (childId: string) => {
return childId === CONTROL_GROUP_EMBEDDABLE_ID
? lastSavedControlGroupState$.value
: {
rawState: {},
references: [],
};
},
setLastSavedControlGroupState: (
savedState: SerializedPanelState<ControlGroupSerializedState>
) => {
lastSavedControlGroupState$.next(savedState);
},
saveNotification$,
reload$,
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
const subscription = combineCompatibleChildrenApis<PublishesDataLoading, boolean | undefined>(
dashboardApi,
parentApi,
'dataLoading$',
apiPublishesDataLoading,
undefined,
Expand All @@ -163,7 +168,7 @@ export const ReactControlExample = ({
return () => {
subscription.unsubscribe();
};
}, [dashboardApi, dataLoading$]);
}, [parentApi, dataLoading$]);

useEffect(() => {
let ignore = false;
Expand Down Expand Up @@ -244,25 +249,20 @@ export const ReactControlExample = ({
};
}, [controlGroupFilters$, filters$, unifiedSearchFilters$]);

const [unsavedChanges, setUnsavedChanges] = useState<string | undefined>(undefined);
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
useEffect(() => {
if (!controlGroupApi) {
return;
}
const subscription = controlGroupApi.unsavedChanges$.subscribe((nextUnsavedChanges) => {
if (!nextUnsavedChanges) {
clearControlGroupRuntimeState();
setUnsavedChanges(undefined);
const subscription = controlGroupApi.hasUnsavedChanges$.subscribe((nextHasUnsavedChanges) => {
if (!nextHasUnsavedChanges) {
unsavedStateManager.clear();
setHasUnsavedChanges(false);
return;
}

setControlGroupRuntimeState(nextUnsavedChanges);

// JSON.stringify removes keys where value is `undefined`
// switch `undefined` to `null` to see when value has been cleared
const replacer = (key: unknown, value: unknown) =>
typeof value === 'undefined' ? null : value;
setUnsavedChanges(JSON.stringify(nextUnsavedChanges, replacer, ' '));
unsavedStateManager.set(controlGroupApi.serializeState());
setHasUnsavedChanges(true);
});

return () => {
Expand All @@ -283,8 +283,8 @@ export const ReactControlExample = ({
color="accent"
size="s"
onClick={() => {
clearControlGroupSerializedState();
clearControlGroupRuntimeState();
savedStateManager.clear();
unsavedStateManager.clear();
window.location.reload();
}}
>
Expand Down Expand Up @@ -346,12 +346,10 @@ export const ReactControlExample = ({
}}
/>
</EuiFlexItem>
{unsavedChanges !== undefined && viewMode === 'edit' && (
{hasUnsavedChanges && viewMode === 'edit' && (
<>
<EuiFlexItem grow={false}>
<EuiToolTip content={<pre>{unsavedChanges}</pre>}>
<EuiBadge color="warning">Unsaved changes</EuiBadge>
</EuiToolTip>
<EuiBadge color="warning">Unsaved changes</EuiBadge>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
Expand All @@ -362,7 +360,7 @@ export const ReactControlExample = ({
return;
}
setIsResetting(true);
await controlGroupApi.asyncResetUnsavedChanges();
await controlGroupApi.resetUnsavedChanges();
if (isMounted()) setIsResetting(false);
}}
>
Expand All @@ -371,11 +369,15 @@ export const ReactControlExample = ({
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
disabled={!controlGroupApi}
onClick={() => {
if (controlGroupApi) {
saveNotification$.next();
setControlGroupSerializedState(controlGroupApi.serializeState());
if (!controlGroupApi) {
return;
}
const savedState = controlGroupApi.serializeState();
parentApi.setLastSavedControlGroupState(savedState);
savedStateManager.set(savedState);
unsavedStateManager.clear();
}}
>
Save
Expand All @@ -400,37 +402,23 @@ export const ReactControlExample = ({
}}
/>
{hasControls && <EuiSpacer size="m" />}
<ReactEmbeddableRenderer
<EmbeddableRenderer
type={CONTROL_GROUP_TYPE}
maybeId={CONTROL_GROUP_EMBEDDABLE_ID}
onApiAvailable={(api) => {
dashboardApi?.setChild(api);
setControlGroupApi(api as ControlGroupApi);
}}
hidePanelChrome={true}
type={CONTROL_GROUP_TYPE}
getParentApi={() => ({
...dashboardApi,
getSerializedStateForChild: getControlGroupSerializedState,
getRuntimeStateForChild: getControlGroupRuntimeState,
})}
getParentApi={() => parentApi}
panelProps={{ hideLoader: true }}
key={`control_group`}
/>
<EuiSpacer size="l" />
{isControlGroupInitialized && (
<div style={{ height: '400px' }}>
<ReactEmbeddableRenderer
type={'data_table'}
getParentApi={() => ({
...dashboardApi,
getSerializedStateForChild: () => ({
rawState: {},
references: [],
}),
})}
<EmbeddableRenderer
type={'search_embeddable'}
getParentApi={() => parentApi}
hidePanelChrome={false}
onApiAvailable={(api) => {
dashboardApi?.setChild(api);
}}
/>
</div>
)}
Expand Down

This file was deleted.

Loading