-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix(dashboard): hide "Add channel" button for users without CreateChannel permission #4097
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(dashboard): hide "Add channel" button for users without CreateChannel permission #4097
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughThe change wraps the "Add channel" menu item and its preceding separator in a Changes
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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. Comment |
|
I have read the CLA Document and I hereby sign the CLA |
|
I have read the CLA Document and I hereby sign the CLA |
eca0310 to
b7af4f5
Compare
|
Fixed 👌 |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In @packages/dashboard/src/lib/components/layout/channel-switcher.tsx:
- Around line 198-210: The submit button permission check uses a fixed
['UpdateChannel'] which hides the button when creating a new channel; update the
PermissionGuard around the submit action to use a conditional requires prop that
uses ['CreateChannel'] when creatingNewEntity is true and ['UpdateChannel']
otherwise (i.e., change the requires prop on PermissionGuard to depend on
creatingNewEntity). Ensure this logic is applied where PermissionGuard is used
for the channel form submit button and aligns with the backend mutation
permission.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/dashboard/src/lib/components/layout/channel-switcher.tsx
🧰 Additional context used
📓 Path-based instructions (2)
packages/dashboard/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/dashboard.mdc)
packages/dashboard/src/**/*.{ts,tsx}: Use React as the UI framework for components in the dashboard package
Use TanStack Query (useQuery or useMutation) for data fetching, not Apollo Client
Import api from '@/graphql/api.js' and graphql from '@/graphql/graphql.js' for GraphQL queries and mutations
Use the api.query() pattern with graphql document when creating useQuery calls, including queryKey and staleTime configuration
Use the api.mutate() pattern with graphql document when creating useMutation calls, with onSuccess and onError handlers
Use FormFieldWrapper component for form controls instead of raw Shadcn react-hook-form components
Use @lingui/react/macro for localization with Trans component for markup and useLingui hook for programmatic strings
Set React component props objects to Readonly<> type for type safety
Files:
packages/dashboard/src/lib/components/layout/channel-switcher.tsx
packages/dashboard/src/**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (.cursor/rules/dashboard.mdc)
Use Shadcn UI & Tailwind CSS for styling and UI components in the dashboard
Files:
packages/dashboard/src/lib/components/layout/channel-switcher.tsx
🧬 Code graph analysis (1)
packages/dashboard/src/lib/components/layout/channel-switcher.tsx (2)
packages/dashboard/src/lib/components/shared/permission-guard.tsx (1)
PermissionGuard(44-51)packages/dashboard/src/lib/components/ui/dropdown-menu.tsx (2)
DropdownMenuSeparator(217-217)DropdownMenuItem(212-212)
🔇 Additional comments (1)
packages/dashboard/src/lib/components/layout/channel-switcher.tsx (1)
4-4: LGTM! Correct import added.The PermissionGuard import is correctly added to support the permission-based rendering of the "Add channel" menu item.
| <PermissionGuard requires={['CreateChannel']}> | ||
| <DropdownMenuSeparator /> | ||
| <DropdownMenuItem className="gap-2 p-2 cursor-pointer" asChild> | ||
| <Link to={'/channels/new'}> | ||
| <div className="bg-background flex size-6 items-center justify-center rounded-md border"> | ||
| <Plus className="size-4" /> | ||
| </div> | ||
| <div className="text-muted-foreground font-medium"> | ||
| <Trans>Add channel</Trans> | ||
| </div> | ||
| </Link> | ||
| </DropdownMenuItem> | ||
| </PermissionGuard> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for route definition and channel creation page
echo "=== Searching for /channels/new route definition ==="
rg -n "channels/new" --type=tsx --type=ts -g '!node_modules' -g '!*.test.*' -g '!*.spec.*'
echo ""
echo "=== Looking for route files ==="
find packages/dashboard/src -type f -name "*route*" -o -name "*Router*" | head -20
echo ""
echo "=== Checking for pages directory ==="
find packages/dashboard/src -type d -name "pages" -o -type d -name "route*"Repository: vendurehq/vendure
Length of output: 444
🏁 Script executed:
#!/bin/bash
# Search for channel creation related files and pages
echo "=== Searching for files matching 'new' in channels directory ==="
fd -e tsx -e ts "new" packages/dashboard/src -g "*channel*"
echo ""
echo "=== Listing channel-related source files ==="
fd -e tsx -e ts "channel" packages/dashboard/src --type f | grep -v node_modules | head -30Repository: vendurehq/vendure
Length of output: 1236
🏁 Script executed:
#!/bin/bash
# Search for PermissionGuard usage in page components
echo "=== Searching for PermissionGuard in dashboard pages ==="
rg -n "PermissionGuard" packages/dashboard/src --type=tsx --type=ts -C 3 | head -100
echo ""
echo "=== Searching for route configuration files ==="
find packages/dashboard/src -type f \( -name "*.config.*" -o -name "*route*" -o -name "*Router*" \) | grep -v node_modulesRepository: vendurehq/vendure
Length of output: 392
🏁 Script executed:
#!/bin/bash
# Check the route tree file
echo "=== Checking routeTree.gen.ts for channel routes ==="
cat packages/dashboard/src/app/routeTree.gen.ts | grep -i channel -C 3 | head -50
echo ""
echo "=== Checking channels.tsx file ==="
head -100 packages/dashboard/src/app/routes/_authenticated/_channels/channels.tsx
echo ""
echo "=== Checking for new channel route or modal ==="
rg "new.*channel|channel.*new" packages/dashboard/src/app/routes -i -A 5 | head -80Repository: vendurehq/vendure
Length of output: 11172
🏁 Script executed:
#!/bin/bash
# Look for the destination of the Link in channel-switcher
echo "=== Check full channel-switcher.tsx file context around line 205 ==="
sed -n '190,220p' packages/dashboard/src/lib/components/layout/channel-switcher.tsx
echo ""
echo "=== Search for how /channels/new is created - could be a modal or dynamic route ==="
rg "channels.*new|createChannelModal|CreateChannelForm" packages/dashboard/src -i -A 2 | head -60Repository: vendurehq/vendure
Length of output: 2389
🏁 Script executed:
#!/bin/bash
# Check if there's a create channel page or modal component
echo "=== Search for create channel related files ==="
find packages/dashboard/src -type f -name "*create*channel*" -o -name "*channel*create*" | grep -v node_modules
echo ""
echo "=== Look at the full channels.tsx file ==="
wc -l packages/dashboard/src/app/routes/_authenticated/_channels/channels.tsx
echo ""
echo "=== Search for PermissionGuard in channel routes ==="
grep -r "PermissionGuard" packages/dashboard/src/app/routes/_authenticated/_channels/ 2>/dev/nullRepository: vendurehq/vendure
Length of output: 1090
🏁 Script executed:
#!/bin/bash
# Read the channels_.$id.tsx file to check permission handling
cat packages/dashboard/src/app/routes/_authenticated/_channels/channels_.$id.tsxRepository: vendurehq/vendure
Length of output: 166
🏁 Script executed:
#!/bin/bash
# Find and read the channels detail file
find packages/dashboard/src/app/routes/_authenticated/_channels -name "channels_*" -type fRepository: vendurehq/vendure
Length of output: 137
🏁 Script executed:
#!/bin/bash
# Read the channels detail page file with proper escaping
file=$(find packages/dashboard/src/app/routes/_authenticated/_channels -name "channels_*" -type f)
cat "$file"Repository: vendurehq/vendure
Length of output: 11778
🏁 Script executed:
#!/bin/bash
# Check what NEW_ENTITY_PATH is
rg "NEW_ENTITY_PATH" packages/dashboard/src -A 2 | head -20Repository: vendurehq/vendure
Length of output: 1803
🏁 Script executed:
#!/bin/bash
# Check the detail-page-route-loader to see if it includes permission checks
echo "=== Checking detail-page-route-loader.tsx ==="
cat packages/dashboard/src/lib/framework/page/detail-page-route-loader.tsxRepository: vendurehq/vendure
Length of output: 2617
🏁 Script executed:
#!/bin/bash
# Check if there's any documentation about permission hierarchy or if UpdateChannel covers CreateChannel
echo "=== Searching for permission definitions or documentation ==="
find packages -name "*.ts" -o -name "*.tsx" | xargs grep -l "CreateChannel\|UpdateChannel" | grep -v node_modules | head -20
echo ""
echo "=== Check for permission definitions in server ==="
find packages -path "*/server/*" -name "*permission*" -o -name "*auth*" | grep -v node_modules | head -20Repository: vendurehq/vendure
Length of output: 2356
🏁 Script executed:
#!/bin/bash
# Check the useDetailPage hook to understand permission logic
echo "=== Checking useDetailPage for mutation permission handling ==="
rg "CreateChannel|UpdateChannel|createDocument|updateDocument" packages/dashboard/src/lib/framework/page/use-detail-page.tsx -B 2 -A 2Repository: vendurehq/vendure
Length of output: 243
🏁 Script executed:
#!/bin/bash
# Find the use-detail-page file
find packages/dashboard/src -name "*use-detail-page*" -type f
echo ""
echo "=== Read the file ==="
file=$(find packages/dashboard/src -name "*use-detail-page*" -type f)
cat "$file" | head -150Repository: vendurehq/vendure
Length of output: 5076
🏁 Script executed:
#!/bin/bash
# Search for where the create/update mutations are actually executed and if they have permission checks
echo "=== Search for mutation execution in detail pages ==="
rg "useMutation|createChannelDocument|updateChannelDocument" packages/dashboard/src/app/routes/_authenticated/_channels/ -B 3 -A 3Repository: vendurehq/vendure
Length of output: 3393
🏁 Script executed:
#!/bin/bash
# Check the full use-detail-page.ts file to see where the mutation is executed
cat packages/dashboard/src/lib/framework/page/use-detail-page.ts | tail -200Repository: vendurehq/vendure
Length of output: 7001
🏁 Script executed:
#!/bin/bash
# Check if the route loader has any permission validation
echo "=== Check for route guards or permission checks in route configuration ==="
grep -A 20 "createFileRoute.*_channels/channels_" packages/dashboard/src/app/routes/_authenticated/_channels/channels_.$id.tsx | head -30
echo ""
echo "=== Check if there's a higher-level authentication/permission middleware ==="
find packages/dashboard/src -name "*auth*" -o -name "*guard*" -o -name "*middleware*" | grep -v node_modules | head -20
echo ""
echo "=== Look for BeforeLoad or similar route-level protection ==="
rg "beforeLoad|beforeNavigate|onBeforeLoad" packages/dashboard/src/app/routes -B 2 -A 5 | head -60Repository: vendurehq/vendure
Length of output: 2055
🏁 Script executed:
#!/bin/bash
# Check the PermissionGuard implementation to understand how it works
echo "=== Check PermissionGuard implementation ==="
cat packages/dashboard/src/lib/components/shared/permission-guard.tsx
echo ""
echo "=== Check if there's backend permission enforcement ==="
rg "CreateChannel.*permission|permission.*CreateChannel" packages/core -A 3 -B 3 | head -50Repository: vendurehq/vendure
Length of output: 1534
🏁 Script executed:
#!/bin/bash
# Look more closely at the permission used in the button in channels_.$id.tsx
echo "=== Check the exact permission used in the Create/Update button ==="
sed -n '130,145p' packages/dashboard/src/app/routes/_authenticated/_channels/channels_.$id.tsx
echo ""
echo "=== Verify if CreateChannel should be used instead ==="
rg "CreateChannel.*permission|requires.*CreateChannel" packages/dashboard/src -B 2 -A 2 | head -40Repository: vendurehq/vendure
Length of output: 1496
🏁 Script executed:
#!/bin/bash
# Find the exact file path and read it
find packages/dashboard/src/app/routes/_authenticated/_channels -name "channels_*" -type f
echo ""
echo "=== Read lines around the button in the detail page ==="
file=$(find packages/dashboard/src/app/routes/_authenticated/_channels -name "channels_*" -type f)
sed -n '130,150p' "$file"Repository: vendurehq/vendure
Length of output: 1194
🏁 Script executed:
#!/bin/bash
# Find the PermissionGuard line with UpdateChannel in the detail page
file=$(find packages/dashboard/src/app/routes/_authenticated/_channels -name "channels_*" -type f)
grep -n "PermissionGuard" "$file"
echo ""
echo "=== Read the exact section with the submit button ==="
grep -n "PermissionGuard\|UpdateChannel\|submit" "$file" -B 2 -A 5Repository: vendurehq/vendure
Length of output: 2333
🏁 Script executed:
#!/bin/bash
# Verify permission hierarchy - check if UpdateChannel includes CreateChannel or if they're separate
echo "=== Search for permission definitions and hierarchy ==="
rg "CreateChannel|UpdateChannel" packages/core/src -B 2 -A 2 | grep -i "permission\|enum\|const" | head -30Repository: vendurehq/vendure
Length of output: 941
🏁 Script executed:
#!/bin/bash
# Verify the exact backend mutation permissions
echo "=== Check backend channel resolver mutations ==="
rg "createChannel|updateChannel" packages/core/src/api/resolvers/admin/channel.resolver.ts -B 5 -A 10 | head -80Repository: vendurehq/vendure
Length of output: 1247
Fix permission check on channel creation form.
The submit button on the channel detail page uses UpdateChannel permission for both create and update operations. For new channel creation, it should check CreateChannel permission to match the backend mutation requirements and the UI checks in the list page.
Currently, a user with only CreateChannel permission can access /channels/new but the submit button will be hidden because it checks for UpdateChannel instead. The backend mutation correctly requires CreateChannel, creating a permission mismatch between frontend and backend.
Update line 120 in packages/dashboard/src/app/routes/_authenticated/_channels/channels_.$id.tsx to conditionally check CreateChannel when creating a new entity:
<PermissionGuard requires={creatingNewEntity ? ['CreateChannel'] : ['UpdateChannel']}>🤖 Prompt for AI Agents
In @packages/dashboard/src/lib/components/layout/channel-switcher.tsx around
lines 198 - 210, The submit button permission check uses a fixed
['UpdateChannel'] which hides the button when creating a new channel; update the
PermissionGuard around the submit action to use a conditional requires prop that
uses ['CreateChannel'] when creatingNewEntity is true and ['UpdateChannel']
otherwise (i.e., change the requires prop on PermissionGuard to depend on
creatingNewEntity). Ensure this logic is applied where PermissionGuard is used
for the channel form submit button and aligns with the backend mutation
permission.
|
Thanks for the quick response - could you just fix that merge conflict? 🙏 |
…nnel permission Wrap the "Add channel" menu item in PermissionGuard to only show it to users with the CreateChannel permission. Fixes vendurehq#4056
b7af4f5 to
40b91e4
Compare
|
Thank you! |
|




Description
Hide the "Add channel" button in the channel switcher dropdown for users who don't have the
CreateChannelpermission.Problem: Currently, all users see the "Add channel" option in the channel selector menu, even seller/vendor admins who don't have permission to create channels. This causes confusion as they can access the form but cannot submit it.
Solution: Wrap the "Add channel" menu item (and its separator) with
<PermissionGuard requires={['CreateChannel']}>to conditionally render it only for users with the appropriate permission. This follows the same pattern used elsewhere in the Dashboard (e.g.,global-views-bar.tsx).Fixes #4056
Breaking changes
No breaking changes.
Screenshots
N/A - The "Add channel" option simply no longer appears for users without the
CreateChannelpermission.Checklist
📌 Always: