mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:21:50 +00:00
Adds global CTA banner (#21950)
Co-authored-by: TJ Kandala <kandalatj@gmail.com>
This commit is contained in:
parent
45ccd0c273
commit
8d9622bcbc
@ -272,10 +272,7 @@ export const Layout: React.FunctionComponent<LayoutProps> = props => {
|
||||
keyboardShortcutForShow={KEYBOARD_SHORTCUT_SHOW_HELP}
|
||||
keyboardShortcuts={props.keyboardShortcuts}
|
||||
/>
|
||||
<GlobalAlerts
|
||||
isSiteAdmin={!!props.authenticatedUser && props.authenticatedUser.siteAdmin}
|
||||
settingsCascade={props.settingsCascade}
|
||||
/>
|
||||
<GlobalAlerts authenticatedUser={props.authenticatedUser} settingsCascade={props.settingsCascade} />
|
||||
{!isSiteInit && <SurveyToast authenticatedUser={props.authenticatedUser} />}
|
||||
{!isSiteInit && !isSignInOrUp && (
|
||||
<GlobalNavbar
|
||||
|
||||
@ -80,6 +80,7 @@ import { aggregateStreamingSearch } from './search/stream'
|
||||
import { listUserRepositories } from './site-admin/backend'
|
||||
import { SiteAdminAreaRoute } from './site-admin/SiteAdminArea'
|
||||
import { SiteAdminSideBarGroups } from './site-admin/SiteAdminSidebar'
|
||||
import { GitHubServiceScopeProvider } from './site/GitHubCodeHostScopeAlert/GithubScopeProvider'
|
||||
import { ThemePreference } from './theme'
|
||||
import { eventLogger } from './tracking/eventLogger'
|
||||
import { withActivation } from './tracking/withActivation'
|
||||
@ -510,68 +511,70 @@ class ColdSourcegraphWebApp extends React.Component<SourcegraphWebAppProps, Sour
|
||||
<Route
|
||||
path="/"
|
||||
render={routeComponentProps => (
|
||||
<LayoutWithActivation
|
||||
{...props}
|
||||
{...routeComponentProps}
|
||||
authenticatedUser={authenticatedUser}
|
||||
viewerSubject={this.state.viewerSubject}
|
||||
settingsCascade={this.state.settingsCascade}
|
||||
showBatchChanges={this.props.showBatchChanges}
|
||||
// Theme
|
||||
isLightTheme={this.isLightTheme()}
|
||||
themePreference={this.state.themePreference}
|
||||
onThemePreferenceChange={this.onThemePreferenceChange}
|
||||
// Search query
|
||||
navbarSearchQueryState={this.state.navbarSearchQueryState}
|
||||
onNavbarQueryChange={this.onNavbarQueryChange}
|
||||
fetchHighlightedFileLineRanges={fetchHighlightedFileLineRanges}
|
||||
parsedSearchQuery={this.state.parsedSearchQuery}
|
||||
setParsedSearchQuery={this.setParsedSearchQuery}
|
||||
patternType={this.state.searchPatternType}
|
||||
setPatternType={this.setPatternType}
|
||||
caseSensitive={this.state.searchCaseSensitivity}
|
||||
setCaseSensitivity={this.setCaseSensitivity}
|
||||
versionContext={this.state.versionContext}
|
||||
setVersionContext={this.setVersionContext}
|
||||
availableVersionContexts={this.state.availableVersionContexts}
|
||||
previousVersionContext={this.state.previousVersionContext}
|
||||
// Extensions
|
||||
platformContext={this.platformContext}
|
||||
extensionsController={this.extensionsController}
|
||||
telemetryService={eventLogger}
|
||||
isSourcegraphDotCom={window.context.sourcegraphDotComMode}
|
||||
showRepogroupHomepage={this.state.showRepogroupHomepage}
|
||||
showOnboardingTour={this.state.showOnboardingTour}
|
||||
showSearchContext={this.state.showSearchContext}
|
||||
hasUserAddedRepositories={this.state.hasUserAddedRepositories}
|
||||
hasUserAddedExternalServices={this.state.hasUserAddedExternalServices}
|
||||
showSearchContextManagement={this.state.showSearchContextManagement}
|
||||
selectedSearchContextSpec={this.getSelectedSearchContextSpec()}
|
||||
setSelectedSearchContextSpec={this.setSelectedSearchContextSpec}
|
||||
getUserSearchContextNamespaces={getUserSearchContextNamespaces}
|
||||
fetchAutoDefinedSearchContexts={fetchAutoDefinedSearchContexts}
|
||||
fetchSearchContexts={fetchSearchContexts}
|
||||
fetchSearchContext={fetchSearchContext}
|
||||
createSearchContext={createSearchContext}
|
||||
updateSearchContext={updateSearchContext}
|
||||
deleteSearchContext={deleteSearchContext}
|
||||
convertVersionContextToSearchContext={convertVersionContextToSearchContext}
|
||||
isSearchContextSpecAvailable={isSearchContextSpecAvailable}
|
||||
defaultSearchContextSpec={this.state.defaultSearchContextSpec}
|
||||
showEnterpriseHomePanels={this.state.showEnterpriseHomePanels}
|
||||
globbing={this.state.globbing}
|
||||
showMultilineSearchConsole={this.state.showMultilineSearchConsole}
|
||||
showQueryBuilder={this.state.showQueryBuilder}
|
||||
enableSmartQuery={this.state.enableSmartQuery}
|
||||
enableCodeMonitoring={this.state.enableCodeMonitoring}
|
||||
fetchSavedSearches={fetchSavedSearches}
|
||||
fetchRecentSearches={fetchRecentSearches}
|
||||
fetchRecentFileViews={fetchRecentFileViews}
|
||||
streamSearch={aggregateStreamingSearch}
|
||||
onUserExternalServicesOrRepositoriesUpdate={
|
||||
this.onUserExternalServicesOrRepositoriesUpdate
|
||||
}
|
||||
/>
|
||||
<GitHubServiceScopeProvider authenticatedUser={authenticatedUser}>
|
||||
<LayoutWithActivation
|
||||
{...props}
|
||||
{...routeComponentProps}
|
||||
authenticatedUser={authenticatedUser}
|
||||
viewerSubject={this.state.viewerSubject}
|
||||
settingsCascade={this.state.settingsCascade}
|
||||
showBatchChanges={this.props.showBatchChanges}
|
||||
// Theme
|
||||
isLightTheme={this.isLightTheme()}
|
||||
themePreference={this.state.themePreference}
|
||||
onThemePreferenceChange={this.onThemePreferenceChange}
|
||||
// Search query
|
||||
navbarSearchQueryState={this.state.navbarSearchQueryState}
|
||||
onNavbarQueryChange={this.onNavbarQueryChange}
|
||||
fetchHighlightedFileLineRanges={fetchHighlightedFileLineRanges}
|
||||
parsedSearchQuery={this.state.parsedSearchQuery}
|
||||
setParsedSearchQuery={this.setParsedSearchQuery}
|
||||
patternType={this.state.searchPatternType}
|
||||
setPatternType={this.setPatternType}
|
||||
caseSensitive={this.state.searchCaseSensitivity}
|
||||
setCaseSensitivity={this.setCaseSensitivity}
|
||||
versionContext={this.state.versionContext}
|
||||
setVersionContext={this.setVersionContext}
|
||||
availableVersionContexts={this.state.availableVersionContexts}
|
||||
previousVersionContext={this.state.previousVersionContext}
|
||||
// Extensions
|
||||
platformContext={this.platformContext}
|
||||
extensionsController={this.extensionsController}
|
||||
telemetryService={eventLogger}
|
||||
isSourcegraphDotCom={window.context.sourcegraphDotComMode}
|
||||
showRepogroupHomepage={this.state.showRepogroupHomepage}
|
||||
showOnboardingTour={this.state.showOnboardingTour}
|
||||
showSearchContext={this.state.showSearchContext}
|
||||
hasUserAddedRepositories={this.state.hasUserAddedRepositories}
|
||||
hasUserAddedExternalServices={this.state.hasUserAddedExternalServices}
|
||||
showSearchContextManagement={this.state.showSearchContextManagement}
|
||||
selectedSearchContextSpec={this.getSelectedSearchContextSpec()}
|
||||
setSelectedSearchContextSpec={this.setSelectedSearchContextSpec}
|
||||
getUserSearchContextNamespaces={getUserSearchContextNamespaces}
|
||||
fetchAutoDefinedSearchContexts={fetchAutoDefinedSearchContexts}
|
||||
fetchSearchContexts={fetchSearchContexts}
|
||||
fetchSearchContext={fetchSearchContext}
|
||||
createSearchContext={createSearchContext}
|
||||
updateSearchContext={updateSearchContext}
|
||||
deleteSearchContext={deleteSearchContext}
|
||||
convertVersionContextToSearchContext={convertVersionContextToSearchContext}
|
||||
isSearchContextSpecAvailable={isSearchContextSpecAvailable}
|
||||
defaultSearchContextSpec={this.state.defaultSearchContextSpec}
|
||||
showEnterpriseHomePanels={this.state.showEnterpriseHomePanels}
|
||||
globbing={this.state.globbing}
|
||||
showMultilineSearchConsole={this.state.showMultilineSearchConsole}
|
||||
showQueryBuilder={this.state.showQueryBuilder}
|
||||
enableSmartQuery={this.state.enableSmartQuery}
|
||||
enableCodeMonitoring={this.state.enableCodeMonitoring}
|
||||
fetchSavedSearches={fetchSavedSearches}
|
||||
fetchRecentSearches={fetchRecentSearches}
|
||||
fetchRecentFileViews={fetchRecentFileViews}
|
||||
streamSearch={aggregateStreamingSearch}
|
||||
onUserExternalServicesOrRepositoriesUpdate={
|
||||
this.onUserExternalServicesOrRepositoriesUpdate
|
||||
}
|
||||
/>
|
||||
</GitHubServiceScopeProvider>
|
||||
)}
|
||||
/>
|
||||
</BrowserRouter>
|
||||
|
||||
@ -237,3 +237,43 @@ export function queryExternalServices(
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
interface ExternalServicesScopeVariables {
|
||||
namespace: Scalars['ID']
|
||||
}
|
||||
|
||||
interface ExternalServicesScopeResult {
|
||||
externalServices: {
|
||||
nodes: {
|
||||
id: ExternalServiceFields['id']
|
||||
kind: ExternalServiceFields['kind']
|
||||
grantedScopes: string[]
|
||||
}[]
|
||||
}
|
||||
}
|
||||
|
||||
export function queryExternalServicesScope(
|
||||
variables: ExternalServicesScopeVariables
|
||||
): Observable<ExternalServicesScopeResult['externalServices']> {
|
||||
return requestGraphQL<ExternalServicesScopeResult, ExternalServicesScopeVariables>(
|
||||
gql`
|
||||
query ExternalServicesScopes($namespace: ID!) {
|
||||
externalServices(first: null, after: null, namespace: $namespace) {
|
||||
nodes {
|
||||
id
|
||||
kind
|
||||
grantedScopes
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables
|
||||
).pipe(
|
||||
map(({ data, errors }) => {
|
||||
if (!data || !data.externalServices || errors) {
|
||||
throw createAggregateError(errors)
|
||||
}
|
||||
return data.externalServices
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
@ -7,12 +7,14 @@ import { Markdown } from '@sourcegraph/shared/src/components/Markdown'
|
||||
import { isSettingsValid, SettingsCascadeProps } from '@sourcegraph/shared/src/settings/settings'
|
||||
import { renderMarkdown } from '@sourcegraph/shared/src/util/markdown'
|
||||
|
||||
import { AuthenticatedUser } from '../auth'
|
||||
import { DismissibleAlert } from '../components/DismissibleAlert'
|
||||
import { Settings } from '../schema/settings.schema'
|
||||
import { SiteFlags } from '../site'
|
||||
import { siteFlags } from '../site/backend'
|
||||
import { DockerForMacAlert } from '../site/DockerForMacAlert'
|
||||
import { FreeUsersExceededAlert } from '../site/FreeUsersExceededAlert'
|
||||
import { GitHubScopeAlert } from '../site/GitHubCodeHostScopeAlert/GitHubScopeAlert'
|
||||
import { LicenseExpirationAlert } from '../site/LicenseExpirationAlert'
|
||||
import { NeedsRepositoryConfigurationAlert } from '../site/NeedsRepositoryConfigurationAlert'
|
||||
|
||||
@ -20,7 +22,7 @@ import { GlobalAlert } from './GlobalAlert'
|
||||
import { Notices } from './Notices'
|
||||
|
||||
interface Props extends SettingsCascadeProps {
|
||||
isSiteAdmin: boolean
|
||||
authenticatedUser: AuthenticatedUser | null
|
||||
}
|
||||
|
||||
interface State {
|
||||
@ -61,6 +63,9 @@ export class GlobalAlerts extends React.PureComponent<Props, State> {
|
||||
)}
|
||||
{/* Only show if the user has already added repositories; if not yet, the user wouldn't experience any Docker for Mac perf issues anyway. */}
|
||||
{window.context.likelyDockerOnMac && <DockerForMacAlert className="global-alerts__alert" />}
|
||||
{window.context.sourcegraphDotComMode && (
|
||||
<GitHubScopeAlert authenticatedUser={this.props.authenticatedUser} />
|
||||
)}
|
||||
{this.state.siteFlags.alerts.map((alert, index) => (
|
||||
<GlobalAlert key={index} alert={alert} className="global-alerts__alert" />
|
||||
))}
|
||||
|
||||
@ -205,6 +205,11 @@ export const commonWebGraphQlResults: Partial<WebGraphQlOperations & SharedGraph
|
||||
pageInfo: { hasNextPage: false, endCursor: null },
|
||||
},
|
||||
}),
|
||||
ExternalServicesScopes: () => ({
|
||||
externalServices: {
|
||||
nodes: [],
|
||||
},
|
||||
}),
|
||||
FetchFeatureFlags: () => ({
|
||||
viewerFeatureFlags: [],
|
||||
}),
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
import InfoIcon from 'mdi-react/InfoCircleIcon'
|
||||
import React, { FunctionComponent } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { DismissibleAlert } from '../../components/DismissibleAlert'
|
||||
import { githubRepoScopeRequired } from '../../user/settings/cloud-ga'
|
||||
|
||||
import { useGitHubScopeContext } from './GithubScopeProvider'
|
||||
|
||||
interface Props {
|
||||
authenticatedUser: { id: string; tags: string[] } | null
|
||||
}
|
||||
|
||||
export const GITHUB_SCOPE_ALERT_KEY = 'GitHubPrivateScopeAlert'
|
||||
|
||||
/**
|
||||
* A global alert telling authenticated users if they need to update GitHub code
|
||||
* host token to access the private repositories.
|
||||
*/
|
||||
export const GitHubScopeAlert: FunctionComponent<Props> = ({ authenticatedUser }) => {
|
||||
const { scopes } = useGitHubScopeContext()
|
||||
|
||||
const shouldTryToDisplayAlert = (): boolean => {
|
||||
if (!authenticatedUser || scopes === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return githubRepoScopeRequired(authenticatedUser.tags, scopes)
|
||||
}
|
||||
|
||||
return shouldTryToDisplayAlert() ? (
|
||||
<DismissibleAlert
|
||||
partialStorageKey={GITHUB_SCOPE_ALERT_KEY}
|
||||
className="alert alert-info d-flex align-items-center"
|
||||
>
|
||||
<InfoIcon className="redesign-d-none icon-inline mr-2 flex-shrink-0" />
|
||||
Update your
|
||||
<Link className="site-alert__link" to="/user/settings/code-hosts">
|
||||
<span className="underline">GitHub code host connection</span>
|
||||
</Link>
|
||||
to search private code with Sourcegraph.
|
||||
</DismissibleAlert>
|
||||
) : null
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
import React, { FunctionComponent, useState, useEffect, useCallback, createContext, useContext } from 'react'
|
||||
|
||||
import { queryExternalServicesScope } from '../../components/externalServices/backend'
|
||||
import { ExternalServiceKind } from '../../graphql-operations'
|
||||
|
||||
type Scopes = string[] | null
|
||||
type SetScopes = (scopes: Scopes) => void
|
||||
|
||||
interface GitHubScopeContext {
|
||||
scopes: Scopes
|
||||
setScopes: SetScopes
|
||||
}
|
||||
|
||||
const GitHubScopeContext = createContext<GitHubScopeContext | undefined>(undefined)
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
authenticatedUser: { id: string; tags: string[] } | null
|
||||
}
|
||||
|
||||
export const GitHubServiceScopeProvider: FunctionComponent<Props> = ({ children, authenticatedUser }) => {
|
||||
const [scopes, setScopes] = useState<string[] | null>(null)
|
||||
|
||||
const fetchGitHubServiceScope = useCallback(async (): Promise<void> => {
|
||||
if (authenticatedUser) {
|
||||
// fetch all code hosts for given user
|
||||
const { nodes: fetchedServices } = await queryExternalServicesScope({
|
||||
namespace: authenticatedUser.id,
|
||||
}).toPromise()
|
||||
|
||||
// check if user has a GitHub code host
|
||||
const gitHubService = fetchedServices.find(({ kind }) => kind === ExternalServiceKind.GITHUB)
|
||||
|
||||
if (gitHubService) {
|
||||
setScopes(gitHubService.grantedScopes)
|
||||
}
|
||||
}
|
||||
}, [authenticatedUser])
|
||||
|
||||
useEffect(() => {
|
||||
fetchGitHubServiceScope().catch(() => {
|
||||
// there's no actionable information we can display here
|
||||
})
|
||||
}, [fetchGitHubServiceScope])
|
||||
|
||||
const { Provider } = GitHubScopeContext
|
||||
|
||||
return <Provider value={{ scopes, setScopes }}>{children}</Provider>
|
||||
}
|
||||
|
||||
export const useGitHubScopeContext = (): GitHubScopeContext => {
|
||||
const context = useContext(GitHubScopeContext)
|
||||
|
||||
if (context === undefined) {
|
||||
throw new Error('useCount must be used within a GitHubServiceScopeProvider')
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@ -18,7 +18,7 @@ interface CodeHostItemProps {
|
||||
name: string
|
||||
icon: React.ComponentType<{ className?: string }>
|
||||
navigateToAuthProvider: (kind: ExternalServiceKind) => void
|
||||
updateAuthRequired?: boolean
|
||||
isTokenUpdateRequired: boolean
|
||||
// optional service object fields when the code host connection is active
|
||||
service?: ListExternalServiceFields
|
||||
|
||||
@ -31,7 +31,7 @@ export const CodeHostItem: React.FunctionComponent<CodeHostItemProps> = ({
|
||||
service,
|
||||
kind,
|
||||
name,
|
||||
updateAuthRequired,
|
||||
isTokenUpdateRequired,
|
||||
icon: Icon,
|
||||
navigateToAuthProvider,
|
||||
onDidRemove,
|
||||
@ -121,7 +121,7 @@ export const CodeHostItem: React.FunctionComponent<CodeHostItemProps> = ({
|
||||
</button>
|
||||
)
|
||||
) : (
|
||||
updateAuthRequired &&
|
||||
isTokenUpdateRequired &&
|
||||
(oauthInFlight ? (
|
||||
<LoaderButton
|
||||
type="button"
|
||||
|
||||
@ -12,6 +12,7 @@ import { AddExternalServiceOptions } from '../../../components/externalServices/
|
||||
import { PageTitle } from '../../../components/PageTitle'
|
||||
import { Scalars, ExternalServiceKind, ListExternalServiceFields } from '../../../graphql-operations'
|
||||
import { SourcegraphContext } from '../../../jscontext'
|
||||
import { useGitHubScopeContext } from '../../../site/GitHubCodeHostScopeAlert/GithubScopeProvider'
|
||||
import { eventLogger } from '../../../tracking/eventLogger'
|
||||
import { UserExternalServicesOrRepositoriesUpdateProps } from '../../../util'
|
||||
import { githubRepoScopeRequired } from '../cloud-ga'
|
||||
@ -64,7 +65,15 @@ export const UserAddCodeHostsPage: React.FunctionComponent<UserAddCodeHostsPageP
|
||||
onUserExternalServicesOrRepositoriesUpdate,
|
||||
}) => {
|
||||
const [statusOrError, setStatusOrError] = useState<Status>()
|
||||
const [updateAuthRequired, setUpdateAuthRequired] = useState(false)
|
||||
const { scopes: gitHubScopes, setScopes: setGitHubScopes } = useGitHubScopeContext()
|
||||
|
||||
// If we have a GitHub service, check whether we need to prompt the user to
|
||||
// update their scope
|
||||
const isGitHubTokenUpdateRequired = gitHubScopes ? githubRepoScopeRequired(user.tags, gitHubScopes) : false
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('UserSettingsCodeHostConnections')
|
||||
}, [])
|
||||
|
||||
const fetchExternalServices = useCallback(async () => {
|
||||
setStatusOrError('loading')
|
||||
@ -83,21 +92,19 @@ export const UserAddCodeHostsPage: React.FunctionComponent<UserAddCodeHostsPageP
|
||||
|
||||
setStatusOrError(services)
|
||||
|
||||
// If we have a GitHub service, check whether we need to prompt the user to
|
||||
// update their scope
|
||||
const gitHubService = services.GITHUB
|
||||
if (gitHubService) {
|
||||
const scopes = gitHubService.grantedScopes || []
|
||||
setUpdateAuthRequired(githubRepoScopeRequired(user.tags, scopes))
|
||||
}
|
||||
|
||||
const repoCount = fetchedServices.reduce((sum, codeHost) => sum + codeHost.repoCount, 0)
|
||||
onUserExternalServicesOrRepositoriesUpdate(fetchedServices.length, repoCount)
|
||||
}, [user.id, user.tags, onUserExternalServicesOrRepositoriesUpdate, setUpdateAuthRequired])
|
||||
}, [user.id, onUserExternalServicesOrRepositoriesUpdate])
|
||||
|
||||
useEffect(() => {
|
||||
eventLogger.logViewEvent('UserSettingsCodeHostConnections')
|
||||
}, [])
|
||||
const resetScopeAndFetchServices = useCallback((): void => {
|
||||
// after the token is updated - we'll set GitHub's scopes to null and
|
||||
// hide the global CTA banner
|
||||
setGitHubScopes(null)
|
||||
|
||||
fetchExternalServices().catch(error => {
|
||||
setStatusOrError(asError(error))
|
||||
})
|
||||
}, [fetchExternalServices, setGitHubScopes])
|
||||
|
||||
useEffect(() => {
|
||||
fetchExternalServices().catch(error => {
|
||||
@ -159,7 +166,7 @@ export const UserAddCodeHostsPage: React.FunctionComponent<UserAddCodeHostsPageP
|
||||
return [
|
||||
...servicesWithProblems.map(getServiceWarningFragment),
|
||||
getAddReposBanner(notYetSyncedServiceNames),
|
||||
getGitHubUpdateAuthBanner(updateAuthRequired),
|
||||
getGitHubUpdateAuthBanner(isGitHubTokenUpdateRequired),
|
||||
]
|
||||
}
|
||||
|
||||
@ -235,25 +242,27 @@ export const UserAddCodeHostsPage: React.FunctionComponent<UserAddCodeHostsPageP
|
||||
{codeHostExternalServices && isServicesByKind(statusOrError) ? (
|
||||
<Container>
|
||||
<ul className="list-group">
|
||||
{Object.entries(codeHostExternalServices).map(([id, { kind, defaultDisplayName, icon }]) =>
|
||||
authProvidersByKind[kind] ? (
|
||||
{Object.entries(codeHostExternalServices).map(([id, { kind, defaultDisplayName, icon }]) => {
|
||||
const isTokenUpdateRequired = ExternalServiceKind.GITHUB && isGitHubTokenUpdateRequired
|
||||
|
||||
return authProvidersByKind[kind] ? (
|
||||
<li key={id} className="list-group-item user-code-hosts-page__code-host-item">
|
||||
<CodeHostItem
|
||||
service={isServicesByKind(statusOrError) ? statusOrError[kind] : undefined}
|
||||
kind={kind}
|
||||
name={defaultDisplayName}
|
||||
updateAuthRequired={
|
||||
id && kind === ExternalServiceKind.GITHUB ? updateAuthRequired : false
|
||||
}
|
||||
isTokenUpdateRequired={isTokenUpdateRequired}
|
||||
navigateToAuthProvider={navigateToAuthProvider}
|
||||
icon={icon}
|
||||
onDidAdd={addNewService}
|
||||
onDidRemove={fetchExternalServices}
|
||||
onDidRemove={
|
||||
isTokenUpdateRequired ? resetScopeAndFetchServices : fetchExternalServices
|
||||
}
|
||||
onDidError={handleError}
|
||||
/>
|
||||
</li>
|
||||
) : null
|
||||
)}
|
||||
})}
|
||||
</ul>
|
||||
</Container>
|
||||
) : (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user