Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Shareable Saved Objects] Add Spaces column to TableListView #172028

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
35f2199
Add Spaces column to TableListViewTable component
nickpeihl Nov 1, 2023
a8fb8ed
Only show Spaces component for shareable objects
nickpeihl Nov 27, 2023
d62272d
Add namespaces property to saved objects
nickpeihl Nov 27, 2023
3683587
Add namespaces to file saved object
nickpeihl Nov 27, 2023
edbc376
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 27, 2023
53b984e
Fix types on test
nickpeihl Nov 8, 2023
e2dde7e
Merge remote-tracking branch 'refs/remotes/origin/add-spaces-to-table…
nickpeihl Nov 27, 2023
b69c8b8
Add savedObjectsManagement to DashboardApplicationService
nickpeihl Nov 28, 2023
b96864f
Add unit test for spaces column
nickpeihl Nov 28, 2023
affb1b8
Add namespaces to event annotation tests
nickpeihl Nov 28, 2023
d8f6254
Add namespaces to graph saved object type
nickpeihl Nov 28, 2023
c8be794
Add namespaces to maps listing saved object
nickpeihl Nov 28, 2023
22bebc8
Assert namespaces on dashboard saved object
nickpeihl Nov 28, 2023
8b6c306
Coalesce undefined namespaces to empty array
nickpeihl Nov 29, 2023
64b7c1c
Merge branch 'main' into add-spaces-to-tablelist
nickpeihl Nov 29, 2023
1999276
Revert "Add namespaces property to saved objects"
nickpeihl Nov 29, 2023
3bafc9b
Revert "Add namespaces to file saved object"
nickpeihl Nov 29, 2023
9166573
Revert "Add namespaces to event annotation tests"
nickpeihl Nov 29, 2023
892beab
Revert "Add namespaces to graph saved object type"
nickpeihl Nov 29, 2023
b4c87d7
Revert "Add namespaces to maps listing saved object"
nickpeihl Nov 29, 2023
3a17ef0
Merge remote-tracking branch 'refs/remotes/origin/add-spaces-to-table…
nickpeihl Nov 29, 2023
0b0c990
Make namespaces optional in UserContentCommonSchema
nickpeihl Nov 29, 2023
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
3 changes: 3 additions & 0 deletions examples/content_management_examples/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"kibanaReact",
"savedObjectsTaggingOss"
],
"optionalPlugins": [
"spaces"
],
"requiredBundles": ["savedObjectsFinder"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { FinderApp } from './finder';

export const renderApp = (
core: CoreStart,
{ contentManagement, savedObjectsTaggingOss }: StartDeps,
{ contentManagement, savedObjectsTaggingOss, spaces }: StartDeps,
{ element, history }: AppMountParameters
) => {
ReactDOM.render(
Expand Down Expand Up @@ -69,6 +69,7 @@ export const renderApp = (
contentClient={contentManagement.client}
core={core}
savedObjectsTagging={savedObjectsTaggingOss}
spaces={spaces}
/>
</Route>
<Route path="/finder">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Side Public License, v 1.
*/

import React from 'react';
import React, { FC, useMemo } from 'react';
import { SpacesContextProps, SpacesPluginStart } from '@kbn/spaces-plugin/public';
import { ContentClientProvider, type ContentClient } from '@kbn/content-management-plugin/public';
import { TableListViewKibanaProvider } from '@kbn/content-management-table-list-view-table';
import type { CoreStart } from '@kbn/core/public';
Expand All @@ -15,23 +16,37 @@ import { FormattedRelative, I18nProvider } from '@kbn/i18n-react';
import { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public';
import { MSearchTable } from './msearch_table';

const getEmptyFunctionComponent: FC<SpacesContextProps> = ({ children }) => <>{children}</>;

export const MSearchApp = (props: {
contentClient: ContentClient;
core: CoreStart;
savedObjectsTagging: SavedObjectTaggingOssPluginStart;
spaces?: SpacesPluginStart;
}) => {
const SpacesContextWrapper = useMemo(
() =>
props.spaces
? props.spaces.ui.components.getSpacesContextProvider
: getEmptyFunctionComponent,
[props.spaces]
);

return (
<ContentClientProvider contentClient={props.contentClient}>
<I18nProvider>
<TableListViewKibanaProvider
core={props.core}
toMountPoint={toMountPoint}
FormattedRelative={FormattedRelative}
savedObjectsTagging={props.savedObjectsTagging.getTaggingApi()}
>
<MSearchTable />
</TableListViewKibanaProvider>
</I18nProvider>
</ContentClientProvider>
<SpacesContextWrapper>
<ContentClientProvider contentClient={props.contentClient}>
<I18nProvider>
<TableListViewKibanaProvider
core={props.core}
toMountPoint={toMountPoint}
FormattedRelative={FormattedRelative}
savedObjectsTagging={props.savedObjectsTagging.getTaggingApi()}
spacesApi={props.spaces}
>
<MSearchTable />
</TableListViewKibanaProvider>
</I18nProvider>
</ContentClientProvider>
</SpacesContextWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { SavedObjectsFindOptionsReference } from '@kbn/core-saved-objects-api-br

const LISTING_LIMIT = 1000;

// TODO Currently each consumer of TableListView needs to pass an itemIsShareable handler to the TableListView.
// Ideally, the contentClient would use the ISavedObjectTypeRegistry.isShareable method to tell us if the saved
// object type is shareable. For this demo we are hard-coding the shareable object types.
const shareableSavedObjects = ['index-pattern'];

export const MSearchTable = () => {
const contentClient = useContentClient();

Expand Down Expand Up @@ -59,6 +64,7 @@ export const MSearchTable = () => {
entityNamePlural={`ContentItems`}
title={`MSearch Demo`}
urlStateEnabled={false}
itemIsShareable={({ type }) => shareableSavedObjects.includes(type)}
emptyPrompt={<>No data found. Try to install some sample data first.</>}
onClickTitle={(item) => {
alert(`Clicked item ${item.attributes.title} (${item.id})`);
Expand Down
2 changes: 2 additions & 0 deletions examples/content_management_examples/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ContentManagementPublicSetup,
ContentManagementPublicStart,
} from '@kbn/content-management-plugin/public';
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
import { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public';

Expand All @@ -21,4 +22,5 @@ export interface SetupDeps {
export interface StartDeps {
contentManagement: ContentManagementPublicStart;
savedObjectsTaggingOss: SavedObjectTaggingOssPluginStart;
spaces?: SpacesPluginStart;
}
1 change: 1 addition & 0 deletions examples/content_management_examples/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"@kbn/content-management-table-list-view",
"@kbn/shared-ux-router",
"@kbn/saved-objects-finder-plugin",
"@kbn/spaces-plugin",
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type TableListViewProps<T extends UserContentCommonSchema = UserContentCo
| 'titleColumnName'
| 'withoutPageTemplateWrapper'
| 'itemIsEditable'
| 'itemIsShareable'
> & {
title: string;
description?: string;
Expand Down Expand Up @@ -74,6 +75,7 @@ export const TableListView = <T extends UserContentCommonSchema>({
additionalRightSideActions,
withoutPageTemplateWrapper,
itemIsEditable,
itemIsShareable,
}: TableListViewProps<T>) => {
const PageTemplate = withoutPageTemplateWrapper
? (React.Fragment as unknown as typeof KibanaPageTemplate)
Expand Down Expand Up @@ -120,6 +122,7 @@ export const TableListView = <T extends UserContentCommonSchema>({
contentEditor={contentEditor}
titleColumnName={titleColumnName}
itemIsEditable={itemIsEditable}
itemIsShareable={itemIsShareable}
withoutPageTemplateWrapper={withoutPageTemplateWrapper}
onFetchSuccess={onFetchSuccess}
setPageDataTestSubject={setPageDataTestSubject}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

import React, { FC, useState } from 'react';
import type { SpacesPluginStart, ShareToSpaceFlyoutProps } from '@kbn/spaces-plugin/public';

interface Props {
spacesApi: SpacesPluginStart;
canShareToSpaces?: boolean;
spaceIds: string[];
type: string;
noun: string;
id: string;
title: string;
refresh(): void;
}

export const SpacesList: FC<Props> = ({
spacesApi,
canShareToSpaces,
type,
noun,
spaceIds,
id,
title,
refresh,
}) => {
const [showFlyout, setShowFlyout] = useState(false);

function onClose() {
setShowFlyout(false);
}

const LazySpaceList = spacesApi.ui.components.getSpaceList;
const LazyShareToSpaceFlyout = spacesApi.ui.components.getShareToSpaceFlyout;

const shareToSpaceFlyoutProps: ShareToSpaceFlyoutProps = {
savedObjectTarget: {
type,
namespaces: spaceIds,
id,
title,
noun,
},
onUpdate: refresh,
onClose,
};

const clickProperties = canShareToSpaces
? { cursorStyle: 'pointer', listOnClick: () => setShowFlyout(true) }
: { cursorStyle: 'not-allowed' };
return (
<>
<LazySpaceList
namespaces={spaceIds}
displayLimit={8}
behaviorContext="outside-space"
{...clickProperties}
/>
{showFlyout && <LazyShareToSpaceFlyout {...shareToSpaceFlyoutProps} />}
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import React, { FC, useContext, useMemo, useCallback } from 'react';
import type { Observable } from 'rxjs';
import type { FormattedRelative } from '@kbn/i18n-react';
import type { SpacesApi } from '@kbn/spaces-plugin/public';
import type { MountPoint, OverlayRef } from '@kbn/core-mount-utils-browser';
import type { OverlayFlyoutOpenOptions } from '@kbn/core-overlays-browser';
import { RedirectAppLinksKibanaProvider } from '@kbn/shared-ux-link-redirect-app';
Expand Down Expand Up @@ -43,6 +44,7 @@ export interface TagListProps {
*/
export interface Services {
canEditAdvancedSettings: boolean;
canShareToSpaces?: boolean;
getListingLimitSettingsUrl: () => string;
notifyError: NotifyFn;
currentAppId$: Observable<string | undefined>;
Expand All @@ -56,6 +58,7 @@ export interface Services {
/** Handler to retrieve the list of available tags */
getTagList: () => Tag[];
TagList: FC<TagListProps>;
spacesApi?: SpacesApi;
/** Predicate function to indicate if some of the saved object references are tags */
itemHasTags: (references: SavedObjectsReference[]) => boolean;
/** Handler to return the url to navigate to the kibana tags management */
Expand Down Expand Up @@ -155,6 +158,11 @@ export interface TableListViewKibanaDependencies {
getTagIdsFromReferences: (references: SavedObjectsReference[]) => string[];
};
};
/**
* The public API from the Spaces plugin. Provide the `spacesApi` to show the Spaces
* column in the table.
*/
spacesApi?: SpacesApi;
/** The <FormattedRelative /> component from the @kbn/i18n-react package */
FormattedRelative: typeof FormattedRelative;
}
Expand All @@ -166,7 +174,7 @@ export const TableListViewKibanaProvider: FC<TableListViewKibanaDependencies> =
children,
...services
}) => {
const { core, toMountPoint, savedObjectsTagging, FormattedRelative } = services;
const { core, toMountPoint, savedObjectsTagging, spacesApi, FormattedRelative } = services;

const searchQueryParser = useMemo(() => {
if (savedObjectsTagging) {
Expand Down Expand Up @@ -228,6 +236,9 @@ export const TableListViewKibanaProvider: FC<TableListViewKibanaDependencies> =
>
<TableListViewProvider
canEditAdvancedSettings={Boolean(core.application.capabilities.advancedSettings?.save)}
canShareToSpaces={Boolean(
core.application.capabilities.savedObjectsManagement.shareIntoSpace
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @cqliu1 Is it necessary to disable the share to space flyout like this?

)}
getListingLimitSettingsUrl={() =>
core.application.getUrlForApp('management', {
path: `/kibana/settings?query=savedObjects:listingLimit`,
Expand All @@ -245,6 +256,7 @@ export const TableListViewKibanaProvider: FC<TableListViewKibanaDependencies> =
itemHasTags={itemHasTags}
getTagIdsFromReferences={getTagIdsFromReferences}
getTagManagementUrl={() => core.http.basePath.prepend(TAG_MANAGEMENT_APP_URL)}
spacesApi={spacesApi}
>
{children}
</TableListViewProvider>
Expand Down
Loading