From dd1da2c292dccb50043a7989a2b0e45c06317141 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 16:22:24 -0600
Subject: [PATCH 01/11] Initial copy/paste of components
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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();
---
.../components/add_source/add_source.tsx | 260 ++++++++++++++++++
.../add_source/add_source_header.tsx | 57 ++++
.../components/add_source/add_source_list.tsx | 158 +++++++++++
.../add_source/available_sources_list.tsx | 97 +++++++
.../add_source/config_completed.tsx | 111 ++++++++
.../add_source/config_docs_links.tsx | 38 +++
.../add_source/configuration_intro.tsx | 131 +++++++++
.../add_source/configure_custom.tsx | 85 ++++++
.../components/add_source/configure_oauth.tsx | 104 +++++++
.../add_source/configured_sources_list.tsx | 120 ++++++++
.../add_source/connect_instance.tsx | 254 +++++++++++++++++
.../components/add_source/index.ts | 8 +
.../components/add_source/re_authenticate.tsx | 76 +++++
.../components/add_source/save_config.tsx | 218 +++++++++++++++
.../components/add_source/save_custom.tsx | 160 +++++++++++
.../components/add_source/source_features.tsx | 223 +++++++++++++++
16 files changed, 2100 insertions(+)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
new file mode 100644
index 00000000000000..6f2824a418681a
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -0,0 +1,260 @@
+/*
+ * 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 FlashMessages from 'shared/components/FlashMessages';
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { SidebarNavigation, Loading, AppView } from 'workplace_search/components';
+import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
+import { staticSourceData } from 'workplace_search/ContentSources/sourceData';
+import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+import { SourceDataItem, FeatureIds } from 'workplace_search/types';
+import {
+ ADD_SOURCE_PATH,
+ SOURCE_ADDED_PATH,
+ getSourcesPath,
+} from 'workplace_search/utils/routePaths';
+
+import { AddSourceHeader } from './AddSourceHeader';
+import { ConfigCompleted } from './ConfigCompleted';
+import { ConfigurationIntro } from './ConfigurationIntro';
+import { ConfigureCustom } from './ConfigureCustom';
+import { ConfigureOauth } from './ConfigureOauth';
+import { ConnectInstance } from './ConnectInstance';
+import { ReAuthenticate } from './ReAuthenticate';
+import { SaveConfig } from './SaveConfig';
+import { SaveCustom } from './SaveCustom';
+
+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 = ({
+ sourceIndex,
+ connect,
+ configure,
+ reAuthenticate,
+}) => {
+ const history = useHistory() as History;
+ const {
+ getSourceConfigData,
+ saveSourceConfig,
+ createContentSource,
+ resetSourceState,
+ } = useActions(SourceLogic);
+ const {
+ sourceConfigData: {
+ name,
+ categories,
+ needsPermissions,
+ accountContextOnly,
+ privateSourcesEnabled,
+ },
+ dataLoading,
+ flashMessages,
+ 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 breadcrumbs = {
+ topLevelPath: getSourcesPath(ADD_SOURCE_PATH, isOrganization),
+ topLevelName: '← Back to sources',
+ };
+
+ 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 ;
+
+ 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) => {
+ history.push(`${getSourcesPath(SOURCE_ADDED_PATH, isOrganization)}/?name=${sourceName}`);
+ };
+
+ const sidebarTitle = () => {
+ 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 remote source , 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 standard source 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 sidebarBlurb =
+ currentStep === Steps.ConnectInstanceStep ? CONNECT_SIDEBAR_BLURB : CONFIG_SIDEBAR_BLURB;
+
+ const sidebar = (
+
+ );
+ const header = ;
+
+ return (
+
+ {!!flashMessages && }
+
+ {currentStep === Steps.ConfigIntroStep && (
+
+ )}
+
+ {currentStep === Steps.SaveConfigStep && (
+
+ )}
+
+ {currentStep === Steps.ConfigCompletedStep && (
+
+ )}
+
+ {currentStep === Steps.ConnectInstanceStep && (
+
+ )}
+
+ {currentStep === Steps.ConfigureCustomStep && (
+
+ )}
+
+ {currentStep === Steps.ConfigureOauthStep && (
+
+ )}
+
+ {currentStep === Steps.SaveCustomStep && (
+
+ )}
+
+ {currentStep === Steps.ReAuthenticateStep && }
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
new file mode 100644
index 00000000000000..5f832ac2765c50
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
@@ -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 'workplace_search/components';
+
+interface AddSourceHeaderProps {
+ name: string;
+ serviceType: string;
+ categories: string[];
+}
+
+export const AddSourceHeader: React.FC = ({
+ name,
+ serviceType,
+ categories,
+}) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {name}
+
+
+
+ {categories.map((category) => startCase(category)).join(', ')}
+
+
+
+
+ >
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
new file mode 100644
index 00000000000000..9c5e82975afacc
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -0,0 +1,158 @@
+/*
+ * 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 noSharedSourcesIcon from 'workplace_search/components/assets/shareCircle.svg';
+
+import { useActions, useValues } from 'kea';
+
+import {
+ EuiFieldSearch,
+ EuiFormRow,
+ EuiSpacer,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPanel,
+ EuiEmptyPrompt,
+} from '@elastic/eui';
+
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { SidebarNavigation, ContentSection, Loading, AppView } from 'workplace_search/components';
+import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
+import { SourceDataItem } from 'workplace_search/types';
+import { SOURCES_PATH, getSourcesPath } from 'workplace_search/utils/routePaths';
+
+import { SourcesLogic } from 'workplace_search/ContentSources/SourcesLogic';
+import { AvailableSourcesList } from './AvailableSourcesList';
+import { ConfiguredSourcesList } from './ConfiguredSourcesList';
+
+const NEW_SOURCE_DESCRIPTION =
+ 'When configuring and connecting a source, you are creating distinct entities with searchable content synchronized from the content platform itself. A source can be added using one of the available source connectors or via Custom API Sources, for additional flexibility.';
+const ORG_SOURCE_DESCRIPTION =
+ 'Shared content sources are available to your entire organization or can be assigned to specific user groups.';
+const PRIVATE_SOURCE_DESCRIPTION =
+ 'Connect a new source to add its content and documents to your search experience.';
+const NO_SOURCES_TITLE = 'Configure and connect your first content source';
+const ORG_SOURCES_TITLE = 'Add a shared content source';
+const PRIVATE_SOURCES_TITLE = 'Add a new content source';
+const PLACEHOLDER = 'Filter sources...';
+
+export const AddSourceList: React.FC = () => {
+ const { contentSources, dataLoading, availableSources, configuredSources } = useValues(
+ SourcesLogic
+ );
+
+ const { initializeSources, resetSourcesState } = useActions(SourcesLogic);
+
+ const { isOrganization } = useValues(AppLogic);
+
+ const [filterValue, setFilterValue] = useState('');
+
+ useEffect(() => {
+ initializeSources();
+ return resetSourcesState;
+ }, []);
+
+ if (dataLoading) return ;
+
+ const hasSources = contentSources.length > 0;
+ const showConfiguredSourcesList = configuredSources.find(
+ ({ serviceType }) => serviceType !== CUSTOM_SERVICE_TYPE
+ );
+
+ const breadcrumbs = {
+ topLevelPath: getSourcesPath(SOURCES_PATH, isOrganization),
+ topLevelName: `${isOrganization ? 'Shared' : 'Private'} content sources`,
+ activeName: 'Add',
+ };
+
+ const SIDEBAR_DESCRIPTION = hasSources ? '' : NEW_SOURCE_DESCRIPTION;
+ const SIDEBAR_CONTEXT_DESCRIPTION = isOrganization
+ ? ORG_SOURCE_DESCRIPTION
+ : PRIVATE_SOURCE_DESCRIPTION;
+ const HAS_SOURCES_TITLE = isOrganization ? ORG_SOURCES_TITLE : PRIVATE_SOURCES_TITLE;
+ const SIDEBAR_TITLE = hasSources ? HAS_SOURCES_TITLE : NO_SOURCES_TITLE;
+
+ const handleFilterChange = (e) => setFilterValue(e.target.value);
+
+ const filterSources = (source, sources): boolean => {
+ if (!filterValue) return true;
+ const filterSource = sources.find(({ serviceType }) => serviceType === source.serviceType);
+ const filteredName = filterSource?.name || '';
+ return filteredName.toLowerCase().indexOf(filterValue.toLowerCase()) > -1;
+ };
+
+ const filterAvailableSources = (source) => filterSources(source, availableSources);
+ const filterConfiguredSources = (source) => filterSources(source, configuredSources);
+
+ const visibleAvailableSources = availableSources.filter(
+ filterAvailableSources
+ ) as SourceDataItem[];
+ const visibleConfiguredSources = configuredSources.filter(
+ filterConfiguredSources
+ ) as SourceDataItem[];
+
+ const sidebar = (
+ {SIDEBAR_CONTEXT_DESCRIPTION}
}
+ />
+ );
+
+ return (
+
+ {showConfiguredSourcesList || isOrganization ? (
+
+
+
+
+
+
+ {showConfiguredSourcesList && (
+
+ )}
+ {isOrganization && }
+
+ ) : (
+
+
+
+
+
+
+
+ No available sources}
+ body={
+
+ Sources will be available for search when an administrator adds them to this
+ organization.
+
+ }
+ />
+
+
+
+
+
+
+
+ )}
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
new file mode 100644
index 00000000000000..d6d3beb00ded72
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
@@ -0,0 +1,97 @@
+/*
+ * 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 { Link } from 'react-router-dom';
+
+import {
+ EuiCard,
+ EuiFlexGrid,
+ EuiFlexItem,
+ EuiSpacer,
+ EuiTitle,
+ EuiText,
+ EuiToolTip,
+} from '@elastic/eui';
+
+import { useValues } from 'kea';
+
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { SourceIcon } from 'workplace_search/components';
+import { SourceDataItem } from 'workplace_search/types';
+import { ADD_CUSTOM_PATH, getSourcesPath } from 'workplace_search/utils/routePaths';
+
+interface AvailableSourcesListProps {
+ sources: SourceDataItem[];
+}
+
+export const AvailableSourcesList: React.FC = ({ sources }) => {
+ const {
+ fpAccount: { minimumPlatinumLicense },
+ } = useValues(AppLogic);
+
+ const getSourceCard = ({ name, serviceType, addPath, accountContextOnly }) => {
+ const disabled = !minimumPlatinumLicense && accountContextOnly;
+ const card = (
+ >}
+ isDisabled={disabled}
+ icon={
+
+ }
+ />
+ );
+
+ if (disabled) {
+ return (
+
+ {card}
+
+ );
+ }
+ return {card};
+ };
+
+ const visibleSources = (
+
+ {sources.map((source, i) => (
+
+ {getSourceCard(source)}
+
+ ))}
+
+ );
+
+ const emptyState = No available sources matching your query.
;
+
+ return (
+ <>
+
+ Available for configuration
+
+
+
+ Configure an available source or build your own with the{' '}
+
+ Custom API Source
+
+ .
+
+
+
+ {sources.length > 0 ? visibleSources : emptyState}
+ >
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
new file mode 100644
index 00000000000000..aff25c97c255e6
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
@@ -0,0 +1,111 @@
+/*
+ * 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 { Link } from 'react-router-dom';
+
+import {
+ EuiButton,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiIcon,
+ EuiLink,
+ EuiSpacer,
+ EuiText,
+ EuiTextAlign,
+} from '@elastic/eui';
+
+import {
+ getSourcesPath,
+ ADD_SOURCE_PATH,
+ SECURITY_PATH,
+ PRIVATE_SOURCES_DOCS_URL,
+} from 'workplace_search/utils/routePaths';
+
+interface ConfigCompletedProps {
+ header: React.ReactNode;
+ name: string;
+ accountContextOnly?: boolean;
+ privateSourcesEnabled: boolean;
+ advanceStep();
+}
+
+export const ConfigCompleted: React.FC = ({
+ name,
+ advanceStep,
+ accountContextOnly,
+ header,
+ privateSourcesEnabled,
+}) => (
+
+ {header}
+
+
+
+
+
+
+
+
+
+
+ {name} Configured
+
+
+
+
+ {!accountContextOnly ? (
+ {name} can now be connected to Workplace Search
+ ) : (
+
+ Users can now link their {name} accounts from their personal dashboards.
+ {!privateSourcesEnabled && (
+
+ Remember to{' '}
+
+ enable private source connection
+ {' '}
+ in Security settings.
+
+ )}
+
+
+ Learn more about private content sources.
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ Configure a new content source
+
+
+
+ {!accountContextOnly && (
+
+
+ Connect {name}
+
+
+ )}
+
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
new file mode 100644
index 00000000000000..b666c859948d5d
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+
+interface ConfigDocsLinksProps {
+ name: string;
+ documentationUrl: string;
+ applicationPortalUrl?: string;
+ applicationLinkTitle?: string;
+}
+
+export const ConfigDocsLinks: React.FC = ({
+ name,
+ documentationUrl,
+ applicationPortalUrl,
+ applicationLinkTitle,
+}) => (
+
+
+
+ Documentation
+
+
+
+ {applicationPortalUrl && (
+
+ {applicationLinkTitle || `${name} Application Portal`}
+
+ )}
+
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
new file mode 100644
index 00000000000000..70fcbec51209e4
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
@@ -0,0 +1,131 @@
+/*
+ * 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 {
+ EuiBadge,
+ EuiButton,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFormRow,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+
+import connectionIllustration from 'workplace_search/components/assets/connectionIllustration.svg';
+
+interface ConfigurationIntroProps {
+ header: React.ReactNode;
+ name: string;
+ advanceStep();
+}
+
+export const ConfigurationIntro: React.FC = ({
+ name,
+ advanceStep,
+ header,
+}) => (
+
+ {header}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ How to add {name}
+
+
+
+ Quick setup, then all of your documents will be searchable.
+
+
+
+
+
+
+
+
+ Step 1
+
+
+
+
+
+
+ Configure an OAuth application
+ One-Time Action
+
+
+ Setup a secure OAuth application through the content source that you or your
+ team will use to connect and synchronize content. You only have to do this
+ once per content source.
+
+
+
+
+
+
+
+
+
+
+ Step 2
+
+
+
+
+
+ Connect the content source
+
+ Use the new OAuth application to connect any number of instances of the
+ content source to Workplace Search.
+
+
+
+
+
+
+
+
+
+ Configure {name}
+
+
+
+
+
+
+
+
+
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
new file mode 100644
index 00000000000000..2a03f8254a9baf
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
@@ -0,0 +1,85 @@
+/*
+ * 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 { useActions, useValues } from 'kea';
+
+import {
+ EuiButton,
+ EuiFieldText,
+ EuiForm,
+ EuiFormRow,
+ EuiLink,
+ EuiSpacer,
+ EuiText,
+} from '@elastic/eui';
+
+import { CUSTOM_SOURCE_DOCS_URL } from 'workplace_search/utils/routePaths';
+import { SourceLogic } from '../../SourceLogic';
+
+interface ConfigureCustomProps {
+ header: React.ReactNode;
+ helpText: string;
+ advanceStep();
+}
+
+export const ConfigureCustom: React.FC = ({
+ helpText,
+ advanceStep,
+ header,
+}) => {
+ const { setCustomSourceNameValue } = useActions(SourceLogic);
+ const { customSourceNameValue, buttonLoading } = useValues(SourceLogic);
+
+ const handleFormSubmit = (e) => {
+ e.preventDefault();
+ advanceStep();
+ };
+
+ const handleNameChange = (e) => setCustomSourceNameValue(e.target.value);
+
+ return (
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
new file mode 100644
index 00000000000000..b45d373fe8b55d
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
@@ -0,0 +1,104 @@
+/*
+ * 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 { Location } from 'history';
+import { useActions, useValues } from 'kea';
+import { useLocation } from 'react-router-dom';
+
+import { parseQueryParams } from 'app_search/utils/queryParams';
+
+import {
+ EuiButton,
+ EuiCheckboxGroup,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFormRow,
+ EuiSpacer,
+} from '@elastic/eui';
+
+import { Loading } from 'workplace_search/components';
+import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+
+interface OauthQueryParams {
+ preContentSourceId: string;
+}
+
+interface ConfigureOauthProps {
+ header: React.ReactNode;
+ name: string;
+ onFormCreated(name: string);
+}
+
+export const ConfigureOauth: React.FC = ({ name, onFormCreated, header }) => {
+ const { search } = useLocation() as Location;
+
+ const { preContentSourceId } = (parseQueryParams(search) as unknown) as OauthQueryParams;
+ const [formLoading, setFormLoading] = useState(false);
+
+ const {
+ getPreContentSourceConfigData,
+ setSelectedGithubOrganizations,
+ createContentSource,
+ } = useActions(SourceLogic);
+ const {
+ currentServiceType,
+ githubOrganizations,
+ selectedGithubOrganizationsMap,
+ sectionLoading,
+ } = useValues(SourceLogic);
+
+ const checkboxOptions = githubOrganizations.map((item) => ({ id: item, label: item }));
+
+ useEffect(() => {
+ getPreContentSourceConfigData(preContentSourceId);
+ }, []);
+
+ const handleChange = (option) => setSelectedGithubOrganizations(option);
+ const formSubmitSuccess = () => onFormCreated(name);
+ const handleFormSubmitError = () => setFormLoading(false);
+ const handleFormSubmut = (e) => {
+ setFormLoading(true);
+ e.preventDefault();
+ createContentSource(currentServiceType, formSubmitSuccess, handleFormSubmitError);
+ };
+
+ const configfieldsForm = (
+
+ );
+
+ return (
+
+ {header}
+ {sectionLoading ? : configfieldsForm}
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
new file mode 100644
index 00000000000000..05e0182c42a5bd
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -0,0 +1,120 @@
+/*
+ * 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 { Link } from 'react-router-dom';
+
+import {
+ EuiButtonEmpty,
+ EuiFlexGrid,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+ EuiToken,
+ EuiToolTip,
+} from '@elastic/eui';
+
+import { SourceIcon } from 'workplace_search/components';
+import { SourceDataItem } from 'workplace_search/types';
+import { getSourcesPath } from 'workplace_search/utils/routePaths';
+
+interface ConfiguredSourcesProps {
+ sources: SourceDataItem[];
+ isOrganization?: boolean;
+}
+
+export const ConfiguredSourcesList: React.FC = ({
+ sources,
+ isOrganization,
+}) => {
+ const unConnectedTooltip = (
+
+
+
+
+
+ );
+
+ const accountOnlyTooltip = (
+
+
+
+
+
+ );
+
+ const visibleSources = (
+
+ {sources.map(({ name, serviceType, addPath, connected, accountContextOnly }, i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+ {name}
+ {!connected &&
+ !accountContextOnly &&
+ isOrganization &&
+ unConnectedTooltip}
+ {accountContextOnly && isOrganization && accountOnlyTooltip}
+
+
+
+
+
+ {(!isOrganization || (isOrganization && !accountContextOnly)) && (
+
+
+ Connect
+
+
+ )}
+
+
+
+
+ ))}
+
+ );
+
+ const emptyState = There are no configured sources matching your query.
;
+
+ return (
+ <>
+
+ Configured content sources
+
+
+ Configured and ready for connection.
+
+
+ {sources.length > 0 ? visibleSources : emptyState}
+
+ >
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
new file mode 100644
index 00000000000000..46a812fcd6f57e
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
@@ -0,0 +1,254 @@
+/*
+ * 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, { useState, useEffect } from 'react';
+
+import { useActions, useValues } from 'kea';
+
+import {
+ EuiButton,
+ EuiCallOut,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFieldText,
+ EuiFormRow,
+ EuiLink,
+ EuiSpacer,
+ EuiSwitch,
+ EuiText,
+ EuiTitle,
+ EuiTextColor,
+ EuiBadge,
+ EuiBadgeGroup,
+} from '@elastic/eui';
+
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+import { FeatureIds, Configuration, Features } from 'workplace_search/types';
+import { DOCUMENT_PERMISSIONS_DOCS_URL } from 'workplace_search/utils/routePaths';
+import { SourceFeatures } from './SourceFeatures';
+
+interface ConnectInstanceProps {
+ header: React.ReactNode;
+ configuration: Configuration;
+ features?: Features;
+ objTypes?: string[];
+ name: string;
+ serviceType: string;
+ sourceDescription: string;
+ connectStepDescription: string;
+ needsPermissions: boolean;
+ onFormCreated(name: string);
+}
+
+export const ConnectInstance: React.FC = ({
+ configuration: { needsSubdomain, hasOauthRedirect },
+ features,
+ objTypes,
+ name,
+ serviceType,
+ sourceDescription,
+ connectStepDescription,
+ needsPermissions,
+ onFormCreated,
+ header,
+}) => {
+ const [formLoading, setFormLoading] = useState(false);
+ const {
+ getSourceConnectData,
+ createContentSource,
+ setSourceLoginValue,
+ setSourcePasswordValue,
+ setSourceSubdomainValue,
+ setSourceIndexPermissionsValue,
+ } = useActions(SourceLogic);
+
+ const { loginValue, passwordValue, indexPermissionsValue, subdomainValue } = useValues(
+ SourceLogic
+ );
+
+ const {
+ isOrganization,
+ fpAccount: { minimumPlatinumLicense },
+ } = useValues(AppLogic);
+
+ // Default indexPermissions to true, if needed
+ useEffect(() => {
+ setSourceIndexPermissionsValue(needsPermissions && isOrganization && minimumPlatinumLicense);
+ }, []);
+
+ const redirectOauth = (oauthUrl: string) => (window.location.href = oauthUrl);
+ const redirectFormCreated = () => onFormCreated(name);
+ const onOauthFormSubmit = () => getSourceConnectData(serviceType, redirectOauth);
+ const handleFormSubmitError = () => setFormLoading(false);
+ const onCredentialsFormSubmit = () =>
+ createContentSource(serviceType, redirectFormCreated, handleFormSubmitError);
+
+ const handleFormSubmit = (e) => {
+ setFormLoading(true);
+ e.preventDefault();
+ const onSubmit = hasOauthRedirect ? onOauthFormSubmit : onCredentialsFormSubmit;
+ onSubmit();
+ };
+
+ const credentialsFields = (
+ <>
+
+ setSourceLoginValue(e.target.value)}
+ />
+
+
+ setSourcePasswordValue(e.target.value)}
+ />
+
+
+ >
+ );
+
+ const subdomainField = (
+ <>
+
+ setSourceSubdomainValue(e.target.value)}
+ />
+
+
+ >
+ );
+
+ const featureBadgeGroup = () => {
+ if (isOrganization) {
+ return null;
+ }
+
+ const isRemote = features?.platinumPrivateContext.includes(FeatureIds.Remote);
+ const isPrivate = features?.platinumPrivateContext.includes(FeatureIds.Private);
+
+ if (isRemote || isPrivate) {
+ return (
+ <>
+
+ {isRemote && Remote }
+ {isPrivate && Private }
+
+
+ >
+ );
+ }
+ };
+
+ const descriptionBlock = (
+
+ {sourceDescription && {sourceDescription}
}
+ {connectStepDescription && {connectStepDescription}
}
+
+
+ );
+
+ const whichDocsLink = (
+
+ Which option should I choose?
+
+ );
+
+ const permissionField = (
+ <>
+
+
+ Document-level permissions
+
+
+
+ Enable document-level permission synchronization}
+ name="index_permissions"
+ onChange={(e) => setSourceIndexPermissionsValue(e.target.checked)}
+ checked={indexPermissionsValue}
+ disabled={!needsPermissions}
+ />
+
+
+ {!needsPermissions && (
+
+ Document-level permissions are not yet available for this source.{' '}
+
+ Learn more
+
+
+ )}
+ {needsPermissions && indexPermissionsValue && (
+
+ Document-level permission information will be synchronized. Additional configuration is
+ required following the initial connection before documents are available for search.
+
+ {whichDocsLink}
+
+ )}
+
+
+ {!indexPermissionsValue && (
+
+
+ All documents accessible to the connecting service user will be synchronized and made
+ available to the organization’s users, or group’s users. Documents are immediately
+ available for search. {needsPermissions && whichDocsLink}
+
+
+ )}
+
+ >
+ );
+
+ const formFields = (
+ <>
+ {isOrganization && minimumPlatinumLicense && permissionField}
+ {!hasOauthRedirect && credentialsFields}
+ {needsSubdomain && subdomainField}
+
+
+
+ Connect {name}
+
+
+ >
+ );
+
+ return (
+
+
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
new file mode 100644
index 00000000000000..02f0e1db7ff0b7
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
@@ -0,0 +1,8 @@
+/*
+ * 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.
+ */
+
+export { AddSource } from './AddSource';
+export { AddSourceList } from './AddSourceList';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
new file mode 100644
index 00000000000000..231f277dfbad6a
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
@@ -0,0 +1,76 @@
+/*
+ * 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 { Location } from 'history';
+import { useActions, useValues } from 'kea';
+import { useLocation } from 'react-router-dom';
+
+import { parseQueryParams } from 'app_search/utils/queryParams';
+
+import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiSpacer } from '@elastic/eui';
+
+import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+
+interface SourceQueryParams {
+ sourceId: string;
+}
+
+interface ReAuthenticateProps {
+ name: string;
+ header: React.ReactNode;
+}
+
+export const ReAuthenticate: React.FC = ({ name, header }) => {
+ const { search } = useLocation() as Location;
+
+ const { sourceId } = (parseQueryParams(search) as unknown) as SourceQueryParams;
+ const [formLoading, setFormLoading] = useState(false);
+
+ const { getSourceReConnectData } = useActions(SourceLogic);
+ const {
+ sourceConnectData: { oauthUrl },
+ } = useValues(SourceLogic);
+
+ useEffect(() => {
+ getSourceReConnectData(sourceId);
+ }, []);
+
+ const handleFormSubmit = (e) => {
+ e.preventDefault();
+ setFormLoading(true);
+ window.location.href = oauthUrl;
+ };
+
+ return (
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
new file mode 100644
index 00000000000000..ada079f88da351
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
@@ -0,0 +1,218 @@
+/*
+ * 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 { useActions, useValues } from 'kea';
+
+import {
+ EuiButton,
+ EuiButtonEmpty,
+ EuiFieldText,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiForm,
+ EuiFormRow,
+ EuiSpacer,
+ EuiSteps,
+} from '@elastic/eui';
+
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { ApiKey } from 'workplace_search/components';
+import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+import { Configuration } from 'workplace_search/types';
+
+import { ConfigDocsLinks } from './ConfigDocsLinks';
+
+interface SaveConfigProps {
+ header: React.ReactNode;
+ name: string;
+ configuration: Configuration;
+ advanceStep();
+ goBackStep?();
+ onDeleteConfig?();
+}
+
+export const SaveConfig: React.FC = ({
+ name,
+ configuration: {
+ isPublicKey,
+ needsBaseUrl,
+ documentationUrl,
+ applicationPortalUrl,
+ applicationLinkTitle,
+ baseUrlTitle,
+ },
+ advanceStep,
+ goBackStep,
+ onDeleteConfig,
+ header,
+}) => {
+ const { setClientIdValue, setClientSecretValue, setBaseUrlValue } = useActions(SourceLogic);
+
+ const {
+ sourceConfigData,
+ buttonLoading,
+ clientIdValue,
+ clientSecretValue,
+ baseUrlValue,
+ } = useValues(SourceLogic);
+
+ const {
+ accountContextOnly,
+ configuredFields: { publicKey, consumerKey },
+ } = sourceConfigData;
+ const {
+ fpAccount: { minimumPlatinumLicense },
+ } = useValues(AppLogic);
+
+ const handleFormSubmission = (e) => {
+ e.preventDefault();
+ advanceStep();
+ };
+
+ const saveButton = (
+
+ Save configuration
+
+ );
+
+ const deleteButton = (
+
+ Remove
+
+ );
+
+ const backButton = Go back ;
+ const showSaveButton = minimumPlatinumLicense || !accountContextOnly;
+
+ const formActions = (
+
+
+ {showSaveButton && {saveButton} }
+
+ {goBackStep && backButton}
+ {onDeleteConfig && deleteButton}
+
+
+
+ );
+
+ const publicKeyStep1 = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ const credentialsStep1 = (
+
+ );
+
+ const publicKeyStep2 = (
+ <>
+
+ setBaseUrlValue(e.target.value)}
+ name="base-uri"
+ />
+
+
+ {formActions}
+ >
+ );
+
+ const credentialsStep2 = (
+
+
+
+
+ setClientIdValue(e.target.value)}
+ name="client-id"
+ />
+
+
+ setClientSecretValue(e.target.value)}
+ name="client-secret"
+ />
+
+ {needsBaseUrl && (
+
+ setBaseUrlValue(e.target.value)}
+ name="base-uri"
+ />
+
+ )}
+
+ {formActions}
+
+
+
+ );
+
+ const oauthSteps = (sourceName: string) => [
+ `Create an OAuth app in your organization's ${sourceName}\u00A0account`,
+ 'Provide the appropriate configuration information',
+ ];
+
+ const configSteps = [
+ {
+ title: oauthSteps(name)[0],
+ children: isPublicKey ? publicKeyStep1 : credentialsStep1,
+ },
+ {
+ title: oauthSteps(name)[1],
+ children: isPublicKey ? publicKeyStep2 : credentialsStep2,
+ },
+ ];
+
+ return (
+ <>
+ {header}
+
+ >
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
new file mode 100644
index 00000000000000..0c7ca14bebb821
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
@@ -0,0 +1,160 @@
+/*
+ * 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 { Link } from 'react-router-dom';
+
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHorizontalRule,
+ EuiIcon,
+ EuiSpacer,
+ EuiText,
+ EuiTextAlign,
+ EuiTitle,
+ EuiLink,
+ EuiPanel,
+} from '@elastic/eui';
+import { CredentialItem } from 'workplace_search/components/CredentialItem';
+
+import { LicenseBadge } from 'workplace_search/components';
+
+import { CustomSource } from 'workplace_search/types';
+import {
+ SOURCES_PATH,
+ SOURCE_DISPLAY_SETTINGS_PATH,
+ CUSTOM_API_DOCUMENT_PERMISSIONS_DOCS_URL,
+ ENT_SEARCH_LICENSE_MANAGEMENT,
+ getContentSourcePath,
+ getSourcesPath,
+} from 'workplace_search/utils/routePaths';
+
+interface SaveCustomProps {
+ documentationUrl: string;
+ newCustomSource: CustomSource;
+ isOrganization: boolean;
+ header: React.ReactNode;
+}
+
+export const SaveCustom: React.FC = ({
+ documentationUrl,
+ newCustomSource: { key, id, accessToken, name },
+ isOrganization,
+ header,
+}) => (
+
+ {header}
+
+
+
+
+
+
+
+
+
+
+ {name} Created
+
+
+
+
+ Your endpoints are ready to accept requests.
+
+ Be sure to copy your API keys below.
+
+
+ Return to Sources
+
+
+
+
+
+
+
+
+
+ API Keys
+
+
+ You'll need these keys to sync documents for this custom source.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Visual Walkthrough
+
+
+
+
+
+ Check out the documentation
+ {' '}
+ to learn more about Custom API Sources.
+
+
+
+
+
+
+ Styling Results
+
+
+
+
+ Use{' '}
+
+ Display Settings
+ {' '}
+ to customize how your documents will appear within your search results. Workplace
+ Search will use fields in alphabetical order by default.
+
+
+
+
+
+
+
+
+
+ Set document-level permissions
+
+
+
+
+
+ Document-level permissions
+ {' '}
+ manage content access content on individual or group attributes. Allow or deny
+ access to specific documents.
+
+
+
+
+
+ Learn about Platinum features
+
+
+
+
+
+
+
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
new file mode 100644
index 00000000000000..b32b889b91c8ce
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
@@ -0,0 +1,223 @@
+/*
+ * 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 { useValues } from 'kea';
+
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLink,
+ EuiPanel,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+
+import { AppLogic } from 'workplace_search/App/AppLogic';
+import { LicenseBadge } from 'workplace_search/components';
+import { Features, FeatureIds } from 'workplace_search/types';
+import { ENT_SEARCH_LICENSE_MANAGEMENT } from 'workplace_search/utils/routePaths';
+
+interface ConnectInstanceProps {
+ features?: Features;
+ objTypes?: string[];
+ name: string;
+}
+
+export const SourceFeatures: React.FC = ({ features, objTypes, name }) => {
+ const {
+ isOrganization,
+ fpAccount: { minimumPlatinumLicense },
+ } = useValues(AppLogic);
+
+ const Feature = ({ title, children }: { title: string; children: React.ReactElement }) => (
+ <>
+
+
+ {title}
+
+
+ {children}
+ >
+ );
+
+ const SyncFrequencyFeature = (
+
+
+
+ This source gets new content from {name} every 2 hours (following the
+ initial sync).
+
+
+
+ );
+
+ const SyncedItemsFeature = (
+
+ <>
+
+ The following items are searchable:
+
+
+
+
+ {objTypes!.map((objType, i) => (
+ {objType}
+ ))}
+
+
+ >
+
+ );
+
+ const SearchableContentFeature = (
+
+
+
+ The following items are searchable:
+
+
+
+ {objTypes!.map((objType, i) => (
+ {objType}
+ ))}
+
+
+
+ );
+
+ const RemoteFeature = (
+
+
+
+ Message data and other information is searchable in real-time from the Workplace Search
+ experience.
+
+
+
+ );
+
+ const PrivateFeature = (
+
+
+
+ Results returned are specific and relevant to you. Connecting this source does not expose
+ your personal data to other search users - only you.
+
+
+
+ );
+
+ const GlobalAccessPermissionsFeature = (
+
+
+
+ All documents accessible to the connecting service user will be synchronized and made
+ available to the organization’s users, or group’s users. Documents are immediately
+ available for search
+
+
+
+ );
+
+ const DocumentLevelPermissionsFeature = (
+
+
+
+ Document-level permissions manage user content access based on defined rules. Allow or
+ deny access to certain documents for individuals and groups.
+
+
+ Explore Platinum features
+
+
+
+ );
+
+ const FeaturesRouter = ({ featureId }: { featureId: FeatureIds }) =>
+ ({
+ [FeatureIds.SyncFrequency]: SyncFrequencyFeature,
+ [FeatureIds.SearchableContent]: SearchableContentFeature,
+ [FeatureIds.SyncedItems]: SyncedItemsFeature,
+ [FeatureIds.Remote]: RemoteFeature,
+ [FeatureIds.Private]: PrivateFeature,
+ [FeatureIds.GlobalAccessPermissions]: GlobalAccessPermissionsFeature,
+ [FeatureIds.DocumentLevelPermissions]: DocumentLevelPermissionsFeature,
+ }[featureId]);
+
+ const IncludedFeatures = () => {
+ let includedFeatures: FeatureIds[] | undefined;
+
+ if (!minimumPlatinumLicense && isOrganization) {
+ includedFeatures = features?.basicOrgContext;
+ }
+ if (minimumPlatinumLicense && isOrganization) {
+ includedFeatures = features?.platinumOrgContext;
+ }
+ if (minimumPlatinumLicense && !isOrganization) {
+ includedFeatures = features?.platinumPrivateContext;
+ }
+
+ if (!includedFeatures?.length) {
+ return null;
+ }
+
+ return (
+
+
+ Included features
+
+ {includedFeatures.map((featureId, i) => (
+
+ ))}
+
+ );
+ };
+
+ const ExcludedFeatures = () => {
+ let excludedFeatures: FeatureIds[] | undefined;
+
+ if (!minimumPlatinumLicense && isOrganization) {
+ excludedFeatures = features?.basicOrgContextExcludedFeatures;
+ }
+
+ if (!excludedFeatures?.length) {
+ return null;
+ }
+
+ return (
+
+
+ {excludedFeatures.map((featureId, i) => (
+
+ ))}
+
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
From 49c22a6dd87633ed1ddedb047b7a107e1bcedcb6 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 16:36:59 -0600
Subject: [PATCH 02/11] Add route helper
---
.../public/applications/workplace_search/routes.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
index 8f62984db1b5ea..be95c6ffe6f38b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
@@ -124,3 +124,5 @@ export const getContentSourcePath = (
export const getGroupPath = (groupId: string) => generatePath(GROUP_PATH, { groupId });
export const getGroupSourcePrioritizationPath = (groupId: string) =>
`${GROUPS_PATH}/${groupId}/source_prioritization`;
+export const getSourcesPath = (path: string, isOrganization: boolean) =>
+ isOrganization ? `${ORG_PATH}${path}` : path;
From 34ca5b959807dca9bf3d58010667e7f6434c7f27 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:15:17 -0600
Subject: [PATCH 03/11] Remove AppView, Sidebar navigation and FlashMessages
Sidebar copy and breadcrumbs will be recreated at the top level in a separate PR
---
.../components/add_source/add_source.tsx | 17 +--
.../components/add_source/add_source_list.tsx | 102 ++++++++----------
2 files changed, 46 insertions(+), 73 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
index 6f2824a418681a..bad77a25f37fed 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -10,9 +10,8 @@ import { History } from 'history';
import { useActions, useValues } from 'kea';
import { useHistory } from 'react-router-dom';
-import FlashMessages from 'shared/components/FlashMessages';
import { AppLogic } from 'workplace_search/App/AppLogic';
-import { SidebarNavigation, Loading, AppView } from 'workplace_search/components';
+import { Loading } from 'workplace_search/components';
import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
import { staticSourceData } from 'workplace_search/ContentSources/sourceData';
import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
@@ -73,7 +72,6 @@ export const AddSource: React.FC = ({
privateSourcesEnabled,
},
dataLoading,
- flashMessages,
newCustomSource,
} = useValues(SourceLogic);
@@ -181,19 +179,10 @@ export const AddSource: React.FC = ({
const sidebarBlurb =
currentStep === Steps.ConnectInstanceStep ? CONNECT_SIDEBAR_BLURB : CONFIG_SIDEBAR_BLURB;
- const sidebar = (
-
- );
const header = ;
return (
-
- {!!flashMessages && }
-
+ <>
{currentStep === Steps.ConfigIntroStep && (
)}
@@ -255,6 +244,6 @@ export const AddSource: React.FC = ({
)}
{currentStep === Steps.ReAuthenticateStep && }
-
+ >
);
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
index 9c5e82975afacc..45437a8fc79682 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -20,7 +20,7 @@ import {
} from '@elastic/eui';
import { AppLogic } from 'workplace_search/App/AppLogic';
-import { SidebarNavigation, ContentSection, Loading, AppView } from 'workplace_search/components';
+import { ContentSection, Loading } from 'workplace_search/components';
import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
import { SourceDataItem } from 'workplace_search/types';
import { SOURCES_PATH, getSourcesPath } from 'workplace_search/utils/routePaths';
@@ -95,64 +95,48 @@ export const AddSourceList: React.FC = () => {
filterConfiguredSources
) as SourceDataItem[];
- const sidebar = (
- {SIDEBAR_CONTEXT_DESCRIPTION}}
- />
- );
-
- return (
-
- {showConfiguredSourcesList || isOrganization ? (
-
-
-
-
-
-
- {showConfiguredSourcesList && (
-
- )}
- {isOrganization && }
-
- ) : (
-
-
-
-
-
-
-
- No available sources}
- body={
-
- Sources will be available for search when an administrator adds them to this
- organization.
-
- }
- />
-
-
-
-
-
-
-
+ return showConfiguredSourcesList || isOrganization ? (
+
+
+
+
+
+
+ {showConfiguredSourcesList && (
+
)}
-
+ {isOrganization && }
+
+ ) : (
+
+
+
+
+
+
+
+ No available sources}
+ body={
+
+ Sources will be available for search when an administrator adds them to this
+ organization.
+
+ }
+ />
+
+
+
+
+
+
+
);
};
From 6c102a2abdc38173bce65781e19fbc2ce3887822 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:15:36 -0600
Subject: [PATCH 04/11] Update component paths
---
.../components/add_source/add_source.tsx | 38 +++++++++----------
.../add_source/add_source_header.tsx | 2 +-
.../components/add_source/add_source_list.tsx | 19 +++++-----
.../add_source/available_sources_list.tsx | 8 ++--
.../add_source/config_completed.tsx | 2 +-
.../add_source/configure_custom.tsx | 4 +-
.../components/add_source/configure_oauth.tsx | 7 ++--
.../add_source/configured_sources_list.tsx | 6 +--
.../add_source/connect_instance.tsx | 10 ++---
.../components/add_source/re_authenticate.tsx | 5 +--
.../components/add_source/save_config.tsx | 10 ++---
.../components/add_source/save_custom.tsx | 8 ++--
.../components/add_source/source_features.tsx | 8 ++--
13 files changed, 61 insertions(+), 66 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
index bad77a25f37fed..2cf91de14b5616 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -10,27 +10,23 @@ import { History } from 'history';
import { useActions, useValues } from 'kea';
import { useHistory } from 'react-router-dom';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { Loading } from 'workplace_search/components';
-import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
-import { staticSourceData } from 'workplace_search/ContentSources/sourceData';
-import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
-import { SourceDataItem, FeatureIds } from 'workplace_search/types';
-import {
- ADD_SOURCE_PATH,
- SOURCE_ADDED_PATH,
- getSourcesPath,
-} from 'workplace_search/utils/routePaths';
-
-import { AddSourceHeader } from './AddSourceHeader';
-import { ConfigCompleted } from './ConfigCompleted';
-import { ConfigurationIntro } from './ConfigurationIntro';
-import { ConfigureCustom } from './ConfigureCustom';
-import { ConfigureOauth } from './ConfigureOauth';
-import { ConnectInstance } from './ConnectInstance';
-import { ReAuthenticate } from './ReAuthenticate';
-import { SaveConfig } from './SaveConfig';
-import { SaveCustom } from './SaveCustom';
+import { AppLogic } from '../../../../app_logic';
+import { Loading } from '../../../../../../applications/shared/loading';
+import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
+import { staticSourceData } from '../../source_data';
+import { SourceLogic } from '../../source_logic';
+import { SourceDataItem, FeatureIds } from '../../../../types';
+import { ADD_SOURCE_PATH, 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',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
index 5f832ac2765c50..22230bb59f8475 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.tsx
@@ -10,7 +10,7 @@ import { startCase } from 'lodash';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui';
-import { SourceIcon } from 'workplace_search/components';
+import { SourceIcon } from '../../../../components/shared/source_icon';
interface AddSourceHeaderProps {
name: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
index 45437a8fc79682..d7e5841660e38d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -19,15 +19,16 @@ import {
EuiEmptyPrompt,
} from '@elastic/eui';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { ContentSection, Loading } from 'workplace_search/components';
-import { CUSTOM_SERVICE_TYPE } from 'workplace_search/constants';
-import { SourceDataItem } from 'workplace_search/types';
-import { SOURCES_PATH, getSourcesPath } from 'workplace_search/utils/routePaths';
-
-import { SourcesLogic } from 'workplace_search/ContentSources/SourcesLogic';
-import { AvailableSourcesList } from './AvailableSourcesList';
-import { ConfiguredSourcesList } from './ConfiguredSourcesList';
+import { AppLogic } from '../../../../app_logic';
+import { ContentSection } from '../../../../components/shared/content_section';
+import { Loading } from '../../../../../../applications/shared/loading';
+import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
+import { SourceDataItem } from '../../../../types';
+import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
+
+import { SourcesLogic } from '../../sources_logic';
+import { AvailableSourcesList } from './available_sources_list';
+import { ConfiguredSourcesList } from './configured_sources_list';
const NEW_SOURCE_DESCRIPTION =
'When configuring and connecting a source, you are creating distinct entities with searchable content synchronized from the content platform itself. A source can be added using one of the available source connectors or via Custom API Sources, for additional flexibility.';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
index d6d3beb00ded72..31e7202b66f0cb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
@@ -19,10 +19,10 @@ import {
import { useValues } from 'kea';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { SourceIcon } from 'workplace_search/components';
-import { SourceDataItem } from 'workplace_search/types';
-import { ADD_CUSTOM_PATH, getSourcesPath } from 'workplace_search/utils/routePaths';
+import { AppLogic } from '../../../../app_logic';
+import { SourceIcon } from '../../../../components/shared/source_icon';
+import { SourceDataItem } from '../../../../types';
+import { ADD_CUSTOM_PATH, getSourcesPath } from '../../../../routes';
interface AvailableSourcesListProps {
sources: SourceDataItem[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
index aff25c97c255e6..57add9c04660f3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
@@ -24,7 +24,7 @@ import {
ADD_SOURCE_PATH,
SECURITY_PATH,
PRIVATE_SOURCES_DOCS_URL,
-} from 'workplace_search/utils/routePaths';
+} from '../../../../routes';
interface ConfigCompletedProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
index 2a03f8254a9baf..e1dd8579aeb693 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
@@ -18,8 +18,8 @@ import {
EuiText,
} from '@elastic/eui';
-import { CUSTOM_SOURCE_DOCS_URL } from 'workplace_search/utils/routePaths';
-import { SourceLogic } from '../../SourceLogic';
+import { CUSTOM_SOURCE_DOCS_URL } from '../../../../routes';
+import { SourceLogic } from '../../source_logic';
interface ConfigureCustomProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
index b45d373fe8b55d..f6aa218bcb51a5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
@@ -10,8 +10,6 @@ import { Location } from 'history';
import { useActions, useValues } from 'kea';
import { useLocation } from 'react-router-dom';
-import { parseQueryParams } from 'app_search/utils/queryParams';
-
import {
EuiButton,
EuiCheckboxGroup,
@@ -21,8 +19,9 @@ import {
EuiSpacer,
} from '@elastic/eui';
-import { Loading } from 'workplace_search/components';
-import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+import { parseQueryParams } from '../../../../../../applications/shared/query_params';
+import { Loading } from '../../../../../../applications/shared/loading';
+import { SourceLogic } from '../../source_logic';
interface OauthQueryParams {
preContentSourceId: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
index 05e0182c42a5bd..abb2745eb0a229 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -20,9 +20,9 @@ import {
EuiToolTip,
} from '@elastic/eui';
-import { SourceIcon } from 'workplace_search/components';
-import { SourceDataItem } from 'workplace_search/types';
-import { getSourcesPath } from 'workplace_search/utils/routePaths';
+import { SourceIcon } from '../../../../components/shared/source_icon';
+import { SourceDataItem } from '../../../../types';
+import { getSourcesPath } from '../../../../routes';
interface ConfiguredSourcesProps {
sources: SourceDataItem[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
index 46a812fcd6f57e..96fe9251103435 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
@@ -25,11 +25,11 @@ import {
EuiBadgeGroup,
} from '@elastic/eui';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
-import { FeatureIds, Configuration, Features } from 'workplace_search/types';
-import { DOCUMENT_PERMISSIONS_DOCS_URL } from 'workplace_search/utils/routePaths';
-import { SourceFeatures } from './SourceFeatures';
+import { AppLogic } from '../../../../app_logic';
+import { SourceLogic } from '../../source_logic';
+import { FeatureIds, Configuration, Features } from '../../../../types';
+import { DOCUMENT_PERMISSIONS_DOCS_URL } from '../../../../routes';
+import { SourceFeatures } from './source_features';
interface ConnectInstanceProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
index 231f277dfbad6a..65cae8061b0b31 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
@@ -10,11 +10,10 @@ import { Location } from 'history';
import { useActions, useValues } from 'kea';
import { useLocation } from 'react-router-dom';
-import { parseQueryParams } from 'app_search/utils/queryParams';
-
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiSpacer } from '@elastic/eui';
+import { parseQueryParams } from '../../../../../../applications/shared/query_params';
-import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
+import { SourceLogic } from '../../source_logic';
interface SourceQueryParams {
sourceId: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
index ada079f88da351..7cfc5cb581c280 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
@@ -20,12 +20,12 @@ import {
EuiSteps,
} from '@elastic/eui';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { ApiKey } from 'workplace_search/components';
-import { SourceLogic } from 'workplace_search/ContentSources/SourceLogic';
-import { Configuration } from 'workplace_search/types';
+import { AppLogic } from '../../../../app_logic';
+import { ApiKey } from '../../../../components/shared/api_key';
+import { SourceLogic } from '../../source_logic';
+import { Configuration } from '../../../../types';
-import { ConfigDocsLinks } from './ConfigDocsLinks';
+import { ConfigDocsLinks } from './config_docs_links';
interface SaveConfigProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
index 0c7ca14bebb821..17510c3ece9147 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
@@ -20,11 +20,11 @@ import {
EuiLink,
EuiPanel,
} from '@elastic/eui';
-import { CredentialItem } from 'workplace_search/components/CredentialItem';
-import { LicenseBadge } from 'workplace_search/components';
+import { CredentialItem } from '../../../../components/shared/credential_item';
+import { LicenseBadge } from '../../../../components/shared/license_badge';
-import { CustomSource } from 'workplace_search/types';
+import { CustomSource } from '../../../../types';
import {
SOURCES_PATH,
SOURCE_DISPLAY_SETTINGS_PATH,
@@ -32,7 +32,7 @@ import {
ENT_SEARCH_LICENSE_MANAGEMENT,
getContentSourcePath,
getSourcesPath,
-} from 'workplace_search/utils/routePaths';
+} from '../../../../routes';
interface SaveCustomProps {
documentationUrl: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
index b32b889b91c8ce..296ee63ebe2710 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
@@ -18,10 +18,10 @@ import {
EuiTitle,
} from '@elastic/eui';
-import { AppLogic } from 'workplace_search/App/AppLogic';
-import { LicenseBadge } from 'workplace_search/components';
-import { Features, FeatureIds } from 'workplace_search/types';
-import { ENT_SEARCH_LICENSE_MANAGEMENT } from 'workplace_search/utils/routePaths';
+import { AppLogic } from '../../../../app_logic';
+import { LicenseBadge } from '../../../../components/shared/license_badge';
+import { Features, FeatureIds } from '../../../../types';
+import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../../routes';
interface ConnectInstanceProps {
features?: Features;
From 13a67b48bf5e29d56ce2ee842c6ef43580743801 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:25:24 -0600
Subject: [PATCH 05/11] =?UTF-8?q?Use=20Kibana=E2=80=99s=20hasPlatinumLicen?=
=?UTF-8?q?se=20over=20minimumPlatinumLicense?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../add_source/available_sources_list.tsx | 9 ++++-----
.../components/add_source/connect_instance.tsx | 14 ++++++++------
.../components/add_source/save_config.tsx | 10 +++++-----
.../components/add_source/source_features.tsx | 16 ++++++++--------
4 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
index 31e7202b66f0cb..517b9c3649959b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
@@ -19,7 +19,8 @@ import {
import { useValues } from 'kea';
-import { AppLogic } from '../../../../app_logic';
+import { LicensingLogic } from '../../../../../../applications/shared/licensing';
+
import { SourceIcon } from '../../../../components/shared/source_icon';
import { SourceDataItem } from '../../../../types';
import { ADD_CUSTOM_PATH, getSourcesPath } from '../../../../routes';
@@ -29,12 +30,10 @@ interface AvailableSourcesListProps {
}
export const AvailableSourcesList: React.FC = ({ sources }) => {
- const {
- fpAccount: { minimumPlatinumLicense },
- } = useValues(AppLogic);
+ const { hasPlatinumLicense } = useValues(LicensingLogic);
const getSourceCard = ({ name, serviceType, addPath, accountContextOnly }) => {
- const disabled = !minimumPlatinumLicense && accountContextOnly;
+ const disabled = !hasPlatinumLicense && accountContextOnly;
const card = (
= ({
header,
}) => {
const [formLoading, setFormLoading] = useState(false);
+
+ const { hasPlatinumLicense } = useValues(LicensingLogic);
+
const {
getSourceConnectData,
createContentSource,
@@ -70,14 +75,11 @@ export const ConnectInstance: React.FC = ({
SourceLogic
);
- const {
- isOrganization,
- fpAccount: { minimumPlatinumLicense },
- } = useValues(AppLogic);
+ const { isOrganization } = useValues(AppLogic);
// Default indexPermissions to true, if needed
useEffect(() => {
- setSourceIndexPermissionsValue(needsPermissions && isOrganization && minimumPlatinumLicense);
+ setSourceIndexPermissionsValue(needsPermissions && isOrganization && hasPlatinumLicense);
}, []);
const redirectOauth = (oauthUrl: string) => (window.location.href = oauthUrl);
@@ -216,7 +218,7 @@ export const ConnectInstance: React.FC = ({
const formFields = (
<>
- {isOrganization && minimumPlatinumLicense && permissionField}
+ {isOrganization && hasPlatinumLicense && permissionField}
{!hasOauthRedirect && credentialsFields}
{needsSubdomain && subdomainField}
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
index 7cfc5cb581c280..0c547c174fbe56 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
@@ -20,7 +20,8 @@ import {
EuiSteps,
} from '@elastic/eui';
-import { AppLogic } from '../../../../app_logic';
+import { LicensingLogic } from '../../../../../../applications/shared/licensing';
+
import { ApiKey } from '../../../../components/shared/api_key';
import { SourceLogic } from '../../source_logic';
import { Configuration } from '../../../../types';
@@ -51,6 +52,8 @@ export const SaveConfig: React.FC = ({
onDeleteConfig,
header,
}) => {
+ const { hasPlatinumLicense } = useValues(LicensingLogic);
+
const { setClientIdValue, setClientSecretValue, setBaseUrlValue } = useActions(SourceLogic);
const {
@@ -65,9 +68,6 @@ export const SaveConfig: React.FC = ({
accountContextOnly,
configuredFields: { publicKey, consumerKey },
} = sourceConfigData;
- const {
- fpAccount: { minimumPlatinumLicense },
- } = useValues(AppLogic);
const handleFormSubmission = (e) => {
e.preventDefault();
@@ -87,7 +87,7 @@ export const SaveConfig: React.FC = ({
);
const backButton = Go back ;
- const showSaveButton = minimumPlatinumLicense || !accountContextOnly;
+ const showSaveButton = hasPlatinumLicense || !accountContextOnly;
const formActions = (
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
index 296ee63ebe2710..6c92f3a9e13ffb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
@@ -18,6 +18,8 @@ import {
EuiTitle,
} from '@elastic/eui';
+import { LicensingLogic } from '../../../../../../applications/shared/licensing';
+
import { AppLogic } from '../../../../app_logic';
import { LicenseBadge } from '../../../../components/shared/license_badge';
import { Features, FeatureIds } from '../../../../types';
@@ -30,10 +32,8 @@ interface ConnectInstanceProps {
}
export const SourceFeatures: React.FC = ({ features, objTypes, name }) => {
- const {
- isOrganization,
- fpAccount: { minimumPlatinumLicense },
- } = useValues(AppLogic);
+ const { hasPlatinumLicense } = useValues(LicensingLogic);
+ const { isOrganization } = useValues(AppLogic);
const Feature = ({ title, children }: { title: string; children: React.ReactElement }) => (
<>
@@ -153,13 +153,13 @@ export const SourceFeatures: React.FC = ({ features, objTy
const IncludedFeatures = () => {
let includedFeatures: FeatureIds[] | undefined;
- if (!minimumPlatinumLicense && isOrganization) {
+ if (!hasPlatinumLicense && isOrganization) {
includedFeatures = features?.basicOrgContext;
}
- if (minimumPlatinumLicense && isOrganization) {
+ if (hasPlatinumLicense && isOrganization) {
includedFeatures = features?.platinumOrgContext;
}
- if (minimumPlatinumLicense && !isOrganization) {
+ if (hasPlatinumLicense && !isOrganization) {
includedFeatures = features?.platinumPrivateContext;
}
@@ -182,7 +182,7 @@ export const SourceFeatures: React.FC = ({ features, objTy
const ExcludedFeatures = () => {
let excludedFeatures: FeatureIds[] | undefined;
- if (!minimumPlatinumLicense && isOrganization) {
+ if (!hasPlatinumLicense && isOrganization) {
excludedFeatures = features?.basicOrgContextExcludedFeatures;
}
From b51cb81c5452124fcec4344d452b16ccff44fc08 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:40:03 -0600
Subject: [PATCH 06/11] Various TypeScript lint fixes
---
.../components/add_source/add_source.tsx | 2 +-
.../components/add_source/add_source_list.tsx | 12 +++++++-----
.../components/add_source/available_sources_list.tsx | 2 +-
.../components/add_source/config_completed.tsx | 2 +-
.../components/add_source/configuration_intro.tsx | 2 +-
.../components/add_source/configure_custom.tsx | 9 +++++----
.../components/add_source/configure_oauth.tsx | 12 +++++++-----
.../add_source/configured_sources_list.tsx | 2 +-
.../components/add_source/connect_instance.tsx | 6 +++---
.../components/add_source/re_authenticate.tsx | 4 ++--
.../components/add_source/save_config.tsx | 10 +++++-----
11 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
index 2cf91de14b5616..fa4f206800fbee 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -121,7 +121,7 @@ export const AddSource: React.FC = ({
const saveCustomSuccess = () => setStep(Steps.SaveCustomStep);
const goToSaveCustom = () => createContentSource(CUSTOM_SERVICE_TYPE, saveCustomSuccess);
- const goToFormSourceCreated = (sourceName) => {
+ const goToFormSourceCreated = (sourceName: string) => {
history.push(`${getSourcesPath(SOURCE_ADDED_PATH, isOrganization)}/?name=${sourceName}`);
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
index d7e5841660e38d..650510619bd0ef 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, ChangeEvent } from 'react';
import noSharedSourcesIcon from 'workplace_search/components/assets/shareCircle.svg';
import { useActions, useValues } from 'kea';
@@ -77,17 +77,19 @@ export const AddSourceList: React.FC = () => {
const HAS_SOURCES_TITLE = isOrganization ? ORG_SOURCES_TITLE : PRIVATE_SOURCES_TITLE;
const SIDEBAR_TITLE = hasSources ? HAS_SOURCES_TITLE : NO_SOURCES_TITLE;
- const handleFilterChange = (e) => setFilterValue(e.target.value);
+ const handleFilterChange = (e: ChangeEvent) => setFilterValue(e.target.value);
- const filterSources = (source, sources): boolean => {
+ const filterSources = (source: SourceDataItem, sources: SourceDataItem[]): boolean => {
if (!filterValue) return true;
const filterSource = sources.find(({ serviceType }) => serviceType === source.serviceType);
const filteredName = filterSource?.name || '';
return filteredName.toLowerCase().indexOf(filterValue.toLowerCase()) > -1;
};
- const filterAvailableSources = (source) => filterSources(source, availableSources);
- const filterConfiguredSources = (source) => filterSources(source, configuredSources);
+ const filterAvailableSources = (source: SourceDataItem) =>
+ filterSources(source, availableSources);
+ const filterConfiguredSources = (source: SourceDataItem) =>
+ filterSources(source, configuredSources);
const visibleAvailableSources = availableSources.filter(
filterAvailableSources
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
index 517b9c3649959b..0d4345c67cfb3c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
@@ -32,7 +32,7 @@ interface AvailableSourcesListProps {
export const AvailableSourcesList: React.FC = ({ sources }) => {
const { hasPlatinumLicense } = useValues(LicensingLogic);
- const getSourceCard = ({ name, serviceType, addPath, accountContextOnly }) => {
+ const getSourceCard = ({ name, serviceType, addPath, accountContextOnly }: SourceDataItem) => {
const disabled = !hasPlatinumLicense && accountContextOnly;
const card = (
= ({
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
index 70fcbec51209e4..2bf5134e59e264 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
@@ -22,7 +22,7 @@ import connectionIllustration from 'workplace_search/components/assets/connectio
interface ConfigurationIntroProps {
header: React.ReactNode;
name: string;
- advanceStep();
+ advanceStep(): void;
}
export const ConfigurationIntro: React.FC = ({
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
index e1dd8579aeb693..3788071979e67b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
+import React, { ChangeEvent, FormEvent } from 'react';
import { useActions, useValues } from 'kea';
@@ -24,7 +24,7 @@ import { SourceLogic } from '../../source_logic';
interface ConfigureCustomProps {
header: React.ReactNode;
helpText: string;
- advanceStep();
+ advanceStep(): void;
}
export const ConfigureCustom: React.FC = ({
@@ -35,12 +35,13 @@ export const ConfigureCustom: React.FC = ({
const { setCustomSourceNameValue } = useActions(SourceLogic);
const { customSourceNameValue, buttonLoading } = useValues(SourceLogic);
- const handleFormSubmit = (e) => {
+ const handleFormSubmit = (e: FormEvent) => {
e.preventDefault();
advanceStep();
};
- const handleNameChange = (e) => setCustomSourceNameValue(e.target.value);
+ const handleNameChange = (e: ChangeEvent) =>
+ setCustomSourceNameValue(e.target.value);
return (
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
index f6aa218bcb51a5..9c2084483c816b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, FormEvent } from 'react';
import { Location } from 'history';
import { useActions, useValues } from 'kea';
@@ -19,6 +19,8 @@ import {
EuiSpacer,
} from '@elastic/eui';
+import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group';
+
import { parseQueryParams } from '../../../../../../applications/shared/query_params';
import { Loading } from '../../../../../../applications/shared/loading';
import { SourceLogic } from '../../source_logic';
@@ -30,7 +32,7 @@ interface OauthQueryParams {
interface ConfigureOauthProps {
header: React.ReactNode;
name: string;
- onFormCreated(name: string);
+ onFormCreated(name: string): void;
}
export const ConfigureOauth: React.FC
= ({ name, onFormCreated, header }) => {
@@ -57,10 +59,10 @@ export const ConfigureOauth: React.FC = ({ name, onFormCrea
getPreContentSourceConfigData(preContentSourceId);
}, []);
- const handleChange = (option) => setSelectedGithubOrganizations(option);
+ const handleChange = (option: string) => setSelectedGithubOrganizations(option);
const formSubmitSuccess = () => onFormCreated(name);
const handleFormSubmitError = () => setFormLoading(false);
- const handleFormSubmut = (e) => {
+ const handleFormSubmut = (e: FormEvent) => {
setFormLoading(true);
e.preventDefault();
createContentSource(currentServiceType, formSubmitSuccess, handleFormSubmitError);
@@ -79,7 +81,7 @@ export const ConfigureOauth: React.FC = ({ name, onFormCrea
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
index abb2745eb0a229..792db71fef02e6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -89,7 +89,7 @@ export const ConfiguredSourcesList: React.FC = ({
{(!isOrganization || (isOrganization && !accountContextOnly)) && (
-
+
Connect
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
index 6dcdb29c76d126..ad183181b4ecad 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, FormEvent } from 'react';
import { useActions, useValues } from 'kea';
@@ -43,7 +43,7 @@ interface ConnectInstanceProps {
sourceDescription: string;
connectStepDescription: string;
needsPermissions: boolean;
- onFormCreated(name: string);
+ onFormCreated(name: string): void;
}
export const ConnectInstance: React.FC = ({
@@ -89,7 +89,7 @@ export const ConnectInstance: React.FC = ({
const onCredentialsFormSubmit = () =>
createContentSource(serviceType, redirectFormCreated, handleFormSubmitError);
- const handleFormSubmit = (e) => {
+ const handleFormSubmit = (e: FormEvent) => {
setFormLoading(true);
e.preventDefault();
const onSubmit = hasOauthRedirect ? onOauthFormSubmit : onCredentialsFormSubmit;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
index 65cae8061b0b31..7336a3b51a4449 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, FormEvent } from 'react';
import { Location } from 'history';
import { useActions, useValues } from 'kea';
@@ -39,7 +39,7 @@ export const ReAuthenticate: React.FC = ({ name, header })
getSourceReConnectData(sourceId);
}, []);
- const handleFormSubmit = (e) => {
+ const handleFormSubmit = (e: FormEvent) => {
e.preventDefault();
setFormLoading(true);
window.location.href = oauthUrl;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
index 0c547c174fbe56..4036bb6a771bb6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
+import React, { FormEvent } from 'react';
import { useActions, useValues } from 'kea';
@@ -32,9 +32,9 @@ interface SaveConfigProps {
header: React.ReactNode;
name: string;
configuration: Configuration;
- advanceStep();
- goBackStep?();
- onDeleteConfig?();
+ advanceStep(): void;
+ goBackStep?(): void;
+ onDeleteConfig?(): void;
}
export const SaveConfig: React.FC = ({
@@ -69,7 +69,7 @@ export const SaveConfig: React.FC = ({
configuredFields: { publicKey, consumerKey },
} = sourceConfigData;
- const handleFormSubmission = (e) => {
+ const handleFormSubmission = (e: FormEvent) => {
e.preventDefault();
advanceStep();
};
From d21a6619fdba935c288b36ec3b25c93fd5a022a2 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:46:37 -0600
Subject: [PATCH 07/11] Fix index paths
---
.../views/content_sources/components/add_source/index.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
index 02f0e1db7ff0b7..8a46eaa7d70e95 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts
@@ -4,5 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export { AddSource } from './AddSource';
-export { AddSourceList } from './AddSourceList';
+export { AddSource } from './add_source';
+export { AddSourceList } from './add_source_list';
From bce570c2760f09c17e84eaf1a45c0ba889fd4d0b Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Wed, 18 Nov 2020 17:50:36 -0600
Subject: [PATCH 08/11] 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
---
.../components/add_source/add_source.tsx | 20 +---
.../components/add_source/add_source_list.tsx | 108 +++++++++---------
2 files changed, 61 insertions(+), 67 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
index fa4f206800fbee..7b6d02c36c0ccc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -12,11 +12,12 @@ 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 { ADD_SOURCE_PATH, SOURCE_ADDED_PATH, getSourcesPath } from '../../../../routes';
+import { SOURCE_ADDED_PATH, getSourcesPath } from '../../../../routes';
import { AddSourceHeader } from './add_source_header';
import { ConfigCompleted } from './config_completed';
@@ -88,11 +89,6 @@ export const AddSource: React.FC = ({
return resetSourceState;
}, []);
- const breadcrumbs = {
- topLevelPath: getSourcesPath(ADD_SOURCE_PATH, isOrganization),
- topLevelName: '← Back to sources',
- };
-
const isCustom = serviceType === CUSTOM_SERVICE_TYPE;
const isRemote = features?.platinumPrivateContext.includes(FeatureIds.Remote);
@@ -125,7 +121,7 @@ export const AddSource: React.FC = ({
history.push(`${getSourcesPath(SOURCE_ADDED_PATH, isOrganization)}/?name=${sourceName}`);
};
- const sidebarTitle = () => {
+ const pageTitle = () => {
if (currentStep === Steps.ConnectInstanceStep || currentStep === Steps.ConfigureOauthStep) {
return 'Connect';
}
@@ -172,17 +168,17 @@ export const AddSource: React.FC = ({
? CONNECT_ORGANIZATION_SOURCE_SIDEBAR_BLURB
: CONNECT_PRIVATE_SOURCE_SIDEBAR_BLURB;
- const sidebarBlurb =
+ const PAGE_DESCRIPTION =
currentStep === Steps.ConnectInstanceStep ? CONNECT_SIDEBAR_BLURB : CONFIG_SIDEBAR_BLURB;
const header = ;
return (
<>
+
{currentStep === Steps.ConfigIntroStep && (
)}
-
{currentStep === Steps.SaveConfigStep && (
= ({
header={header}
/>
)}
-
{currentStep === Steps.ConfigCompletedStep && (
= ({
header={header}
/>
)}
-
{currentStep === Steps.ConnectInstanceStep && (
= ({
header={header}
/>
)}
-
{currentStep === Steps.ConfigureCustomStep && (
= ({
header={header}
/>
)}
-
{currentStep === Steps.ConfigureOauthStep && (
)}
-
{currentStep === Steps.SaveCustomStep && (
= ({
header={header}
/>
)}
-
{currentStep === Steps.ReAuthenticateStep && }
>
);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
index 650510619bd0ef..24c3a8f8ddb3b4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -21,10 +21,10 @@ import {
import { AppLogic } from '../../../../app_logic';
import { ContentSection } from '../../../../components/shared/content_section';
+import { ViewContentHeader } from '../../../../components/shared/view_content_header';
import { Loading } from '../../../../../../applications/shared/loading';
import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
import { SourceDataItem } from '../../../../types';
-import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
import { SourcesLogic } from '../../sources_logic';
import { AvailableSourcesList } from './available_sources_list';
@@ -64,18 +64,14 @@ export const AddSourceList: React.FC = () => {
({ serviceType }) => serviceType !== CUSTOM_SERVICE_TYPE
);
- const breadcrumbs = {
- topLevelPath: getSourcesPath(SOURCES_PATH, isOrganization),
- topLevelName: `${isOrganization ? 'Shared' : 'Private'} content sources`,
- activeName: 'Add',
- };
-
- const SIDEBAR_DESCRIPTION = hasSources ? '' : NEW_SOURCE_DESCRIPTION;
- const SIDEBAR_CONTEXT_DESCRIPTION = isOrganization
+ const BASE_DESCRIPTION = hasSources ? '' : NEW_SOURCE_DESCRIPTION;
+ const PAGE_CONTEXT_DESCRIPTION = isOrganization
? ORG_SOURCE_DESCRIPTION
: PRIVATE_SOURCE_DESCRIPTION;
+
+ const PAGE_DESCRIPTION = BASE_DESCRIPTION + PAGE_CONTEXT_DESCRIPTION;
const HAS_SOURCES_TITLE = isOrganization ? ORG_SOURCES_TITLE : PRIVATE_SOURCES_TITLE;
- const SIDEBAR_TITLE = hasSources ? HAS_SOURCES_TITLE : NO_SOURCES_TITLE;
+ const PAGE_TITLE = hasSources ? HAS_SOURCES_TITLE : NO_SOURCES_TITLE;
const handleFilterChange = (e: ChangeEvent) => setFilterValue(e.target.value);
@@ -98,48 +94,56 @@ export const AddSourceList: React.FC = () => {
filterConfiguredSources
) as SourceDataItem[];
- return showConfiguredSourcesList || isOrganization ? (
-
-
-
-
-
-
- {showConfiguredSourcesList && (
-
- )}
- {isOrganization && }
-
- ) : (
-
-
-
-
-
-
-
- No available sources}
- body={
-
- Sources will be available for search when an administrator adds them to this
- organization.
-
- }
+ return (
+ <>
+
+ {showConfiguredSourcesList || isOrganization ? (
+
+
+
+
+
+
+ {showConfiguredSourcesList && (
+
-
-
-
-
-
-
-
+ )}
+ {isOrganization && }
+
+ ) : (
+
+
+
+
+
+
+
+ No available sources}
+ body={
+
+ Sources will be available for search when an administrator adds them to this
+ organization.
+
+ }
+ />
+
+
+
+
+
+
+
+ )}
+ >
);
};
From c7c4bd2863e554b5c8dae21d8b7a6b9e29dfc5ad Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Thu, 19 Nov 2020 08:26:24 -0600
Subject: [PATCH 09/11] Temporarily add parseQueryParams
This is a placeholder until https://github.com/elastic/kibana/pull/83750 lands
---
.../public/applications/shared/query_params/index.ts | 7 +++++++
.../applications/shared/query_params/query_params.ts | 10 ++++++++++
2 files changed, 17 insertions(+)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/query_params/index.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/query_params/query_params.ts
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/query_params/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/query_params/index.ts
new file mode 100644
index 00000000000000..61eb1792911eeb
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/query_params/index.ts
@@ -0,0 +1,7 @@
+/*
+ * 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.
+ */
+
+export { parseQueryParams } from './query_params';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/query_params/query_params.ts b/x-pack/plugins/enterprise_search/public/applications/shared/query_params/query_params.ts
new file mode 100644
index 00000000000000..f39760d27fbf33
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/query_params/query_params.ts
@@ -0,0 +1,10 @@
+/*
+ * 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 queryString from 'query-string';
+
+export const parseQueryParams = (search: string) =>
+ queryString.parse(search, { arrayFormat: 'bracket' });
From 7fae6a403d02cb883f21894faaaa4eb9b53a52e8 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Thu, 19 Nov 2020 11:35:33 -0600
Subject: [PATCH 10/11] Remove optional from isOrganization
Looks like the value is always passed
---
.../components/add_source/configured_sources_list.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
index 792db71fef02e6..7e23b88c575382 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -26,7 +26,7 @@ import { getSourcesPath } from '../../../../routes';
interface ConfiguredSourcesProps {
sources: SourceDataItem[];
- isOrganization?: boolean;
+ isOrganization: boolean;
}
export const ConfiguredSourcesList: React.FC = ({
From cffe5d7a9aa480d253350118c418c09c554ad182 Mon Sep 17 00:00:00 2001
From: scottybollinger
Date: Thu, 19 Nov 2020 11:36:32 -0600
Subject: [PATCH 11/11] =?UTF-8?q?Remove=20=E2=80=98!!=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../components/add_source/configured_sources_list.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
index 7e23b88c575382..a95d5ca75b0b69 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -89,7 +89,7 @@ export const ConfiguredSourcesList: React.FC = ({
{(!isOrganization || (isOrganization && !accountContextOnly)) && (
-
+
Connect