1- import { useCallback , useState } from 'react'
1+ import React , { useCallback , useState } from 'react'
22
33import { mdiPencil , mdiTrashCan } from '@mdi/js'
44import { parseISO } from 'date-fns'
@@ -23,6 +23,8 @@ import {
2323 H5 ,
2424 LineChart ,
2525 Series ,
26+ Modal ,
27+ Alert ,
2628} from '@sourcegraph/wildcard'
2729
2830import { CopyableText } from '../../../../components/CopyableText'
@@ -73,22 +75,31 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
7375 const [ updateCodyGatewayConfig , { loading : updateCodyGatewayConfigLoading , error : updateCodyGatewayConfigError } ] =
7476 useMutation < UpdateCodyGatewayConfigResult , UpdateCodyGatewayConfigVariables > ( UPDATE_CODY_GATEWAY_CONFIG )
7577
76- const onToggleCompletions = useCallback (
77- async ( value : boolean ) => {
78- try {
79- await updateCodyGatewayConfig ( {
80- variables : {
81- productSubscriptionID,
82- access : { enabled : value } ,
83- } ,
84- } )
85- await refetchSubscription ( )
86- } catch ( error ) {
87- logger . error ( error )
88- }
89- } ,
90- [ productSubscriptionID , refetchSubscription , updateCodyGatewayConfig ]
91- )
78+ const [ codyServicesStateChange , setCodyServicesStateChange ] = useState < boolean | undefined > ( )
79+
80+ const onCancelToggleCodyServices = useCallback ( ( ) => {
81+ setCodyServicesStateChange ( undefined )
82+ } , [ ] )
83+
84+ const onToggleCodyServices = useCallback ( async ( ) => {
85+ if ( typeof codyServicesStateChange !== 'boolean' ) {
86+ return
87+ }
88+ try {
89+ await updateCodyGatewayConfig ( {
90+ variables : {
91+ productSubscriptionID,
92+ access : { enabled : codyServicesStateChange } ,
93+ } ,
94+ } )
95+ await refetchSubscription ( )
96+ } catch ( error ) {
97+ logger . error ( error )
98+ } finally {
99+ // Reset the intent to change state.
100+ setCodyServicesStateChange ( undefined )
101+ }
102+ } , [ productSubscriptionID , refetchSubscription , updateCodyGatewayConfig , codyServicesStateChange ] )
92103
93104 return (
94105 < >
@@ -105,7 +116,7 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
105116 id = "cody-gateway-enabled"
106117 value = { codyGatewayAccess . enabled }
107118 disabled = { updateCodyGatewayConfigLoading || ! viewerCanAdminister }
108- onToggle = { onToggleCompletions }
119+ onToggle = { setCodyServicesStateChange }
109120 className = "mr-1 align-text-bottom"
110121 />
111122 Access to hosted Cody services
@@ -207,6 +218,14 @@ export const CodyServicesSection: React.FunctionComponent<Props> = ({
207218 ) }
208219 { accessTokenError && < ErrorAlert error = { accessTokenError } className = "mb-0" /> }
209220 </ Container >
221+
222+ { typeof codyServicesStateChange === 'boolean' && (
223+ < ToggleCodyServicesConfirmationModal
224+ onAccept = { onToggleCodyServices }
225+ onCancel = { onCancelToggleCodyServices }
226+ targetState = { codyServicesStateChange }
227+ />
228+ ) }
210229 </ >
211230 )
212231}
@@ -506,3 +525,37 @@ const EmbeddingsRateLimitUsage: React.FunctionComponent<RateLimitUsageProps> = (
506525 </ >
507526 )
508527}
528+
529+ interface ToggleCodyServicesConfirmationModalProps {
530+ onAccept : ( ) => void
531+ onCancel : ( ) => void
532+ targetState : boolean
533+ }
534+
535+ const ToggleCodyServicesConfirmationModal : React . FunctionComponent < ToggleCodyServicesConfirmationModalProps > = ( {
536+ onCancel,
537+ onAccept,
538+ targetState,
539+ } ) => {
540+ const labelId = 'toggle-cody-services'
541+ return (
542+ < Modal onDismiss = { onCancel } aria-labelledby = { labelId } >
543+ < H3 id = { labelId } > { targetState ? 'Enable' : 'Disable' } access to Cody Gateway</ H3 >
544+ < Text >
545+ Cody Gateway is a Sourcegraph managed service that allows customer instances to talk to upstream LLMs
546+ and generate embeddings under our negotiated terms with third party providers in a safe manner.
547+ </ Text >
548+
549+ < Alert variant = "info" > Note that changes may take up to 10 minutes to propagate.</ Alert >
550+
551+ < div className = "d-flex justify-content-end" >
552+ < Button className = "mr-2" onClick = { onCancel } outline = { true } variant = "secondary" >
553+ Cancel
554+ </ Button >
555+ < Button variant = "primary" onClick = { onAccept } >
556+ { targetState ? 'Enable' : 'Disable' }
557+ </ Button >
558+ </ div >
559+ </ Modal >
560+ )
561+ }
0 commit comments