@@ -413,8 +413,6 @@ export function CredentialsManager() {
413413 const [ workspaceVars , setWorkspaceVars ] = useState < Record < string , string > > ( { } )
414414 const [ renamingKey , setRenamingKey ] = useState < string | null > ( null )
415415 const [ pendingKeyValue , setPendingKeyValue ] = useState < string > ( '' )
416- const [ changeToken , setChangeToken ] = useState ( 0 )
417-
418416 const [ selectedCredentialId , setSelectedCredentialId ] = useState < string | null > ( null )
419417 const [ prevSelectedCredentialId , setPrevSelectedCredentialId ] = useState <
420418 string | null | undefined
@@ -431,7 +429,8 @@ export function CredentialsManager() {
431429 const scrollContainerRef = useRef < HTMLDivElement > ( null )
432430 const initialVarsRef = useRef < UIEnvironmentVariable [ ] > ( [ ] )
433431 const hasChangesRef = useRef ( false )
434- const hasSavedRef = useRef ( false )
432+ const hasSavedPersonalRef = useRef ( false )
433+ const hasSavedWorkspaceRef = useRef ( false )
435434 const shouldBlockNavRef = useRef ( false )
436435 const pendingNavigationUrlRef = useRef < string | null > ( null )
437436
@@ -558,7 +557,7 @@ export function CredentialsManager() {
558557 if ( newWorkspaceRows . some ( ( row ) => row . key && row . value ) ) return true
559558
560559 return false
561- } , [ envVars , workspaceVars , newWorkspaceRows , changeToken ] )
560+ } , [ envVars , workspaceVars , newWorkspaceRows ] )
562561
563562 const hasConflicts = useMemo ( ( ) => {
564563 return envVars . some ( ( envVar ) => ! ! envVar . key && allWorkspaceKeys . has ( envVar . key ) )
@@ -588,7 +587,10 @@ export function CredentialsManager() {
588587 useEffect ( ( ) => ( ) => resetNavGuard ( ) , [ resetNavGuard ] )
589588
590589 useEffect ( ( ) => {
591- if ( hasSavedRef . current ) return
590+ if ( hasSavedPersonalRef . current ) {
591+ hasSavedPersonalRef . current = false
592+ return
593+ }
592594
593595 const existingVars = Object . values ( personalEnvData || { } )
594596 const initialVars = [
@@ -604,12 +606,12 @@ export function CredentialsManager() {
604606
605607 useEffect ( ( ) => {
606608 if ( ! workspaceEnvData ) return
607- if ( hasSavedRef . current ) {
608- hasSavedRef . current = false
609- } else {
610- setWorkspaceVars ( workspaceEnvData . workspace || { } )
611- initialWorkspaceVarsRef . current = workspaceEnvData . workspace || { }
609+ if ( hasSavedWorkspaceRef . current ) {
610+ hasSavedWorkspaceRef . current = false
611+ return
612612 }
613+ setWorkspaceVars ( workspaceEnvData . workspace || { } )
614+ initialWorkspaceVarsRef . current = workspaceEnvData . workspace || { }
613615 } , [ workspaceEnvData ] )
614616
615617 const scrollToBottom = useCallback ( ( ) => {
@@ -967,86 +969,86 @@ export function CredentialsManager() {
967969 const handleSave = async ( ) => {
968970 if ( isListSaving ) return
969971
970- const prevInitialVars = [ ...initialVarsRef . current ]
971- const prevInitialWorkspaceVars = { ...initialWorkspaceVarsRef . current }
972972 const mutations : Promise < unknown > [ ] = [ ]
973973
974- try {
975- setShowUnsavedChanges ( false )
976- hasSavedRef . current = true
977-
978- const mergedWorkspaceVars = { ...workspaceVars }
979- for ( const row of newWorkspaceRows ) {
980- if ( row . key && row . value ) {
981- mergedWorkspaceVars [ row . key ] = row . value
982- }
974+ setShowUnsavedChanges ( false )
975+
976+ const mergedWorkspaceVars = { ...workspaceVars }
977+ for ( const row of newWorkspaceRows ) {
978+ if ( row . key && row . value ) {
979+ mergedWorkspaceVars [ row . key ] = row . value
983980 }
981+ }
984982
985- initialWorkspaceVarsRef . current = { ...mergedWorkspaceVars }
986- initialVarsRef . current = JSON . parse ( JSON . stringify ( envVars . filter ( ( v ) => v . key && v . value ) ) )
983+ const validVariables = envVars
984+ . filter ( ( v ) => v . key && v . value )
985+ . reduce < Record < string , string > > ( ( acc , { key, value } ) => ( { ...acc , [ key ] : value } ) , { } )
987986
988- setChangeToken ( ( prev ) => prev + 1 )
987+ const before = initialWorkspaceVarsRef . current
988+ const after = mergedWorkspaceVars
989+ const toUpsert : Record < string , string > = { }
990+ const toDelete : string [ ] = [ ]
989991
990- const validVariables = envVars
991- . filter ( ( v ) => v . key && v . value )
992- . reduce < Record < string , string > > ( ( acc , { key, value } ) => ( { ...acc , [ key ] : value } ) , { } )
992+ for ( const [ k , v ] of Object . entries ( after ) ) {
993+ if ( ! ( k in before ) || before [ k ] !== v ) {
994+ toUpsert [ k ] = v
995+ }
996+ }
993997
994- const before = prevInitialWorkspaceVars
995- const after = mergedWorkspaceVars
996- const toUpsert : Record < string , string > = { }
997- const toDelete : string [ ] = [ ]
998+ for ( const k of Object . keys ( before ) ) {
999+ if ( ! ( k in after ) ) toDelete . push ( k )
1000+ }
9981001
999- for ( const [ k , v ] of Object . entries ( after ) ) {
1000- if ( ! ( k in before ) || before [ k ] !== v ) {
1001- toUpsert [ k ] = v
1002- }
1002+ const personalChanged = ( ( ) => {
1003+ const initialMap = new Map (
1004+ initialVarsRef . current . filter ( ( v ) => v . key && v . value ) . map ( ( v ) => [ v . key , v . value ] )
1005+ )
1006+ const currentKeys = Object . keys ( validVariables )
1007+ if ( initialMap . size !== currentKeys . length ) return true
1008+ for ( const [ key , value ] of Object . entries ( validVariables ) ) {
1009+ if ( initialMap . get ( key ) !== value ) return true
10031010 }
1011+ return false
1012+ } ) ( )
10041013
1005- for ( const k of Object . keys ( before ) ) {
1006- if ( ! ( k in after ) ) toDelete . push ( k )
1007- }
1014+ const workspaceChanged =
1015+ workspaceId && ( Object . keys ( toUpsert ) . length > 0 || toDelete . length > 0 )
10081016
1009- const personalChanged = ( ( ) => {
1010- const initialMap = new Map (
1011- prevInitialVars . filter ( ( v ) => v . key && v . value ) . map ( ( v ) => [ v . key , v . value ] )
1012- )
1013- const currentKeys = Object . keys ( validVariables )
1014- if ( initialMap . size !== currentKeys . length ) return true
1015- for ( const [ key , value ] of Object . entries ( validVariables ) ) {
1016- if ( initialMap . get ( key ) !== value ) return true
1017- }
1018- return false
1019- } ) ( )
1020-
1021- if ( personalChanged ) {
1022- mutations . push ( savePersonalMutation . mutateAsync ( { variables : validVariables } ) )
1023- }
1024- if ( workspaceId && ( Object . keys ( toUpsert ) . length || toDelete . length ) ) {
1025- mutations . push (
1026- ( async ( ) => {
1027- if ( Object . keys ( toUpsert ) . length ) {
1028- await upsertWorkspaceMutation . mutateAsync ( { workspaceId, variables : toUpsert } )
1029- }
1030- if ( toDelete . length ) {
1031- await removeWorkspaceMutation . mutateAsync ( { workspaceId, keys : toDelete } )
1032- }
1033- } ) ( )
1034- )
1035- }
1017+ if ( personalChanged ) {
1018+ mutations . push ( savePersonalMutation . mutateAsync ( { variables : validVariables } ) )
1019+ }
1020+ if ( workspaceChanged ) {
1021+ mutations . push (
1022+ ( async ( ) => {
1023+ if ( Object . keys ( toUpsert ) . length ) {
1024+ await upsertWorkspaceMutation . mutateAsync ( { workspaceId, variables : toUpsert } )
1025+ }
1026+ if ( toDelete . length ) {
1027+ await removeWorkspaceMutation . mutateAsync ( { workspaceId, keys : toDelete } )
1028+ }
1029+ } ) ( )
1030+ )
1031+ }
1032+
1033+ hasSavedPersonalRef . current = personalChanged
1034+ hasSavedWorkspaceRef . current = Boolean ( workspaceChanged )
10361035
1036+ try {
10371037 const results = await Promise . allSettled ( mutations )
10381038 const firstFailure = results . find ( ( r ) : r is PromiseRejectedResult => r . status === 'rejected' )
10391039 if ( firstFailure ) throw firstFailure . reason
10401040
1041+ initialWorkspaceVarsRef . current = { ...mergedWorkspaceVars }
1042+ initialVarsRef . current = JSON . parse ( JSON . stringify ( envVars . filter ( ( v ) => v . key && v . value ) ) )
1043+
10411044 setWorkspaceVars ( mergedWorkspaceVars )
10421045 setNewWorkspaceRows ( [ createEmptyEnvVar ( ) ] )
10431046 if ( mutations . length > 0 ) {
10441047 toast . success ( 'Secrets saved' )
10451048 }
10461049 } catch ( error ) {
1047- hasSavedRef . current = false
1048- initialVarsRef . current = prevInitialVars
1049- initialWorkspaceVarsRef . current = prevInitialWorkspaceVars
1050+ hasSavedPersonalRef . current = false
1051+ hasSavedWorkspaceRef . current = false
10501052 logger . error ( 'Failed to save environment variables:' , error )
10511053 toast . error ( 'Failed to save secrets' )
10521054 } finally {
0 commit comments