feat: Host-injected dashboard nav items, filtered by user permission - #2701
Open
camielvs wants to merge 1 commit into
Open
feat: Host-injected dashboard nav items, filtered by user permission#2701camielvs wants to merge 1 commit into
camielvs wants to merge 1 commit into
Conversation
Adds a `window.__TANGLE_EXTRA_NAV_ITEMS__` config contract, alongside the existing `__TANGLE_AI_MODELS__` / `__TANGLE_EXTRA_FLAGS__` ones, so a deployment can add its own links to the dashboard sidebar without forking the layout. Items render under Settings; an item may declare `requiresPermission`, in which case it is only shown to users whose `/api/users/me` permissions include it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🎩 PreviewA preview build has been created at: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a
window.__TANGLE_EXTRA_NAV_ITEMS__config contract so a deployment can add its own links to the dashboard sidebar without forkingDashboardLayout. It sits alongside the existing injection points (__TANGLE_AI_MODELS__,__TANGLE_EXTRA_FLAGS__,__TANGLE_ANNOUNCEMENTS__).Items render in the utility block directly under Settings. An item may declare
requiresPermission; it is then shown only to users whose/api/users/mepermissions include that string — reusing the samepermissionsarray that already gates the Hugging Face auth button and run actions.Injected config is validated before use, following the
aiModels.tsreader pattern: items without a usable label or href are dropped, aniconthat isn't in the Lucide set is dropped (rather than crashing the sidebar), and hrefs are restricted to same-origin paths orhttp(s)URLs so a host assembling this config from a less-trusted source can't turn a nav item into ajavascript:sink.Two notes for reviewers:
ExtraNavItemsusesuseQuery(userQueryOptions)rather than theuseUserDetails()wrapper, because that wrapper isuseSuspenseQueryand would suspend the whole dashboard shell on first paint. The item appears when/api/users/meresolves; the rest of the sidebar never waits on it.Related Issue and Pull requests
Consumed by a matching Shopify-side overlay change that surfaces an admin dashboard link.
Type of Change
Checklist
Screenshots (if applicable)
Verified locally with the config above injected and
/api/users/mereturning["read", "write", "admin"]— "Admin" renders under Settings with the same styling as Docs/Settings, links to/admin/, and gets notarget="_blank"since it is same-origin. With["read", "write"]the item is absent.Test Instructions
pnpm start, then in the devtools console before load (or via anindex.htmlscript block) setwindow.__TANGLE_EXTRA_NAV_ITEMS__as above.admin, the item shows under Settings; without it, the item is hidden.pnpm vitest run src/config/extraNavItems.test.ts src/routes/Dashboard/ExtraNavItems.test.tsxAdditional Comments
pnpm validateand the fullpnpm testsuite (215 files, 2260 tests) pass locally.