Skip to content

Product tour#3065

Open
mnocon wants to merge 1 commit into4.6from
product-tour
Open

Product tour#3065
mnocon wants to merge 1 commit into4.6from
product-tour

Conversation

@mnocon
Copy link
Contributor

@mnocon mnocon commented Feb 18, 2026

Target: 4.6, 5.0

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

Contains still some TODOs, but initial feedback is welcome.

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
Contributor Author

Choose a reason for hiding this comment

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

"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
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
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

@sonarqubecloud
Copy link

@github-actions
Copy link

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@111:```yaml hl_lines="6 10"
docs/administration/back_office/configure_product_tour.md@112:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 0, 14) =]]
docs/administration/back_office/configure_product_tour.md@113:```

001⫶ibexa:
002⫶ system:
003⫶ default:
004⫶ product_tour:
005⫶ my_general_scenario:
006❇️ type: 'general'
007⫶ steps:
008⫶ welcome_step:
009⫶ step_title_translation_key: title
010❇️ background_image: build/images/headless.png
011⫶ blocks:
012⫶ - type: title
013⫶ params:
014⫶ text_translation_key: subtitle

docs/administration/back_office/configure_product_tour.md@178:```yaml
docs/administration/back_office/configure_product_tour.md@179:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 11, 14) =]]
docs/administration/back_office/configure_product_tour.md@180:```

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

docs/administration/back_office/configure_product_tour.md@186:```yaml
docs/administration/back_office/configure_product_tour.md@187:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 14, 17) =]]
docs/administration/back_office/configure_product_tour.md@188:```

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

docs/administration/back_office/configure_product_tour.md@194:```yaml
docs/administration/back_office/configure_product_tour.md@195:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 17, 21) =]]
docs/administration/back_office/configure_product_tour.md@196:```

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@202:```yaml
docs/administration/back_office/configure_product_tour.md@203:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 21, 25) =]]
docs/administration/back_office/configure_product_tour.md@204:```

001⫶ - type: image
002⫶ params:
003⫶ src: /bundles/ibexaadminui/img/feature-screenshot.jpg
004⫶ alt_translation_key: tour.image.alt

docs/administration/back_office/configure_product_tour.md@210:```yaml
docs/administration/back_office/configure_product_tour.md@211:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 25, 29) =]]
docs/administration/back_office/configure_product_tour.md@212:```

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@218:```yaml
docs/administration/back_office/configure_product_tour.md@219:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 29, 36) =]]
docs/administration/back_office/configure_product_tour.md@220:```

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@228:```yaml
docs/administration/back_office/configure_product_tour.md@229:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml', 36, 39) =]]
docs/administration/back_office/configure_product_tour.md@230:```

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

docs/administration/back_office/configure_product_tour.md@252:```yaml
docs/administration/back_office/configure_product_tour.md@253:[[= include_file('code_samples/back_office/product_tour/config/general_scenario.yaml') =]]
docs/administration/back_office/configure_product_tour.md@254:```

001⫶ibexa:
002⫶ system:
003⫶ default:
004⫶ product_tour:
005⫶ my_general_scenario:
006⫶ type: 'general'
007⫶ steps:
008⫶ welcome_step:
009⫶ step_title_translation_key: title
010⫶ background_image: build/images/headless.png
011⫶ blocks:
012⫶ - type: title
013⫶ params:
014⫶ text_translation_key: subtitle
015⫶ - type: text
016⫶ params:
017⫶ text_translation_key: tour.step.description
018⫶ - type: link
019⫶ params:
020⫶ url: https://doc.ibexa.co
021⫶ text_translation_key: tour.link.documentation
022⫶ - type: image
023⫶ params:
024⫶ src: /bundles/ibexaadminui/img/feature-screenshot.jpg
025⫶ alt_translation_key: tour.image.alt
026⫶ - type: video
027⫶ params:
028⫶ # 'Big Buck Bunny' licensed under CC 3.0 by the Blender foundation. Hosted by archive.org
029⫶ url: https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4
030⫶ - type: list
031⫶ params:
032⫶ title_translation_key: tour.list.title
033⫶ items_translation_keys:
034⫶ - tour.list.item1
035⫶ - tour.list.item2
036⫶ - tour.list.item3
037⫶ - type: twig_template
038⫶ params:
039⫶ 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@120:```yaml hl_lines="6 10"
docs/administration/back_office/configure_product_tour.md@121:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 0, 15) =]]
docs/administration/back_office/configure_product_tour.md@122:```

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

docs/administration/back_office/configure_product_tour.md@139:```yaml
docs/administration/back_office/configure_product_tour.md@140:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 7, 15) =]]
docs/administration/back_office/configure_product_tour.md@141:```

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@148:```yaml
docs/administration/back_office/configure_product_tour.md@149:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 15, 23) =]]
docs/administration/back_office/configure_product_tour.md@150:```

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@163:```yaml
docs/administration/back_office/configure_product_tour.md@164:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml', 31, 39) =]]
docs/administration/back_office/configure_product_tour.md@165:```

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@260:```yaml
docs/administration/back_office/configure_product_tour.md@261:[[= include_file('code_samples/back_office/product_tour/config/targetable_scenario.yaml') =]]
docs/administration/back_office/configure_product_tour.md@262:```

001⫶ibexa:
002⫶ system:
003⫶ default:
004⫶ product_tour:
005⫶ targetable_dashboard_scenario:
006⫶ type: 'targetable'
007⫶ steps:
008⫶ dashboard_options:
009⫶ step_title_translation_key: Open Dashboard options
010⫶ target: ".ibexa-db-header__more"
011⫶ # No interaction_mode specified or the value is set to null
012⫶ blocks:
013⫶ - type: text
014⫶ params:
015⫶ text_translation_key: Learn how to customize the blocks displayed on your dashboard
016⫶ open_dashboard_options:
017⫶ step_title_translation_key: Open Dashboard options
018⫶ target: '.ibexa-db-header__more'
019⫶ interaction_mode: clickable
020⫶ blocks:
021⫶ - type: text
022⫶ params:
023⫶ text_translation_key: Click here to customize your dashboard
024⫶ customize_dashboard:
025⫶ step_title_translation_key: Customize Dashboard
026⫶ target: '.ibexa-db-actions-popup-menu'
027⫶ interaction_mode: clickable
028⫶ blocks:
029⫶ - type: text
030⫶ params:
031⫶ text_translation_key: Choose "Customize dashboard"
032⫶ drag_and_drop_step:
033⫶ step_title_translation_key: Drag-and-drop blocks
034⫶ target: ".c-pb-toolbox-blocks-group__blocks > * .c-pb-toolbox-block__content:first-of-type"
035⫶ interaction_mode: draggable
036⫶ blocks:
037⫶ - type: text
038⫶ params:
039⫶ 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/api/event_reference/integrated_help_events.md@53:```php hl_lines="35-37 39-41 43-45 47-58"
docs/api/event_reference/integrated_help_events.md@54:[[= include_file('code_samples/back_office/product_tour/src/EventSubscriber/NotificationScenarioSubscriber.php') =]]
docs/api/event_reference/integrated_help_events.md@55:```

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

@mnocon mnocon marked this pull request as ready for review February 18, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments