mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
cleaning up embeddable types (#75560)
This commit is contained in:
parent
b82e4d8a84
commit
40d8edc2a0
13 changed files with 56 additions and 33 deletions
|
@ -65,8 +65,8 @@ export const createEditBookAction = (getStartServices: () => Promise<StartServic
|
||||||
const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => {
|
const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => {
|
||||||
const newInput = await attributeService.wrapAttributes(attributes, useRefType, embeddable);
|
const newInput = await attributeService.wrapAttributes(attributes, useRefType, embeddable);
|
||||||
if (!useRefType && (embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId) {
|
if (!useRefType && (embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId) {
|
||||||
// Remove the savedObejctId when un-linking
|
// Set the saved object ID to null so that update input will remove the existing savedObjectId...
|
||||||
newInput.savedObjectId = null;
|
(newInput as BookByValueInput & { savedObjectId: unknown }).savedObjectId = null;
|
||||||
}
|
}
|
||||||
embeddable.updateInput(newInput);
|
embeddable.updateInput(newInput);
|
||||||
if (useRefType) {
|
if (useRefType) {
|
||||||
|
|
|
@ -29,11 +29,7 @@ import {
|
||||||
EuiText,
|
EuiText,
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import {
|
import { EmbeddableRenderer, ViewMode } from '../../../src/plugins/embeddable/public';
|
||||||
EmbeddableInput,
|
|
||||||
EmbeddableRenderer,
|
|
||||||
ViewMode,
|
|
||||||
} from '../../../src/plugins/embeddable/public';
|
|
||||||
import {
|
import {
|
||||||
HELLO_WORLD_EMBEDDABLE,
|
HELLO_WORLD_EMBEDDABLE,
|
||||||
MULTI_TASK_TODO_EMBEDDABLE,
|
MULTI_TASK_TODO_EMBEDDABLE,
|
||||||
|
@ -41,6 +37,9 @@ import {
|
||||||
ListContainerFactory,
|
ListContainerFactory,
|
||||||
SearchableListContainerFactory,
|
SearchableListContainerFactory,
|
||||||
} from '../../embeddable_examples/public';
|
} from '../../embeddable_examples/public';
|
||||||
|
import { SearchableContainerInput } from '../../embeddable_examples/public/searchable_list_container/searchable_list_container';
|
||||||
|
import { TodoInput } from '../../embeddable_examples/public/todo';
|
||||||
|
import { MultiTaskTodoInput } from '../../embeddable_examples/public/multi_task_todo';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
listContainerEmbeddableFactory: ListContainerFactory;
|
listContainerEmbeddableFactory: ListContainerFactory;
|
||||||
|
@ -51,7 +50,7 @@ export function ListContainerExample({
|
||||||
listContainerEmbeddableFactory,
|
listContainerEmbeddableFactory,
|
||||||
searchableListContainerEmbeddableFactory,
|
searchableListContainerEmbeddableFactory,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const listInput: EmbeddableInput = {
|
const listInput: SearchableContainerInput = {
|
||||||
id: 'hello',
|
id: 'hello',
|
||||||
title: 'My todo list',
|
title: 'My todo list',
|
||||||
viewMode: ViewMode.VIEW,
|
viewMode: ViewMode.VIEW,
|
||||||
|
@ -69,7 +68,7 @@ export function ListContainerExample({
|
||||||
task: 'Goes out on Wednesdays!',
|
task: 'Goes out on Wednesdays!',
|
||||||
icon: 'broom',
|
icon: 'broom',
|
||||||
title: 'Take out the trash',
|
title: 'Take out the trash',
|
||||||
},
|
} as TodoInput,
|
||||||
},
|
},
|
||||||
'3': {
|
'3': {
|
||||||
type: TODO_EMBEDDABLE,
|
type: TODO_EMBEDDABLE,
|
||||||
|
@ -77,12 +76,12 @@ export function ListContainerExample({
|
||||||
id: '3',
|
id: '3',
|
||||||
icon: 'broom',
|
icon: 'broom',
|
||||||
title: 'Vaccum the floor',
|
title: 'Vaccum the floor',
|
||||||
},
|
} as TodoInput,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchableInput: EmbeddableInput = {
|
const searchableInput: SearchableContainerInput = {
|
||||||
id: '1',
|
id: '1',
|
||||||
title: 'My searchable todo list',
|
title: 'My searchable todo list',
|
||||||
viewMode: ViewMode.VIEW,
|
viewMode: ViewMode.VIEW,
|
||||||
|
@ -101,7 +100,7 @@ export function ListContainerExample({
|
||||||
task: 'Goes out on Wednesdays!',
|
task: 'Goes out on Wednesdays!',
|
||||||
icon: 'broom',
|
icon: 'broom',
|
||||||
title: 'Take out the trash',
|
title: 'Take out the trash',
|
||||||
},
|
} as TodoInput,
|
||||||
},
|
},
|
||||||
'3': {
|
'3': {
|
||||||
type: MULTI_TASK_TODO_EMBEDDABLE,
|
type: MULTI_TASK_TODO_EMBEDDABLE,
|
||||||
|
@ -110,7 +109,7 @@ export function ListContainerExample({
|
||||||
icon: 'searchProfilerApp',
|
icon: 'searchProfilerApp',
|
||||||
title: 'Learn more',
|
title: 'Learn more',
|
||||||
tasks: ['Go to school', 'Watch planet earth', 'Read the encyclopedia'],
|
tasks: ['Go to school', 'Watch planet earth', 'Read the encyclopedia'],
|
||||||
},
|
} as MultiTaskTodoInput,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,12 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { isErrorEmbeddable, IContainer, ReferenceOrValueEmbeddable } from '../../embeddable_plugin';
|
import {
|
||||||
|
isErrorEmbeddable,
|
||||||
|
IContainer,
|
||||||
|
ReferenceOrValueEmbeddable,
|
||||||
|
EmbeddableInput,
|
||||||
|
} from '../../embeddable_plugin';
|
||||||
import { DashboardContainer } from '../embeddable';
|
import { DashboardContainer } from '../embeddable';
|
||||||
import { getSampleDashboardInput } from '../test_helpers';
|
import { getSampleDashboardInput } from '../test_helpers';
|
||||||
import {
|
import {
|
||||||
|
@ -145,7 +150,7 @@ test('Add to library returns reference type input', async () => {
|
||||||
|
|
||||||
embeddable = embeddablePluginMock.mockRefOrValEmbeddable<ContactCardEmbeddable>(embeddable, {
|
embeddable = embeddablePluginMock.mockRefOrValEmbeddable<ContactCardEmbeddable>(embeddable, {
|
||||||
mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id },
|
mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id },
|
||||||
mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id },
|
mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id } as EmbeddableInput,
|
||||||
});
|
});
|
||||||
const dashboard = embeddable.getRoot() as IContainer;
|
const dashboard = embeddable.getRoot() as IContainer;
|
||||||
const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels));
|
const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels));
|
||||||
|
|
|
@ -24,7 +24,11 @@ import _ from 'lodash';
|
||||||
import { ActionByType, IncompatibleActionError } from '../../ui_actions_plugin';
|
import { ActionByType, IncompatibleActionError } from '../../ui_actions_plugin';
|
||||||
import { ViewMode, PanelState, IEmbeddable } from '../../embeddable_plugin';
|
import { ViewMode, PanelState, IEmbeddable } from '../../embeddable_plugin';
|
||||||
import { SavedObject } from '../../../../saved_objects/public';
|
import { SavedObject } from '../../../../saved_objects/public';
|
||||||
import { PanelNotFoundError, EmbeddableInput } from '../../../../embeddable/public';
|
import {
|
||||||
|
PanelNotFoundError,
|
||||||
|
EmbeddableInput,
|
||||||
|
SavedObjectEmbeddableInput,
|
||||||
|
} from '../../../../embeddable/public';
|
||||||
import {
|
import {
|
||||||
placePanelBeside,
|
placePanelBeside,
|
||||||
IPanelPlacementBesideArgs,
|
IPanelPlacementBesideArgs,
|
||||||
|
@ -143,7 +147,7 @@ export class ClonePanelAction implements ActionByType<typeof ACTION_CLONE_PANEL>
|
||||||
},
|
},
|
||||||
{ references: _.cloneDeep(savedObjectToClone.references) }
|
{ references: _.cloneDeep(savedObjectToClone.references) }
|
||||||
);
|
);
|
||||||
panelState.explicitInput.savedObjectId = clonedSavedObject.id;
|
(panelState.explicitInput as SavedObjectEmbeddableInput).savedObjectId = clonedSavedObject.id;
|
||||||
}
|
}
|
||||||
this.core.notifications.toasts.addSuccess({
|
this.core.notifications.toasts.addSuccess({
|
||||||
title: i18n.translate('dashboard.panel.clonedToast', {
|
title: i18n.translate('dashboard.panel.clonedToast', {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { coreMock } from '../../../../../core/public/mocks';
|
||||||
import { CoreStart } from 'kibana/public';
|
import { CoreStart } from 'kibana/public';
|
||||||
import { UnlinkFromLibraryAction } from '.';
|
import { UnlinkFromLibraryAction } from '.';
|
||||||
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
|
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
|
||||||
import { ViewMode } from '../../../../embeddable/public';
|
import { ViewMode, SavedObjectEmbeddableInput } from '../../../../embeddable/public';
|
||||||
|
|
||||||
const { setup, doStart } = embeddablePluginMock.createInstance();
|
const { setup, doStart } = embeddablePluginMock.createInstance();
|
||||||
setup.registerEmbeddableFactory(
|
setup.registerEmbeddableFactory(
|
||||||
|
@ -142,7 +142,11 @@ test('Unlink unwraps all attributes from savedObject', async () => {
|
||||||
attribute4: { nestedattribute: 'hello from the nest' },
|
attribute4: { nestedattribute: 'hello from the nest' },
|
||||||
};
|
};
|
||||||
|
|
||||||
embeddable = embeddablePluginMock.mockRefOrValEmbeddable<ContactCardEmbeddable>(embeddable, {
|
embeddable = embeddablePluginMock.mockRefOrValEmbeddable<
|
||||||
|
ContactCardEmbeddable,
|
||||||
|
{ attributes: unknown; id: string },
|
||||||
|
SavedObjectEmbeddableInput
|
||||||
|
>(embeddable, {
|
||||||
mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id },
|
mockedByReferenceInput: { savedObjectId: 'testSavedObjectId', id: embeddable.id },
|
||||||
mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id },
|
mockedByValueInput: { attributes: complicatedAttributes, id: embeddable.id },
|
||||||
});
|
});
|
||||||
|
|
|
@ -474,7 +474,8 @@ export class DashboardAppController {
|
||||||
: undefined;
|
: undefined;
|
||||||
container.addOrUpdateEmbeddable<EmbeddableInput>(
|
container.addOrUpdateEmbeddable<EmbeddableInput>(
|
||||||
incomingEmbeddable.type,
|
incomingEmbeddable.type,
|
||||||
explicitInput,
|
// This ugly solution is temporary - https://github.com/elastic/kibana/pull/70272 fixes this whole section
|
||||||
|
(explicitInput as unknown) as EmbeddableInput,
|
||||||
embeddableId
|
embeddableId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
} from './embeddable_saved_object_converters';
|
} from './embeddable_saved_object_converters';
|
||||||
import { SavedDashboardPanel } from '../../types';
|
import { SavedDashboardPanel } from '../../types';
|
||||||
import { DashboardPanelState } from '../embeddable';
|
import { DashboardPanelState } from '../embeddable';
|
||||||
|
import { EmbeddableInput } from '../../../../embeddable/public';
|
||||||
|
|
||||||
test('convertSavedDashboardPanelToPanelState', () => {
|
test('convertSavedDashboardPanelToPanelState', () => {
|
||||||
const savedDashboardPanel: SavedDashboardPanel = {
|
const savedDashboardPanel: SavedDashboardPanel = {
|
||||||
|
@ -93,7 +94,7 @@ test('convertPanelStateToSavedDashboardPanel', () => {
|
||||||
something: 'hi!',
|
something: 'hi!',
|
||||||
id: '123',
|
id: '123',
|
||||||
savedObjectId: 'savedObjectId',
|
savedObjectId: 'savedObjectId',
|
||||||
},
|
} as EmbeddableInput,
|
||||||
type: 'search',
|
type: 'search',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ test('convertPanelStateToSavedDashboardPanel will not add an undefined id when n
|
||||||
explicitInput: {
|
explicitInput: {
|
||||||
id: '123',
|
id: '123',
|
||||||
something: 'hi!',
|
something: 'hi!',
|
||||||
},
|
} as EmbeddableInput,
|
||||||
type: 'search',
|
type: 'search',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
IEmbeddable,
|
IEmbeddable,
|
||||||
} from '../embeddables';
|
} from '../embeddables';
|
||||||
|
|
||||||
export interface PanelState<E extends { id: string; [key: string]: unknown } = { id: string }> {
|
export interface PanelState<E extends EmbeddableInput & { id: string } = { id: string }> {
|
||||||
// The type of embeddable in this panel. Will be used to find the factory in which to
|
// The type of embeddable in this panel. Will be used to find the factory in which to
|
||||||
// load the embeddable.
|
// load the embeddable.
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -43,7 +43,7 @@ export interface ContainerOutput extends EmbeddableOutput {
|
||||||
export interface ContainerInput<PanelExplicitInput = {}> extends EmbeddableInput {
|
export interface ContainerInput<PanelExplicitInput = {}> extends EmbeddableInput {
|
||||||
hidePanelTitles?: boolean;
|
hidePanelTitles?: boolean;
|
||||||
panels: {
|
panels: {
|
||||||
[key: string]: PanelState<PanelExplicitInput & { [id: string]: unknown } & { id: string }>;
|
[key: string]: PanelState<PanelExplicitInput & EmbeddableInput & { id: string }>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,6 @@ export interface EmbeddableInput {
|
||||||
* Visualization filters used to narrow down results.
|
* Visualization filters used to narrow down results.
|
||||||
*/
|
*/
|
||||||
filters?: Filter[];
|
filters?: Filter[];
|
||||||
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EmbeddableOutput {
|
export interface EmbeddableOutput {
|
||||||
|
|
|
@ -19,7 +19,13 @@
|
||||||
|
|
||||||
import * as Rx from 'rxjs';
|
import * as Rx from 'rxjs';
|
||||||
import { skip } from 'rxjs/operators';
|
import { skip } from 'rxjs/operators';
|
||||||
import { isErrorEmbeddable, EmbeddableOutput, ContainerInput, ViewMode } from '../lib';
|
import {
|
||||||
|
isErrorEmbeddable,
|
||||||
|
EmbeddableOutput,
|
||||||
|
ContainerInput,
|
||||||
|
ViewMode,
|
||||||
|
SavedObjectEmbeddableInput,
|
||||||
|
} from '../lib';
|
||||||
import {
|
import {
|
||||||
FilterableEmbeddableInput,
|
FilterableEmbeddableInput,
|
||||||
FilterableEmbeddable,
|
FilterableEmbeddable,
|
||||||
|
@ -648,7 +654,7 @@ test('container stores ErrorEmbeddables when a saved object cannot be found', as
|
||||||
panels: {
|
panels: {
|
||||||
'123': {
|
'123': {
|
||||||
type: 'vis',
|
type: 'vis',
|
||||||
explicitInput: { id: '123', savedObjectId: '456' },
|
explicitInput: { id: '123', savedObjectId: '456' } as SavedObjectEmbeddableInput,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
viewMode: ViewMode.EDIT,
|
viewMode: ViewMode.EDIT,
|
||||||
|
@ -669,7 +675,7 @@ test('ErrorEmbeddables get updated when parent does', async (done) => {
|
||||||
panels: {
|
panels: {
|
||||||
'123': {
|
'123': {
|
||||||
type: 'vis',
|
type: 'vis',
|
||||||
explicitInput: { id: '123', savedObjectId: '456' },
|
explicitInput: { id: '123', savedObjectId: '456' } as SavedObjectEmbeddableInput,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
viewMode: ViewMode.EDIT,
|
viewMode: ViewMode.EDIT,
|
||||||
|
|
|
@ -42,7 +42,7 @@ import {
|
||||||
ExpressionRenderError,
|
ExpressionRenderError,
|
||||||
} from '../../../../plugins/expressions/public';
|
} from '../../../../plugins/expressions/public';
|
||||||
import { buildPipeline } from '../legacy/build_pipeline';
|
import { buildPipeline } from '../legacy/build_pipeline';
|
||||||
import { Vis } from '../vis';
|
import { Vis, SerializedVis } from '../vis';
|
||||||
import { getExpressions, getUiActions } from '../services';
|
import { getExpressions, getUiActions } from '../services';
|
||||||
import { VIS_EVENT_TO_TRIGGER } from './events';
|
import { VIS_EVENT_TO_TRIGGER } from './events';
|
||||||
import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory';
|
import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory';
|
||||||
|
@ -63,6 +63,7 @@ export interface VisualizeInput extends EmbeddableInput {
|
||||||
vis?: {
|
vis?: {
|
||||||
colors?: { [key: string]: string };
|
colors?: { [key: string]: string };
|
||||||
};
|
};
|
||||||
|
savedVis?: SerializedVis;
|
||||||
table?: unknown;
|
table?: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import {
|
||||||
import { StartServicesGetter } from '../../../../../../../src/plugins/kibana_utils/public';
|
import { StartServicesGetter } from '../../../../../../../src/plugins/kibana_utils/public';
|
||||||
import { StartDependencies } from '../../../plugin';
|
import { StartDependencies } from '../../../plugin';
|
||||||
import { Config, FactoryContext } from './types';
|
import { Config, FactoryContext } from './types';
|
||||||
|
import { SearchInput } from '../../../../../../../src/plugins/discover/public';
|
||||||
|
|
||||||
export interface Params {
|
export interface Params {
|
||||||
start: StartServicesGetter<Pick<StartDependencies, 'data' | 'uiActionsEnhanced'>>;
|
start: StartServicesGetter<Pick<StartDependencies, 'data' | 'uiActionsEnhanced'>>;
|
||||||
|
@ -89,7 +90,7 @@ export class DashboardToDashboardDrilldown
|
||||||
};
|
};
|
||||||
|
|
||||||
if (context.embeddable) {
|
if (context.embeddable) {
|
||||||
const input = context.embeddable.getInput();
|
const input = context.embeddable.getInput() as Readonly<SearchInput>;
|
||||||
if (isQuery(input.query) && config.useCurrentFilters) state.query = input.query;
|
if (isQuery(input.query) && config.useCurrentFilters) state.query = input.query;
|
||||||
|
|
||||||
// if useCurrentDashboardDataRange is enabled, then preserve current time range
|
// if useCurrentDashboardDataRange is enabled, then preserve current time range
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Action } from '../../../../../../src/plugins/ui_actions/public';
|
import { Action } from '../../../../../../src/plugins/ui_actions/public';
|
||||||
import { DiscoverUrlGeneratorState } from '../../../../../../src/plugins/discover/public';
|
import {
|
||||||
|
DiscoverUrlGeneratorState,
|
||||||
|
SearchInput,
|
||||||
|
} from '../../../../../../src/plugins/discover/public';
|
||||||
import {
|
import {
|
||||||
ApplyGlobalFilterActionContext,
|
ApplyGlobalFilterActionContext,
|
||||||
esFilters,
|
esFilters,
|
||||||
|
@ -59,7 +62,7 @@ export class ExploreDataChartAction extends AbstractExploreDataAction<ExploreDat
|
||||||
if (embeddable) {
|
if (embeddable) {
|
||||||
state.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined;
|
state.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined;
|
||||||
|
|
||||||
const input = embeddable.getInput();
|
const input = embeddable.getInput() as Readonly<SearchInput>;
|
||||||
|
|
||||||
if (input.timeRange && !state.timeRange) state.timeRange = input.timeRange;
|
if (input.timeRange && !state.timeRange) state.timeRange = input.timeRange;
|
||||||
if (input.query) state.query = input.query;
|
if (input.query) state.query = input.query;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue