Skip to content

Product tour#3065

Open
mnocon wants to merge 15 commits into4.6from
product-tour
Open

Product tour#3065
mnocon wants to merge 15 commits into4.6from
product-tour

Conversation

@mnocon
Copy link
Copy Markdown
Contributor

@mnocon mnocon commented Feb 18, 2026

Target: 4.6, 5.0

Documentation for the Product Tour feature - an extension of Integrated Help.

TODO: screenshots are missing in indicated places

User doc PR: ibexa/documentation-user#390

Covers https://github.com/ibexa/integrated-help/pull/59 and https://github.com/ibexa/integrated-help/pull/58 as well

alt_translation_key: tour.image.alt
- type: video
params:
# 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

composer.json Outdated
"ibexa/share": "~4.6.x-dev",
"ibexa/phpstan": "~4.6.-dev"
"ibexa/phpstan": "~4.6.-dev",
"ibexa/integrated-help": "dev-dev as 4.6.x-dev"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TMP branch to make PHPStan happy

With the following example, the scenario is modified to trigger only when certain conditions are matched. When the current user has a pending [notification]([[= user_doc =]]/getting_started/notifications/), a custom onboarding scenario is triggered.

First, define a custom product tour scenario.
It contains a placeholder step with a single block.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A scenario MUST have at least one step, with at least one block - that's why I need to add a placeholder step in Yaml and remove all of them in PHP code

@mnocon mnocon marked this pull request as ready for review February 18, 2026 08:05

Clickable and draggable modes are designed for single actions only (buttons, links).
You can't select an entire form.
If the interaction with the highlighted element results in redirection to a new page or opening a modal window where the previous target element can't be found, the "Previous" navigation step will be disabled.

This comment was marked as resolved.

Embed images with alternative text:

```yaml
[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 21, 25) =]]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't be better to give a example with asset added to public folder. Before block give example that 'I add a photo public/img/welcome.jpg and in config put img/welcome.jpg

``` yaml
ibexa:
system:
default:

This comment was marked as resolved.

@@ -0,0 +1,39 @@
ibexa:
system:
default:

This comment was marked as resolved.

@@ -0,0 +1,39 @@
ibexa:
system:
default:

This comment was marked as resolved.


For **general scenario**, the scenario appears at the earliest opportunity (on any page after logging in), with an exception of the user settings area.

For **targeted scenarios**, the scenario begins if the target element is found in the DOM.

This comment was marked as resolved.

The steps building the scenario support three interaction modes:

- Standard - Users navigate between steps using "Previous" and "Next" buttons
- Clickable - Users must click the highlighted element to proceed to the next step
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea: we can mention, that if someone would want to go to prev step in clickable or draggable mode it is possible only by restarting tour (for example via user setting after finishing tour)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in f12bdcb

@ibexa ibexa deleted a comment from github-actions bot Mar 30, 2026
@ibexa ibexa deleted a comment from sonarqubecloud bot Mar 30, 2026
@ibexa ibexa deleted a comment from sonarqubecloud bot Mar 30, 2026
Users can complete a tour with one of the following actions:

- by finishing all steps
- by skipping it with the **Exit tour** button
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This button differs depending on the tour type. Target tour has "Exit tour" button but general tour exit button has "Skip" label.

@mnocon mnocon requested a review from a team March 31, 2026 10:19
@ibexa-workflow-automation-1 ibexa-workflow-automation-1 bot requested review from adriendupuis, dabrt and julitafalcondusza and removed request for a team March 31, 2026 10:19
```

The product tour scenarios are meant to be translatable.
It's recommended to use translation keys instead of literal values in the YAML configuration, and provide the translations separately.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Ibexa recommends..."? I don't like "we recommend", which prevails in our doc, but would suggest trying to eliminate passive voice

@adriendupuis adriendupuis added the Wait with merge PRs that shouldn't be merged instantly label Apr 2, 2026
@adriendupuis adriendupuis mentioned this pull request Apr 2, 2026
7 tasks
mnocon and others added 5 commits April 9, 2026 15:09
Co-authored-by: Tomasz Dąbrowski <64841871+dabrt@users.noreply.github.com>
Co-authored-by: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/back_office/product_tour/config/general_scenario.yaml


code_samples/back_office/product_tour/config/general_scenario.yaml

docs/administration/back_office/configure_product_tour.md@131:```yaml hl_lines="6 11"
docs/administration/back_office/configure_product_tour.md@132:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 0, 14) =]]
docs/administration/back_office/configure_product_tour.md@133:```

001⫶ibexa:
002⫶ system:
003⫶ admin_group:
004⫶ product_tour:
005⫶ my_general_scenario:
006❇️ type: 'general'
007⫶ scenario_title_translation_key: tour.my_general_scenario.title
008⫶ steps:
009⫶ welcome_step:
010⫶ step_title_translation_key: title
011❇️ background_image: /public/img/background.jpg
012⫶ blocks:
013⫶ - type: title
014⫶ params:

docs/administration/back_office/configure_product_tour.md@205:```yaml
docs/administration/back_office/configure_product_tour.md@206:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 12, 15) =]]
docs/administration/back_office/configure_product_tour.md@207:```

001⫶ - type: title
002⫶ params:
003⫶ text_translation_key: subtitle

docs/administration/back_office/configure_product_tour.md@213:```yaml
docs/administration/back_office/configure_product_tour.md@214:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 15, 18) =]]
docs/administration/back_office/configure_product_tour.md@215:```

001⫶ - type: text
002⫶ params:
003⫶ text_translation_key: tour.step.description

docs/administration/back_office/configure_product_tour.md@221:```yaml
docs/administration/back_office/configure_product_tour.md@222:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 18, 22) =]]
docs/administration/back_office/configure_product_tour.md@223:```

001⫶ - type: link
002⫶ params:
003⫶ url: https://doc.ibexa.co
004⫶ text_translation_key: tour.link.documentation

docs/administration/back_office/configure_product_tour.md@229:```yaml
docs/administration/back_office/configure_product_tour.md@230:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 30, 37) =]]
docs/administration/back_office/configure_product_tour.md@231:```

001⫶ - type: list
002⫶ params:
003⫶ title_translation_key: tour.list.title
004⫶ items_translation_keys:
005⫶ - tour.list.item1
006⫶ - tour.list.item2
007⫶ - tour.list.item3

docs/administration/back_office/configure_product_tour.md@247:```yaml
docs/administration/back_office/configure_product_tour.md@248:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 22, 26) =]]
docs/administration/back_office/configure_product_tour.md@249:```

001⫶ - type: image
002⫶ params:
003⫶ src: /public/img/diagram.jpg
004⫶ alt_translation_key: tour.image.alt

docs/administration/back_office/configure_product_tour.md@255:```yaml
docs/administration/back_office/configure_product_tour.md@256:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 26, 30) =]]
docs/administration/back_office/configure_product_tour.md@257:```

001⫶ - type: video
002⫶ params:
003⫶ # 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org
004⫶ url: https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4

docs/administration/back_office/configure_product_tour.md@263:```yaml
docs/administration/back_office/configure_product_tour.md@264:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 37, 40) =]]
docs/administration/back_office/configure_product_tour.md@265:```

001⫶ - type: twig_template
002⫶ params:
003⫶ template: custom_template.html.twig

docs/administration/back_office/configure_product_tour.md@287:```yaml
docs/administration/back_office/configure_product_tour.md@288:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml') =]]
docs/administration/back_office/configure_product_tour.md@289:```

001⫶ibexa:
002⫶ system:
003⫶ admin_group:
004⫶ product_tour:
005⫶ my_general_scenario:
006⫶ type: 'general'
007⫶ scenario_title_translation_key: tour.my_general_scenario.title
008⫶ steps:
009⫶ welcome_step:
010⫶ step_title_translation_key: title
011⫶ background_image: /public/img/background.jpg
012⫶ blocks:
013⫶ - type: title
014⫶ params:
015⫶ text_translation_key: subtitle
016⫶ - type: text
017⫶ params:
018⫶ text_translation_key: tour.step.description
019⫶ - type: link
020⫶ params:
021⫶ url: https://doc.ibexa.co
022⫶ text_translation_key: tour.link.documentation
023⫶ - type: image
024⫶ params:
025⫶ src: /public/img/diagram.jpg
026⫶ alt_translation_key: tour.image.alt
027⫶ - type: video
028⫶ params:
029⫶ # 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org
030⫶ url: https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4
031⫶ - type: list
032⫶ params:
033⫶ title_translation_key: tour.list.title
034⫶ items_translation_keys:
035⫶ - tour.list.item1
036⫶ - tour.list.item2
037⫶ - tour.list.item3
038⫶ - type: twig_template
039⫶ params:
040⫶ template: custom_template.html.twig


code_samples/back_office/product_tour/config/targetable_scenario.yaml


code_samples/back_office/product_tour/config/targetable_scenario.yaml

docs/administration/back_office/configure_product_tour.md@140:```yaml hl_lines="6 11"
docs/administration/back_office/configure_product_tour.md@141:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 0, 15) =]]
docs/administration/back_office/configure_product_tour.md@142:```

001⫶ibexa:
002⫶ system:
003⫶ admin_group:
004⫶ product_tour:
005⫶ targetable_dashboard_scenario:
006❇️ type: 'targetable'
007⫶ scenario_title_translation_key: tour.targetable_dashboard_scenario.title
008⫶ steps:
009⫶ dashboard_options:
010⫶ step_title_translation_key: Open Dashboard options
011❇️ target: ".ibexa-db-header__more"
012⫶ # No interaction_mode specified or the value is set to null
013⫶ blocks:
014⫶ - type: text
015⫶ params:

docs/administration/back_office/configure_product_tour.md@165:```yaml
docs/administration/back_office/configure_product_tour.md@166:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 8, 16) =]]
docs/administration/back_office/configure_product_tour.md@167:```

001⫶ dashboard_options:
002⫶ step_title_translation_key: Open Dashboard options
003⫶ target: ".ibexa-db-header__more"
004⫶ # No interaction_mode specified or the value is set to null
005⫶ blocks:
006⫶ - type: text
007⫶ params:
008⫶ text_translation_key: Learn how to customize the blocks displayed on your dashboard

docs/administration/back_office/configure_product_tour.md@176:```yaml
docs/administration/back_office/configure_product_tour.md@177:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 16, 24) =]]
docs/administration/back_office/configure_product_tour.md@178:```

001⫶ open_dashboard_options:
002⫶ step_title_translation_key: Open Dashboard options
003⫶ target: '.ibexa-db-header__more'
004⫶ interaction_mode: clickable
005⫶ blocks:
006⫶ - type: text
007⫶ params:
008⫶ text_translation_key: Click here to customize your dashboard

docs/administration/back_office/configure_product_tour.md@187:```yaml
docs/administration/back_office/configure_product_tour.md@188:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 32, 40) =]]
docs/administration/back_office/configure_product_tour.md@189:```

001⫶ drag_and_drop_step:
002⫶ step_title_translation_key: Drag-and-drop blocks
003⫶ target: ".c-pb-toolbox-blocks-group__blocks > * .c-pb-toolbox-block__content:first-of-type"
004⫶ interaction_mode: draggable
005⫶ blocks:
006⫶ - type: text
007⫶ params:
008⫶ text_translation_key: Drag-and-drop blocks from the sidebar to the dashboard to customize it

docs/administration/back_office/configure_product_tour.md@295:```yaml
docs/administration/back_office/configure_product_tour.md@296:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml') =]]
docs/administration/back_office/configure_product_tour.md@297:```

001⫶ibexa:
002⫶ system:
003⫶ admin_group:
004⫶ product_tour:
005⫶ targetable_dashboard_scenario:
006⫶ type: 'targetable'
007⫶ scenario_title_translation_key: tour.targetable_dashboard_scenario.title
008⫶ steps:
009⫶ dashboard_options:
010⫶ step_title_translation_key: Open Dashboard options
011⫶ target: ".ibexa-db-header__more"
012⫶ # No interaction_mode specified or the value is set to null
013⫶ blocks:
014⫶ - type: text
015⫶ params:
016⫶ text_translation_key: Learn how to customize the blocks displayed on your dashboard
017⫶ open_dashboard_options:
018⫶ step_title_translation_key: Open Dashboard options
019⫶ target: '.ibexa-db-header__more'
020⫶ interaction_mode: clickable
021⫶ blocks:
022⫶ - type: text
023⫶ params:
024⫶ text_translation_key: Click here to customize your dashboard
025⫶ customize_dashboard:
026⫶ step_title_translation_key: Customize Dashboard
027⫶ target: '.ibexa-db-actions-popup-menu'
028⫶ interaction_mode: clickable
029⫶ blocks:
030⫶ - type: text
031⫶ params:
032⫶ text_translation_key: Choose "Customize dashboard"
033⫶ drag_and_drop_step:
034⫶ step_title_translation_key: Drag-and-drop blocks
035⫶ target: ".c-pb-toolbox-blocks-group__blocks > * .c-pb-toolbox-block__content:first-of-type"
036⫶ interaction_mode: draggable
037⫶ blocks:
038⫶ - type: text
039⫶ params:
040⫶ text_translation_key: Drag-and-drop blocks from the sidebar to the dashboard to customize it


code_samples/back_office/product_tour/src/EventSubscriber/NotificationScenarioSubscriber.php


code_samples/back_office/product_tour/src/EventSubscriber/NotificationScenarioSubscriber.php

docs/administration/back_office/customize_product_tour.md@43:```php hl_lines="35-37 39-41 43-45 47-58"
docs/administration/back_office/customize_product_tour.md@44:[[= include_file('code_samples/back_office/product_tour/src/EventSubscriber/NotificationScenarioSubscriber.php') =]]
docs/administration/back_office/customize_product_tour.md@45:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\EventSubscriber;
006⫶
007⫶use Ibexa\Contracts\Core\Repository\NotificationService;
008⫶use Ibexa\Contracts\IntegratedHelp\Event\RenderProductTourScenarioEvent;
009⫶use Ibexa\IntegratedHelp\ProductTour\Block\LinkBlock;
010⫶use Ibexa\IntegratedHelp\ProductTour\Block\TextBlock;
011⫶use Ibexa\IntegratedHelp\ProductTour\ProductTourStep;
012⫶use Symfony\Component\EventDispatcher\EventSubscriberInterface;
013⫶
014⫶final class NotificationScenarioSubscriber implements EventSubscriberInterface
015⫶{
016⫶ private NotificationService $notificationService;
017⫶
018⫶ public function __construct(NotificationService $notificationService)
019⫶ {
020⫶ $this->notificationService = $notificationService;
021⫶ }
022⫶
023⫶ public static function getSubscribedEvents(): array
024⫶ {
025⫶ return [
026⫶ RenderProductTourScenarioEvent::class => ['onRenderScenario'],
027⫶ ];
028⫶ }
029⫶
030⫶ public function onRenderScenario(RenderProductTourScenarioEvent $event): void
031⫶ {
032⫶ $scenario = $event->getScenario();
033⫶ $steps = $scenario->getSteps();
034⫶
035❇️ if ($scenario->getIdentifier() !== 'notifications') {
036❇️ return;
037❇️ }
038⫶
039❇️ foreach ($steps as $step) {
040❇️ $scenario->removeStep($step);
041❇️ }
042⫶
043❇️ if (!$this->hasUnreadNotifications()) {
044❇️ return;
045❇️ }
046⫶
047❇️ $customStep = new ProductTourStep();
048❇️ $customStep->setIdentifier('custom_step_identifier');
049❇️ $customStep->setInteractionMode('clickable');
050❇️ $customStep->setTarget('.ibexa-header-user-menu__notifications-toggler');
051❇️ $customStep->setTitle('You have unread notifications');
052❇️ $customStep->addBlock(new TextBlock('Click here to preview your unread notifications.'));
053❇️ $customStep->addBlock(new LinkBlock(
054❇️ 'https://doc.ibexa.co/projects/userguide/en/latest/getting_started/notifications/',
055❇️ 'Learn more about notifications'
056❇️ ));
057❇️
058❇️ $scenario->addStep($customStep);
059⫶ }
060⫶
061⫶ private function hasUnreadNotifications(): bool
062⫶ {
063⫶ return $this->notificationService->getPendingNotificationCount() > 0;
064⫶ }
065⫶}

Download colorized diff

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs DOC review Wait with merge PRs that shouldn't be merged instantly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants