diff --git a/examples/content_management_examples/public/examples/msearch/msearch_table.tsx b/examples/content_management_examples/public/examples/msearch/msearch_table.tsx index 17d8d992c4620..604be1f403e0c 100644 --- a/examples/content_management_examples/public/examples/msearch/msearch_table.tsx +++ b/examples/content_management_examples/public/examples/msearch/msearch_table.tsx @@ -61,7 +61,7 @@ export const MSearchTable = () => { title={`MSearch Demo`} urlStateEnabled={false} emptyPrompt={<>No data found. Try to install some sample data first.} - onClickTitle={(item) => { + getOnClickTitle={(item) => () => { alert(`Clicked item ${item.attributes.title} (${item.id})`); }} /> diff --git a/packages/content-management/table_list_view/src/table_list_view.tsx b/packages/content-management/table_list_view/src/table_list_view.tsx index 7270fd953a83e..1fd8cc8cc70c2 100644 --- a/packages/content-management/table_list_view/src/table_list_view.tsx +++ b/packages/content-management/table_list_view/src/table_list_view.tsx @@ -31,7 +31,7 @@ export type TableListViewProps({ editItem, deleteItems, getDetailViewLink, - onClickTitle, + getOnClickTitle, rowItemActions, id: listingId, contentEditor, @@ -114,7 +114,7 @@ export const TableListView = ({ deleteItems={deleteItems} rowItemActions={rowItemActions} getDetailViewLink={getDetailViewLink} - onClickTitle={onClickTitle} + getOnClickTitle={getOnClickTitle} id={listingId} contentEditor={contentEditor} titleColumnName={titleColumnName} diff --git a/packages/content-management/table_list_view_table/src/components/item_details.tsx b/packages/content-management/table_list_view_table/src/components/item_details.tsx index 0bd48456c4732..36138839a7daa 100644 --- a/packages/content-management/table_list_view_table/src/components/item_details.tsx +++ b/packages/content-management/table_list_view_table/src/components/item_details.tsx @@ -19,7 +19,7 @@ import { TagBadge } from './tag_badge'; type InheritedProps = Pick< TableListViewTableProps, - 'onClickTitle' | 'getDetailViewLink' | 'id' + 'getOnClickTitle' | 'getDetailViewLink' | 'id' >; interface Props extends InheritedProps { item: T; @@ -39,7 +39,7 @@ export function ItemDetails({ item, searchTerm = '', getDetailViewLink, - onClickTitle, + getOnClickTitle, onClickTag, }: Props) { const { @@ -59,20 +59,21 @@ export function ItemDetails({ ); const onClickTitleHandler = useMemo(() => { + const onClickTitle = getOnClickTitle?.(item); if (!onClickTitle || getDetailViewLink?.(item)) { return undefined; } return ((e) => { e.preventDefault(); - onClickTitle(item); + onClickTitle(); }) as React.MouseEventHandler; - }, [item, onClickTitle, getDetailViewLink]); + }, [getOnClickTitle, item, getDetailViewLink]); const renderTitle = useCallback(() => { const href = getDetailViewLink ? getDetailViewLink(item) : undefined; - if (!href && !onClickTitle) { + if (!href && !getOnClickTitle?.(item)) { // This item is not clickable return {title}; } @@ -93,9 +94,9 @@ export function ItemDetails({ ); }, [ getDetailViewLink, + getOnClickTitle, id, item, - onClickTitle, onClickTitleHandler, redirectAppLinksCoreStart, searchTerm, diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx index 24f9e9db2b564..eef7c839a0359 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx @@ -87,7 +87,7 @@ export interface TableListViewTableProps< /** Handler to set the item title "href" value. If it returns undefined there won't be a link for this item. */ getDetailViewLink?: (entity: T) => string | undefined; /** Handler to execute when clicking the item title */ - onClickTitle?: (item: T) => void; + getOnClickTitle?: (item: T) => (() => void) | undefined; createItem?(): void; deleteItems?(items: T[]): Promise; /** @@ -256,7 +256,7 @@ function TableListViewTableComp({ editItem, deleteItems, getDetailViewLink, - onClickTitle, + getOnClickTitle, id: listingId = 'userContent', contentEditor = { enabled: false }, titleColumnName, @@ -269,9 +269,9 @@ function TableListViewTableComp({ setPageDataTestSubject(`${entityName}LandingPage`); }, [entityName, setPageDataTestSubject]); - if (!getDetailViewLink && !onClickTitle) { + if (!getDetailViewLink && !getOnClickTitle) { throw new Error( - `[TableListView] One o["getDetailViewLink" or "onClickTitle"] prop must be provided.` + `[TableListView] One o["getDetailViewLink" or "getOnClickTitle"] prop must be provided.` ); } @@ -443,6 +443,12 @@ function TableListViewTableComp({ if (item.managed) { ret[item.id] = { + edit: { + enabled: false, + reason: i18n.translate('contentManagement.tableList.managedItemNoEdit', { + defaultMessage: 'This item is managed by Elastic. Clone it before making changes.', + }), + }, ...ret[item.id], delete: { enabled: false, @@ -450,12 +456,6 @@ function TableListViewTableComp({ defaultMessage: 'This item is managed by Elastic. It cannot be deleted.', }), }, - edit: { - enabled: false, - reason: i18n.translate('contentManagement.tableList.managedItemNoEdit', { - defaultMessage: 'This item is managed by Elastic. Clone it before making changes.', - }), - }, }; } @@ -517,7 +517,7 @@ function TableListViewTableComp({ id={listingId} item={record} getDetailViewLink={getDetailViewLink} - onClickTitle={onClickTitle} + getOnClickTitle={getOnClickTitle} onClickTag={(tag, withModifierKey) => { if (withModifierKey) { addOrRemoveExcludeTagFilter(tag); @@ -623,7 +623,7 @@ function TableListViewTableComp({ contentEditor.enabled, listingId, getDetailViewLink, - onClickTitle, + getOnClickTitle, searchQuery.text, addOrRemoveExcludeTagFilter, addOrRemoveIncludeTagFilter, diff --git a/src/plugins/event_annotation_listing/public/components/table_list.test.tsx b/src/plugins/event_annotation_listing/public/components/table_list.test.tsx index 804d027f44cbb..43b0fd632ab19 100644 --- a/src/plugins/event_annotation_listing/public/components/table_list.test.tsx +++ b/src/plugins/event_annotation_listing/public/components/table_list.test.tsx @@ -235,9 +235,9 @@ describe('annotation list view', () => { it('opens editor when title is clicked', async () => { act(() => { - wrapper.find(TableListViewTable).prop('onClickTitle')!({ + wrapper.find(TableListViewTable).prop('getOnClickTitle')!({ id: '1234', - } as UserContentCommonSchema); + } as UserContentCommonSchema)!(); }); await new Promise((resolve) => setTimeout(resolve, 0)); diff --git a/src/plugins/event_annotation_listing/public/components/table_list.tsx b/src/plugins/event_annotation_listing/public/components/table_list.tsx index 603d39e193360..1bc2a9a898b12 100644 --- a/src/plugins/event_annotation_listing/public/components/table_list.tsx +++ b/src/plugins/event_annotation_listing/public/components/table_list.tsx @@ -239,7 +239,7 @@ export const EventAnnotationGroupTableList = ({ entityNamePlural={i18n.translate('eventAnnotationListing.tableList.entityNamePlural', { defaultMessage: 'annotation groups', })} - onClickTitle={editItem} + getOnClickTitle={(item) => () => editItem(item)} {...parentProps} /> {flyout} diff --git a/src/plugins/files_management/public/app.tsx b/src/plugins/files_management/public/app.tsx index caf3ba59d10f7..4ff90db067640 100644 --- a/src/plugins/files_management/public/app.tsx +++ b/src/plugins/files_management/public/app.tsx @@ -78,7 +78,9 @@ export const App: FunctionComponent = () => { initialFilter="" initialPageSize={50} listingLimit={1000} - onClickTitle={({ attributes }) => setSelectedFile(attributes as unknown as FileJSON)} + getOnClickTitle={({ attributes }) => + () => + setSelectedFile(attributes as unknown as FileJSON)} deleteItems={async (items) => { await filesClient.bulkDelete({ ids: items.map(({ id }) => id) }); }} diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index bf07e1151c298..267b9baf6adf4 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -261,8 +261,23 @@ const useTableListViewProps = ( editItem, emptyPrompt: noItemsFragment, createItem: createNewVis, - rowItemActions: ({ attributes: { readOnly } }) => - !visualizeCapabilities.save || readOnly ? { edit: { enabled: false } } : undefined, + rowItemActions: ({ managed, attributes: { readOnly } }) => + !visualizeCapabilities.save || readOnly + ? { + edit: { + enabled: false, + reason: managed + ? i18n.translate('visualizations.managedLegacyVisMessage', { + defaultMessage: + 'This visualization is managed by Elastic and cannot be changed.', + }) + : i18n.translate('visualizations.readOnlyLegacyVisMessage', { + defaultMessage: + "These details can't be edited because this visualization is no longer supported.", + }), + }, + } + : undefined, }; return props; @@ -388,9 +403,9 @@ export const VisualizeListing = () => { entityNamePlural={i18n.translate('visualizations.listing.table.entityNamePlural', { defaultMessage: 'visualizations', })} - onClickTitle={(item) => { - tableViewProps.editItem?.(item); - }} + getOnClickTitle={(item) => + item.attributes.readOnly ? undefined : () => tableViewProps.editItem?.(item) + } getDetailViewLink={({ editor, attributes: { error, readOnly } }) => readOnly || (editor && 'onEdit' in editor) ? undefined diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx index b8cd9c610e9a5..6d5340d8b706d 100644 --- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx @@ -139,7 +139,9 @@ function MapsListViewComp({ history }: Props) { defaultMessage: 'maps', })} title={APP_NAME} - onClickTitle={({ id }) => history.push(getEditPath(id))} + getOnClickTitle={({ id }) => + () => + history.push(getEditPath(id))} /> ); }