Workspace settings promise only what exists: the Soon rows Deployments, Project defaults, Spaces and sharing and Applications are gone from Workspace mode's sidebar, with the Artifacts group they left empty, and the sidebar no longer draws Soon rows at all. None had a plan behind it. Permissions loses its five locked Soon settings (forking private repositories, who can create spaces, default sharing, who can deploy to production, who can publish packages), so every setting on it saves. The permissions and workspaces guides say the same. Checked: the site's typecheck, its tests and a production build, the deploy tool's tests and the docs build.
6 files+26−2020/6 viewed
| 1 | 1 | --- | |
| 2 | 2 | title: Permissions | |
| 3 | − | description: Who may do what in a workspace, in one place, part by part — repositories, teams, chat, artifacts, deployments and packages — what each setting does, and which are still to come. | |
| 3 | + | description: Who may do what in a workspace, in one place, part by part — repositories, teams and chat — and what each setting does. | |
| 4 | 4 | --- | |
| 5 | − | ||
| 6 | − | import Soon from '../../../components/Soon.astro'; | |
| 7 | 5 | ||
| 8 | 6 | **Permissions** is where a workspace's owners decide who may do what, part | |
| 9 | 7 | by part: `g1t.sh/<workspace>/-/permissions`, under **Workspace → Access** | |
| ⋯ | |||
| 11 | 9 | setting says what it decides, and each card saves on its own with its | |
| 12 | 10 | **Save** button; the change holds on everyone's next request and is | |
| 13 | 11 | recorded in the [audit log](/guides/audit-log/). | |
| 14 | − | ||
| 15 | − | A setting marked **Soon** is not configurable yet. It is shown the way it | |
| 16 | − | will be, locked, with the rule that holds today under it, so nobody has to | |
| 17 | − | look elsewhere to learn what members can do. | |
| 18 | 12 | ||
| 19 | 13 | ## Code | |
| 20 | 14 | ||
| ⋯ | |||
| 26 | 20 | | **Repository admins can change visibility** | Whether a member with Admin on a repository can make it public or private. | On | | |
| 27 | 21 | | **Repository admins can delete and transfer repositories** | Whether a member with Admin on a repository can delete it, or transfer it to a workspace where they can create one. | Off | | |
| 28 | 22 | | **Repository admins can add outside collaborators** | Whether a member with Admin on a repository can give a role on it to someone outside the workspace. | On | | |
| 29 | − | | **Members can fork private repositories** <Soon /> | Whether a member may fork a private repository under their own name. | g1t has no personal forks: work happens on branches of the repository itself. | | |
| 30 | 23 | ||
| 31 | 24 | The five switches are the workspace's | |
| 32 | 25 | [member privileges](/guides/workspaces/#member-privileges), the same ones | |
| ⋯ | |||
| 50 | 43 | [Chat settings](/guides/chat/#workspace-chat-settings), under **Workspace → | |
| 51 | 44 | Chat**: they are about what a channel's own members may do, not who may do | |
| 52 | 45 | what in the workspace. | |
| 53 | − | ||
| 54 | − | ## Artifacts | |
| 55 | 46 | ||
| 56 | − | | Setting | What it decides | Today | | |
| 57 | − | | --- | --- | --- | | |
| 58 | − | | **Who can create spaces** <Soon /> | Who may add a space beside the ones the workspace has. | Any member, from **+** beside **Spaces** in the Artifacts sidebar. | | |
| 59 | − | | **Default sharing** <Soon /> | Who a new artifact is shared with before its author chooses. | A new artifact is its author's, shared with the people and teams they add, or opened to the workspace from its **Share** menu. See [sharing](/guides/artifacts/#sharing). | | |
| 60 | − | ||
| 61 | − | ## Deployments and packages | |
| 62 | − | ||
| 63 | − | | Setting | What it decides | Today | | |
| 64 | − | | --- | --- | --- | | |
| 65 | − | | **Who can deploy to production** <Soon /> | Who may deploy a project's production environment, and redeploy or take it down. | Anyone with Write on the project's repository redeploys or takes an app down; turning deployments on for a project takes Admin. See [deployments](/guides/deployments/). | | |
| 66 | − | | **Who can publish packages** <Soon /> | Who may publish a new version of one of the workspace's packages. | Anyone with Write on the package's repository, or a token given write on packages. See [packages](/guides/packages/). | | |
| 67 | − | ||
| 68 | 47 | ## Through the API | |
| 69 | 48 | ||
| 70 | − | Every setting that exists is set the way it was before it had this page: | |
| 49 | + | Every setting is set the way it was before it had this page: | |
| 71 | 50 | ||
| 72 | 51 | | Setting | Route | MCP | | |
| 73 | 52 | | --- | --- | --- | | |
| 74 | 53 | | Base permission | [`PUT /workspaces/{workspace}/base_permission`](/reference/api/access/set-base-permission/) | `access` `set_base_permission` | | |
| 75 | 54 | | Member privileges, who can create teams | [`PATCH /workspaces/{workspace}`](/reference/api/workspaces/update-workspace/) with `members_can_…` or `team_creation` | `workspace` `update` | | |
| 76 | 55 | | Public and private channels | The chat service's workspace settings, as [Chat settings](/guides/chat/#workspace-chat-settings) saves them | | | |
| 77 | − | ||
| 78 | − | A setting marked Soon has no route yet. | |
| 79 | 56 | ||
| 80 | 57 | ## Next | |
| 81 | 58 | ||
| 722 | 722 | for it. There is no second Settings inside it: every page is in the | |
| 723 | 723 | sidebar, under the group it belongs to, and the group you are in stays | |
| 724 | 724 | open while the others fold when you select their name. A page only owners | |
| 725 | − | open is left out for members; a page that is coming is a greyed **Soon** | |
| 726 | − | row, with a hint saying what it will hold. | |
| 725 | + | open is left out for members. | |
| 727 | 726 | ||
| 728 | 727 | | Group | Page | Who | | | |
| 729 | 728 | | --- | --- | --- | --- | | |
| ⋯ | |||
| 731 | 730 | | **General** | **General** | Owners | The icon, the display name, a one-line description, the address (the slug), [requiring two-factor authentication](#require-two-factor-authentication), [data residency](#data-residency), and deleting the workspace. `-/settings` | | |
| 732 | 731 | | **Access** | **Members** | Members | Who is in the workspace and their roles, with search and filters; owners [invite people](#add-people), change roles, and see **Outside collaborators**. `-/members` | | |
| 733 | 732 | | | **Invitations** | Owners | Every invitation to join, filtered by where it stands; send one again, revoke it, copy its link. `-/members/invitations` | | |
| 734 | − | | | [**Permissions**](/guides/permissions/) | Owners | Who may do what, part by part: the base permission, repositories, teams, chat, artifacts, deployments and packages. `-/permissions` | | |
| 733 | + | | | [**Permissions**](/guides/permissions/) | Owners | Who may do what, part by part: the base permission, repositories, teams and chat. `-/permissions` | | |
| 735 | 734 | | | [**Access tokens**](#workspace-access-tokens) | Members | The workspace's own tokens. Owners create and delete them. `-/tokens` | | |
| 736 | 735 | | | **Personal access tokens** | Owners | The workspace's rules for members' tokens, and approving them. `-/personal-access-tokens` | | |
| 737 | 736 | | **Money** | [**Usage**](/guides/usage-and-billing/#the-usage-page) | Members | What the workspace used, by product, project and day. `-/usage` | | |
| ⋯ | |||
| 741 | 740 | | | **Actions** | Members | How workflows run in the workspace: what jobs' tokens may do, and for owners the [workflows the workspace manages](#workflows-the-workspace-manages) in its repositories. `-/actions` | | |
| 742 | 741 | | | [**Secrets and variables**](/guides/secrets-and-variables/) | Members | What runs and deployments are given. Owners change them. `-/secrets` | | |
| 743 | 742 | | | [**Webhooks**](/guides/webhooks/) | Members | Where the workspace's events are sent. Owners add and change them. `-/webhooks` | | |
| 744 | − | | | **Deployments**, **Project defaults** | | Soon: defaults for every project's deployments, and what a new project starts with. | | |
| 745 | 743 | | **Chat** | [**Chat settings**](/guides/chat/#workspace-chat-settings) | Members | Renaming and archiving channels, emoji, default channels. Owners change it. `-/settings/chat` | | |
| 746 | 744 | | | **Emoji** | Members | The workspace's own emoji. `-/emoji` | | |
| 747 | − | | **Artifacts** | **Spaces and sharing** | | Soon: which spaces a workspace starts with, and how a new artifact is shared by default. | | |
| 748 | 745 | | **Security** | **Security settings** | Members | The workspace's security policies. `-/security/settings` | | |
| 749 | 746 | | | [**Guardrails**](/guides/guardrails/) | Members | How long checks, the merge queue and merge checks may run. `-/guardrails` | | |
| 750 | 747 | | | [**Rules**](/guides/rules/) | Members | Rulesets across projects. `-/rules` | | |
| 751 | 748 | | | [**Audit log**](/guides/audit-log/) | Members | Every change, by whom, to what. `-/audit` | | |
| 752 | 749 | | **Integrations** | [**Integrations**](/guides/integrations/) | Members | The tools connected for everyone. `-/integrations` | | |
| 753 | − | | | **Applications** | | Soon: OAuth applications the workspace registers. | | |
| 754 | 750 | ||
| 755 | 751 | Each page's address is under `g1t.sh/<workspace>/`. The page's header | |
| 756 | 752 | shows where you are: **General**, **Members / Invitations**, **Permissions**. | |
| 202 | 202 | } | |
| 203 | 203 | ||
| 204 | 204 | /** | |
| 205 | − | * Something a project will have, shown where it will live so people can | |
| 206 | − | * see where g1t is going. Not a link: nothing is behind it yet. | |
| 207 | − | */ | |
| 208 | − | function SidebarSoon({ icon, children, about }: { icon: ReactNode; children: ReactNode; about: string }) { | |
| 209 | − | return ( | |
| 210 | − | <SidebarMenuItem> | |
| 211 | − | <Hint label={about} side="right"> | |
| 212 | − | <SidebarMenuButton asChild variant="faint"> | |
| 213 | − | <div aria-disabled="true" className="cursor-default"> | |
| 214 | − | {icon} | |
| 215 | − | <span className="min-w-0 grow truncate">{children}</span> | |
| 216 | − | <span className="sr-only">{about}</span> | |
| 217 | − | <SoonPill /> | |
| 218 | − | </div> | |
| 219 | − | </SidebarMenuButton> | |
| 220 | − | </Hint> | |
| 221 | − | </SidebarMenuItem> | |
| 222 | − | ); | |
| 223 | − | } | |
| 224 | − | ||
| 225 | − | /** | |
| 226 | 205 | * A page that is coming, as a link to its roadmap page: faint, with Soon, | |
| 227 | 206 | * and marked current on any of its section's Soon pages. | |
| 228 | 207 | */ | |
| ⋯ | |||
| 1325 | 1304 | actions: <PlayCircle size={15} />, | |
| 1326 | 1305 | secrets: <Lock size={15} />, | |
| 1327 | 1306 | webhooks: <Webhook size={15} />, | |
| 1328 | − | deployments: <Rocket size={15} />, | |
| 1329 | − | projects: <Layers size={15} />, | |
| 1330 | 1307 | "chat-settings": <MessagesSquare size={15} />, | |
| 1331 | 1308 | emoji: <Smile size={15} />, | |
| 1332 | − | "artifact-settings": <Shapes size={15} />, | |
| 1333 | 1309 | "security-settings": <Shield size={15} />, | |
| 1334 | 1310 | guardrails: <Gauge size={15} />, | |
| 1335 | 1311 | rules: <Scale size={15} />, | |
| 1336 | 1312 | audit: <History size={15} />, | |
| 1337 | 1313 | integrations: <Plug size={15} />, | |
| 1338 | − | applications: <Blocks size={15} />, | |
| 1339 | 1314 | }; | |
| 1340 | 1315 | ||
| 1341 | 1316 | /** | |
| ⋯ | |||
| 1370 | 1345 | /** | |
| 1371 | 1346 | * The Workspace mode's sidebar: the workspace's settings area, every page | |
| 1372 | 1347 | * one click away. Its overview, then the groups in lib/workspace-nav.ts | |
| 1373 | − | * (General, Access, Money, Compute, Code, Chat, Artifacts, | |
| 1374 | − | * Security, Integrations), each folding, the one you are in held open. | |
| 1375 | − | * Pages only owners open are left out for members, and a group with none | |
| 1376 | − | * left goes with them; a page that is coming is a Soon row, not a link. | |
| 1348 | + | * (General, Access, Money, Compute, Code, Chat, Security, Integrations), | |
| 1349 | + | * each folding, the one you are in held open. Pages only owners open are | |
| 1350 | + | * left out for members, and a group with none left goes with them. | |
| 1377 | 1351 | */ | |
| 1378 | 1352 | export function WorkspaceSidebar({ slug, owner }: { slug: string; owner: boolean }) { | |
| 1379 | 1353 | const { pathname } = useLocation(); | |
| ⋯ | |||
| 1395 | 1369 | <Fragment key={group.key}> | |
| 1396 | 1370 | <Rule /> | |
| 1397 | 1371 | <FoldingGroup title={group.title} current={here?.group === group.key}> | |
| 1398 | − | {group.pages.filter(shown).map((page) => | |
| 1399 | − | page.soon ? ( | |
| 1400 | − | <SidebarSoon key={page.key} icon={WORKSPACE_PAGE_ICONS[page.key] ?? <Sparkles size={15} />} about={page.soon}> | |
| 1401 | − | {page.label} | |
| 1402 | − | </SidebarSoon> | |
| 1403 | − | ) : ( | |
| 1404 | − | <SidebarLink | |
| 1405 | − | key={page.key} | |
| 1406 | − | to={`/${slug}/-/${page.path}`} | |
| 1407 | − | icon={WORKSPACE_PAGE_ICONS[page.key] ?? <Settings size={15} />} | |
| 1408 | − | current={here?.page === page.key} | |
| 1409 | − | > | |
| 1410 | − | {page.label} | |
| 1411 | − | </SidebarLink> | |
| 1412 | − | ), | |
| 1413 | − | )} | |
| 1372 | + | {group.pages.filter(shown).map((page) => ( | |
| 1373 | + | <SidebarLink | |
| 1374 | + | key={page.key} | |
| 1375 | + | to={`/${slug}/-/${page.path}`} | |
| 1376 | + | icon={WORKSPACE_PAGE_ICONS[page.key] ?? <Settings size={15} />} | |
| 1377 | + | current={here?.page === page.key} | |
| 1378 | + | > | |
| 1379 | + | {page.label} | |
| 1380 | + | </SidebarLink> | |
| 1381 | + | ))} | |
| 1414 | 1382 | </FoldingGroup> | |
| 1415 | 1383 | </Fragment> | |
| 1416 | 1384 | ))} | |
| 142 | 142 | for (const page of group.pages) { | |
| 143 | 143 | assert.ok(!keys.has(page.key), `${page.key} twice`); | |
| 144 | 144 | keys.add(page.key); | |
| 145 | − | if (!page.soon) assert.equal(modeOf(`/acme/-/${page.path}`, "acme"), "workspace", page.path); | |
| 145 | + | assert.equal(modeOf(`/acme/-/${page.path}`, "acme"), "workspace", page.path); | |
| 146 | 146 | } | |
| 147 | 147 | } | |
| 148 | 148 | }); |
| 28 | 28 | /** | |
| 29 | 29 | * Workspace mode's pages, in the groups its sidebar lists them under: the | |
| 30 | 30 | * workspace's settings area, every page one click away. `owner` marks the | |
| 31 | − | * pages only owners open; the sidebar shows members the rest. A page that | |
| 32 | − | * is not here yet is a `soon` row: what the group will hold, not a link. | |
| 31 | + | * pages only owners open; the sidebar shows members the rest. | |
| 33 | 32 | * `path` is under `-/`. | |
| 34 | 33 | */ | |
| 35 | − | export type WorkspaceSettingsPage = { key: string; label: string; path: string; owner?: boolean; soon?: string }; | |
| 34 | + | export type WorkspaceSettingsPage = { key: string; label: string; path: string; owner?: boolean }; | |
| 36 | 35 | ||
| 37 | 36 | export type WorkspaceSettingsGroup = { key: string; title: string; pages: WorkspaceSettingsPage[] }; | |
| 38 | 37 | ||
| ⋯ | |||
| 74 | 73 | { key: "actions", label: "Actions", path: "actions" }, | |
| 75 | 74 | { key: "secrets", label: "Secrets and variables", path: "secrets" }, | |
| 76 | 75 | { key: "webhooks", label: "Webhooks", path: "webhooks" }, | |
| 77 | − | { | |
| 78 | − | key: "deployments", | |
| 79 | − | label: "Deployments", | |
| 80 | − | path: "soon/deployments", | |
| 81 | − | soon: "Defaults for every project's deployments: environments, who approves production, and the domains the workspace owns.", | |
| 82 | − | }, | |
| 83 | − | { | |
| 84 | − | key: "projects", | |
| 85 | − | label: "Project defaults", | |
| 86 | − | path: "soon/projects", | |
| 87 | − | soon: "What a new project starts with: its visibility, branch rules and merge method.", | |
| 88 | − | }, | |
| 89 | 76 | ], | |
| 90 | 77 | }, | |
| 91 | 78 | { | |
| ⋯ | |||
| 94 | 81 | pages: [ | |
| 95 | 82 | { key: "chat-settings", label: "Chat settings", path: "settings/chat" }, | |
| 96 | 83 | { key: "emoji", label: "Emoji", path: "emoji" }, | |
| 97 | − | ], | |
| 98 | − | }, | |
| 99 | − | { | |
| 100 | − | key: "artifacts", | |
| 101 | − | title: "Artifacts", | |
| 102 | − | pages: [ | |
| 103 | − | { | |
| 104 | − | key: "artifact-settings", | |
| 105 | − | label: "Spaces and sharing", | |
| 106 | − | path: "soon/artifact-settings", | |
| 107 | − | soon: "Which spaces a workspace starts with, and how a new artifact is shared by default.", | |
| 108 | − | }, | |
| 109 | 84 | ], | |
| 110 | 85 | }, | |
| 111 | 86 | { | |
| ⋯ | |||
| 121 | 96 | { | |
| 122 | 97 | key: "integrations", | |
| 123 | 98 | title: "Integrations", | |
| 124 | − | pages: [ | |
| 125 | − | { key: "integrations", label: "Integrations", path: "integrations" }, | |
| 126 | − | { | |
| 127 | − | key: "applications", | |
| 128 | − | label: "Applications", | |
| 129 | − | path: "soon/applications", | |
| 130 | − | soon: "OAuth applications the workspace registers, and the ones it lets its members authorize.", | |
| 131 | − | }, | |
| 132 | − | ], | |
| 99 | + | pages: [{ key: "integrations", label: "Integrations", path: "integrations" }], | |
| 133 | 100 | }, | |
| 134 | 101 | ]; | |
| 135 | 102 | ||
| ⋯ | |||
| 147 | 114 | let found: { group: string; page: string; depth: number } | null = null; | |
| 148 | 115 | for (const group of WORKSPACE_SETTINGS_GROUPS) { | |
| 149 | 116 | for (const page of group.pages) { | |
| 150 | − | if (page.soon) continue; | |
| 151 | 117 | if (rest === page.path || rest.startsWith(`${page.path}/`)) { | |
| 152 | 118 | const depth = page.path.split("/").length; | |
| 153 | 119 | if (!found || depth > found.depth) found = { group: group.key, page: page.key, depth }; | |
| 1 | − | import { Code2, MessagesSquare, Rocket, Shapes, UsersRound } from "lucide-react"; | |
| 1 | + | import { Code2, MessagesSquare, UsersRound } from "lucide-react"; | |
| 2 | 2 | import { type ReactNode, useState } from "react"; | |
| 3 | 3 | import { Form, Link, data, useNavigation } from "react-router"; | |
| 4 | 4 | ||
| ⋯ | |||
| 17 | 17 | import type { Route } from "./+types/permissions"; | |
| 18 | 18 | import { page } from "../../lib/meta"; | |
| 19 | 19 | import { ErrorText, SubmitButton } from "../../components/ui"; | |
| 20 | − | import { Badge } from "../../components/ui/badge"; | |
| 21 | 20 | import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../../components/ui/card"; | |
| 22 | 21 | import { RadioGroup, RadioOption } from "../../components/ui/radio-group"; | |
| 23 | 22 | import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../components/ui/select"; | |
| ⋯ | |||
| 32 | 31 | /** | |
| 33 | 32 | * Permissions: who may do what in the workspace, in one place, a section | |
| 34 | 33 | * for each part of g1t. What exists today saves through the service that | |
| 35 | − | * owns it (identity for repositories and teams, chat for channels); what | |
| 36 | − | * does not yet is shown as it will be, marked | |
| 37 | − | * Soon, with the rule that holds today. Owners only. | |
| 34 | + | * owns it (identity for repositories and teams, chat for channels). | |
| 35 | + | * Owners only. | |
| 38 | 36 | */ | |
| 39 | 37 | export async function loader({ params, context }: Route.LoaderArgs) { | |
| 40 | 38 | const viewer = getViewer(context); | |
| ⋯ | |||
| 160 | 158 | } | |
| 161 | 159 | ||
| 162 | 160 | /** A setting's heading inside a part, and a line on what it decides. */ | |
| 163 | − | function Setting({ title, about, soon, children }: { title: string; about: ReactNode; soon?: boolean; children: ReactNode }) { | |
| 161 | + | function Setting({ title, about, children }: { title: string; about: ReactNode; children: ReactNode }) { | |
| 164 | 162 | return ( | |
| 165 | 163 | <div> | |
| 166 | − | <h3 className="flex items-center gap-2 text-sm font-medium"> | |
| 167 | − | {title} | |
| 168 | − | {soon && <Badge>Soon</Badge>} | |
| 169 | − | </h3> | |
| 164 | + | <h3 className="text-sm font-medium">{title}</h3> | |
| 170 | 165 | <p className="mt-1 text-xs leading-relaxed text-faint">{about}</p> | |
| 171 | 166 | <div className="mt-3">{children}</div> | |
| 172 | 167 | </div> | |
| ⋯ | |||
| 192 | 187 | ); | |
| 193 | 188 | } | |
| 194 | 189 | ||
| 195 | − | /** | |
| 196 | − | * A setting g1t will have but does not yet: the control as it will be, | |
| 197 | − | * off, with the rule that holds today, so nobody looks for it elsewhere. | |
| 198 | − | */ | |
| 199 | − | function Stub({ title, about, today, control }: { title: string; about: string; today: string; control: ReactNode }) { | |
| 200 | − | return ( | |
| 201 | − | <Setting title={title} about={about} soon> | |
| 202 | − | <div aria-disabled="true" className="opacity-70"> | |
| 203 | − | {control} | |
| 204 | − | </div> | |
| 205 | − | <p className="mt-2 text-xs text-muted"> | |
| 206 | − | <span className="font-medium text-fg-soft">Not configurable yet; today:</span> {today} | |
| 207 | − | </p> | |
| 208 | − | </Setting> | |
| 209 | − | ); | |
| 210 | − | } | |
| 211 | − | ||
| 212 | − | /** A who-can choice as a stub shows it: the rule that holds, chosen and locked. */ | |
| 213 | − | function LockedChoice({ name, options, value }: { name: string; options: { value: string; label: string; description?: string }[]; value: string }) { | |
| 214 | − | return ( | |
| 215 | − | <RadioGroup name={name} value={value} disabled aria-label={name.replace(/_/g, " ")} className="grid gap-2 sm:grid-cols-2"> | |
| 216 | − | {options.map((option) => ( | |
| 217 | − | <RadioOption key={option.value} value={option.value} label={option.label} description={option.description} disabled /> | |
| 218 | − | ))} | |
| 219 | − | </RadioGroup> | |
| 220 | − | ); | |
| 221 | − | } | |
| 222 | − | ||
| 223 | − | const MEMBERS_OR_OWNERS = [ | |
| 224 | − | { value: "members", label: "Any member", description: "The default." }, | |
| 225 | − | { value: "owners", label: "Owners only" }, | |
| 226 | − | ]; | |
| 227 | − | ||
| 228 | 190 | export default function WorkspacePermissions({ loaderData, actionData, params }: Route.ComponentProps) { | |
| 229 | 191 | const { slug, base, privileges, teamCreation, channels } = loaderData; | |
| 230 | 192 | return ( | |
| ⋯ | |||
| 232 | 194 | <Part icon={<Code2 />} title="Code" about="What members may do with the workspace's repositories, beyond the role each repository gives them. Owners always can do all of it."> | |
| 233 | 195 | <BasePermissionSetting key={base} base={base} slug={params.owner} answer={actionData} /> | |
| 234 | 196 | <PrivilegesSetting key={JSON.stringify(privileges)} privileges={privileges} answer={actionData} /> | |
| 235 | − | <Stub | |
| 236 | − | title="Members can fork private repositories" | |
| 237 | − | about="Whether a member may make a fork of a private repository under their own name." | |
| 238 | − | today="g1t has no personal forks, so nothing is forked; work happens on branches of the repository itself." | |
| 239 | − | control={<SwitchCard title="Members can fork private repositories" checked={false} disabled />} | |
| 240 | − | /> | |
| 241 | 197 | </Part> | |
| 242 | 198 | ||
| 243 | 199 | <Part icon={<UsersRound />} title="People and teams" about="Who may shape the workspace's teams."> | |
| ⋯ | |||
| 252 | 208 | <p className="text-sm text-muted">Chat didn't answer. Reload to try again.</p> | |
| 253 | 209 | </Setting> | |
| 254 | 210 | )} | |
| 255 | − | </Part> | |
| 256 | − | ||
| 257 | − | <Part icon={<Shapes />} title="Artifacts" about="Who may make the places documents live, and how a new one is shared."> | |
| 258 | − | <Stub | |
| 259 | − | title="Who can create spaces" | |
| 260 | − | about="Who may add a space beside the ones the workspace has." | |
| 261 | − | today="any member can create a space, from + beside Spaces in the Artifacts sidebar." | |
| 262 | − | control={<LockedChoice name="create_spaces" options={MEMBERS_OR_OWNERS} value="members" />} | |
| 263 | − | /> | |
| 264 | − | <Stub | |
| 265 | − | title="Default sharing" | |
| 266 | − | about="Who a new artifact is shared with before its author chooses." | |
| 267 | − | today="a new artifact is its author's, shared with the people and teams they add, or opened to the workspace from its Share menu." | |
| 268 | − | control={ | |
| 269 | − | <LockedChoice | |
| 270 | − | name="default_sharing" | |
| 271 | − | options={[ | |
| 272 | − | { value: "author", label: "Its author", description: "Shared only with whom they add." }, | |
| 273 | − | { value: "workspace", label: "Everyone in the workspace" }, | |
| 274 | − | ]} | |
| 275 | − | value="author" | |
| 276 | − | /> | |
| 277 | − | } | |
| 278 | − | /> | |
| 279 | − | </Part> | |
| 280 | − | ||
| 281 | − | <Part icon={<Rocket />} title="Deployments and packages" about="Who may put code in front of people, and publish what others install."> | |
| 282 | − | <Stub | |
| 283 | − | title="Who can deploy to production" | |
| 284 | − | about="Who may deploy a project's production environment, and redeploy or take it down." | |
| 285 | − | today="anyone with Write on the project's repository redeploys or takes an app down; turning deployments on for a project takes Admin." | |
| 286 | − | control={<LockedChoice name="deploy_production" options={[{ value: "write", label: "Write on the repository", description: "The rule today." }, { value: "admin", label: "Admin on the repository" }, { value: "owners", label: "Owners only" }]} value="write" />} | |
| 287 | − | /> | |
| 288 | − | <Stub | |
| 289 | − | title="Who can publish packages" | |
| 290 | − | about="Who may publish a new version of one of the workspace's packages." | |
| 291 | − | today="anyone with Write on the package's repository, or a token given write on packages, publishes new versions and tags." | |
| 292 | − | control={<LockedChoice name="publish_packages" options={[{ value: "write", label: "Write on the repository", description: "The rule today." }, { value: "admin", label: "Admin on the repository" }, { value: "owners", label: "Owners only" }]} value="write" />} | |
| 293 | − | /> | |
| 294 | 211 | </Part> | |
| 295 | 212 | ||
| 296 | 213 | <p className="text-xs text-faint"> | |