Skip to content

feat: Allow Users to Save Tour Pipelines#2339

Draft
camielvs wants to merge 1 commit into
05-27-fix_guided_tours_ephemeral_statefrom
05-28-feat_save_and_resume_paused_tours
Draft

feat: Allow Users to Save Tour Pipelines#2339
camielvs wants to merge 1 commit into
05-27-fix_guided_tours_ephemeral_statefrom
05-28-feat_save_and_resume_paused_tours

Conversation

@camielvs
Copy link
Copy Markdown
Collaborator

@camielvs camielvs commented May 28, 2026

Description

Adds a Save this pipeline affordance at the end of every tour. Curious users who want to keep poking at the pipeline they just walked through (or use it as a starting point) can convert the ephemeral tour pipeline into a real, durable one.

Surfaces only on the last tour step, as a small link-style button below the primary Done action, under a "Continue exploring:" label. Clicking it:

  1. Closes the tour popover (so the mask doesn't interfere with the dialog),
  2. Opens a name-picker dialog,
  3. On submit, serializes the current spec with the new name, writes it to the durable IndexedDB store, and navigates the user into the regular /editor/$name route with the new file open.

If the user just clicks Done, behavior is unchanged: tour ends, temp pipeline stays in session storage until the next tour starts (which resets it).

Architecture

TourCompletionActions extension (src/providers/TourProvider/tourPopover.tsx)

  • The existing Done button (from the framework PR) is now joined by a conditional "Save this pipeline" button when saveExploreHandler is registered. Both render in the last step's content area.
  • A module-level saveExploreHandler slot + registerSaveExploreHandler(cb) API bridges the React tree gap between the reactour popover (rendered above TourModeProvider in the tree, no access to it) and the dialog host (rendered below SharedStoreProvider, has the spec access we need). The popover only knows "is something registered? if so, call it". The dialog host is what registers itself.

TourSaveExploreDialog (src/providers/TourProvider/TourSaveExploreDialog.tsx, mounted inside EditorV2Content)

  • Owns the dialog open/close state.
  • Registers a setOpen(true) handler with registerSaveExploreHandler on mount when tourMode is active; clears it on unmount.
  • On submit: reads the current root spec from useSharedStores().navigation, renames it in-memory via usePipelineActions().renamePipeline, serializes to YAML, and calls tourMode.promoteToPipeline(name, yaml).

promoteToPipeline (src/providers/TourProvider/TourModeContext.tsx + Tour.tsx)

  • New field on the TourModeContext value. The implementation lives in TourPage (above the storage override) where usePipelineStorage() resolves to the durable IndexedDB service.
  • Creates a new file in the durable store with the provided name and YAML, then navigates to /editor/$name. Errors surface via useToastNotification.

Why the indirection through a module-level handler

The natural place to render the dialog is inside EditorV2, where SharedStoreProvider exposes the live spec. The natural place to render the trigger button is the popover, which reactour mounts above our TourModeProvider. React Context can't bridge that gap (the popover renders outside the provider's subtree). The module-level slot is the smallest possible bridge: one writer, one reader, scoped by lifecycle of the dialog host.

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

image.png

Test Instructions

Pre-req: a registered tour (use this branch with #2306 on top).

Happy path

  • Start a tour and step through to the final step.
  • Confirm the popover footer shows Done (primary) and, below it, Save this pipeline (small link).
  • Click Save this pipeline. The popover closes, a name dialog opens.
  • Enter a unique name and submit. You should land in /editor/<name> with the pipeline open and editable. The file appears in the regular pipelines list.
  • The original tour pipeline (__tour__<slug>) remains in session storage; it'll be reset on the next tour start.

Cancel / dismiss

  • Reach the last step again. Click Save this pipeline, then Close the name dialog without submitting.
  • You're now in the tour route with no popover. The Exit Tour button in the nav bar still works.

Name collision

  • Save the tour pipeline as some name. Reach the last step of any tour again and try to save with the same name. The dialog should flag "Name already exists".

Regression

  • Click Done on the last step (don't touch Save). The tour ends, you land on /learn/tours, nothing is added to the pipelines list.
  • Tours other than the last step show no Save button. ESC, the mask, and the (hidden) close button still don't dismiss the popover.

Additional Comments

The "Continue exploring:" framing is intentional — users who walk through a guided tour and walk away should not feel obligated to save anything. Save is opt-in for the curious.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

🎩 Preview

A preview build has been created at: 05-28-feat_save_and_resume_paused_tours/e8f940e

Copy link
Copy Markdown
Collaborator Author

camielvs commented May 28, 2026

@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from e1a0ce6 to 98d9144 Compare May 28, 2026 21:54
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 288fe40 to 1733fc8 Compare May 28, 2026 21:54
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch 3 times, most recently from 2805208 to 931f929 Compare May 29, 2026 00:44
@camielvs camielvs changed the title feat: Save and Resume Paused Tours feat: Allow Users to Save Tour Pipelines May 29, 2026
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from 931f929 to d56854f Compare May 29, 2026 01:08
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 1733fc8 to 444aa16 Compare May 29, 2026 01:08
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from d56854f to eed0e9a Compare May 29, 2026 01:10
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 444aa16 to 38b4021 Compare May 29, 2026 01:10
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from eed0e9a to a906d43 Compare May 29, 2026 01:21
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 38b4021 to b2e2959 Compare May 29, 2026 01:21
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from a906d43 to 9d3d7e9 Compare May 29, 2026 01:26
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from b2e2959 to 63df8cc Compare May 29, 2026 01:26
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from 9d3d7e9 to ea34dec Compare May 29, 2026 01:27
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 63df8cc to e33f721 Compare May 29, 2026 01:28
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from e33f721 to b4e258c Compare May 29, 2026 01:28
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from ea34dec to 7f7afb8 Compare May 29, 2026 01:28
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from b4e258c to 9978c0a Compare May 29, 2026 01:31
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from 7f7afb8 to d12e944 Compare May 29, 2026 01:31
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 9978c0a to 5d19fd6 Compare May 29, 2026 01:35
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from d12e944 to 3eb354f Compare May 29, 2026 01:35
@camielvs camielvs force-pushed the 05-28-feat_save_and_resume_paused_tours branch from 3eb354f to e8f940e Compare May 29, 2026 01:37
@camielvs camielvs force-pushed the 05-27-fix_guided_tours_ephemeral_state branch from 5d19fd6 to 297bd4c Compare May 29, 2026 01:37
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