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,
+ }),
+ };
+}