From 574af418a2dd30ad19eee0a4c49b82b41c489470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Rica=20Pais=20da=20Silva?= Date: Wed, 2 Oct 2024 11:19:44 +0200 Subject: [PATCH] [Inventory] Add Sharing button (#194535) ## Summary Adds a Share link button to the Inventory page, next to the Add Data button on the top right of the screen. This creates a short link and copies it to the user's clipboard so they can share it. https://github.com/user-attachments/assets/42c7b2f9-da19-4ced-8d28-211234bea4cf ## How to Test - Log in and go to Inventory page. Ensure there is data loaded and entities are showing. - Put a filter on the inventory to restrict the results to a given state, such as `entity.type : "service"`. - Click on the `Share` button and wait until you get a success toast message. - Open a new empty tab on the browser and paste the link into the url bar to navigate to the page. **Expected Result**: The page should navigate to the Inventory page and load into the same state as the page on the original browser tab. Closes #192325 --------- Co-authored-by: Elastic Machine --- .../app_root/header_action_menu/index.tsx | 2 + .../header_action_menu/share_link.tsx | 82 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/share_link.tsx diff --git a/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/index.tsx index 5ae0f4dd24574..ad139ba5100da 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/index.tsx @@ -8,10 +8,12 @@ import React from 'react'; import { EuiHeaderLinks } from '@elastic/eui'; import { AddDataContextMenu } from './add_data_action_menu'; +import { ShareLink } from './share_link'; export function HeaderActionMenuItems() { return ( + ); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/share_link.tsx b/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/share_link.tsx new file mode 100644 index 0000000000000..54cceae2c4ad6 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/app_root/header_action_menu/share_link.tsx @@ -0,0 +1,82 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useState } from 'react'; +import copy from 'copy-to-clipboard'; +import { i18n } from '@kbn/i18n'; +import { EuiButtonEmpty } from '@elastic/eui'; +import { useKibana } from '../../../hooks/use_kibana'; + +const SHARE_BUTTON_LABEL = i18n.translate('xpack.inventory.shareLink.shareButtonLabel', { + defaultMessage: 'Share', +}); + +const SHARE_TOAST_SUCCESS_LABEL = i18n.translate( + 'xpack.inventory.shareLink.shareToastSuccessLabel', + { defaultMessage: 'Short URL copied to clipboard!' } +); + +const SHARE_TOAST_FAILURE_LABEL = i18n.translate( + 'xpack.inventory.shareLink.shareToastFailureLabel', + { defaultMessage: 'Short URL unable to be copied.' } +); + +function useShortUrlService() { + const { + services: { share, notifications }, + } = useKibana(); + + const [isLoading, setIsLoading] = useState(false); + + const copyShortUrl = useCallback(async () => { + setIsLoading(true); + + try { + const shortUrls = share.url.shortUrls.get(null); + + const { url } = await shortUrls.createFromLongUrl(window.location.toString()); + + setIsLoading(false); + + if (copy(url)) { + notifications.toasts.addSuccess({ + title: SHARE_TOAST_SUCCESS_LABEL, + iconType: 'copyClipboard', + }); + } else { + throw new Error('Clipboard copy error'); + } + } catch (e) { + const err = e as Error; + notifications.toasts.addDanger({ + title: SHARE_TOAST_FAILURE_LABEL, + iconType: 'error', + text: err.message, + }); + } + }, [share, notifications.toasts]); + + return { + isLoading, + copyShortUrl, + }; +} + +export function ShareLink() { + const { isLoading, copyShortUrl } = useShortUrlService(); + + return ( + + {SHARE_BUTTON_LABEL} + + ); +}