shadcn.io is not affiliated with official shadcn/ui
User Permissions Dashboard Block for Radix UI
One person's access to 16 permissions in five categories, each granted or not granted with the role it comes from, a popover on a denied one naming the smallest role that would grant it, and a side cell with their roles.
Installation
Overview
Answer why someone can or can't do something, with this access review panel for React with Radix UI. A search in the header, an Autocomplete over eight people, picks whose access to read. The panel lists 16 permissions in five categories (Users, Billing, Projects, Developers and Audit log), each with a check or a cross and the words "Granted" or "Not granted", and its reason: "From Editor, via Design team" or "No role grants it". A denied row has a button that opens a Popover naming the smallest role that would grant it. The end cell shows the person's initials and name, their roles as outline Badges with the team each comes through, "Granted 11, denied 5", and a Switch that, when on, tints what is denied and quiets the rest. It's built from Autocomplete, Popover, Badge, Button, Switch and Guides. For admin consoles and access reviews.
FAQ
How do I load my people and roles?
Edit PEOPLE (each with the roles they hold and where each comes from), PERMISSIONS (each with the roles that grant it) and LADDER, the order of roles from smallest to largest. A permission is granted when any role a person holds appears in its list, and the reason names the first one.
How is the smallest role chosen?
The first role in LADDER that appears in the permission's list. The popover says so and offers no button: nothing is assigned in this demo. In your app, link it to the screen where an admin changes the person's role.
Why does the switch dim rows instead of hiding them?
Hiding granted rows would shorten the list and move the page. With the switch on, denied rows get a solid tint and the granted ones go quiet in a calmer text weight, and a line says how many are denied. The count and the reasons stay readable either way.
How does the search behave?
Typing narrows the list of people by name. Choosing one, or typing a name in full, switches the review; a partial name keeps the last person in view until you choose.
What stays local, and how do I wire it for real?
The people, roles and grants are typed and no one is assigned anything. To make it real, load each person's effective permissions from your authorisation service with the role that grants each one, and send the role change from the popover to the same service.