Skip to content

Commit

Permalink
[visualize embeddable] fix panel disappears from dashboard when cance…
Browse files Browse the repository at this point in the history
…ling edit after dashboard save
  • Loading branch information
nreese committed Sep 24, 2024
1 parent 8953422 commit 5ae5129
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ export function DashboardEmptyScreen() {
const isEditMode = useMemo(() => {
return viewMode === 'edit';
}, [viewMode]);
const { originatingPath, originatingApp } = useMemo(() => {
const appContext = dashboardApi.getAppContext();
return {
originatingApp: appContext?.currentAppId,
originatingPath: appContext?.getCurrentPath?.() ?? '',
};
}, [dashboardApi]);

const goToLens = useCallback(() => {
if (!lensAlias || !lensAlias.alias) return;
Expand All @@ -70,19 +63,19 @@ export function DashboardEmptyScreen() {
if (trackUiMetric) {
trackUiMetric(METRIC_TYPE.CLICK, `${lensAlias.name}:create`);
}
const appContext = dashboardApi.getAppContext();
getStateTransfer().navigateToEditor(lensAlias.alias.app, {
path: lensAlias.alias.path,
state: {
originatingApp,
originatingPath,
originatingApp: appContext?.currentAppId,
originatingPath: appContext?.getCurrentPath?.() ?? '',
searchSessionId: search.session.getSessionId(),
},
});
}, [
getStateTransfer,
lensAlias,
originatingApp,
originatingPath,
dashboardApi,
search.session,
usageCollection,
]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { i18n } from '@kbn/i18n';
import {
PublishingSubject,
apiHasAppContext,
apiPublishesTimeRange,
} from '@kbn/presentation-publishing';
import { TimeRange } from '@kbn/es-query';
import type { Vis } from '../vis';
import { urlFor } from '../utils/saved_visualize_utils';
import { getCapabilities, getEmbeddable } from '../services';

export function initializeEditApi({
customTimeRange$,
description$,
parentApi,
savedObjectId$,
searchSessionId$,
title$,
vis$,
uuid,
}: {
customTimeRange$: PublishingSubject<TimeRange | undefined>;
description$: PublishingSubject<string | undefined>;
parentApi?: unknown;
savedObjectId$: PublishingSubject<string | undefined>;
searchSessionId$: PublishingSubject<string | undefined>;
title$: PublishingSubject<string | undefined>;
vis$: PublishingSubject<Vis>;
uuid: string;
}) {
return !parentApi || !apiHasAppContext(parentApi)
? {}
: {
getTypeDisplayName: () =>
i18n.translate('visualizations.displayName', {
defaultMessage: 'visualization',
}),
onEdit: async () => {
const stateTransferService = getEmbeddable().getStateTransfer();
const visId = savedObjectId$.getValue();
const editPath = visId ? urlFor(visId) : '#/edit_by_value';
const parentTimeRange = apiPublishesTimeRange(parentApi)
? parentApi.timeRange$.getValue()
: {};
const customTimeRange = customTimeRange$.getValue();
const parentApiContext = parentApi.getAppContext();

await stateTransferService.navigateToEditor('visualize', {
path: editPath,
state: {
embeddableId: uuid,
valueInput: {
savedVis: vis$.getValue().serialize(),
title: title$.getValue(),
description: description$.getValue(),
timeRange: customTimeRange ?? parentTimeRange,
},
originatingApp: parentApiContext?.currentAppId,
searchSessionId: searchSessionId$.getValue() || undefined,
originatingPath: parentApiContext?.getCurrentPath?.(),
},
});
},
isEditingEnabled: () => {
const readOnly = Boolean(vis$.getValue().type.disableEdit);
if (readOnly) return false;
const capabilities = getCapabilities();
const isByValue = !savedObjectId$.getValue();
if (isByValue)
return Boolean(
capabilities.dashboard?.showWriteControls && capabilities.visualize?.show
);
else return Boolean(capabilities.visualize?.save);
},
};
}
2 changes: 1 addition & 1 deletion src/plugins/visualizations/public/embeddable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const isVisualizeRuntimeState = (state: unknown): state is VisualizeRunti
);
};

export type VisualizeApi = HasEditCapabilities &
export type VisualizeApi = Partial<HasEditCapabilities> &
PublishesDataViews &
PublishesDataLoading &
HasVisualizeConfig &
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { i18n } from '@kbn/i18n';
import { dispatchRenderComplete } from '@kbn/kibana-utils-plugin/public';
import { apiPublishesSettings } from '@kbn/presentation-containers';
import {
apiHasAppContext,
apiHasDisableTriggers,
apiHasExecutionContext,
apiIsOfType,
Expand All @@ -42,9 +41,8 @@ import React, { useEffect, useRef } from 'react';
import { BehaviorSubject, switchMap } from 'rxjs';
import { VISUALIZE_APP_NAME, VISUALIZE_EMBEDDABLE_TYPE } from '../../common/constants';
import { VIS_EVENT_TO_TRIGGER } from './events';
import { getCapabilities, getInspector, getUiActions, getUsageCollection } from '../services';
import { getInspector, getUiActions, getUsageCollection } from '../services';
import { ACTION_CONVERT_TO_LENS } from '../triggers';
import { urlFor } from '../utils/saved_visualize_utils';
import type { SerializedVis, Vis } from '../vis';
import { createVisInstance } from './create_vis_instance';
import { getExpressionRendererProps } from './get_expression_renderer_props';
Expand All @@ -58,6 +56,7 @@ import {
VisualizeSerializedState,
isVisualizeSavedObjectState,
} from './types';
import { initializeEditApi } from './initialize_edit_api';

export const getVisualizeEmbeddableFactory: (deps: {
embeddableStart: EmbeddableStart;
Expand Down Expand Up @@ -160,8 +159,6 @@ export const getVisualizeEmbeddableFactory: (deps: {
? parentApi.disableTriggers
: undefined;

const parentApiContext = apiHasAppContext(parentApi) ? parentApi.getAppContext() : undefined;

const inspectorAdapters$ = new BehaviorSubject<Record<string, unknown>>({});

// Track data views
Expand Down Expand Up @@ -209,47 +206,16 @@ export const getVisualizeEmbeddableFactory: (deps: {
},
getVis: () => vis$.getValue(),
getInspectorAdapters: () => inspectorAdapters$.getValue(),
getTypeDisplayName: () =>
i18n.translate('visualizations.displayName', {
defaultMessage: 'visualization',
}),
onEdit: async () => {
const stateTransferService = embeddableStart.getStateTransfer();
const visId = savedObjectId$.getValue();
const editPath = visId ? urlFor(visId) : '#/edit_by_value';
const parentTimeRange = apiPublishesTimeRange(parentApi)
? parentApi.timeRange$.getValue()
: {};
const customTimeRange = customTimeRangeApi.timeRange$.getValue();

await stateTransferService.navigateToEditor('visualize', {
path: editPath,
state: {
embeddableId: uuid,
valueInput: {
savedVis: vis$.getValue().serialize(),
title: api.panelTitle?.getValue(),
description: api.panelDescription?.getValue(),
timeRange: customTimeRange ?? parentTimeRange,
},
originatingApp: parentApiContext?.currentAppId ?? '',
searchSessionId: searchSessionId$.getValue() || undefined,
originatingPath: parentApiContext?.getCurrentPath?.(),
},
});
},
isEditingEnabled: () => {
if (viewMode$.getValue() !== 'edit') return false;
const readOnly = Boolean(vis$.getValue().type.disableEdit);
if (readOnly) return false;
const capabilities = getCapabilities();
const isByValue = !savedObjectId$.getValue();
if (isByValue)
return Boolean(
capabilities.dashboard?.showWriteControls && capabilities.visualize?.show
);
else return Boolean(capabilities.visualize?.save);
},
...initializeEditApi({
customTimeRange$: customTimeRangeApi.timeRange$,
description$: titlesApi.panelDescription,
parentApi,
savedObjectId$,
searchSessionId$,
title$: titlesApi.panelTitle,
vis$,
uuid,
}),
updateVis: async (visUpdates) => {
const currentSerializedVis = vis$.getValue().serialize();
serializedVis$.next({
Expand Down

0 comments on commit 5ae5129

Please sign in to comment.