-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Workplace Search] Migrate AddSource tree (#83799)
* Initial copy/paste of components Changes for pre-commit hooks were: - Linting - Lodash imports - changed enum names in add_source because there were collistions with component names. So SaveConfig becomes SaveConfigStep because there is a component by the same name - replaced apostrophe’s with ‘'’ per lint rule Finally, the linter didn’t like this expression: asOauthRedirect ? onOauthFormSubmit() : onCredentialsFormSubmit(); … so I changed it to: const onSubmit = hasOauthRedirect ? onOauthFormSubmit : onCredentialsFormSubmit; onSubmit(); * Add route helper * Remove AppView, Sidebar navigation and FlashMessages Sidebar copy and breadcrumbs will be recreated at the top level in a separate PR * Update component paths * Use Kibana’s hasPlatinumLicense over minimumPlatinumLicense * Various TypeScript lint fixes * Fix index paths * Remove in-page breadcrumbs and move sidebar copy In Kibana, breadcrumbs will be at the top-level and not in the view Also, we have no sidebar with contextual copy. The Figma designs call for this copy to be above the main content. For now I am placing this in the existing ViewContentHeader component. This will be slightly broken because of the structure of ViewContentHeader but that is expected for now since it cannot be rendered in the browser yet to fix * Temporarily add parseQueryParams This is a placeholder until #83750 lands * Remove optional from isOrganization Looks like the value is always passed * Remove ‘!!’
- Loading branch information
1 parent
3d0770f
commit ad5cf9e
Showing
17 changed files
with
2,070 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
235 changes: 235 additions & 0 deletions
235
.../applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import React, { useEffect, useState } from 'react'; | ||
|
||
import { History } from 'history'; | ||
import { useActions, useValues } from 'kea'; | ||
import { useHistory } from 'react-router-dom'; | ||
|
||
import { AppLogic } from '../../../../app_logic'; | ||
import { Loading } from '../../../../../../applications/shared/loading'; | ||
import { ViewContentHeader } from '../../../../components/shared/view_content_header'; | ||
import { CUSTOM_SERVICE_TYPE } from '../../../../constants'; | ||
import { staticSourceData } from '../../source_data'; | ||
import { SourceLogic } from '../../source_logic'; | ||
import { SourceDataItem, FeatureIds } from '../../../../types'; | ||
import { SOURCE_ADDED_PATH, getSourcesPath } from '../../../../routes'; | ||
|
||
import { AddSourceHeader } from './add_source_header'; | ||
import { ConfigCompleted } from './config_completed'; | ||
import { ConfigurationIntro } from './configuration_intro'; | ||
import { ConfigureCustom } from './configure_custom'; | ||
import { ConfigureOauth } from './configure_oauth'; | ||
import { ConnectInstance } from './connect_instance'; | ||
import { ReAuthenticate } from './re_authenticate'; | ||
import { SaveConfig } from './save_config'; | ||
import { SaveCustom } from './save_custom'; | ||
|
||
enum Steps { | ||
ConfigIntroStep = 'Config Intro', | ||
SaveConfigStep = 'Save Config', | ||
ConfigCompletedStep = 'Config Completed', | ||
ConnectInstanceStep = 'Connect Instance', | ||
ConfigureCustomStep = 'Configure Custom', | ||
ConfigureOauthStep = 'Configure Oauth', | ||
SaveCustomStep = 'Save Custom', | ||
ReAuthenticateStep = 'ReAuthenticate', | ||
} | ||
|
||
interface AddSourceProps { | ||
sourceIndex: number; | ||
connect?: boolean; | ||
configure?: boolean; | ||
reAuthenticate?: boolean; | ||
} | ||
|
||
export const AddSource: React.FC<AddSourceProps> = ({ | ||
sourceIndex, | ||
connect, | ||
configure, | ||
reAuthenticate, | ||
}) => { | ||
const history = useHistory() as History; | ||
const { | ||
getSourceConfigData, | ||
saveSourceConfig, | ||
createContentSource, | ||
resetSourceState, | ||
} = useActions(SourceLogic); | ||
const { | ||
sourceConfigData: { | ||
name, | ||
categories, | ||
needsPermissions, | ||
accountContextOnly, | ||
privateSourcesEnabled, | ||
}, | ||
dataLoading, | ||
newCustomSource, | ||
} = useValues(SourceLogic); | ||
|
||
const { | ||
serviceType, | ||
configuration, | ||
features, | ||
objTypes, | ||
sourceDescription, | ||
connectStepDescription, | ||
addPath, | ||
} = staticSourceData[sourceIndex] as SourceDataItem; | ||
|
||
const { isOrganization } = useValues(AppLogic); | ||
|
||
useEffect(() => { | ||
getSourceConfigData(serviceType); | ||
return resetSourceState; | ||
}, []); | ||
|
||
const isCustom = serviceType === CUSTOM_SERVICE_TYPE; | ||
const isRemote = features?.platinumPrivateContext.includes(FeatureIds.Remote); | ||
|
||
const getFirstStep = () => { | ||
if (isCustom) return Steps.ConfigureCustomStep; | ||
if (connect) return Steps.ConnectInstanceStep; | ||
if (configure) return Steps.ConfigureOauthStep; | ||
if (reAuthenticate) return Steps.ReAuthenticateStep; | ||
return Steps.ConfigIntroStep; | ||
}; | ||
|
||
const [currentStep, setStep] = useState(getFirstStep()); | ||
|
||
if (dataLoading) return <Loading />; | ||
|
||
const goToConfigurationIntro = () => setStep(Steps.ConfigIntroStep); | ||
const goToSaveConfig = () => setStep(Steps.SaveConfigStep); | ||
const setConfigCompletedStep = () => setStep(Steps.ConfigCompletedStep); | ||
const goToConfigCompleted = () => saveSourceConfig(false, setConfigCompletedStep); | ||
|
||
const goToConnectInstance = () => { | ||
setStep(Steps.ConnectInstanceStep); | ||
history.push(`${getSourcesPath(addPath, isOrganization)}/connect`); | ||
}; | ||
|
||
const saveCustomSuccess = () => setStep(Steps.SaveCustomStep); | ||
const goToSaveCustom = () => createContentSource(CUSTOM_SERVICE_TYPE, saveCustomSuccess); | ||
|
||
const goToFormSourceCreated = (sourceName: string) => { | ||
history.push(`${getSourcesPath(SOURCE_ADDED_PATH, isOrganization)}/?name=${sourceName}`); | ||
}; | ||
|
||
const pageTitle = () => { | ||
if (currentStep === Steps.ConnectInstanceStep || currentStep === Steps.ConfigureOauthStep) { | ||
return 'Connect'; | ||
} | ||
if (currentStep === Steps.ReAuthenticateStep) { | ||
return 'Re-authenticate'; | ||
} | ||
if (currentStep === Steps.ConfigureCustomStep || currentStep === Steps.SaveCustomStep) { | ||
return 'Create a'; | ||
} | ||
return 'Configure'; | ||
}; | ||
|
||
const CREATE_CUSTOM_SOURCE_SIDEBAR_BLURB = | ||
'Custom API Sources provide a set of feature-rich endpoints for indexing data from any content repository.'; | ||
const CONFIGURE_ORGANIZATION_SOURCE_SIDEBAR_BLURB = | ||
'Follow the configuration flow to add a new content source to Workplace Search. First, create an OAuth application in the content source. After that, connect as many instances of the content source that you need.'; | ||
const CONFIGURE_PRIVATE_SOURCE_SIDEBAR_BLURB = | ||
'Follow the configuration flow to add a new private content source to Workplace Search. Private content sources are added by each person via their own personal dashboards. Their data stays safe and visible only to them.'; | ||
const CONNECT_ORGANIZATION_SOURCE_SIDEBAR_BLURB = `Upon successfully connecting ${name}, source content will be synced to your organization and will be made available and searchable.`; | ||
const CONNECT_PRIVATE_REMOTE_SOURCE_SIDEBAR_BLURB = ( | ||
<> | ||
{name} is a <strong>remote source</strong>, which means that each time you search, we reach | ||
out to the content source and get matching results directly from {name}'s servers. | ||
</> | ||
); | ||
const CONNECT_PRIVATE_STANDARD_SOURCE_SIDEBAR_BLURB = ( | ||
<> | ||
{name} is a <strong>standard source</strong> for which content is synchronized on a regular | ||
basis, in a relevant and secure way. | ||
</> | ||
); | ||
|
||
const CONNECT_PRIVATE_SOURCE_SIDEBAR_BLURB = isRemote | ||
? CONNECT_PRIVATE_REMOTE_SOURCE_SIDEBAR_BLURB | ||
: CONNECT_PRIVATE_STANDARD_SOURCE_SIDEBAR_BLURB; | ||
const CONFIGURE_SOURCE_SIDEBAR_BLURB = accountContextOnly | ||
? CONFIGURE_PRIVATE_SOURCE_SIDEBAR_BLURB | ||
: CONFIGURE_ORGANIZATION_SOURCE_SIDEBAR_BLURB; | ||
|
||
const CONFIG_SIDEBAR_BLURB = isCustom | ||
? CREATE_CUSTOM_SOURCE_SIDEBAR_BLURB | ||
: CONFIGURE_SOURCE_SIDEBAR_BLURB; | ||
const CONNECT_SIDEBAR_BLURB = isOrganization | ||
? CONNECT_ORGANIZATION_SOURCE_SIDEBAR_BLURB | ||
: CONNECT_PRIVATE_SOURCE_SIDEBAR_BLURB; | ||
|
||
const PAGE_DESCRIPTION = | ||
currentStep === Steps.ConnectInstanceStep ? CONNECT_SIDEBAR_BLURB : CONFIG_SIDEBAR_BLURB; | ||
|
||
const header = <AddSourceHeader name={name} serviceType={serviceType} categories={categories} />; | ||
|
||
return ( | ||
<> | ||
<ViewContentHeader title={pageTitle()} description={PAGE_DESCRIPTION} /> | ||
{currentStep === Steps.ConfigIntroStep && ( | ||
<ConfigurationIntro name={name} advanceStep={goToSaveConfig} header={header} /> | ||
)} | ||
{currentStep === Steps.SaveConfigStep && ( | ||
<SaveConfig | ||
name={name} | ||
configuration={configuration} | ||
advanceStep={goToConfigCompleted} | ||
goBackStep={goToConfigurationIntro} | ||
header={header} | ||
/> | ||
)} | ||
{currentStep === Steps.ConfigCompletedStep && ( | ||
<ConfigCompleted | ||
name={name} | ||
accountContextOnly={accountContextOnly} | ||
advanceStep={goToConnectInstance} | ||
privateSourcesEnabled={privateSourcesEnabled} | ||
header={header} | ||
/> | ||
)} | ||
{currentStep === Steps.ConnectInstanceStep && ( | ||
<ConnectInstance | ||
name={name} | ||
serviceType={serviceType} | ||
configuration={configuration} | ||
features={features} | ||
objTypes={objTypes} | ||
sourceDescription={sourceDescription} | ||
connectStepDescription={connectStepDescription} | ||
needsPermissions={!!needsPermissions} | ||
onFormCreated={goToFormSourceCreated} | ||
header={header} | ||
/> | ||
)} | ||
{currentStep === Steps.ConfigureCustomStep && ( | ||
<ConfigureCustom | ||
helpText={configuration.helpText} | ||
advanceStep={goToSaveCustom} | ||
header={header} | ||
/> | ||
)} | ||
{currentStep === Steps.ConfigureOauthStep && ( | ||
<ConfigureOauth name={name} onFormCreated={goToFormSourceCreated} header={header} /> | ||
)} | ||
{currentStep === Steps.SaveCustomStep && ( | ||
<SaveCustom | ||
documentationUrl={configuration.documentationUrl} | ||
newCustomSource={newCustomSource} | ||
isOrganization={isOrganization} | ||
header={header} | ||
/> | ||
)} | ||
{currentStep === Steps.ReAuthenticateStep && <ReAuthenticate name={name} header={header} />} | ||
</> | ||
); | ||
}; |
57 changes: 57 additions & 0 deletions
57
...ations/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import React from 'react'; | ||
|
||
import { startCase } from 'lodash'; | ||
|
||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui'; | ||
|
||
import { SourceIcon } from '../../../../components/shared/source_icon'; | ||
|
||
interface AddSourceHeaderProps { | ||
name: string; | ||
serviceType: string; | ||
categories: string[]; | ||
} | ||
|
||
export const AddSourceHeader: React.FC<AddSourceHeaderProps> = ({ | ||
name, | ||
serviceType, | ||
categories, | ||
}) => { | ||
return ( | ||
<> | ||
<EuiSpacer size="s" /> | ||
<EuiFlexGroup | ||
alignItems="flexStart" | ||
justifyContent="center" | ||
gutterSize="m" | ||
responsive={false} | ||
> | ||
<EuiFlexItem grow={false}> | ||
<SourceIcon | ||
serviceType={serviceType} | ||
fullBleed={true} | ||
name={name} | ||
className="adding-a-source__icon" | ||
/> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiText size="m"> | ||
<h3 className="adding-a-source__name"> | ||
<EuiTextColor color="default">{name}</EuiTextColor> | ||
</h3> | ||
</EuiText> | ||
<EuiText size="xs" color="subdued"> | ||
{categories.map((category) => startCase(category)).join(', ')} | ||
</EuiText> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
<EuiSpacer size="xl" /> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.