@@ -40,7 +40,7 @@ interface BenchmarkEditorProps {
4040 busy : boolean
4141 saving : boolean
4242 stage : RunBenchmarkStageBody [ 'stage' ] | null
43- onUpdate : ( body : UpdateBenchmarkBody ) => void
43+ onUpdate : ( body : UpdateBenchmarkBody , onSaved : ( ) => void ) => void
4444 onRun : ( stage : RunBenchmarkStageBody [ 'stage' ] , runLabel ?: string ) => void
4545}
4646
@@ -53,7 +53,16 @@ function BenchmarkEditor({
5353 onUpdate,
5454 onRun,
5555} : BenchmarkEditorProps ) {
56- const [ draft , setDraft ] = useState ( benchmark . artifacts )
56+ const [ edit , setEdit ] = useState < {
57+ version : number
58+ artifacts : BenchmarkCase [ 'artifacts' ]
59+ } | null > ( null )
60+ const draft = edit ?. artifacts ?? benchmark . artifacts
61+ const changeDraft = ( patch : Partial < BenchmarkCase [ 'artifacts' ] > ) =>
62+ setEdit ( ( current ) => ( {
63+ version : current ?. version ?? benchmark . version ,
64+ artifacts : { ...( current ?. artifacts ?? benchmark . artifacts ) , ...patch } ,
65+ } ) )
5766 const [ runLabel , setRunLabel ] = useState ( '' )
5867 const { artifacts } = benchmark
5968 const referenceDirty =
@@ -76,31 +85,32 @@ function BenchmarkEditor({
7685
7786 return (
7887 < div className = 'flex flex-col gap-8 divide-y divide-[var(--border)] [&>section+section]:pt-8' >
88+ { edit && edit . version !== benchmark . version && (
89+ < div role = 'alert' className = 'flex items-center gap-3 text-[var(--text-muted)] text-small' >
90+ This benchmark changed on the server. Your edits are preserved; copy any text you need
91+ before loading the latest version.
92+ < Chip onClick = { ( ) => setEdit ( null ) } > Discard local edits</ Chip >
93+ </ div >
94+ ) }
7995 < BenchmarkReference
8096 artifacts = { draft }
8197 busy = { busy }
8298 saving = { saving }
8399 stage = { stage }
84100 referenceDirty = { referenceDirty }
85101 redactionDirty = { redactionDirty }
86- onChange = { ( patch ) => setDraft ( ( current ) => ( { ... current , ... patch } ) ) }
102+ onChange = { changeDraft }
87103 onSave = { ( ) => {
88104 onUpdate (
89- referenceDirty
90- ? {
91- version : benchmark . version ,
92- ...( draft . taskBrief !== artifacts . taskBrief
93- ? { taskBrief : draft . taskBrief }
94- : { } ) ,
95- ...( draft . referenceSpec !== artifacts . referenceSpec
96- ? { referenceSpec : draft . referenceSpec }
97- : { } ) ,
98- }
99- : {
100- version : benchmark . version ,
101- redactedSpec : draft . redactedSpec ,
102- blanks : draft . blanks ,
103- }
105+ {
106+ version : edit ?. version ?? benchmark . version ,
107+ ...( draft . taskBrief !== artifacts . taskBrief ? { taskBrief : draft . taskBrief } : { } ) ,
108+ ...( draft . referenceSpec !== artifacts . referenceSpec
109+ ? { referenceSpec : draft . referenceSpec }
110+ : { } ) ,
111+ ...( redactionDirty ? { redactedSpec : draft . redactedSpec , blanks : draft . blanks } : { } ) ,
112+ } ,
113+ ( ) => setEdit ( ( current ) => ( current === edit ? null : current ) )
104114 )
105115 } }
106116 onRun = { onRun }
@@ -122,8 +132,8 @@ function BenchmarkEditor({
122132 >
123133 { ! canPlan && (
124134 < p className = 'text-[var(--text-muted)] text-small' >
125- Plan mode requires permission to create organization workspaces. An organization
126- administrator can update the selected user’s access .
135+ The selected user needs Plan mode access and permission to create organization
136+ workspaces .
127137 </ p >
128138 ) }
129139 { artifacts . generatedSpec ? (
@@ -310,15 +320,15 @@ export function BenchmarkDetail({
310320 < BenchmarkHistory organizationId = { organizationId } benchmarkId = { benchmarkId } />
311321 ) : (
312322 < BenchmarkEditor
313- key = { ` ${ benchmark . id } : ${ benchmark . version } ` }
323+ key = { benchmark . id }
314324 benchmark = { benchmark }
315325 canPlan = { canPlan }
316326 busy = { busy }
317327 saving = { updateBenchmark . isPending }
318328 stage = { stage }
319- onUpdate = { ( body ) => {
329+ onUpdate = { ( body , onSaved ) => {
320330 runStage . reset ( )
321- updateBenchmark . mutate ( body )
331+ updateBenchmark . mutate ( body , { onSuccess : onSaved } )
322332 } }
323333 onRun = { ( nextStage , runLabel ) => {
324334 updateBenchmark . reset ( )
0 commit comments