Skip to content

feat: add guided tour#3051

Open
yashmehrotra wants to merge 3 commits into
mainfrom
tour
Open

feat: add guided tour#3051
yashmehrotra wants to merge 3 commits into
mainfrom
tour

Conversation

@yashmehrotra

@yashmehrotra yashmehrotra commented Jun 22, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

Release Notes

  • New Features

    • Added an interactive guided tour with a “Take a tour” menu.
    • Tour progress/controls are powered by an in-app tooltip and support route-aware and target-based steps.
    • Added tour targeting labels across key UI areas (navigation, tables, buttons, detail sections, and chart/timeline views).
  • Bug Fixes

    • Improved resilience when handling incomplete flow error payloads.
  • Tests

    • Added unit tests covering guided tour step building and progression logic.
  • Refactor

    • Updated the version display component to support ref forwarding.

@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aws-preview Ready Ready Preview Jun 24, 2026 4:47am
flanksource-ui Ready Ready Preview Jun 24, 2026 4:47am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a multi-section guided product tour using react-joyride, backed by Jotai state atoms and pure step-advancement logic. Tour entry points are wired into both Clerk and Kratos user profile dropdowns and mounted in SidebarLayout. Numerous components across health, catalog, config, playbooks, and views pages receive data-tour attributes for targeting. Also fixes optional chaining in the Kratos error handler.

Changes

Guided Tour Feature

Layer / File(s) Summary
Tour step types, target finders, and section step arrays
src/components/GuidedTour/guidedTourSteps.ts, package.json
Defines TourStepData, tourTarget, DOM target-finding utilities, ordered step arrays per section (dashboardSteps, healthSteps, catalogSteps, playbookSteps, viewSteps), buildTourSteps(), and the tourSteps export. Adds react-joyride ^3.1.0 dependency.
Pure tour advancement and event reduction logic
src/components/GuidedTour/guidedTourSteps.ts
Implements resolveAutoAdvance (pathname/param/regex gating), resolveTargetNotFound (finish vs. skip-forward vs. skip-section), and reduceTourEvent (maps Joyride button events to run/stepIndex updates).
Jotai atoms and tour control hooks
src/components/GuidedTour/guidedTourState.ts
Defines tourRunAtom, tourStepIndexAtom, tourMenuOpenAtom, tourStepsAtom; adds useCanRunPlaybooks, useStartTour, and useStartTourSection.
GuidedTour, TourMenu, and TourTooltip components
src/components/GuidedTour/GuidedTour.tsx, src/components/GuidedTour/TourMenu.tsx, src/components/GuidedTour/TourTooltip.tsx
GuidedTour drives react-joyride in controlled mode with effects for auto-advance on route/param changes, click-listener attachment on dynamic DOM targets, and scroll-into-view positioning. TourMenu renders a section-picker modal (filtered by canRunPlaybooks). TourTooltip renders the styled step tooltip with title, body, doc link, progress, and navigation buttons.
Tour entry points in user profile and sidebar layout
src/ui/Layout/SidebarLayout.tsx, src/components/Users/UserProfile.tsx, src/components/Authentication/Kratos/KratosUserProfileDropdown.tsx, src/components/VersionInfo/VersionInfo.tsx
SidebarLayout mounts <GuidedTour />. UserProfile adds a "Start interactive tour" menu action for both Clerk and Kratos auth paths. KratosUserProfileDropdown gains a startTour prop and MenuItem. VersionInfo is refactored to forwardRef for DOM ref targeting.
data-tour attribute instrumentation
src/components/Layout/AppSidebar.tsx, src/ui/Tabs/TabbedLinks.tsx, src/ui/Buttons/DialogButton.tsx, src/components/Canary/..., src/components/Configs/..., src/components/Playbooks/..., src/pages/...
Adds data-tour (and data-tour-status, data-tour-name, data-tour-class, data-tour-type) attributes to sidebar nav links, tabbed nav links, dialog buttons, health/canary rows and detail panels, config/catalog cells and list items, playbook cards and run form elements, and page-level containers.
Unit tests for guidedTourSteps
src/components/GuidedTour/__tests__/guidedTourSteps.unit.test.ts
Tests tourTarget, resolveAutoAdvance, resolveTargetNotFound, reduceTourEvent, tourSteps per-section metadata, and buildTourSteps section filtering and playbooks omission.

Kratos Error Handler Fix

Layer / File(s) Summary
Optional chaining in handleGetFlowError
src/components/Authentication/Kratos/ory/hooks.ts
Updates the error id switch and two redirect assignments to use optional chaining on err.response?.data?.error?.id and err.response?.data?.redirect_browser_to.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UserProfile
  participant TourMenu
  participant GuidedTour
  participant Joyride
  participant DOM

  User->>UserProfile: clicks "Start interactive tour"
  UserProfile->>TourMenu: useStartTour() → tourMenuOpenAtom = true
  TourMenu->>User: renders section picker modal
  User->>TourMenu: selects a section
  TourMenu->>GuidedTour: useStartTourSection() → tourStepsAtom, tourRunAtom=true
  GuidedTour->>Joyride: renders with steps/run/stepIndex (controlled)
  Joyride->>User: displays TourTooltip on target element
  User->>Joyride: clicks Next
  Joyride->>GuidedTour: onEvent(STEP_AFTER NEXT)
  GuidedTour->>GuidedTour: reduceTourEvent → stepIndex+1
  GuidedTour->>DOM: resolveAutoAdvance checks pathname/params
  GuidedTour->>DOM: advanceOnTargetClick attaches click listener
  DOM->>GuidedTour: target click → stepIndex+1 or endTour
  Joyride->>GuidedTour: onEvent(TARGET_NOT_FOUND)
  GuidedTour->>GuidedTour: resolveTargetNotFound → skip or finish
Loading

Possibly related PRs

  • flanksource/flanksource-ui#3047: Both PRs modify handleGetFlowError in src/components/Authentication/Kratos/ory/hooks.ts, with the retrieved PR changing return_to sanitization for /oidc/* routes and this PR adding optional chaining on redirect_browser_to reads.

Suggested reviewers

  • adityathebe
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.59% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'feat: add guided tour' directly and clearly describes the main change: introducing a guided tour feature to the application.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tour
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch tour

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedreact-joyride@​3.1.0991009990100

View full report

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/components/GuidedTour/__tests__/guidedTourSteps.unit.test.ts (1)

27-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression tests for empty-param gating and PREV-at-zero behavior.

These two boundaries are currently untested and are easy to regress in the pure reducers.

Suggested test additions
 describe("resolveAutoAdvance", () => {
@@
   it("does not advance when the gated param is absent", () => {
     expect(resolveAutoAdvance(steps, 2, ctx("/health"))).toBeNull();
   });
+
+  it("does not advance when the gated param is present but empty", () => {
+    expect(resolveAutoAdvance(steps, 2, ctx("/health", "checkId="))).toBeNull();
+  });
@@
 describe("reduceTourEvent", () => {
@@
   it("goes back on a prev-button step:after event", () => {
     expect(reduceTourEvent({ ...base, action: ACTIONS.PREV })).toEqual({
       run: true,
       stepIndex: 0
     });
   });
+
+  it("does not go below zero on prev from the first step", () => {
+    expect(
+      reduceTourEvent({ ...base, action: ACTIONS.PREV, index: 0 })
+    ).toEqual({
+      run: true,
+      stepIndex: 0
+    });
+  });

Also applies to: 152-194

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/GuidedTour/__tests__/guidedTourSteps.unit.test.ts` around
lines 27 - 50, Add two new test cases to the resolveAutoAdvance test suite.
First, add a test that verifies the behavior when a parameter is present but
empty (like "checkId=" with no value) to cover empty-param gating scenarios.
Second, add a test that verifies what happens when attempting to navigate to the
previous step (using PREV) when currently at step index 0, which is a boundary
condition that should be tested. These tests should follow the same pattern as
the existing tests in the suite and use the ctx() helper function with
appropriate parameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Authentication/Kratos/ory/hooks.ts`:
- Line 54: The code assigns err.response?.data?.redirect_browser_to directly to
window.location.href without verifying that redirect_browser_to is actually
defined. If Kratos returns an incomplete response where redirect_browser_to is
undefined, this will cause uncontrolled navigation. Add a guard condition to
check if redirect_browser_to exists before assigning it to window.location.href,
and implement a controlled fallback behavior (such as redirecting to a safe
route or resetting the state) when it is undefined. This same fix needs to be
applied to both instances mentioned (line 54 and line 85).

In `@src/components/GuidedTour/guidedTourSteps.ts`:
- Around line 588-590: The PREV action handler does not guard against
decrementing the step index below zero, which occurs when at index 0. Add a
guard condition in the block where action === ACTIONS.PREV to check if index is
greater than 0 before returning the decremented stepIndex. If the index is
already at 0, either return the current state unchanged or handle it
appropriately to prevent the invalid negative index that causes tour state
desyncing.
- Around line 522-523: The paramPresent variable in guidedTourSteps.ts currently
checks if the query parameter is non-null, but URLSearchParams.get() returns an
empty string for parameters like ?param=, which passes the null check and
incorrectly advances the tour. Modify the condition to also verify that the
parameter value is not an empty string, so only parameters with actual non-empty
values are treated as present for the auto-advance gate logic.

---

Nitpick comments:
In `@src/components/GuidedTour/__tests__/guidedTourSteps.unit.test.ts`:
- Around line 27-50: Add two new test cases to the resolveAutoAdvance test
suite. First, add a test that verifies the behavior when a parameter is present
but empty (like "checkId=" with no value) to cover empty-param gating scenarios.
Second, add a test that verifies what happens when attempting to navigate to the
previous step (using PREV) when currently at step index 0, which is a boundary
condition that should be tested. These tests should follow the same pattern as
the existing tests in the suite and use the ctx() helper function with
appropriate parameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 486ff875-9f0b-40c4-8be0-e4ef5ead1b0e

📥 Commits

Reviewing files that changed from the base of the PR and between 964cda8 and 509e6b3.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (30)
  • package.json
  • src/components/Authentication/Kratos/KratosUserProfileDropdown.tsx
  • src/components/Authentication/Kratos/ory/hooks.ts
  • src/components/Canary/CanaryPopup/CheckDetails.tsx
  • src/components/Canary/CanaryPopup/CheckDetailsTabs.tsx
  • src/components/Canary/CanaryPopup/CheckRunNow.tsx
  • src/components/Canary/CanaryTable.tsx
  • src/components/Canary/index.tsx
  • src/components/Configs/ConfigList/MRTConfigListColumn.tsx
  • src/components/Configs/ConfigSummary/Cells/ConfigSummaryTableVirtualAggregateColumn.tsx
  • src/components/Configs/ConfigSummary/ConfigSummaryList.tsx
  • src/components/GuidedTour/GuidedTour.tsx
  • src/components/GuidedTour/TourMenu.tsx
  • src/components/GuidedTour/TourTooltip.tsx
  • src/components/GuidedTour/__tests__/guidedTourSteps.unit.test.ts
  • src/components/GuidedTour/guidedTourState.ts
  • src/components/GuidedTour/guidedTourSteps.ts
  • src/components/Layout/AppSidebar.tsx
  • src/components/Playbooks/Runs/PlaybookRunsList.tsx
  • src/components/Playbooks/Runs/Submit/SubmitPlaybookRunForm.tsx
  • src/components/Playbooks/Settings/PlaybookSpecCard.tsx
  • src/components/Users/UserProfile.tsx
  • src/components/VersionInfo/VersionInfo.tsx
  • src/pages/config/ConfigList.tsx
  • src/pages/config/details/ConfigDetailsPage.tsx
  • src/pages/playbooks/PlaybookRunsDetails.tsx
  • src/pages/views/components/ViewContainer.tsx
  • src/ui/Buttons/DialogButton.tsx
  • src/ui/Layout/SidebarLayout.tsx
  • src/ui/Tabs/TabbedLinks.tsx

case "session_refresh_required":
// We need to re-authenticate to perform this action
window.location.href = err.response?.data.redirect_browser_to;
window.location.href = err.response?.data?.redirect_browser_to;

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard redirect_browser_to before assigning window.location.href

Both branches now allow undefined to flow into window.location.href. If Kratos returns a partial payload, this can trigger incorrect navigation rather than a controlled fallback. Add a null check (and fallback route/reset) before redirecting.

Suggested fix
       case "session_refresh_required":
         // We need to re-authenticate to perform this action
-        window.location.href = err.response?.data?.redirect_browser_to;
+        if (err.response?.data?.redirect_browser_to) {
+          window.location.href = err.response.data.redirect_browser_to;
+          return;
+        }
+        resetFlow(undefined);
+        await router.push("/" + flowType);
         return;
@@
       case "browser_location_change_required":
         // Ory Kratos asked us to point the user to this URL.
-        window.location.href = err.response?.data?.redirect_browser_to;
+        if (err.response?.data?.redirect_browser_to) {
+          window.location.href = err.response.data.redirect_browser_to;
+          return;
+        }
+        resetFlow(undefined);
+        await router.push("/" + flowType);
         return;

Also applies to: 85-85

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Authentication/Kratos/ory/hooks.ts` at line 54, The code
assigns err.response?.data?.redirect_browser_to directly to window.location.href
without verifying that redirect_browser_to is actually defined. If Kratos
returns an incomplete response where redirect_browser_to is undefined, this will
cause uncontrolled navigation. Add a guard condition to check if
redirect_browser_to exists before assigning it to window.location.href, and
implement a controlled fallback behavior (such as redirecting to a safe route or
resetting the state) when it is undefined. This same fix needs to be applied to
both instances mentioned (line 54 and line 85).

Comment on lines +522 to +523
const paramPresent =
!!data.advanceOnParam && ctx.params.get(data.advanceOnParam) != null;

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Treat empty query-param values as absent for auto-advance gates.

URLSearchParams.get() returns "" for ?param=, and the current condition advances on that. This can skip gated steps before a real selection exists.

Suggested fix
-  const paramPresent =
-    !!data.advanceOnParam && ctx.params.get(data.advanceOnParam) != null;
+  const paramValue = data.advanceOnParam
+    ? ctx.params.get(data.advanceOnParam)
+    : null;
+  const paramPresent = paramValue != null && paramValue !== "";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const paramPresent =
!!data.advanceOnParam && ctx.params.get(data.advanceOnParam) != null;
const paramValue = data.advanceOnParam
? ctx.params.get(data.advanceOnParam)
: null;
const paramPresent = paramValue != null && paramValue !== "";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/GuidedTour/guidedTourSteps.ts` around lines 522 - 523, The
paramPresent variable in guidedTourSteps.ts currently checks if the query
parameter is non-null, but URLSearchParams.get() returns an empty string for
parameters like ?param=, which passes the null check and incorrectly advances
the tour. Modify the condition to also verify that the parameter value is not an
empty string, so only parameters with actual non-empty values are treated as
present for the auto-advance gate logic.

Comment on lines +588 to +590
if (action === ACTIONS.PREV) {
return { run: true, stepIndex: index - 1 };
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard PREV transitions from producing a negative step index.

A PREV event at index 0 currently returns -1, which is an invalid controlled index and can desync tour state.

Suggested fix
    if (action === ACTIONS.PREV) {
-      return { run: true, stepIndex: index - 1 };
+      return { run: true, stepIndex: Math.max(0, index - 1) };
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (action === ACTIONS.PREV) {
return { run: true, stepIndex: index - 1 };
}
if (action === ACTIONS.PREV) {
return { run: true, stepIndex: Math.max(0, index - 1) };
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/GuidedTour/guidedTourSteps.ts` around lines 588 - 590, The
PREV action handler does not guard against decrementing the step index below
zero, which occurs when at index 0. Add a guard condition in the block where
action === ACTIONS.PREV to check if index is greater than 0 before returning the
decremented stepIndex. If the index is already at 0, either return the current
state unchanged or handle it appropriately to prevent the invalid negative index
that causes tour state desyncing.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/GuidedTour/GuidedTour.tsx`:
- Around line 109-118: The visibility check using `offsetParent === null` in the
GuidedTour component incorrectly identifies fixed-position elements as hidden,
causing tour targets in the AppSidebar (which uses position: fixed) to be
skipped. Replace this visibility check with a more robust approach that
tolerates fixed positioning by using getBoundingClientRect() to verify the
element has visible dimensions, or alternatively use getClientRects().length to
confirm the element renders. This will ensure fixed-position tour targets are
correctly identified as visible and clickable rather than being incorrectly
skipped.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a2dfcf41-26d9-464b-9cbd-2f2a345aae5d

📥 Commits

Reviewing files that changed from the base of the PR and between 509e6b3 and 41b42fd.

📒 Files selected for processing (3)
  • src/components/GuidedTour/GuidedTour.tsx
  • src/components/GuidedTour/TourMenu.tsx
  • src/components/GuidedTour/guidedTourSteps.ts
✅ Files skipped from review due to trivial changes (1)
  • src/components/GuidedTour/guidedTourSteps.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/GuidedTour/TourMenu.tsx

Comment on lines +109 to +118
if (element) {
// Present but hidden (e.g. the Graph tab on tall viewports) can never
// be clicked — skip now rather than waiting it out.
if (element.offsetParent === null) {
skip();
return;
}
attached = element;
element.addEventListener("click", onClick, { once: true });
return;

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.

🎯 Functional Correctness | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the data-tour targets and their containers to see if any are position:fixed.
rg -n 'data-tour' src --type=tsx --type=ts -C1 | head -n 80

Repository: flanksource/flanksource-ui

Length of output: 192


🏁 Script executed:

# Find data-tour attributes in tsx/ts files without type filter
rg 'data-tour' src --type ts -C 1 | head -100

Repository: flanksource/flanksource-ui

Length of output: 7141


🏁 Script executed:

# Inspect the GuidedTour.tsx file to understand the context better
ast-grep outline src/components/GuidedTour/GuidedTour.tsx

Repository: flanksource/flanksource-ui

Length of output: 374


🏁 Script executed:

# Search for any CSS or inline styles that set position:fixed in relation to tour elements
rg 'position.*fixed' src --type ts --type js -C 2 | head -100

Repository: flanksource/flanksource-ui

Length of output: 3291


🏁 Script executed:

# Read GuidedTour.tsx around lines 109-118 to see the full context
sed -n '100,130p' src/components/GuidedTour/GuidedTour.tsx

Repository: flanksource/flanksource-ui

Length of output: 1037


🏁 Script executed:

# Check AppSidebar styling and positioning
grep -n 'className\|style\|position' src/components/Layout/AppSidebar.tsx | head -40

Repository: flanksource/flanksource-ui

Length of output: 1583


🏁 Script executed:

# Search for CSS classes or Tailwind utilities that might apply position:fixed to AppSidebar
rg 'fixed|sticky' src/components/Layout/AppSidebar.tsx -B2 -A2

Repository: flanksource/flanksource-ui

Length of output: 164


🏁 Script executed:

# View the full AppSidebar component to understand its structure
cat -n src/components/Layout/AppSidebar.tsx | head -100

Repository: flanksource/flanksource-ui

Length of output: 3828


🏁 Script executed:

# Check what Sidebar component is being used and if it has fixed positioning
rg 'from.*Sidebar|import.*Sidebar' src/components/Layout/AppSidebar.tsx -A5

Repository: flanksource/flanksource-ui

Length of output: 164


🏁 Script executed:

# Check the Layout or main app structure to see if AppSidebar is positioned fixed
rg -l 'AppSidebar' src --type ts --type tsx | xargs grep -l 'fixed\|sticky\|position' | head -5

Repository: flanksource/flanksource-ui

Length of output: 192


🏁 Script executed:

# Find the sidebar component file
find src -name 'sidebar*' -type f

Repository: flanksource/flanksource-ui

Length of output: 246


🏁 Script executed:

# Check the sidebar component for positioning styles
cat src/components/ui/sidebar.tsx | head -150

Repository: flanksource/flanksource-ui

Length of output: 4669


🏁 Script executed:

# Search for position styling in the sidebar component
grep -n 'position\|fixed\|sticky' src/components/ui/sidebar.tsx

Repository: flanksource/flanksource-ui

Length of output: 300


offsetParent === null misclassifies fixed-position targets as hidden.

The Sidebar component (used by AppSidebar) applies position: fixed via the CSS class "fixed" (sidebar.tsx:245). Since AppSidebar contains elements with data-tour attributes for navigation targets, these tour targets would have offsetParent === null despite being fully visible and clickable. The check at lines 109–118 would incorrectly skip() these targets. Consider a visibility check that tolerates fixed positioning (e.g. getBoundingClientRect() dimensions or getClientRects().length).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/GuidedTour/GuidedTour.tsx` around lines 109 - 118, The
visibility check using `offsetParent === null` in the GuidedTour component
incorrectly identifies fixed-position elements as hidden, causing tour targets
in the AppSidebar (which uses position: fixed) to be skipped. Replace this
visibility check with a more robust approach that tolerates fixed positioning by
using getBoundingClientRect() to verify the element has visible dimensions, or
alternatively use getClientRects().length to confirm the element renders. This
will ensure fixed-position tour targets are correctly identified as visible and
clickable rather than being incorrectly skipped.

}
];

const healthSteps: Step[] = [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • Tour file per "guide"
  • Use onboarding checklist (like storybook) - with floating panel (minimizable / dismissisable to localstorage) and Menu -> Getting Started link
  • Split tours into Admin vs Operator and then by category

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.

2 participants