Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/platform/plugins/shared/controls/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@kbn/controls-schemas",
"@kbn/presentation-util",
"@kbn/control-group-renderer",
"@kbn/controls-renderer"
"@kbn/controls-renderer",
],
"exclude": ["target/**/*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,88 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { BehaviorSubject } from 'rxjs';
import type { PublishesESQLVariable } from '@kbn/esql-types';
import type { Observable } from 'rxjs';
import { BehaviorSubject, combineLatest, map, switchMap } from 'rxjs';
import { apiPublishesESQLVariable, type ESQLControlVariable } from '@kbn/esql-types';
import { combineCompatibleChildrenApis } from '@kbn/presentation-containers';
import type { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public';
import type { PublishingSubject } from '@kbn/presentation-publishing';
import type { AggregateQuery } from '@kbn/es-query';
import { getESQLQueryVariables } from '@kbn/esql-utils';

export const initializeESQLVariablesManager = (
children$: PublishingSubject<{ [key: string]: DefaultEmbeddableApi }>
) => {
const esqlVariables$ = new BehaviorSubject<ESQLControlVariable[]>([]);
const childrenESQLVariablesSubscription = combineCompatibleChildrenApis<
PublishesESQLVariable,
ESQLControlVariable[]
>({ children$ }, 'esqlVariable$', apiPublishesESQLVariable, []).subscribe((newESQLVariables) => {
esqlVariables$.next(newESQLVariables);
});
const esqlRelatedPanels$ = new BehaviorSubject<Map<string, string[]>>(new Map());

const childrenESQLVariablesSubscription = children$
.pipe(
switchMap((children) => {
const esqlVariableChildren: Array<
Observable<{ uuid: string; variable: ESQLControlVariable }>
> = [];
const esqlQueryChildren: Array<Observable<{ uuid: string; esql: string }>> = [];

for (const child of Object.values(children)) {
if (apiPublishesESQLQuery(child)) {
esqlQueryChildren.push(
child.query$.pipe(map(({ esql }) => ({ esql, uuid: child.uuid })))
);
} else if (apiPublishesESQLVariable(child)) {
esqlVariableChildren.push(
child.esqlVariable$.pipe(map((variable) => ({ variable, uuid: child.uuid })))
);
}
}

return combineLatest([
combineLatest(esqlVariableChildren),
combineLatest(esqlQueryChildren),
]);
})
)
.subscribe(([esqlVariablesWithUUIDs, esqlQueries]) => {
esqlVariables$.next(esqlVariablesWithUUIDs.map(({ variable }) => variable));

const nextESQLRelatedPanels: Map<string, string[]> = new Map();
for (const { esql, uuid } of esqlQueries) {
const variables = getESQLQueryVariables(esql);
if (variables.length > 0) {
const relatedPanelUUIDs = variables
.map(
(variableName) =>
esqlVariablesWithUUIDs.find(({ variable: { key } }) => key === variableName)?.uuid
)
.filter(Boolean) as string[];
nextESQLRelatedPanels.set(uuid, relatedPanelUUIDs);

for (const relatedUUID of relatedPanelUUIDs) {
nextESQLRelatedPanels.set(relatedUUID, [
...(nextESQLRelatedPanels.get(relatedUUID) ?? []),
uuid,
]);
}
}
}
esqlRelatedPanels$.next(nextESQLRelatedPanels);
});

return {
api: {
esqlVariables$,
},
internalApi: {
esqlRelatedPanels$,
},
cleanup: () => {
childrenESQLVariablesSubscription.unsubscribe();
},
};
};

interface PublishesESQLQuery {
query$: PublishingSubject<AggregateQuery>;
}
const apiPublishesESQLQuery = (api: unknown): api is PublishesESQLQuery =>
Boolean((api as PublishesESQLQuery).query$) &&
'esql' in (api as PublishesESQLQuery).query$?.value;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import type { Reference } from '@kbn/content-management-utils';
import type { EmbeddablePackageState } from '@kbn/embeddable-plugin/public';
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, map } from 'rxjs';
import { v4 } from 'uuid';
import { getReferencesForPanelId } from '../../common';

Expand Down Expand Up @@ -137,6 +137,27 @@ export function getDashboardApi({

const trackOverlayApi = initializeTrackOverlay(trackPanel.setFocusedPanelId);

const arePanelsRelated$ = new BehaviorSubject<(a: string, b: string) => boolean>(() => false);

const relatedPanelSubscription = esqlVariablesManager.internalApi.esqlRelatedPanels$
.pipe(
map((esqlRelatedPanels) => (uuid: string) => {
const relatedPanelUUIDs = [];

const esqlRelatedPanelUUIDs = esqlRelatedPanels.get(uuid);
if (esqlRelatedPanelUUIDs) {
for (const relatedUUID of esqlRelatedPanelUUIDs) {
relatedPanelUUIDs.push(relatedUUID);
}
}

return relatedPanelUUIDs;
})
)
.subscribe((getRelatedPanels) =>
arePanelsRelated$.next((a: string, b: string) => getRelatedPanels(a).includes(b))
);

const isFetchPaused$ = new BehaviorSubject<boolean>(false); // TODO: Make this work and probably move it to another file

const dashboardApi = {
Expand Down Expand Up @@ -243,6 +264,7 @@ export function getDashboardApi({
...unifiedSearchManager.internalApi,
dashboardContainerRef$,
setDashboardContainerRef: (ref: HTMLElement | null) => dashboardContainerRef$.next(ref),
arePanelsRelated$,
// serializeControls: () => controlGroupManager.internalApi.serializeControlGroup(),
// untilControlsInitialized: controlGroupManager.internalApi.untilControlsInitialized,
};
Expand All @@ -269,6 +291,7 @@ export function getDashboardApi({
layoutManager.cleanup();
esqlVariablesManager.cleanup();
timesliceManager.cleanup();
relatedPanelSubscription.unsubscribe();
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,5 @@ export interface DashboardInternalApi {
controlGroupInput: ControlsGroupState | undefined;
controlGroupReferences: Reference[];
};
arePanelsRelated$: BehaviorSubject<(a: string, b: string) => boolean>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,25 @@ export const Item = React.forwardRef<HTMLDivElement, Props>(
useMargins,
viewMode,
dashboardContainerRef,
arePanelsRelated,
] = useBatchedPublishingSubjects(
dashboardApi.highlightPanelId$,
dashboardApi.scrollToPanelId$,
dashboardApi.expandedPanelId$,
dashboardApi.focusedPanelId$,
dashboardApi.settings.useMargins$,
dashboardApi.viewMode$,
dashboardInternalApi.dashboardContainerRef$
dashboardInternalApi.dashboardContainerRef$,
dashboardInternalApi.arePanelsRelated$
);

const expandPanel = expandedPanelId !== undefined && expandedPanelId === id;
const hidePanel = expandedPanelId !== undefined && expandedPanelId !== id;
const focusPanel = focusedPanelId !== undefined && focusedPanelId === id;
const blurPanel = focusedPanelId !== undefined && focusedPanelId !== id;
const blurPanel =
focusedPanelId !== undefined &&
focusedPanelId !== id &&
!arePanelsRelated(id, focusedPanelId);
const classes = classNames('dshDashboardGrid__item', {
'dshDashboardGrid__item--expanded': expandPanel,
'dshDashboardGrid__item--hidden': hidePanel,
Expand Down