blob: 5234f5c2b6d60826a03a87b9e31aa916c789b537 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import React, { useCallback, useEffect, useState } from 'react'
import { Link, useHistory, useParams } from 'react-router-dom'
import { Button, Card, Elevation, Icon, Intent, } from '@blueprintjs/core'
import Nav from '@/components/Nav'
import Sidebar from '@/components/Sidebar'
import AppCrumbs from '@/components/Breadcrumbs'
import Content from '@/components/Content'
import ContentLoader from '@/components/loaders/ContentLoader'
import useConnectionManager from '@/hooks/useConnectionManager'
import useSettingsManager from '@/hooks/useSettingsManager'
import useConnectionValidation from '@/hooks/useConnectionValidation'
import ConnectionForm from '@/pages/configure/connections/ConnectionForm'
import DeleteAction from '@/components/actions/DeleteAction'
import DeleteConfirmationMessage from '@/components/actions/DeleteConfirmationMessage'
import { integrationsData } from '@/data/integrations'
import { NullSettings } from '@/data/NullSettings'
import { ProviderConnectionLimits, ProviderFormLabels, ProviderFormPlaceholders, Providers } from '@/data/Providers'
import '@/styles/integration.scss'
import '@/styles/connections.scss'
import '@/styles/configure.scss'
export default function ConfigureConnection () {
const history = useHistory()
const { providerId, connectionId } = useParams()
const [activeProvider, setActiveProvider] = useState(integrationsData.find(p => p.id === providerId))
// const [activeConnection, setActiveConnection] = useState(NullConnection)
const [showConnectionSettings, setShowConnectionSettings] = useState(true)
const [deleteId, setDeleteId] = useState(false)
const [settings, setSettings] = useState(NullSettings)
const {
testConnection,
saveConnection,
// fetchConnection,
activeConnection,
name,
endpointUrl,
proxy,
username,
password,
token,
initialTokenStore,
errors,
testStatus,
testResponse,
allTestResponses,
isSaving: isSavingConnection,
isTesting: isTestingConnection,
isFetching: isLoadingConnection,
setName,
setEndpointUrl,
setProxy,
setUsername,
setPassword,
setToken,
setInitialTokenStore,
// saveComplete: saveConnectionComplete,
showError: showConnectionError,
isDeleting: isDeletingConnection,
deleteConnection,
deleteComplete
} = useConnectionManager({
activeProvider,
connectionId,
}, true)
const {
saveSettings,
// errors: settingsErrors,
isSaving,
// isTesting,
// showError,
} = useSettingsManager({
activeProvider,
activeConnection,
settings
})
const {
validate,
errors: validationErrors,
isValid: isValidForm
} = useConnectionValidation({
activeProvider,
name,
endpointUrl,
proxy,
token,
username,
password
})
const cancel = () => {
history.push(`/integrations/${activeProvider.id}`)
}
const renderProviderSettings = useCallback((providerId, activeProvider) => {
console.log('>>> RENDERING PROVIDER SETTINGS...')
let settingsComponent = null
if (activeProvider && activeProvider.settings) {
settingsComponent = activeProvider.settings({
activeProvider,
activeConnection,
isSaving,
isSavingConnection,
setSettings
})
} else {
// @todo create & display "fallback/empty settings" view
console.log('>> WARNING: NO PROVIDER SETTINGS RENDERED, PROVIDER = ', activeProvider)
}
return settingsComponent
}, [activeConnection, isSaving, isSavingConnection])
useEffect(() => {
console.log('>>>> DETECTED PROVIDER ID = ', providerId)
console.log('>>>> DETECTED CONNECTION ID = ', connectionId)
if (connectionId && providerId) {
setActiveProvider(integrationsData.find(p => p.id === providerId))
} else {
console.log('NO PARAMS!')
}
}, [connectionId, providerId, integrationsData])
useEffect(() => {
}, [settings])
useEffect(() => {
if (deleteComplete) {
console.log('>>> DELETE COMPLETE!')
history.replace(`/integrations/${deleteComplete.provider?.id}`)
}
}, [deleteComplete, history])
// useEffect(() => {
// // CONNECTION SAVED!
// }, [saveConnectionComplete])
return (
<>
<div className='container'>
<Nav />
<Sidebar />
<Content>
<main className='main'>
<AppCrumbs
items={[
{ href: '/', icon: false, text: 'Dashboard' },
{ href: '/integrations', icon: false, text: 'Integrations' },
{ href: `/integrations/${activeProvider.id}`, icon: false, text: `${activeProvider.name}` },
{
href: `/connections/configure/${activeProvider.id}/${activeConnection && activeConnection.ID}`,
icon: false,
text: `${activeConnection ? activeConnection.name : 'Configure'} Settings`,
current: true
}
]}
/>
<div className='configureConnection' style={{ width: '100%' }}>
{!isLoadingConnection && (
<Link style={{ float: 'right', marginLeft: '10px', color: '#777777' }} to={`/integrations/${activeProvider.id}`}>
<Icon icon='fast-backward' size={16} /> Connection List
</Link>
)}
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
<div>
<span style={{ marginRight: '10px' }}>{activeProvider.icon}</span>
</div>
{isLoadingConnection && (
<ContentLoader title='Loading Connection ...' message='Please wait while connection settings are loaded.' />
)}
{!isLoadingConnection && (
<div style={{ justifyContent: 'flex-start' }}>
<div style={{ display: 'flex' }}>
<h1 style={{ margin: 0 }}>
Manage <strong style={{ fontWeight: 900 }}>{activeProvider.name}</strong> Settings
</h1>
{activeProvider.multiConnection && (
<div style={{ paddingTop: '5px' }}>
<DeleteAction
id={deleteId}
connection={activeConnection}
text='Delete'
showConfirmation={() => setDeleteId(activeConnection.ID)}
onConfirm={deleteConnection}
onCancel={(e) => setDeleteId(null)}
isDisabled={isDeletingConnection}
isLoading={isDeletingConnection}
>
<DeleteConfirmationMessage title={`DELETE "${activeConnection.name}"`} />
</DeleteAction>
</div>
)}
</div>
{activeConnection && (
<>
{[Providers.GITLAB, Providers.JIRA].includes(activeProvider.id) &&
(<h2 style={{ margin: 0 }}>#{activeConnection.ID} {activeConnection.name}</h2>)}
<p className='page-description'>Manage settings and options for this connection.</p>
</>
)}
</div>
)}
</div>
{!isLoadingConnection && activeProvider && activeConnection && (
<>
<Card
interactive={false}
elevation={Elevation.ZERO}
style={{ backgroundColor: '#f8f8f8', width: '100%', marginBottom: '20px' }}
>
<Button
type='button'
icon={showConnectionSettings ? 'eye-on' : 'eye-off'}
intent={showConnectionSettings ? Intent.PRIMARY : Intent.DISABLED}
style={{ margin: '2px', float: 'right' }}
onClick={() => setShowConnectionSettings(!showConnectionSettings)}
minimal
small
/>
{showConnectionSettings
? (
<div className='editConnection' style={{ display: 'flex' }}>
<ConnectionForm
isValid={isValidForm}
validationErrors={validationErrors}
activeProvider={activeProvider}
name={name}
endpointUrl={endpointUrl}
proxy={proxy}
token={token}
initialTokenStore={initialTokenStore}
username={username}
password={password}
// JIRA and GITLAB are multi-connection plugins, for now we intentially won't include additional settings during save...
onSave={() => saveConnection(![Providers.GITLAB, Providers.JIRA].includes(activeProvider.id) ? settings : {})}
onTest={testConnection}
onCancel={cancel}
onValidate={validate}
onNameChange={setName}
onEndpointChange={setEndpointUrl}
onProxyChange={setProxy}
onTokenChange={setToken}
onUsernameChange={setUsername}
onPasswordChange={setPassword}
isSaving={isSavingConnection}
isTesting={isTestingConnection}
testStatus={testStatus}
testResponse={testResponse}
allTestResponses={allTestResponses}
errors={errors}
showError={showConnectionError}
authType={[Providers.JENKINS, Providers.JIRA].includes(activeProvider.id) ? 'plain' : 'token'}
showLimitWarning={false}
sourceLimits={ProviderConnectionLimits}
labels={ProviderFormLabels[activeProvider.id]}
placeholders={ProviderFormPlaceholders[activeProvider.id]}
/>
</div>
)
: (
<>
<h2 style={{ margin: 0 }}>Configure Connection</h2>
<p className='description' style={{ margin: 0 }}>
( Click the <strong>Visibility</strong> icon to your right to edit connection )
</p>
</>
)}
{/* {validationErrors.length > 0 && (
<FormValidationErrors errors={validationErrors} />
)} */}
</Card>
{/* <div style={{ marginTop: '30px' }}>
{renderProviderSettings(providerId, activeProvider)}
</div> */}
{/* <div className='form-actions-block' style={{ display: 'flex', marginTop: '60px', justifyContent: 'space-between' }}>
<div />
<div>
<Button icon='remove' text='Cancel' onClick={cancel} disabled={isSaving} />
<Button
icon='cloud-upload'
intent={Intent.PRIMARY}
text='Save Settings'
loading={isSaving}
disabled={isSaving || providerId === Providers.JENKINS}
onClick={saveSettings}
style={{ marginLeft: '10px' }}
/>
</div>
</div> */}
</>
)}
</div>
</main>
</Content>
</div>
</>
)
}