Skip to content

Commit

Permalink
Remove UiComponent and related code (#148037)
Browse files Browse the repository at this point in the history
## Summary

- Removes `UiComponent` and its usages.
- Fixes UI Actions TypeScript types.


### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Anton Dosov <dosantappdev@gmail.com>
Co-authored-by: Dima Arnautov <arnautov.dima@gmail.com>
  • Loading branch information
4 people authored Jan 9, 2023
1 parent 5921abb commit 039ed99
Show file tree
Hide file tree
Showing 78 changed files with 366 additions and 827 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import { createAction, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { ViewMode, isReferenceOrValueEmbeddable } from '@kbn/embeddable-plugin/public';
import { DASHBOARD_CONTAINER_TYPE } from '@kbn/dashboard-plugin/public';
import { BookEmbeddable, BOOK_EMBEDDABLE } from './book_embeddable';
Expand All @@ -18,31 +18,30 @@ interface ActionContext {

export const ACTION_ADD_BOOK_TO_LIBRARY = 'ACTION_ADD_BOOK_TO_LIBRARY';

export const createAddBookToLibraryAction = () =>
createAction({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.addToLibrary', {
defaultMessage: 'Add Book To Library',
}),
id: ACTION_ADD_BOOK_TO_LIBRARY,
type: ACTION_ADD_BOOK_TO_LIBRARY,
order: 100,
getIconType: () => 'folderCheck',
isCompatible: async ({ embeddable }: ActionContext) => {
return (
embeddable.type === BOOK_EMBEDDABLE &&
embeddable.getInput().viewMode === ViewMode.EDIT &&
embeddable.getRoot().isContainer &&
embeddable.getRoot().type !== DASHBOARD_CONTAINER_TYPE &&
isReferenceOrValueEmbeddable(embeddable) &&
!embeddable.inputIsRefType(embeddable.getInput())
);
},
execute: async ({ embeddable }: ActionContext) => {
if (!isReferenceOrValueEmbeddable(embeddable)) {
throw new IncompatibleActionError();
}
const newInput = await embeddable.getInputAsRefType();
embeddable.updateInput(newInput);
},
});
export const createAddBookToLibraryActionDefinition = () => ({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.addToLibrary', {
defaultMessage: 'Add Book To Library',
}),
id: ACTION_ADD_BOOK_TO_LIBRARY,
type: ACTION_ADD_BOOK_TO_LIBRARY,
order: 100,
getIconType: () => 'folderCheck',
isCompatible: async ({ embeddable }: ActionContext) => {
return (
embeddable.type === BOOK_EMBEDDABLE &&
embeddable.getInput().viewMode === ViewMode.EDIT &&
embeddable.getRoot().isContainer &&
embeddable.getRoot().type !== DASHBOARD_CONTAINER_TYPE &&
isReferenceOrValueEmbeddable(embeddable) &&
!embeddable.inputIsRefType(embeddable.getInput())
);
},
execute: async ({ embeddable }: ActionContext) => {
if (!isReferenceOrValueEmbeddable(embeddable)) {
throw new IncompatibleActionError();
}
const newInput = await embeddable.getInputAsRefType();
embeddable.updateInput(newInput);
},
});
110 changes: 53 additions & 57 deletions examples/embeddable_examples/public/book/edit_book_action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import React from 'react';
import { OverlayStart } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { createAction } from '@kbn/ui-actions-plugin/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import {
ViewMode,
Expand Down Expand Up @@ -39,61 +38,58 @@ interface ActionContext {

export const ACTION_EDIT_BOOK = 'ACTION_EDIT_BOOK';

export const createEditBookAction = (getStartServices: () => Promise<StartServices>) =>
createAction({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.edit', { defaultMessage: 'Edit Book' }),
id: ACTION_EDIT_BOOK,
type: ACTION_EDIT_BOOK,
order: 100,
getIconType: () => 'documents',
isCompatible: async ({ embeddable }: ActionContext) => {
return (
embeddable.type === BOOK_EMBEDDABLE && embeddable.getInput().viewMode === ViewMode.EDIT
);
},
execute: async ({ embeddable }: ActionContext) => {
const { openModal, getAttributeService, savedObjectsClient } = await getStartServices();
const attributeService = getAttributeService<BookSavedObjectAttributes>(BOOK_SAVED_OBJECT, {
saveMethod: async (attributes: BookSavedObjectAttributes, savedObjectId?: string) => {
if (savedObjectId) {
return savedObjectsClient.update(BOOK_EMBEDDABLE, savedObjectId, attributes);
}
return savedObjectsClient.create(BOOK_EMBEDDABLE, attributes);
},
checkForDuplicateTitle: (props: OnSaveProps) => {
return new Promise(() => {
return true;
});
},
});
const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => {
const newInput = await attributeService.wrapAttributes(
attributes,
useRefType,
embeddable.getExplicitInput()
);
if (!useRefType && (embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId) {
// Set the saved object ID to null so that update input will remove the existing savedObjectId...
(newInput as BookByValueInput & { savedObjectId: unknown }).savedObjectId = null;
}
embeddable.updateInput(newInput);
if (useRefType) {
// Ensures that any duplicate embeddables also register the changes. This mirrors the behavior of going back and forth between apps
embeddable.getRoot().reload();
export const createEditBookActionDefinition = (getStartServices: () => Promise<StartServices>) => ({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.edit', { defaultMessage: 'Edit Book' }),
id: ACTION_EDIT_BOOK,
type: ACTION_EDIT_BOOK,
order: 100,
getIconType: () => 'documents',
isCompatible: async ({ embeddable }: ActionContext) => {
return embeddable.type === BOOK_EMBEDDABLE && embeddable.getInput().viewMode === ViewMode.EDIT;
},
execute: async ({ embeddable }: ActionContext) => {
const { openModal, getAttributeService, savedObjectsClient } = await getStartServices();
const attributeService = getAttributeService<BookSavedObjectAttributes>(BOOK_SAVED_OBJECT, {
saveMethod: async (attributes: BookSavedObjectAttributes, savedObjectId?: string) => {
if (savedObjectId) {
return savedObjectsClient.update(BOOK_EMBEDDABLE, savedObjectId, attributes);
}
};
const overlay = openModal(
toMountPoint(
<CreateEditBookComponent
savedObjectId={(embeddable.getInput() as BookByReferenceInput).savedObjectId}
attributes={embeddable.getOutput().attributes}
onSave={(attributes: BookSavedObjectAttributes, useRefType: boolean) => {
overlay.close();
onSave(attributes, useRefType);
}}
/>
)
return savedObjectsClient.create(BOOK_EMBEDDABLE, attributes);
},
checkForDuplicateTitle: (props: OnSaveProps) => {
return new Promise(() => {
return true;
});
},
});
const onSave = async (attributes: BookSavedObjectAttributes, useRefType: boolean) => {
const newInput = await attributeService.wrapAttributes(
attributes,
useRefType,
embeddable.getExplicitInput()
);
},
});
if (!useRefType && (embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId) {
// Set the saved object ID to null so that update input will remove the existing savedObjectId...
(newInput as BookByValueInput & { savedObjectId: unknown }).savedObjectId = null;
}
embeddable.updateInput(newInput);
if (useRefType) {
// Ensures that any duplicate embeddables also register the changes. This mirrors the behavior of going back and forth between apps
embeddable.getRoot().reload();
}
};
const overlay = openModal(
toMountPoint(
<CreateEditBookComponent
savedObjectId={(embeddable.getInput() as BookByReferenceInput).savedObjectId}
attributes={embeddable.getOutput().attributes}
onSave={(attributes: BookSavedObjectAttributes, useRefType: boolean) => {
overlay.close();
onSave(attributes, useRefType);
}}
/>
)
);
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import { createAction, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { ViewMode, isReferenceOrValueEmbeddable } from '@kbn/embeddable-plugin/public';
import { DASHBOARD_CONTAINER_TYPE } from '@kbn/dashboard-plugin/public';
import { BookEmbeddable, BOOK_EMBEDDABLE } from './book_embeddable';
Expand All @@ -18,31 +18,30 @@ interface ActionContext {

export const ACTION_UNLINK_BOOK_FROM_LIBRARY = 'ACTION_UNLINK_BOOK_FROM_LIBRARY';

export const createUnlinkBookFromLibraryAction = () =>
createAction({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.unlinkFromLibrary', {
defaultMessage: 'Unlink Book from Library Item',
}),
id: ACTION_UNLINK_BOOK_FROM_LIBRARY,
type: ACTION_UNLINK_BOOK_FROM_LIBRARY,
order: 100,
getIconType: () => 'folderExclamation',
isCompatible: async ({ embeddable }: ActionContext) => {
return (
embeddable.type === BOOK_EMBEDDABLE &&
embeddable.getInput().viewMode === ViewMode.EDIT &&
embeddable.getRoot().isContainer &&
embeddable.getRoot().type !== DASHBOARD_CONTAINER_TYPE &&
isReferenceOrValueEmbeddable(embeddable) &&
embeddable.inputIsRefType(embeddable.getInput())
);
},
execute: async ({ embeddable }: ActionContext) => {
if (!isReferenceOrValueEmbeddable(embeddable)) {
throw new IncompatibleActionError();
}
const newInput = await embeddable.getInputAsValueType();
embeddable.updateInput(newInput);
},
});
export const createUnlinkBookFromLibraryActionDefinition = () => ({
getDisplayName: () =>
i18n.translate('embeddableExamples.book.unlinkFromLibrary', {
defaultMessage: 'Unlink Book from Library Item',
}),
id: ACTION_UNLINK_BOOK_FROM_LIBRARY,
type: ACTION_UNLINK_BOOK_FROM_LIBRARY,
order: 100,
getIconType: () => 'folderExclamation',
isCompatible: async ({ embeddable }: ActionContext) => {
return (
embeddable.type === BOOK_EMBEDDABLE &&
embeddable.getInput().viewMode === ViewMode.EDIT &&
embeddable.getRoot().isContainer &&
embeddable.getRoot().type !== DASHBOARD_CONTAINER_TYPE &&
isReferenceOrValueEmbeddable(embeddable) &&
embeddable.inputIsRefType(embeddable.getInput())
);
},
execute: async ({ embeddable }: ActionContext) => {
if (!isReferenceOrValueEmbeddable(embeddable)) {
throw new IncompatibleActionError();
}
const newInput = await embeddable.getInputAsValueType();
embeddable.updateInput(newInput);
},
});
12 changes: 6 additions & 6 deletions examples/embeddable_examples/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ import {
TodoRefEmbeddableFactory,
TodoRefEmbeddableFactoryDefinition,
} from './todo/todo_ref_embeddable_factory';
import { createEditBookAction } from './book/edit_book_action';
import { createEditBookActionDefinition } from './book/edit_book_action';
import { BOOK_EMBEDDABLE } from './book/book_embeddable';
import {
BookEmbeddableFactory,
BookEmbeddableFactoryDefinition,
} from './book/book_embeddable_factory';
import { createAddBookToLibraryAction } from './book/add_book_to_library_action';
import { createUnlinkBookFromLibraryAction } from './book/unlink_book_from_library_action';
import { createAddBookToLibraryActionDefinition } from './book/add_book_to_library_action';
import { createUnlinkBookFromLibraryActionDefinition } from './book/unlink_book_from_library_action';
import {
SIMPLE_EMBEDDABLE,
SimpleEmbeddableFactory,
Expand Down Expand Up @@ -157,19 +157,19 @@ export class EmbeddableExamplesPlugin
}))
);

const editBookAction = createEditBookAction(async () => ({
const editBookAction = createEditBookActionDefinition(async () => ({
getAttributeService: (await core.getStartServices())[1].embeddable.getAttributeService,
openModal: (await core.getStartServices())[0].overlays.openModal,
savedObjectsClient: (await core.getStartServices())[0].savedObjects.client,
}));
deps.uiActions.registerAction(editBookAction);
deps.uiActions.attachAction(CONTEXT_MENU_TRIGGER, editBookAction.id);

const addBookToLibraryAction = createAddBookToLibraryAction();
const addBookToLibraryAction = createAddBookToLibraryActionDefinition();
deps.uiActions.registerAction(addBookToLibraryAction);
deps.uiActions.attachAction(CONTEXT_MENU_TRIGGER, addBookToLibraryAction.id);

const unlinkBookFromLibraryAction = createUnlinkBookFromLibraryAction();
const unlinkBookFromLibraryAction = createUnlinkBookFromLibraryActionDefinition();
deps.uiActions.registerAction(unlinkBookFromLibraryAction);
deps.uiActions.attachAction(CONTEXT_MENU_TRIGGER, unlinkBookFromLibraryAction.id);
}
Expand Down
40 changes: 20 additions & 20 deletions examples/ui_action_examples/public/hello_world_action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import React from 'react';
import { EuiText, EuiModalBody, EuiButton } from '@elastic/eui';
import { OverlayStart } from '@kbn/core/public';
import { createAction } from '@kbn/ui-actions-plugin/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';

export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD';
Expand All @@ -18,22 +17,23 @@ interface StartServices {
openModal: OverlayStart['openModal'];
}

export const createHelloWorldAction = (getStartServices: () => Promise<StartServices>) =>
createAction({
id: ACTION_HELLO_WORLD,
type: ACTION_HELLO_WORLD,
getDisplayName: () => 'Hello World!',
execute: async () => {
const { openModal } = await getStartServices();
const overlay = openModal(
toMountPoint(
<EuiModalBody>
<EuiText data-test-subj="helloWorldActionText">Hello world!</EuiText>
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
Close
</EuiButton>
</EuiModalBody>
)
);
},
});
export const createHelloWorldActionDefinition = (
getStartServices: () => Promise<StartServices>
) => ({
id: ACTION_HELLO_WORLD,
type: ACTION_HELLO_WORLD,
getDisplayName: () => 'Hello World!',
execute: async () => {
const { openModal } = await getStartServices();
const overlay = openModal(
toMountPoint(
<EuiModalBody>
<EuiText data-test-subj="helloWorldActionText">Hello world!</EuiText>
<EuiButton data-test-subj="closeModal" onClick={() => overlay.close()}>
Close
</EuiButton>
</EuiModalBody>
)
);
},
});
4 changes: 2 additions & 2 deletions examples/ui_action_examples/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { Plugin, CoreSetup, CoreStart } from '@kbn/core/public';
import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { createHelloWorldAction } from './hello_world_action';
import { createHelloWorldActionDefinition } from './hello_world_action';
import { helloWorldTrigger } from './hello_world_trigger';

export interface UiActionExamplesSetupDependencies {
Expand All @@ -29,7 +29,7 @@ export class UiActionExamplesPlugin
) {
uiActions.registerTrigger(helloWorldTrigger);

const helloWorldAction = createHelloWorldAction(async () => ({
const helloWorldAction = createHelloWorldActionDefinition(async () => ({
openModal: (await core.getStartServices())[0].overlays.openModal,
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';

import { EditPanelAction, isFilterableEmbeddable, ViewMode } from '@kbn/embeddable-plugin/public';
import { type IEmbeddable, isErrorEmbeddable } from '@kbn/embeddable-plugin/public';
import { KibanaThemeProvider, reactToUiComponent } from '@kbn/kibana-react-plugin/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import type { ApplicationStart } from '@kbn/core/public';
Expand Down Expand Up @@ -46,7 +46,7 @@ export class FiltersNotificationAction implements Action<FiltersNotificationActi
} = pluginServices.getServices());
}

private FilterIconButton = ({ context }: { context: FiltersNotificationActionContext }) => {
public readonly MenuItem = ({ context }: { context: FiltersNotificationActionContext }) => {
const { embeddable } = context;

const editPanelAction = new EditPanelAction(
Expand Down Expand Up @@ -76,8 +76,6 @@ export class FiltersNotificationAction implements Action<FiltersNotificationActi
);
};

public readonly MenuItem = reactToUiComponent(this.FilterIconButton);

public getDisplayName({ embeddable }: FiltersNotificationActionContext) {
if (!embeddable.getRoot() || !embeddable.getRoot().isContainer) {
throw new IncompatibleActionError();
Expand Down
Loading

0 comments on commit 039ed99

Please sign in to comment.