Skip to content

feat(skills): show downloading state in Yours tab, remove toggle swit…#580

Merged
alchemistklk merged 3 commits intomainfrom
feat/skill-download-state
Mar 26, 2026
Merged

feat(skills): show downloading state in Yours tab, remove toggle swit…#580
alchemistklk merged 3 commits intomainfrom
feat/skill-download-state

Conversation

@alchemistklk
Copy link
Copy Markdown
Contributor

@alchemistklk alchemistklk commented Mar 26, 2026

…ch, fix back navigation

  • Show actively downloading skills as cards at the top of the Yours tab with spinner and "Installing..." state, including correct sub-tab counts
  • Replace toggle switch with simple Install/Uninstall buttons on skill cards
  • Persist skills page view state (tab, sub-tab, tag, search) in URL search params so back navigation restores the exact view
  • Fix skill detail back button to use history-aware navigation with fallback

What

Why

How

Affected areas

  • Desktop app (Electron shell)
  • Controller (backend / API)
  • Web dashboard (React UI)
  • OpenClaw runtime
  • Skills
  • Shared schemas / packages
  • Build / CI / Tooling

Checklist

  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes
  • pnpm generate-types run (if API routes/schemas changed)
  • No credentials or tokens in code or logs
  • No any types introduced (use unknown with narrowing)

Screenshots / recordings

Notes for reviewers

Summary by CodeRabbit

  • New Features

    • Skills view state (tabs, sub-tabs, tag, search) now persists in the URL and detail links preserve query context.
    • Back navigation from skill detail intelligently returns to the skills list when appropriate.
  • Improvements

    • "Yours" now includes actively downloading/queued skills alongside installed ones.
    • Replaced install toggle with explicit Install/Uninstall buttons and added "Installing…"/"Uninstalling…" status.
  • Tests

    • Added tests covering view-state parsing, patching, detail routing, and back-navigation behavior.

…ch, fix back navigation

- Show actively downloading skills as cards at the top of the Yours tab
  with spinner and "Installing..." state, including correct sub-tab counts
- Replace toggle switch with simple Install/Uninstall buttons on skill cards
- Persist skills page view state (tab, sub-tab, tag, search) in URL search
  params so back navigation restores the exact view
- Fix skill detail back button to use history-aware navigation with fallback
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

Adds a URL-driven Skills view state module, wires it into the Skills page and Skill detail page for search-param-backed navigation and back-navigation handling, replaces switch-based install UI with explicit buttons, and adds tests for the new utilities.

Changes

Cohort / File(s) Summary
State management & tests
apps/web/src/lib/skills-view-state.ts, apps/web/tests/skills-view-state.test.ts
New module exporting TopTab, YoursSubTab, SkillsViewState, parsing/creation/patch helpers for URLSearchParams, detail path/state helpers, and back-navigation logic; accompanied by Vitest coverage for parsing, patching, detail path, and back-navigation behaviors.
Skills page UI & state wiring
apps/web/src/pages/skills.tsx
Replaces local React state with URL search-param–backed view state via the new helpers; SkillCard now accepts detailTo and uses createSkillDetailState(); replaces Switch install toggle with explicit Install/Uninstall buttons; adjusts “Yours” composition to include queued/downloading items and resolves queue source for cards.
Skill detail back navigation
apps/web/src/pages/community-skill-detail.tsx
Introduces getSkillsBackNavigation usage and handleBack to navigate by history delta or path replace; replaces Link back anchors with buttons and switches to useLocation/useNavigate hooks for navigation state handling.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SkillsPage
    participant Browser as BrowserHistory
    participant DetailPage
    participant URL as URLSearchParams

    User->>SkillsPage: click skill (uses `detailTo`, includes state {fromSkillsList: true})
    SkillsPage->>Browser: push detail route (path + URLSearchParams)
    Note right of Browser: history index increments
    User->>DetailPage: view detail
    User->>DetailPage: click Back
    DetailPage->>Browser: inspect history.state, Browser.index
    alt openedFromSkillsList && Browser.canGoBack
        DetailPage->>Browser: navigate(delta: -1)
    else
        DetailPage->>SkillsPage: navigate(to: /workspace/skills + URLSearchParams, replace:true)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • lefarcen

Poem

🐰
I hopped through params, tabs, and query light,
I stitched a trail so back-links find their way,
Buttons trump switches, detail links hold tight,
A breadcrumb path to skills for every day,
Hop—state preserved—now let the users play!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a concise summary of changes but the required template sections (What, Why, How) lack substantive detail, and the checklist remains unchecked. Expand the What/Why/How sections with more context, complete the checklist items to confirm testing and compliance, and provide any relevant issue links or reviewer notes.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: showing downloading state in Yours tab and removing the toggle switch.

✏️ 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 feat/skill-download-state

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 and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Mar 26, 2026

Deploying nexu-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: b067eb9
Status: ✅  Deploy successful!
Preview URL: https://0fac547f.nexu-docs.pages.dev
Branch Preview URL: https://feat-skill-download-state.nexu-docs.pages.dev

View logs

@alchemistklk
Copy link
Copy Markdown
Contributor Author

/cr

@slack-code-review-channel
Copy link
Copy Markdown

✅ CR topic created in Feishu topic group Refly CR.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a49a6f8506

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/web/src/pages/skills.tsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/pages/skills.tsx`:
- Around line 135-138: The Link component (to={detailTo}
state={createSkillDetailState()} draggable={false}) currently wraps the entire
Skill card including the install/uninstall buttons, which nests interactive
controls inside an anchor; refactor the JSX so the Link only wraps the navigable
content (title, description, header) and move the install/uninstall Button(s)
into a separate footer/container sibling to the Link (e.g., a card-footer div)
so they are not children of Link; ensure any handlers that used
stopPropagation/preventDefault are removed or adjusted and that accessible focus
order and keyboard behavior remain correct for the Link and the separate Button
components (install/uninstall).
- Around line 179-208: The new CTA/status text ("Installing…", "Uninstalling…",
"Install", "Uninstall") is hardcoded and skips localization; update the
component to use the existing translation hook/strings instead of literal
text—e.g., import/use useTranslation() (or accept translated props from
SkillsPage) and replace the hardcoded labels inside the conditional rendering
(the branches guarded by isQueueActive/isMutating/pendingAction and the
Install/Uninstall buttons that call handleInstall/handleUninstall) with the
appropriate t('install'), t('installing'), t('uninstall'), t('uninstalling') (or
the project’s existing translation keys) so all CTA/status copy is localized.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a6bd7077-987b-4d4e-ad16-e1c30f767d8b

📥 Commits

Reviewing files that changed from the base of the PR and between cd19976 and a49a6f8.

📒 Files selected for processing (4)
  • apps/web/src/lib/skills-view-state.ts
  • apps/web/src/pages/community-skill-detail.tsx
  • apps/web/src/pages/skills.tsx
  • apps/web/tests/skills-view-state.test.ts

Comment thread apps/web/src/pages/skills.tsx Outdated
Comment thread apps/web/src/pages/skills.tsx
…exists

Queued skills without a catalog entry would 404 on the detail page.
Render those cards as plain containers instead of links while installing.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/web/src/pages/skills.tsx (1)

135-138: ⚠️ Potential issue | 🟠 Major

Split the footer actions out of the Link.

The footer still cancels click/key events inside a wrapping Link, so the whole bottom row becomes a dead zone and the Install/Uninstall buttons remain nested interactive content inside an anchor. That leaves the earlier keyboard/screen-reader issue unresolved.

Also applies to: 165-176, 185-209

🧹 Nitpick comments (1)
apps/web/src/pages/skills.tsx (1)

351-383: Consider precomputing slug lookup maps once.

yourSkillsList and skillSource resolution now do repeated find() scans over allSkills and installedSkills. With the page rerendering on each search-param update, this path trends quadratic as the catalog grows. A slug-keyed Map would keep the list assembly/render path linear.

Also applies to: 782-785

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/pages/skills.tsx` around lines 351 - 383, The code repeatedly
calls allSkills.find(...) and installedSkills.find(...) when building installed,
downloadingWithSource and elsewhere (see installed, downloadingWithSource,
yourSkillsList, skillSource), causing O(n^2) behavior on rerenders; fix by
creating a slug-keyed Map (e.g., const skillBySlug = new Map(allSkills.map(s =>
[s.slug, s]))) once before these mappings and use skillBySlug.get(slug) instead
of find(), and likewise create installedBySlug for installedSkills if needed;
update installed, downloadingWithSource, yourSkillsList and skillSource to use
the precomputed maps for O(1) lookups.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/pages/skills.tsx`:
- Around line 617-623: The onClick handler is clearing the hidden tab's URL
state (setting yoursSubTab and activeTag unconditionally) which loses the
inactive tab's last sub-view; update the handler that calls updateViewState so
it only changes topTab and does not overwrite yoursSubTab or activeTag for the
non-active tab—i.e., set topTab to tab.id and only modify yoursSubTab/activeTag
when you really intend to change that tab's own state (use conditional logic
based on tab.id instead of always setting yoursSubTab/null and activeTag),
preserving the inactive tab's params so the search-param flow in
skills-view-state (the logic keyed off topTab) can restore them.

---

Nitpick comments:
In `@apps/web/src/pages/skills.tsx`:
- Around line 351-383: The code repeatedly calls allSkills.find(...) and
installedSkills.find(...) when building installed, downloadingWithSource and
elsewhere (see installed, downloadingWithSource, yourSkillsList, skillSource),
causing O(n^2) behavior on rerenders; fix by creating a slug-keyed Map (e.g.,
const skillBySlug = new Map(allSkills.map(s => [s.slug, s]))) once before these
mappings and use skillBySlug.get(slug) instead of find(), and likewise create
installedBySlug for installedSkills if needed; update installed,
downloadingWithSource, yourSkillsList and skillSource to use the precomputed
maps for O(1) lookups.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9f32efe4-8ce2-4ea8-b0b0-f91b53bc7a89

📥 Commits

Reviewing files that changed from the base of the PR and between a49a6f8 and b067eb9.

📒 Files selected for processing (1)
  • apps/web/src/pages/skills.tsx

Comment thread apps/web/src/pages/skills.tsx
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 26, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Adds a URL-driven Skills view state module, wires it into the Skills page and Skill detail page for search-param-backed navigation and back-navigation handling, replaces switch-based install UI with explicit buttons, and adds tests for the new utilities.

Changes

Cohort / File(s) Summary
State management & tests
apps/web/src/lib/skills-view-state.ts, apps/web/tests/skills-view-state.test.ts
New module exporting TopTab, YoursSubTab, SkillsViewState, parsing/creation/patch helpers for URLSearchParams, detail path/state helpers, and back-navigation logic; accompanied by Vitest coverage for parsing, patching, detail path, and back-navigation behaviors.
Skills page UI & state wiring
apps/web/src/pages/skills.tsx
Replaces local React state with URL search-param–backed view state via the new helpers; SkillCard now accepts detailTo and uses createSkillDetailState(); replaces Switch install toggle with explicit Install/Uninstall buttons; adjusts “Yours” composition to include queued/downloading items and resolves queue source for cards.
Skill detail back navigation
apps/web/src/pages/community-skill-detail.tsx
Introduces getSkillsBackNavigation usage and handleBack to navigate by history delta or path replace; replaces Link back anchors with buttons and switches to useLocation/useNavigate hooks for navigation state handling.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SkillsPage
    participant Browser as BrowserHistory
    participant DetailPage
    participant URL as URLSearchParams

    User->>SkillsPage: click skill (uses `detailTo`, includes state {fromSkillsList: true})
    SkillsPage->>Browser: push detail route (path + URLSearchParams)
    Note right of Browser: history index increments
    User->>DetailPage: view detail
    User->>DetailPage: click Back
    DetailPage->>Browser: inspect history.state, Browser.index
    alt openedFromSkillsList && Browser.canGoBack
        DetailPage->>Browser: navigate(delta: -1)
    else
        DetailPage->>SkillsPage: navigate(to: /workspace/skills + URLSearchParams, replace:true)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • lefarcen

Poem

🐰
I hopped through params, tabs, and query light,
I stitched a trail so back-links find their way,
Buttons trump switches, detail links hold tight,
A breadcrumb path to skills for every day,
Hop—state preserved—now let the users play!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a concise summary of changes but the required template sections (What, Why, How) lack substantive detail, and the checklist remains unchecked. Expand the What/Why/How sections with more context, complete the checklist items to confirm testing and compliance, and provide any relevant issue links or reviewer notes.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: showing downloading state in Yours tab and removing the toggle switch.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/skill-download-state

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 and usage tips.

@alchemistklk alchemistklk merged commit 83463b7 into main Mar 26, 2026
8 checks passed
@lefarcen lefarcen mentioned this pull request Mar 30, 2026
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