Skip to content

feat: Learning Hub Tour Framework#2299

Draft
camielvs wants to merge 1 commit into
05-20-feat_learning_hub_guided_toursfrom
05-20-feat_learning_hub_tour_framework_and_first_tour
Draft

feat: Learning Hub Tour Framework#2299
camielvs wants to merge 1 commit into
05-20-feat_learning_hub_guided_toursfrom
05-20-feat_learning_hub_tour_framework_and_first_tour

Conversation

@camielvs
Copy link
Copy Markdown
Collaborator

@camielvs camielvs commented May 21, 2026

Description

Adds the foundational groundwork for guided tours in the UI, using Reactour. Tours live at their own URL (/tour/$tourId) so they're refreshable, shareable, and own their lifecycle cleanly.

Supports forward/back controls, interactive activities ("click here", "drag this" etc) and dynamic highlighting of relevant UI elements. Interactive steps include fallback options if the interaction has already been completed or is otherwise unavailable.

Tours run inside a fresh ephemeral pipeline (__tour__<slug>). When the user leaves the tour route the pipeline is deleted — tours have no save state, every visit starts fresh. If the user wants to keep the work, "Save as new pipeline" in the editor's tour-mode action bar promotes the temp pipeline into a regular one.

Architecture

Route (/tour/$tourId, src/routes/Tour.tsx)

  • Owns the tour pipeline lifecycle: creates a fresh __tour__<slug> on mount, deletes it on unmount unless promoted
  • Snapshots the editor's window layout on entry, restores it on exit so the user's saved arrangement isn't disturbed
  • Bridges the URL's ?step=N and reactour's internal currentStep so browser back/forward navigates tour steps
  • Defers reactour activation until the editor DOM mounts (waitForSelector('[data-testid="editor-v2"]')) — step selectors target editor DOM
  • Falls back to /learn/tours if tourId doesn't match a registered tour

Tour mode context (src/providers/TourProvider/TourModeContext.tsx)

  • Exposes useTourMode() to editor components: { tour, tempPipelineName, markPipelinePromoted }
  • Editor menu bar uses this to render a "Tour" badge, hide rename/delete actions in the File menu, and show Resume / Save as new pipeline / Exit buttons while the popover is dismissed

Reactour wrapper (src/providers/TourProvider/TourProvider.tsx)

  • Wraps the app in <TourProvider> from reactour with custom Prev / Next / Finish buttons and styling
  • Finish navigates to /learn/tours; X / ESC dismiss the popover but stay on the route so the user can poke around or resume
  • Clamps the popover to the viewport so the step badge isn't clipped near screen edges

Editor bridge (src/routes/v2/pages/Editor/components/EditorTourBridge.tsx)

  • Implements three interaction primitives any step can declare: interaction: "undock-window" | "redock-window" | "select-task"
  • Follows window positions so the highlight tracks a floating panel as the user drags it
  • Falls back to non-interactive copy (fallbackContent) when the prompted state is already satisfied

Orphan cleanup (src/providers/TourProvider/TourOrphanCleanup.tsx)

  • Sweeps __tour__* pipelines on app load to catch tab-close / crash orphans. Route unmount handles every normal exit path; this covers what the browser kills before we can run.

Learn page wiringFeaturedTours and ToursLibrary link directly to /tour/$tourId for registered tours; unregistered IDs render as "Coming soon"

Registry is intentionally empty

src/components/Learn/tours/registry.ts ships with const tours: TourDefinition[] = []. Until the first tour is registered (see #2306), every tile on the Learn page renders as "Coming soon". This keeps the framework merge-safe on its own.

How to add a tour

  1. Create src/components/Learn/tours/<yourTour>.tour.ts exporting a TourDefinition
  2. Import + push into the tours array in registry.ts
  3. Add the data-tour="..." / data-window-id / etc. anchors on the UI elements the steps target
  4. To target a task node by name, use the data-task-name attribute (already exposed via createEntityNode's domAttributes)

Related Issue and Pull requests

Progresses https://github.com/Shopify/oasis-frontend/issues/583

Type of Change

  • New feature

Checklist

  • I have tested this does not break current pipelines / runs functionality
  • I have tested the changes on staging

Screenshots (if applicable)

image.png

image.png

Test Instructions

With the registry empty, the visible behavior is:

  • /learn/tours and the dashboard Featured Tours tile render every tour as "Coming soon"
  • No tour can be started; no tour UI appears anywhere
  • Existing editor / runs / dashboard flows are unaffected
  • Navigating to /tour/anything redirects to /learn/tours

Regression check: confirm pipelines list, editor menu bar, dockable / floating windows, and task nodes behave identically to master — none of the tour engine should be visible until a tour registers.

Additional Comments

More tours are intended to follow the first one, covering a range of topics.

Copy link
Copy Markdown
Collaborator Author

camielvs commented May 21, 2026

@camielvs camielvs mentioned this pull request May 21, 2026
3 tasks
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

🎩 Preview

A preview build has been created at: 05-20-feat_learning_hub_tour_framework_and_first_tour/3adc6cd

@camielvs camielvs added the #gsd:50583 Learning Hub label May 21, 2026 — with Graphite App
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch 3 times, most recently from 08e1624 to 90d5b9d Compare May 21, 2026 22:07
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from 0f30f2c to 4cc74f0 Compare May 21, 2026 22:07
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch from 90d5b9d to d89055f Compare May 21, 2026 22:36
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from 4cc74f0 to fd9690e Compare May 21, 2026 22:37
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch 4 times, most recently from a0e7c17 to a98fb46 Compare May 22, 2026 18:40
@camielvs camielvs changed the title feat: Learning Hub Tour Framework and First Tour feat: Learning Hub Tour Framework May 22, 2026
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch from a98fb46 to 9f459c8 Compare May 22, 2026 19:29
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from fd9690e to 8c23f4e Compare May 22, 2026 21:53
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch from 9f459c8 to e7770ca Compare May 22, 2026 21:53
@camielvs camielvs mentioned this pull request May 22, 2026
8 tasks
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch from e7770ca to e26abd3 Compare May 23, 2026 00:09
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from 8c23f4e to b781af4 Compare May 23, 2026 00:12
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch 2 times, most recently from d95e8da to 6246686 Compare May 23, 2026 00:21
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from b781af4 to 12125e7 Compare May 23, 2026 00:21
Introduces the guided tour framework using [Reactour](https://docs.reactour.dev/),
exposed as a dedicated `/tour/$tourId` route rather than an imperative
provider call. The route owns:

- The temp tour pipeline lifecycle (create on mount, delete on unmount,
  no persisted "save state" — tours always start fresh)
- Editor layout snapshot/restore around the tour
- URL ↔ reactour step sync (`?step=N` is a stable, shareable deep-link
  and survives same-tab refresh via the URL itself)
- A `TourModeContext` consumed by `EditorMenuBar` and `FileMenu` to show
  tour-specific UI (badge, Resume/Save-as/Exit buttons when the popover
  is closed) and hide destructive actions

Engine bits live under `src/providers/TourProvider/`:
- `TourProvider.tsx` — slim reactour wrapper, app-wide
- `tourPopover.tsx` — styles, position fn, FinishButton, clamp bridge
- `tourPipelineLifecycle.ts` — create/delete/promote/cleanup helpers
- `TourOrphanCleanup.tsx` — sweeps tour pipelines on app load (catches
  tab-close orphans), skipped while user is on a tour route
- `TourModeContext.tsx` — context hook for editor components
- `waitForSelector.ts` — DOM utility

`EditorV2` accepts an optional `pipelineRef` prop so the tour route can
render the same editor against a temp pipeline it resolved itself.

Layout snapshot/restore is exposed from `windowPersistence` so the tour
doesn't reach into localStorage directly.

`registry.ts` ships with `tours: TourDefinition[] = []` — the first
tour lands in the stacked PR.
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_tour_framework_and_first_tour branch from 6246686 to 3adc6cd Compare May 23, 2026 00:22
@camielvs camielvs force-pushed the 05-20-feat_learning_hub_guided_tours branch from 12125e7 to 77a5131 Compare May 23, 2026 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50583 Learning Hub

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant