22
33import { useState , useRef , useEffect , useCallback } from 'react'
44import { Icon } from '@iconify/react'
5+ import { emit } from '@/lib/events'
56
67export type PermissionLevel = 'default' | 'full'
78
89const LEVELS : Array < { id : PermissionLevel ; label : string ; icon : string ; desc : string } > = [
9- { id : 'default' , label : 'Default permissions' , icon : 'lucide:shield' , desc : 'Agent proposes edits for review before applying' } ,
10- { id : 'full' , label : 'Full access' , icon : 'lucide:shield-off' , desc : 'Agent auto-applies edits and runs commands without confirmation' } ,
10+ {
11+ id : 'default' ,
12+ label : 'Default permissions' ,
13+ icon : 'lucide:shield' ,
14+ desc : 'Agent proposes edits for review before applying' ,
15+ } ,
16+ {
17+ id : 'full' ,
18+ label : 'Full access' ,
19+ icon : 'lucide:shield-off' ,
20+ desc : 'Agent auto-applies edits and runs commands without confirmation' ,
21+ } ,
1122]
1223
1324const STORAGE_KEY = 'code-editor:agent-permissions'
@@ -32,8 +43,10 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
3243 const buttonRef = useRef < HTMLButtonElement > ( null )
3344
3445 useEffect ( ( ) => {
35- try { localStorage . setItem ( STORAGE_KEY , level ) } catch { }
36- window . dispatchEvent ( new CustomEvent ( 'permissions-change' , { detail : { permissions : level } } ) )
46+ try {
47+ localStorage . setItem ( STORAGE_KEY , level )
48+ } catch { }
49+ emit ( 'permissions-change' , { permissions : level } )
3750 } , [ level ] )
3851
3952 useEffect ( ( ) => {
@@ -48,7 +61,7 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
4861 } , [ open ] )
4962
5063 const toggle = useCallback ( ( ) => {
51- setOpen ( v => {
64+ setOpen ( ( v ) => {
5265 if ( ! v && buttonRef . current ) {
5366 const rect = buttonRef . current . getBoundingClientRect ( )
5467 setMenuPos ( { left : rect . left , bottom : window . innerHeight - rect . top + 4 } )
@@ -57,7 +70,7 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
5770 } )
5871 } , [ ] )
5972
60- const current = LEVELS . find ( l => l . id === level ) ?? LEVELS [ 0 ]
73+ const current = LEVELS . find ( ( l ) => l . id === level ) ?? LEVELS [ 0 ]
6174 const isMd = size === 'md'
6275
6376 return (
@@ -69,14 +82,17 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
6982 level === 'full'
7083 ? 'text-[var(--warning,#eab308)] bg-[color-mix(in_srgb,var(--warning,#eab308)_8%,transparent)] hover:bg-[color-mix(in_srgb,var(--warning,#eab308)_12%,transparent)]'
7184 : 'text-[var(--text-secondary)] bg-[color-mix(in_srgb,var(--text-primary)_4%,transparent)] hover:bg-[color-mix(in_srgb,var(--text-primary)_7%,transparent)]'
72- } ${
73- isMd ? 'gap-1.5 px-3 py-1.5 text-[13px]' : 'gap-1 px-2 py-1 text-[11px]'
74- } `}
85+ } ${ isMd ? 'gap-1.5 px-3 py-1.5 text-[13px]' : 'gap-1 px-2 py-1 text-[11px]' } `}
7586 title = { current . desc }
7687 >
7788 < Icon icon = { current . icon } width = { isMd ? 14 : 12 } height = { isMd ? 14 : 12 } />
78- { isMd ? current . label : ( level === 'full' ? 'Full' : 'Default' ) }
79- < Icon icon = "lucide:chevron-down" width = { isMd ? 10 : 8 } height = { isMd ? 10 : 8 } className = "opacity-50" />
89+ { isMd ? current . label : level === 'full' ? 'Full' : 'Default' }
90+ < Icon
91+ icon = "lucide:chevron-down"
92+ width = { isMd ? 10 : 8 }
93+ height = { isMd ? 10 : 8 }
94+ className = "opacity-50"
95+ />
8096 </ button >
8197
8298 { open && menuPos && (
@@ -86,10 +102,13 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
86102 className = "fixed z-[9991] w-56 bg-[var(--bg-elevated)] border border-[var(--border)] rounded-xl shadow-xl py-1"
87103 style = { { left : menuPos . left , bottom : menuPos . bottom } }
88104 >
89- { LEVELS . map ( l => (
105+ { LEVELS . map ( ( l ) => (
90106 < button
91107 key = { l . id }
92- onClick = { ( ) => { setLevel ( l . id ) ; setOpen ( false ) } }
108+ onClick = { ( ) => {
109+ setLevel ( l . id )
110+ setOpen ( false )
111+ } }
93112 className = { `w-full flex items-center gap-2.5 px-3 py-2 text-left transition-colors cursor-pointer ${
94113 l . id === level
95114 ? l . id === 'full'
@@ -101,9 +120,13 @@ export function PermissionsToggle({ size = 'sm' }: Props) {
101120 < Icon icon = { l . icon } width = { 14 } height = { 14 } className = "shrink-0" />
102121 < div className = "flex-1 min-w-0" >
103122 < div className = "text-[12px] font-medium" > { l . label } </ div >
104- < div className = "text-[10px] text-[var(--text-disabled)] leading-tight" > { l . desc } </ div >
123+ < div className = "text-[10px] text-[var(--text-disabled)] leading-tight" >
124+ { l . desc }
125+ </ div >
105126 </ div >
106- { l . id === level && < Icon icon = "lucide:check" width = { 12 } height = { 12 } className = "shrink-0" /> }
127+ { l . id === level && (
128+ < Icon icon = "lucide:check" width = { 12 } height = { 12 } className = "shrink-0" />
129+ ) }
107130 </ button >
108131 ) ) }
109132 </ div >
0 commit comments