Access request
ProAsk for a role you don't have on an environment. Says who decides, when the app knows. Once sent it shows as pending, with withdraw. A role at or below the one you hold there is locked, with the reason.
Preview
Install
With the Candor CLI
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/access-request
Brings in: button, environment-band, locale, locked, team, terms, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import * as React from "react"
import { AccessRequest, type SentAccessRequest } from "@/components/access-request"
import type { Environment, Role } from "@/lib/team"
const environments: Environment[] = [
{ id: "env-prod", name: "Acme API", production: true, hue: 3, connection: "connected" },
{ id: "env-staging", name: "Acme API", detail: "Staging", production: false, hue: 2, connection: "connected" },
]
const roles: Role[] = [
{ id: "contributor", label: "Contributor", rank: 1 },
{ id: "approver", label: "Approver", rank: 2 },
{ id: "admin", label: "Admin", rank: 3 },
]
const deciders = { "env-prod": ["Priya", "Dana"], "env-staging": ["Priya"] }
export default function Example() {
const [sent, setSent] = React.useState<SentAccessRequest | null>(null)
return (
<AccessRequest
className="w-full max-w-md"
environments={environments}
roles={roles}
requestable={["approver", "admin"]}
current={{ "env-staging": "contributor" }}
deciders={deciders}
note="Raising a role always needs approval."
sent={sent}
onSend={(environmentId, role) => setSent({ environment: environmentId, role, at: new Date().toISOString(), deciders: deciders[environmentId as keyof typeof deciders] })}
onWithdraw={() => setSent(null)}
/>
)
}<AccessRequest>
| Prop | Type | Default | Description |
|---|---|---|---|
| environmentsrequired | Environment[] | — | The environments a role can be asked for on. |
| rolesrequired | Role[] | — | Every role, so the one you hold can be named. |
| requestablerequired | string[] | — | Role ids that can be asked for. |
| currentrequired | Record<string, string | undefined> | — | The viewer's role id per environment id. |
| decidersrequired | Record<string, string[]> | — | Who decides, per environment id. |
| note | string | undefined | — | The app's rule, e.g. "Raising a role always needs approval." |
| sent | SentAccessRequest | null | undefined | — | The request already sent; set, the form gives way to a pending note. null/undefined means none sent. |
| onSendrequired | (environmentId: string, roleId: string, reason: string) => void | — | Called on send with the environment id, role id and the reason given. |
| onWithdraw | (() => void) | undefined | — | Shows Withdraw on a pending request; called when it's clicked. |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under accessRequest in <LocaleProvider strings={{ … }}>; the table is exported as accessRequestStrings.
| Key | English |
|---|---|
| sentLabel | Access request |
| formLabel | Ask for access |
| heading | Ask for more access |
| withA | a {role} |
| withAn | an {role} |
| chooseEnvironment | Choose the {environment}. |
| chooseAccess | Choose the access you need. |
| alreadyThere | You’re already {role} there. |
| sayWhy | Say why you need it; the deciders see this. |
| askedFor | You asked to be {role} on {place}. |
| waitingFor | Waiting for {deciders}. |
| withdraw | Withdraw |
| production | Production |
| youAre | You’re {role} on this {environment}. |
| noRole | You have no role on this {environment}. |
| role | Role |
| why | Why |
| decidedBy | Decided by {deciders}. |
| send | Send request |
Types
- SentAccessRequest
{ /** The environment's id, as onSend gave it; shown by its name. (A name that matches no id is shown as it is.) */ environment: string /** The role's id, shown by its label. */ role: string at: string deciders: string[] }