-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[embeddable] remove legacy embeddable factories from 'Add from librar…
…y' flyout (#202823) Part of #180059 PR removes legacy embeddable factory support from Canvas and Dashboard `Add from library` flyout PR also does the following clean-ups 1) Renames folder, files, and component from `add_panel_flyout` to `add_from_library_flyout`. When component was originally created, dashboard `Add panel` button did not exist, and `Add from library` button was called `Add panel`. Now that dashboard contains `Add panel` and `Add from library` buttons, the old naming convention is super confusing and not longer lines up with the current UI. 2) moves registry to `add_from_library` folder so that the registry is in closer proximity to its usage. 2) Renames `registerReactEmbeddableSavedObject` to `registerAddFromLibraryType` because `registerReactEmbeddableSavedObject` does not clearly specifying what the registry enables. --------- Co-authored-by: kibanamachine <[email protected]> Co-authored-by: Elastic Machine <[email protected]>
- Loading branch information
1 parent
178baa8
commit d508b5d
Showing
25 changed files
with
284 additions
and
658 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
src/plugins/embeddable/public/add_from_library/add_from_library_flyout.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* 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 * as React from 'react'; | ||
import { fireEvent, render, screen } from '@testing-library/react'; | ||
import { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common'; | ||
|
||
import { AddFromLibraryFlyout } from './add_from_library_flyout'; | ||
import { usageCollection } from '../kibana_services'; | ||
import { getMockPresentationContainer } from '@kbn/presentation-containers/mocks'; | ||
import { registerAddFromLibraryType } from './registry'; | ||
import { PresentationContainer } from '@kbn/presentation-containers'; | ||
import { HasType } from '@kbn/presentation-publishing'; | ||
|
||
// Mock saved objects finder component so we can call the onChoose method. | ||
jest.mock('@kbn/saved-objects-finder-plugin/public', () => { | ||
return { | ||
SavedObjectFinder: jest | ||
.fn() | ||
.mockImplementation( | ||
({ | ||
onChoose, | ||
}: { | ||
onChoose: (id: string, type: string, name: string, so: unknown) => Promise<void>; | ||
}) => ( | ||
<> | ||
<button | ||
id="soFinderAddButton" | ||
data-test-subj="soFinderAddButton" | ||
onClick={() => | ||
onChoose?.( | ||
'awesomeId', | ||
'AWESOME_EMBEDDABLE', | ||
'Awesome sauce', | ||
{} as unknown as SavedObjectCommon | ||
) | ||
} | ||
> | ||
Add embeddable! | ||
</button> | ||
</> | ||
) | ||
), | ||
}; | ||
}); | ||
|
||
describe('add from library flyout', () => { | ||
let container: PresentationContainer & HasType; | ||
const onAdd = jest.fn(); | ||
|
||
beforeAll(() => { | ||
registerAddFromLibraryType({ | ||
onAdd, | ||
savedObjectType: 'AWESOME_EMBEDDABLE', | ||
savedObjectName: 'Awesome sauce', | ||
getIconForSavedObject: () => 'happyface', | ||
}); | ||
}); | ||
|
||
beforeEach(() => { | ||
onAdd.mockClear(); | ||
container = { | ||
type: 'DASHBOARD_CONTAINER', | ||
...getMockPresentationContainer(), | ||
}; | ||
}); | ||
|
||
test('renders SavedObjectFinder', async () => { | ||
const { container: componentContainer } = render( | ||
<AddFromLibraryFlyout container={container} /> | ||
); | ||
|
||
// component should not contain an extra flyout | ||
// https://github.com/elastic/kibana/issues/64789 | ||
const flyout = componentContainer.querySelector('.euiFlyout'); | ||
expect(flyout).toBeNull(); | ||
const dummyButton = screen.queryAllByTestId('soFinderAddButton'); | ||
expect(dummyButton).toHaveLength(1); | ||
}); | ||
|
||
test('calls the registered onAdd method', async () => { | ||
render(<AddFromLibraryFlyout container={container} />); | ||
expect(Object.values(container.children$.value).length).toBe(0); | ||
fireEvent.click(screen.getByTestId('soFinderAddButton')); | ||
// flush promises | ||
await new Promise((r) => setTimeout(r, 1)); | ||
|
||
expect(onAdd).toHaveBeenCalledWith(container, {}); | ||
}); | ||
|
||
test('runs telemetry function on add embeddable', async () => { | ||
render(<AddFromLibraryFlyout container={container} />); | ||
|
||
expect(Object.values(container.children$.value).length).toBe(0); | ||
fireEvent.click(screen.getByTestId('soFinderAddButton')); | ||
// flush promises | ||
await new Promise((r) => setTimeout(r, 1)); | ||
|
||
expect(usageCollection.reportUiCounter).toHaveBeenCalledWith( | ||
'DASHBOARD_CONTAINER', | ||
'click', | ||
'AWESOME_EMBEDDABLE:add' | ||
); | ||
}); | ||
}); |
109 changes: 109 additions & 0 deletions
109
src/plugins/embeddable/public/add_from_library/add_from_library_flyout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* 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 React, { useCallback } from 'react'; | ||
|
||
import { i18n } from '@kbn/i18n'; | ||
import { EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; | ||
import { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common'; | ||
import { | ||
SavedObjectFinder, | ||
SavedObjectFinderProps, | ||
type SavedObjectMetaData, | ||
} from '@kbn/saved-objects-finder-plugin/public'; | ||
|
||
import { METRIC_TYPE } from '@kbn/analytics'; | ||
import { apiHasType } from '@kbn/presentation-publishing'; | ||
import { CanAddNewPanel } from '@kbn/presentation-containers'; | ||
import { | ||
core, | ||
savedObjectsTaggingOss, | ||
contentManagement, | ||
usageCollection, | ||
} from '../kibana_services'; | ||
import { EmbeddableFactoryNotFoundError } from '../lib'; | ||
import { getAddFromLibraryType, useAddFromLibraryTypes } from './registry'; | ||
|
||
const runAddTelemetry = ( | ||
parent: unknown, | ||
savedObject: SavedObjectCommon, | ||
savedObjectMetaData: SavedObjectMetaData | ||
) => { | ||
if (!apiHasType(parent)) return; | ||
const type = savedObjectMetaData.getSavedObjectSubType | ||
? savedObjectMetaData.getSavedObjectSubType(savedObject) | ||
: savedObjectMetaData.type; | ||
|
||
usageCollection?.reportUiCounter?.(parent.type, METRIC_TYPE.CLICK, `${type}:add`); | ||
}; | ||
|
||
export const AddFromLibraryFlyout = ({ | ||
container, | ||
modalTitleId, | ||
}: { | ||
container: CanAddNewPanel; | ||
modalTitleId?: string; | ||
}) => { | ||
const libraryTypes = useAddFromLibraryTypes(); | ||
|
||
const onChoose: SavedObjectFinderProps['onChoose'] = useCallback( | ||
async ( | ||
id: SavedObjectCommon['id'], | ||
type: SavedObjectCommon['type'], | ||
name: string, | ||
savedObject: SavedObjectCommon | ||
) => { | ||
const libraryType = getAddFromLibraryType(type); | ||
if (!libraryType) { | ||
core.notifications.toasts.addWarning(new EmbeddableFactoryNotFoundError(type).message); | ||
return; | ||
} | ||
|
||
libraryType.onAdd(container, savedObject); | ||
runAddTelemetry(container, savedObject, libraryType.savedObjectMetaData); | ||
}, | ||
[container] | ||
); | ||
|
||
return ( | ||
<> | ||
<EuiFlyoutHeader hasBorder> | ||
<EuiTitle size="s"> | ||
<h2 id={modalTitleId}> | ||
{i18n.translate('embeddableApi.addPanel.Title', { defaultMessage: 'Add from library' })} | ||
</h2> | ||
</EuiTitle> | ||
</EuiFlyoutHeader> | ||
<EuiFlyoutBody> | ||
<SavedObjectFinder | ||
id="embeddableAddPanel" | ||
services={{ | ||
contentClient: contentManagement.client, | ||
savedObjectsTagging: savedObjectsTaggingOss?.getTaggingApi(), | ||
uiSettings: core.uiSettings, | ||
}} | ||
onChoose={onChoose} | ||
savedObjectMetaData={libraryTypes} | ||
showFilter={true} | ||
noItemsMessage={i18n.translate('embeddableApi.addPanel.noMatchingObjectsMessage', { | ||
defaultMessage: 'No matching objects found.', | ||
})} | ||
getTooltipText={(item) => { | ||
return item.managed | ||
? i18n.translate('embeddableApi.addPanel.managedPanelTooltip', { | ||
defaultMessage: | ||
'Elastic manages this panel. Adding it to a dashboard unlinks it from the library.', | ||
}) | ||
: undefined; | ||
}} | ||
/> | ||
</EuiFlyoutBody> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.