@@ -83,52 +83,10 @@ type LoaderRole = LoaderData["roles"][number];
8383type LoaderPermission = LoaderData [ "allPermissions" ] [ number ] ;
8484type RolePermission = LoaderRole [ "permissions" ] [ number ] ;
8585
86- // Permission name → display group. The wire-format Permission only
87- // carries `name` and `description`, so this lives client-side.
88- const PERMISSION_GROUP_BY_NAME : Record < string , string > = {
89- "read:runs" : "Runs" ,
90- "write:runs" : "Runs" ,
91- "read:tags" : "Runs" ,
92- "read:batch" : "Runs" ,
93- "write:batch" : "Runs" ,
94- "read:tasks" : "Tasks" ,
95- "write:tasks" : "Tasks" ,
96- "trigger:tasks" : "Tasks" ,
97- "batchTrigger:tasks" : "Tasks" ,
98- "deploy:tasks" : "Tasks" ,
99- "read:waitpoints" : "Waitpoints" ,
100- "write:waitpoints" : "Waitpoints" ,
101- "read:inputStreams" : "Realtime" ,
102- "write:inputStreams" : "Realtime" ,
103- "read:deployments" : "Deployments" ,
104- "read:prompts" : "Prompts" ,
105- "write:prompts" : "Prompts" ,
106- "update:prompts" : "Prompts" ,
107- "read:query" : "Query" ,
108- "read:tokens" : "Tokens" ,
109- "write:tokens" : "Tokens" ,
110- "read:envvars" : "Environment" ,
111- "write:envvars" : "Environment" ,
112- "read:apiKeys" : "Environment" ,
113- "write:apiKeys" : "Environment" ,
114- "read:members" : "Organisation" ,
115- "manage:members" : "Organisation" ,
116- "manage:billing" : "Organisation" ,
117- } ;
118-
119- const GROUP_ORDER = [
120- "Runs" ,
121- "Tasks" ,
122- "Waitpoints" ,
123- "Realtime" ,
124- "Deployments" ,
125- "Prompts" ,
126- "Query" ,
127- "Tokens" ,
128- "Environment" ,
129- "Organisation" ,
130- "Other" ,
131- ] as const ;
86+ // Permissions are bucketed by `permission.group` from the plugin.
87+ // Section order = first-seen order in `allPermissions()`. Permissions
88+ // without a group fall into "Other" at the bottom.
89+ const FALLBACK_GROUP = "Other" ;
13290
13391export default function Page ( ) {
13492 const { roles, assignableRoleIds, allPermissions, systemRoles } =
@@ -353,16 +311,17 @@ function conditionLabel(conditions: Record<string, unknown>): string {
353311function groupPermissions (
354312 permissions : LoaderPermission [ ]
355313) : { group : string ; permissions : LoaderPermission [ ] } [ ] {
314+ // Insertion-ordered map: groups appear in the order their first
315+ // permission was seen. Plugins that want a specific section order
316+ // just emit permissions in that order from `allPermissions()`.
356317 const buckets = new Map < string , LoaderPermission [ ] > ( ) ;
357318 for ( const permission of permissions ) {
358- const group = PERMISSION_GROUP_BY_NAME [ permission . name ] ?? "Other" ;
319+ const group = permission . group ?? FALLBACK_GROUP ;
359320 const list = buckets . get ( group ) ?? [ ] ;
360321 list . push ( permission ) ;
361322 buckets . set ( group , list ) ;
362323 }
363- return GROUP_ORDER . flatMap ( ( group ) =>
364- buckets . has ( group ) ? [ { group, permissions : buckets . get ( group ) ! } ] : [ ]
365- ) ;
324+ return Array . from ( buckets , ( [ group , permissions ] ) => ( { group, permissions } ) ) ;
366325}
367326
368327function CreateRoleUpsell ( ) {
0 commit comments