diff --git a/locales/en/plugin__kubevirt-plugin.json b/locales/en/plugin__kubevirt-plugin.json
index aa953627c..4d919ff88 100644
--- a/locales/en/plugin__kubevirt-plugin.json
+++ b/locales/en/plugin__kubevirt-plugin.json
@@ -55,7 +55,7 @@
"<0>The descheduler evicts a running pod so that the pod can be rescheduled on a more suitable node.0> <2>Note: This setting is disabled if the VirtualMachine is not live migratable.2>": "<0>The descheduler evicts a running pod so that the pod can be rescheduled on a more suitable node.0> <2>Note: This setting is disabled if the VirtualMachine is not live migratable.2>",
"<0>This is a Windows VirtualMachine but no Service for the RDP (Remote Desktop Protocol) can be found.0> <2>For better experience accessing Windows console, it is recommended to use the RDP.<1>Create RDP Service1>2>": "<0>This is a Windows VirtualMachine but no Service for the RDP (Remote Desktop Protocol) can be found.0> <2>For better experience accessing Windows console, it is recommended to use the RDP.<1>Create RDP Service1>2>",
"<0>Unattend.xml0><1>Unattend can be used to configure windows setup and can be picked up several times during windows setup/configuration.1><2><0>{t('Learn more')}0>2>": "<0>Unattend.xml0><1>Unattend can be used to configure windows setup and can be picked up several times during windows setup/configuration.1><2><0>{t('Learn more')}0>2>",
- "<0>Welcome to0><1>OpenShift Virtualization1><2>Use OpenShift Virtualization to run and manage virtualized workloads alongside container workloads. You can use it to manage both Linux and Windows virtual machines.2><3>What do you want to do next?3><4>4><5>5>": "<0>Welcome to0><1>OpenShift Virtualization1><2>Use OpenShift Virtualization to run and manage virtualized workloads alongside container workloads. You can use it to manage both Linux and Windows virtual machines.2><3>What do you want to do next?3><4>4><5>5>",
+ "<0>Welcome to0><1>OpenShift Virtualization1><2>Use OpenShift Virtualization to run and manage virtualized workloads alongside container workloads. You can manage both Linux and Windows virtual machines.2><3>What do you want to do next?3><4>4><5>5>": "<0>Welcome to0><1>OpenShift Virtualization1><2>Use OpenShift Virtualization to run and manage virtualized workloads alongside container workloads. You can manage both Linux and Windows virtual machines.2><3>What do you want to do next?3><4>4><5>5>",
"2xlarge": "2xlarge",
"3 (default)": "3 (default)",
"4xlarge": "4xlarge",
@@ -176,6 +176,7 @@
"Available only on Nodes with labels": "Available only on Nodes with labels",
"Available volumes": "Available volumes",
"Average latency": "Average latency",
+ "Back": "Back",
"Back to form": "Back to form",
"Back to form (Deletes DataVolume)": "Back to form (Deletes DataVolume)",
"Balances performance, compatible with a broad range of workloads": "Balances performance, compatible with a broad range of workloads",
@@ -185,6 +186,7 @@
"BandwidthPerMigration limits the amount of network bandwith live migrations are allowed to use. The value is in quantity per second. Defaults to 0 (no limit). ": "BandwidthPerMigration limits the amount of network bandwith live migrations are allowed to use. The value is in quantity per second. Defaults to 0 (no limit). ",
"Base template": "Base template",
"Based on the file extension it seems like you are trying to upload a file which is not supported ({{fileNameExtText}}).": "Based on the file extension it seems like you are trying to upload a file which is not supported ({{fileNameExtText}}).",
+ "Before creating a virtual machine, we recommend that you configure the public SSH key. It will be saved in the project as a secret. You can configure the public SSH key at a later time, but this is the easiest way.": "Before creating a virtual machine, we recommend that you configure the public SSH key. It will be saved in the project as a secret. You can configure the public SSH key at a later time, but this is the easiest way.",
"Before you boot the VirtualMachine (VM) for the first time, add a public SSH key. Only RHEL 9 supports dynamic key injection, and in RHEL 9 you must enable dynamic SSH when you create the VM.": "Before you boot the VirtualMachine (VM) for the first time, add a public SSH key. Only RHEL 9 supports dynamic key injection, and in RHEL 9 you must enable dynamic SSH when you create the VM.",
"BIOS": "BIOS",
"Blank": "Blank",
@@ -321,7 +323,6 @@
"Create a new blank PVC": "Create a new blank PVC",
"Create a new custom Template": "Create a new custom Template",
"Create a Virtual Machine from a template": "Create a Virtual Machine from a template",
- "Create a virtual machine from a template (Quick start)": "Create a virtual machine from a template (Quick start)",
"Create a Windows boot source": "Create a Windows boot source",
"Create activation key": "Create activation key",
"Create DataSource": "Create DataSource",
@@ -437,6 +438,7 @@
"Disks tab": "Disks tab",
"Display name": "Display name",
"display name text area": "display name text area",
+ "Do not show this again": "Do not show this again",
"Documentation": "Documentation",
"Domain": "Domain",
"Download": "Download",
@@ -568,13 +570,13 @@
"Guest system logs are disabled at VirtualMachine": "Guest system logs are disabled at VirtualMachine",
"Guest system logs disabled at cluster": "Guest system logs disabled at cluster",
"Guest system logs not ready. Restart required": "Guest system logs not ready. Restart required",
+ "Guided tour": "Guided tour",
"Hardware devices": "Hardware devices",
"Hardware Devices": "Hardware Devices",
"Hardware devices ({{devices}})": "Hardware devices ({{devices}})",
"Headless mode": "Headless mode",
"Healthy": "Healthy",
"Help": "Help",
- "Hide": "Hide",
"High performance": "High performance",
"History": "History",
"Host devices": "Host devices",
@@ -654,6 +656,7 @@
"Learn how to create, import, and run virtual machines on OpenShift with step-by-step instructions and tasks.": "Learn how to create, import, and run virtual machines on OpenShift with step-by-step instructions and tasks.",
"Learn how to use VirtualMachines": "Learn how to use VirtualMachines",
"Learn more": "Learn more",
+ "Learn more about key areas to complete workflows, increase productivity, and familiarize yourself with Virtualization using our resources.": "Learn more about key areas to complete workflows, increase productivity, and familiarize yourself with Virtualization using our resources.",
"Learn more about MigrationPolicies": "Learn more about MigrationPolicies",
"Learn more about network latency checkups": "Learn more about network latency checkups",
"Learn more about Operators": "Learn more about Operators",
@@ -781,6 +784,7 @@
"Networks misconfigured": "Networks misconfigured",
"New": "New",
"New secret name": "New secret name",
+ "Next": "Next",
"NICs": "NICs",
"No": "No",
"No active users": "No active users",
@@ -853,8 +857,10 @@
"O series": "O series",
"Off": "Off",
"OFF": "OFF",
+ "Okay, got it!": "Okay, got it!",
"On": "On",
"ON": "ON",
+ "On the Configuration tab on the VirtualMachine page, you can search for and edit any configurable item using the search box.": "On the Configuration tab on the VirtualMachine page, you can search for and edit any configurable item using the search box.",
"Only {{volumeMode}} volume mode is available for {{storageClass}} with {{accessMode}} access mode": "Only {{volumeMode}} volume mode is available for {{storageClass}} with {{accessMode}} access mode",
"Only one disk can be bootable at a time, this option is disabled if the VirtualMachine is running or if this disk is the current boot source": "Only one disk can be bootable at a time, this option is disabled if the VirtualMachine is running or if this disk is the current boot source",
"Only one disk can be bootable at a time. The bootable flag will be removed from \"{{initialBootDiskName}}\" and placed on this disk.": "Only one disk can be bootable at a time. The bootable flag will be removed from \"{{initialBootDiskName}}\" and placed on this disk.",
@@ -929,6 +935,7 @@
"Project is required.": "Project is required.",
"Project labels": "Project labels",
"Project name to clone the template to": "Project name to clone the template to",
+ "Project selector": "Project selector",
"Provider": "Provider",
"Provisioning": "Provisioning",
"Public SSH key": "Public SSH key",
@@ -1027,6 +1034,7 @@
"Search by labels...": "Search by labels...",
"Search by name...": "Search by name...",
"Search by reason...": "Search by reason...",
+ "Search for configurable items": "Search for configurable items",
"Secondary NAD networks": "Secondary NAD networks",
"seconds": "seconds",
"Secret name": "Secret name",
@@ -1085,9 +1093,9 @@
"Set the public SSH key to automatically apply to any new VirtualMachine you create in the selected project.": "Set the public SSH key to automatically apply to any new VirtualMachine you create in the selected project.",
"Set the volume metadata to use the volume as a bootable image.": "Set the volume metadata to use the volume as a bootable image.",
"Settings": "Settings",
+ "Settings configurations": "Settings configurations",
"Share this disk between multiple VirtualMachines": "Share this disk between multiple VirtualMachines",
"Shared access (RWX)": "Shared access (RWX)",
- "Show": "Show",
"Show all": "Show all",
"Show all alerts": "Show all alerts",
"Show less": "Show less",
@@ -1135,11 +1143,13 @@
"Start this VirtualMachine after creation ({{runStrategy}})": "Start this VirtualMachine after creation ({{runStrategy}})",
"Start this VirtualMachine in pause mode": "Start this VirtualMachine in pause mode",
"Start time": "Start time",
+ "Start Tour": "Start Tour",
"Start VirtualMachine once created": "Start VirtualMachine once created",
"Started": "Started",
"Status": "Status",
"Status & Conditions": "Status & Conditions",
"Status conditions": "Status conditions",
+ "Step {{current}}/{{size}}": "Step {{current}}/{{size}}",
"Stop": "Stop",
"Storage": "Storage",
"Storage ({{disks}})": "Storage ({{disks}})",
@@ -1195,6 +1205,7 @@
"Templates": "Templates",
"Templates provided by {{providerName}} are not editable.": "Templates provided by {{providerName}} are not editable.",
"Terms": "Terms",
+ "Thank you for taking the tour. Stay up-to-date with Openshift Virtualization on our <4>Blog4> or continue to learn more in our <8>documentation8>.": "Thank you for taking the tour. Stay up-to-date with Openshift Virtualization on our <4>Blog4> or continue to learn more in our <8>documentation8>.",
"The channel to track and receive the updates from.": "The channel to track and receive the updates from.",
"The cloud-init service is enabled by default in Fedora and RHEL images.": "The cloud-init service is enabled by default in Fedora and RHEL images.",
"The DataImportCron polls disk images and imports them as PersistentVolumeClaims. You can configure the image source and other settings on the DataImportCron details page.": "The DataImportCron polls disk images and imports them as PersistentVolumeClaims. You can configure the image source and other settings on the DataImportCron details page.",
@@ -1235,6 +1246,7 @@
"Time zone": "Time zone",
"Timeout": "Timeout",
"Timeout (minutes)": "Timeout (minutes)",
+ "To create virtual machines in a project, you must first create a new project and become the administrator.": "To create virtual machines in a project, you must first create a new project and become the administrator.",
"To edit this template, contact your administrator.": "To edit this template, contact your administrator.",
"To enable Quick create button, fill all the required parameters and storage fields": "To enable Quick create button, fill all the required parameters and storage fields",
"To gain unlimited bandwidth, set to 0": "To gain unlimited bandwidth, set to 0",
@@ -1271,7 +1283,6 @@
"Upload": "Upload",
"Upload (Upload a new file to a PVC)": "Upload (Upload a new file to a PVC)",
"Upload a base image from local disk": "Upload a base image from local disk",
- "Upload a boot source (Quick start)": "Upload a boot source (Quick start)",
"Upload a new file to a PVC. A new PVC will be created.": "Upload a new file to a PVC. A new PVC will be created.",
"Upload a new volume, or use an existing PersistentVolumeClaim (PVC), VolumeSnapshot or DataSource.": "Upload a new volume, or use an existing PersistentVolumeClaim (PVC), VolumeSnapshot or DataSource.",
"Upload canceled": "Upload canceled",
@@ -1401,11 +1412,13 @@
"VolumeSnapshot project": "VolumeSnapshot project",
"Warning": "Warning",
"Warnings": "Warnings",
+ "We hope you found this tour helpful. If you have any <4>feedback4>, we would appreciate hearing from you.": "We hope you found this tour helpful. If you have any <4>feedback4>, we would appreciate hearing from you.",
"We suggest you to create a custom Template from this {{ providerName }} Template.": "We suggest you to create a custom Template from this {{ providerName }} Template.",
"Weight": "Weight",
"Weight must be a number between 1-100": "Weight must be a number between 1-100",
"Welcome information": "Welcome information",
"Welcome modal": "Welcome modal",
+ "When selecting a DataSource that your virtual machines can boot from, you can add a volume that is not listed by clicking the <1>Add volume1> button.": "When selecting a DataSource that your virtual machines can boot from, you can add a volume that is not listed by clicking the <1>Add volume1> button.",
"Whether to attach the default graphics device or not. VNC will not be available if checked": "Whether to attach the default graphics device or not. VNC will not be available if checked",
"Whether to attach the default graphics device or not. VNC will not be available if checked.": "Whether to attach the default graphics device or not. VNC will not be available if checked.",
"Will make disk persistent on next reboot": "Will make disk persistent on next reboot",
@@ -1425,12 +1438,14 @@
"XML structure is not valid": "XML structure is not valid",
"YAML": "YAML",
"Yes": "Yes",
+ "You are ready to go!": "You are ready to go!",
"You can customize the Templates storage by overriding the original parameters": "You can customize the Templates storage by overriding the original parameters",
"You can edit bootable metadata": "You can edit bootable metadata",
"You can edit the boot order in the <1>{t('Disks tab')}1>": "You can edit the boot order in the <1>{t('Disks tab')}1>",
"You can host and manage virtualized workloads on the same platform as container-based workloads.": "You can host and manage virtualized workloads on the same platform as container-based workloads.",
"You can select the boot source in the <2>Disks2> tab.": "You can select the boot source in the <2>Disks2> tab.",
"You can select up to {{MAX_VIEW_COLS}} columns": "You can select up to {{MAX_VIEW_COLS}} columns",
+ "You can set the cluster and your individual preferences in the Settings tab on the Overview page.": "You can set the cluster and your individual preferences in the Settings tab on the Overview page.",
"You can use cloud-init to initialize the operating system with a specific configuration when the VirtualMachine is started.": "You can use cloud-init to initialize the operating system with a specific configuration when the VirtualMachine is started.",
"You don't have permission to perform this action": "You don't have permission to perform this action",
"You must ensure that the configuration is correct before starting the VirtualMachine.": "You must ensure that the configuration is correct before starting the VirtualMachine.",
diff --git a/package.json b/package.json
index da7d2f8c8..aac5c6c03 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"react-helmet": "^6.1.0",
"react-hook-form": "^7.31.2",
"react-i18next": "^11.14.3",
+ "react-joyride": "^2.8.2",
"react-router-dom": "5.3.x",
"react-router-dom-v5-compat": "^6.22.0",
"react-tagsinput": "^3.19.0",
diff --git a/src/utils/components/GuidedTour/GuidedTour.tsx b/src/utils/components/GuidedTour/GuidedTour.tsx
new file mode 100644
index 000000000..485317de4
--- /dev/null
+++ b/src/utils/components/GuidedTour/GuidedTour.tsx
@@ -0,0 +1,69 @@
+import React, { FC } from 'react';
+import Joyride, { ACTIONS, CallBackProps, EVENTS } from 'react-joyride';
+import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
+
+import { isEmpty } from '@kubevirt-utils/utils/utils';
+import { useSignals } from '@preact/signals-react/runtime';
+
+import TourPopover from './components/TourPopover/TourPopover';
+import {
+ nextStep,
+ prevStep,
+ runningTourSignal,
+ stepIndexSignal,
+ stopTour,
+ tourSteps,
+} from './utils/constants';
+
+const GuidedTour: FC = () => {
+ const location = useLocation();
+ const navigate = useNavigate();
+
+ useSignals();
+ return (
+ {
+ const { action, index, size, step, type } = callbackProps;
+ const route = step?.data?.route;
+
+ if (!isEmpty(route) && location.pathname !== route) {
+ navigate(route);
+ }
+
+ if (action === ACTIONS.CLOSE) {
+ stopTour();
+ return;
+ }
+
+ if (type === EVENTS.STEP_AFTER) {
+ if (action === ACTIONS.PREV) {
+ prevStep();
+ return;
+ }
+ if (action === ACTIONS.NEXT) {
+ if (index === size - 1) {
+ stopTour();
+ return;
+ }
+ nextStep();
+ return;
+ }
+ }
+ }}
+ styles={{
+ options: {
+ zIndex: 10000,
+ },
+ }}
+ continuous
+ disableScrollParentFix
+ floaterProps={{ disableAnimation: true }}
+ run={runningTourSignal.value}
+ stepIndex={stepIndexSignal.value}
+ steps={tourSteps}
+ tooltipComponent={TourPopover as any}
+ />
+ );
+};
+
+export default GuidedTour;
diff --git a/src/utils/components/GuidedTour/components/AddVolumeContent/AddVolumeContent.tsx b/src/utils/components/GuidedTour/components/AddVolumeContent/AddVolumeContent.tsx
new file mode 100644
index 000000000..fe9aebf80
--- /dev/null
+++ b/src/utils/components/GuidedTour/components/AddVolumeContent/AddVolumeContent.tsx
@@ -0,0 +1,17 @@
+import React, { FC } from 'react';
+import { Trans } from 'react-i18next';
+
+import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+
+const AddVolumeContent: FC = () => {
+ const { t } = useKubevirtTranslation();
+
+ return (
+
+ When selecting a DataSource that your virtual machines can boot from, you can add a volume
+ that is not listed by clicking the Add volume button.
+
+ );
+};
+
+export default AddVolumeContent;
diff --git a/src/utils/components/GuidedTour/components/EndTourContent/EndTourContent.tsx b/src/utils/components/GuidedTour/components/EndTourContent/EndTourContent.tsx
new file mode 100644
index 000000000..e4359db2a
--- /dev/null
+++ b/src/utils/components/GuidedTour/components/EndTourContent/EndTourContent.tsx
@@ -0,0 +1,30 @@
+import React, { FC } from 'react';
+import { Trans } from 'react-i18next';
+import { Link } from 'react-router-dom-v5-compat';
+
+import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+
+const EndTourContent: FC = () => {
+ const { t } = useKubevirtTranslation();
+
+ return (
+
+ Thank you for taking the tour.
+
+ Stay up-to-date with Openshift Virtualization on our{' '}
+
+ Blog
+ {' '}
+ or continue to learn more in our{' '}
+
+ documentation
+
+ .
+
+ );
+};
+
+export default EndTourContent;
diff --git a/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.scss b/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.scss
new file mode 100644
index 000000000..c705f67db
--- /dev/null
+++ b/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.scss
@@ -0,0 +1,4 @@
+.kv-tour-popover__feedback-footer {
+ background-color: var(--pf-v5-global--BackgroundColor--dark-transparent-100);
+ padding: var(--pf-v5-global--spacer--md);
+}
diff --git a/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.tsx b/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.tsx
new file mode 100644
index 000000000..fa928830d
--- /dev/null
+++ b/src/utils/components/GuidedTour/components/EndTourFooter/EndTourFooter.tsx
@@ -0,0 +1,25 @@
+import React, { FC } from 'react';
+import { Trans } from 'react-i18next';
+import { Link } from 'react-router-dom-v5-compat';
+
+import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+
+const EndTourFooter: FC = () => {
+ const { t } = useKubevirtTranslation();
+
+ return (
+
+
+ We hope you found this tour helpful.
+
+ If you have any{' '}
+
+ feedback
+
+ , we would appreciate hearing from you.
+
+