diff --git a/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/create_button.tsx b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/create_button.tsx new file mode 100644 index 000000000000000..e80fae858127104 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/create_button.tsx @@ -0,0 +1,47 @@ +/* + * 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 { EuiButton } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { ServiceGroupsTour } from '../service_groups_tour'; +import { useServiceGroupsTour } from '../use_service_groups_tour'; + +interface Props { + onClick: () => void; +} + +export function CreateButton({ onClick }: Props) { + const { tourEnabled, dismissTour } = useServiceGroupsTour('createGroup'); + return ( + + { + dismissTour(); + onClick(); + }} + > + {i18n.translate('xpack.apm.serviceGroups.createGroupLabel', { + defaultMessage: 'Create group', + })} + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/edit_button.tsx b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/edit_button.tsx new file mode 100644 index 000000000000000..8325ffd40195791 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/edit_button.tsx @@ -0,0 +1,47 @@ +/* + * 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 { EuiButton } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { ServiceGroupsTour } from '../service_groups_tour'; +import { useServiceGroupsTour } from '../use_service_groups_tour'; + +interface Props { + onClick: () => void; +} + +export function EditButton({ onClick }: Props) { + const { tourEnabled, dismissTour } = useServiceGroupsTour('editGroup'); + return ( + + { + dismissTour(); + onClick(); + }} + > + {i18n.translate('xpack.apm.serviceGroups.editGroupLabel', { + defaultMessage: 'Edit group', + })} + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/save_button.tsx b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/save_button.tsx index 61828e240c20ab6..c0da29625d7ca3b 100644 --- a/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/save_button.tsx +++ b/x-pack/plugins/apm/public/components/app/service_groups/service_group_save/save_button.tsx @@ -4,11 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiButton } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; import { useAnyOfApmParams } from '../../../../hooks/use_apm_params'; import { useFetcher } from '../../../../hooks/use_fetcher'; +import { CreateButton } from './create_button'; +import { EditButton } from './edit_button'; import { SaveGroupModal } from './save_modal'; export function ServiceGroupSaveButton() { @@ -32,16 +32,18 @@ export function ServiceGroupSaveButton() { ); const savedServiceGroup = data?.serviceGroup; + function onClick() { + setIsModalVisible((state) => !state); + } + return ( <> - { - setIsModalVisible((state) => !state); - }} - > - {isGroupEditMode ? EDIT_GROUP_LABEL : CREATE_GROUP_LABEL} - + {isGroupEditMode ? ( + + ) : ( + + )} + {isModalVisible && ( ); } - -const CREATE_GROUP_LABEL = i18n.translate( - 'xpack.apm.serviceGroups.createGroupLabel', - { defaultMessage: 'Create group' } -); -const EDIT_GROUP_LABEL = i18n.translate( - 'xpack.apm.serviceGroups.editGroupLabel', - { defaultMessage: 'Edit group' } -); diff --git a/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_group_card.tsx b/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_group_card.tsx index 0975bbb4ae3079f..a73b849ee014ee8 100644 --- a/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_group_card.tsx +++ b/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_group_card.tsx @@ -18,12 +18,15 @@ import { ServiceGroup, SERVICE_GROUP_COLOR_DEFAULT, } from '../../../../../common/service_groups'; +import { ServiceGroupsTour } from '../service_groups_tour'; +import { useServiceGroupsTour } from '../use_service_groups_tour'; interface Props { serviceGroup: ServiceGroup; hideServiceCount?: boolean; onClick?: () => void; href?: string; + withTour?: boolean; } export function ServiceGroupsCard({ @@ -31,7 +34,10 @@ export function ServiceGroupsCard({ hideServiceCount = false, onClick, href, + withTour, }: Props) { + const { tourEnabled, dismissTour } = useServiceGroupsTour('serviceGroupCard'); + const cardProps: EuiCardProps = { style: { width: 286, height: 186 }, icon: ( @@ -69,10 +75,39 @@ export function ServiceGroupsCard({ )} ), - onClick, + onClick: () => { + dismissTour(); + if (onClick) { + onClick(); + } + }, href, }; + if (withTour) { + return ( + + + + + + ); + } + return ( diff --git a/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_groups_list.tsx b/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_groups_list.tsx index 06c138f7f01cd07..224e9822a8b60d2 100644 --- a/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_groups_list.tsx +++ b/x-pack/plugins/apm/public/components/app/service_groups/service_groups_list/service_groups_list.tsx @@ -38,6 +38,7 @@ export function ServiceGroupsListItems({ items }: Props) { /> ))} void; + children: React.ReactElement; +} + +export function ServiceGroupsTour({ + tourEnabled, + dismissTour, + title, + content, + children, +}: Props) { + return ( + + {content} + + + {i18n.translate( + 'xpack.apm.serviceGroups.tour.content.link.docs', + { + defaultMessage: 'docs', + } + )} + + ), + }} + /> + + } + isStepOpen={tourEnabled} + onFinish={() => {}} + maxWidth={300} + minWidth={300} + step={1} + stepsTotal={1} + title={title} + anchorPosition="leftUp" + footerAction={ + + {i18n.translate('xpack.apm.serviceGroups.tour.dismiss', { + defaultMessage: 'Dismiss', + })} + + } + > + {children} + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/service_groups/use_service_groups_tour.tsx b/x-pack/plugins/apm/public/components/app/service_groups/use_service_groups_tour.tsx new file mode 100644 index 000000000000000..ba27b0e2640e8ad --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_groups/use_service_groups_tour.tsx @@ -0,0 +1,31 @@ +/* + * 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 { useLocalStorage } from '../../../hooks/use_local_storage'; +import { TourType } from './service_groups_tour'; + +const INITIAL_STATE: Record = { + createGroup: true, + editGroup: true, + serviceGroupCard: true, +}; + +export function useServiceGroupsTour(type: TourType) { + const [tourEnabled, setTourEnabled] = useLocalStorage( + 'apm.serviceGroupsTour', + INITIAL_STATE + ); + + return { + tourEnabled: tourEnabled[type], + dismissTour: () => + setTourEnabled({ + ...tourEnabled, + [type]: false, + }), + }; +}