From 5d6c3c6cbf0f97b3b78be9c8b63385b53485a68f Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 14:28:20 -0600 Subject: [PATCH 01/13] Initial copy/paste of source logic Only changed lodash imports and import order for linting --- .../views/content_sources/source_logic.ts | 580 ++++++++++++++++++ 1 file changed, 580 insertions(+) create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts new file mode 100644 index 0000000000000..b135a0a66f380 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -0,0 +1,580 @@ +/* + * 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 { keys, pickBy } from 'lodash'; + +import { kea, MakeLogicType } from 'kea'; + +import http from 'shared/http'; +import routes from 'workplace_search/routes'; + +import { handleAPIError } from 'app_search/utils/handleAPIError'; +import { DEFAULT_META } from 'shared/constants/defaultMeta'; +import { IMeta, IFlashMessagesProps } from 'shared/types'; +import { AppLogic } from 'workplace_search/App/AppLogic'; +import { NOT_FOUND_PATH } from 'workplace_search/utils/routePaths'; +import { IObject, ContentSourceFullData, CustomSource } from 'workplace_search/types'; + +import { SourcesLogic } from './SourcesLogic'; + +export interface SourceActions { + onInitializeSource(contentSource: ContentSourceFullData): ContentSourceFullData; + onUpdateSourceName(name: string): string; + setSourceConfigData(sourceConfigData: SourceConfigData): SourceConfigData; + setSourceConnectData(sourceConnectData: SourceConnectData): SourceConnectData; + setFlashMessages(flashMessages: IFlashMessagesProps): { flashMessages: IFlashMessagesProps }; + setSearchResults(searchResultsResponse: SearchResultsResponse): SearchResultsResponse; + initializeFederatedSummary(sourceId: string): { sourceId: string }; + onUpdateSummary(summary: IObject[]): IObject[]; + setContentFilterValue(contentFilterValue: string): string; + setActivePage(activePage: number): number; + setClientIdValue(clientIdValue: string): string; + setClientSecretValue(clientSecretValue: string): string; + setBaseUrlValue(baseUrlValue: string): string; + setCustomSourceNameValue(customSourceNameValue: string): string; + setSourceLoginValue(loginValue: string): string; + setSourcePasswordValue(passwordValue: string): string; + setSourceSubdomainValue(subdomainValue: string): string; + setSourceIndexPermissionsValue(indexPermissionsValue: boolean): boolean; + setCustomSourceData(data: CustomSource): CustomSource; + setPreContentSourceConfigData(data: PreContentSourceResponse): PreContentSourceResponse; + setSelectedGithubOrganizations(option: string): string; + searchContentSourceDocuments(sourceId: string): { sourceId: string }; + updateContentSource( + sourceId: string, + source: { name: string } + ): { sourceId: string; source: { name: string } }; + resetSourceState(): void; + removeContentSource( + sourceId: string, + successCallback: () => void + ): { sourceId: string; successCallback() }; + createContentSource( + serviceType: string, + successCallback: () => void, + errorCallback?: () => void + ): { serviceType: string; successCallback(); errorCallback?() }; + saveSourceConfig( + isUpdating: boolean, + successCallback?: () => void + ): { isUpdating: boolean; successCallback?() }; + initializeSource(sourceId: string, history: IObject): { sourceId: string; history: IObject }; + getSourceConfigData(serviceType: string): { serviceType: string }; + getSourceConnectData( + serviceType: string, + successCallback: (oauthUrl: string) => string + ): { serviceType: string; successCallback(oauthUrl: string) }; + getSourceReConnectData(serviceType: string): { serviceType: string }; + getPreContentSourceConfigData(preContentSourceId: string): { preContentSourceId: string }; +} + +interface SourceConfigData { + serviceType: string; + name: string; + configured: boolean; + categories: string[]; + needsPermissions?: boolean; + privateSourcesEnabled: boolean; + configuredFields: { + publicKey: string; + privateKey: string; + consumerKey: string; + baseUrl?: string; + clientId?: string; + clientSecret?: string; + }; + accountContextOnly?: boolean; +} + +interface SourceConnectData { + oauthUrl: string; + serviceType: string; +} + +interface SourceValues { + contentSource: ContentSourceFullData; + flashMessages: IFlashMessagesProps; + dataLoading: boolean; + sectionLoading: boolean; + buttonLoading: boolean; + contentItems: IObject[]; + contentMeta: IMeta; + contentFilterValue: string; + customSourceNameValue: string; + clientIdValue: string; + clientSecretValue: string; + baseUrlValue: string; + loginValue: string; + passwordValue: string; + subdomainValue: string; + indexPermissionsValue: boolean; + sourceConfigData: SourceConfigData; + sourceConnectData: SourceConnectData; + newCustomSource: CustomSource; + currentServiceType: string; + githubOrganizations: string[]; + selectedGithubOrganizationsMap: IObject; + selectedGithubOrganizations: IObject; +} + +interface SearchResultsResponse { + results: IObject[]; + meta: IMeta; +} + +interface PreContentSourceResponse { + id: string; + serviceType: string; + githubOrganizations: string[]; +} + +export const SourceLogic = kea>({ + actions: { + onInitializeSource: (contentSource: ContentSourceFullData) => contentSource, + onUpdateSourceName: (name: string) => name, + setSourceConfigData: (sourceConfigData: SourceConfigData) => sourceConfigData, + setSourceConnectData: (sourceConnectData: SourceConnectData) => sourceConnectData, + onUpdateSummary: (summary: IObject[]) => summary, + setFlashMessages: (flashMessages: IFlashMessagesProps) => ({ flashMessages }), + setSearchResults: (searchResultsResponse: SearchResultsResponse) => searchResultsResponse, + setContentFilterValue: (contentFilterValue: string) => contentFilterValue, + setActivePage: (activePage: number) => activePage, + setClientIdValue: (clientIdValue: string) => clientIdValue, + setClientSecretValue: (clientSecretValue: string) => clientSecretValue, + setBaseUrlValue: (baseUrlValue: string) => baseUrlValue, + setCustomSourceNameValue: (customSourceNameValue: string) => customSourceNameValue, + setSourceLoginValue: (loginValue: string) => loginValue, + setSourcePasswordValue: (passwordValue: string) => passwordValue, + setSourceSubdomainValue: (subdomainValue: string) => subdomainValue, + setSourceIndexPermissionsValue: (indexPermissionsValue: boolean) => indexPermissionsValue, + setCustomSourceData: (data: CustomSource) => data, + setPreContentSourceConfigData: (data: PreContentSourceResponse) => data, + setSelectedGithubOrganizations: (option: string) => option, + initializeSource: (sourceId: string, history: IObject) => ({ sourceId, history }), + initializeFederatedSummary: (sourceId: string) => ({ sourceId }), + searchContentSourceDocuments: (sourceId: string) => ({ sourceId }), + updateContentSource: (sourceId: string, source: { name: string }) => ({ sourceId, source }), + removeContentSource: (sourceId: string, successCallback: () => void) => ({ + sourceId, + successCallback, + }), + getSourceConfigData: (serviceType: string) => ({ serviceType }), + getSourceConnectData: (serviceType: string, successCallback: (oauthUrl: string) => string) => ({ + serviceType, + successCallback, + }), + getSourceReConnectData: (serviceType: string) => ({ serviceType }), + getPreContentSourceConfigData: (preContentSourceId: string) => ({ preContentSourceId }), + saveSourceConfig: (isUpdating: boolean, successCallback?: () => void) => ({ + isUpdating, + successCallback, + }), + createContentSource: ( + serviceType: string, + successCallback: () => void, + errorCallback?: () => void + ) => ({ serviceType, successCallback, errorCallback }), + resetSourceState: () => true, + }, + reducers: { + contentSource: [ + {} as ContentSourceFullData, + { + onInitializeSource: (_, contentSource) => contentSource, + onUpdateSourceName: (contentSource, name) => ({ + ...contentSource, + name, + }), + onUpdateSummary: (contentSource, summary) => ({ + ...contentSource, + summary, + }), + }, + ], + sourceConfigData: [ + {} as SourceConfigData, + { + setSourceConfigData: (_, sourceConfigData) => sourceConfigData, + }, + ], + sourceConnectData: [ + {} as SourceConnectData, + { + setSourceConnectData: (_, sourceConnectData) => sourceConnectData, + }, + ], + flashMessages: [ + {}, + { + setFlashMessages: (_, { flashMessages }) => flashMessages, + onUpdateSourceName: (_, name) => ({ success: [`Successfully changed name to ${name}`] }), + resetSourceState: () => ({}), + removeContentSource: () => ({}), + saveSourceConfig: () => ({}), + getSourceConnectData: () => ({}), + createContentSource: () => ({}), + }, + ], + dataLoading: [ + true, + { + onInitializeSource: () => false, + setSourceConfigData: () => false, + resetSourceState: () => false, + setPreContentSourceConfigData: () => false, + }, + ], + buttonLoading: [ + false, + { + setFlashMessages: () => false, + setSourceConnectData: () => false, + setSourceConfigData: () => false, + resetSourceState: () => false, + removeContentSource: () => true, + saveSourceConfig: () => true, + getSourceConnectData: () => true, + createContentSource: () => true, + }, + ], + sectionLoading: [ + true, + { + searchContentSourceDocuments: () => true, + getPreContentSourceConfigData: () => true, + setSearchResults: () => false, + setPreContentSourceConfigData: () => false, + }, + ], + contentItems: [ + [], + { + setSearchResults: (_, { results }) => results, + }, + ], + contentMeta: [ + DEFAULT_META, + { + setActivePage: (state, activePage) => setPage(state, activePage), + setContentFilterValue: (state) => setPage(state, DEFAULT_META.page.current), + setSearchResults: (_, { meta }) => meta, + }, + ], + contentFilterValue: [ + '', + { + setContentFilterValue: (_, contentFilterValue) => contentFilterValue, + resetSourceState: () => '', + }, + ], + clientIdValue: [ + '', + { + setClientIdValue: (_, clientIdValue) => clientIdValue, + setSourceConfigData: (_, { configuredFields: { clientId } }) => clientId || '', + resetSourceState: () => '', + }, + ], + clientSecretValue: [ + '', + { + setClientSecretValue: (_, clientSecretValue) => clientSecretValue, + setSourceConfigData: (_, { configuredFields: { clientSecret } }) => clientSecret || '', + resetSourceState: () => '', + }, + ], + baseUrlValue: [ + '', + { + setBaseUrlValue: (_, baseUrlValue) => baseUrlValue, + setSourceConfigData: (_, { configuredFields: { baseUrl } }) => baseUrl || '', + resetSourceState: () => '', + }, + ], + loginValue: [ + '', + { + setSourceLoginValue: (_, loginValue) => loginValue, + resetSourceState: () => '', + }, + ], + passwordValue: [ + '', + { + setSourcePasswordValue: (_, passwordValue) => passwordValue, + resetSourceState: () => '', + }, + ], + subdomainValue: [ + '', + { + setSourceSubdomainValue: (_, subdomainValue) => subdomainValue, + resetSourceState: () => '', + }, + ], + indexPermissionsValue: [ + false, + { + setSourceIndexPermissionsValue: (_, indexPermissionsValue) => indexPermissionsValue, + resetSourceState: () => false, + }, + ], + customSourceNameValue: [ + '', + { + setCustomSourceNameValue: (_, customSourceNameValue) => customSourceNameValue, + resetSourceState: () => '', + }, + ], + newCustomSource: [ + {} as CustomSource, + { + setCustomSourceData: (_, newCustomSource) => newCustomSource, + resetSourceState: () => ({} as CustomSource), + }, + ], + currentServiceType: [ + '', + { + setPreContentSourceConfigData: (_, { serviceType }) => serviceType, + resetSourceState: () => '', + }, + ], + githubOrganizations: [ + [], + { + setPreContentSourceConfigData: (_, { githubOrganizations }) => githubOrganizations, + resetSourceState: () => [], + }, + ], + selectedGithubOrganizationsMap: [ + {}, + { + setSelectedGithubOrganizations: (state, option) => ({ + ...state, + ...{ [option]: !state[option] }, + }), + resetSourceState: () => [], + }, + ], + }, + selectors: ({ selectors }) => ({ + selectedGithubOrganizations: [ + () => [selectors.selectedGithubOrganizationsMap], + (orgsMap) => keys(pickBy(orgsMap)), + ], + }), + listeners: ({ actions, values }) => ({ + initializeSource: ({ sourceId, history }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationContentSourcePath(sourceId) + : routes.fritoPieAccountContentSourcePath(sourceId); + + http(route) + .then(({ data }) => { + actions.onInitializeSource(data); + if (data.isFederatedSource) { + actions.initializeFederatedSummary(sourceId); + } + }) + .catch((error) => { + if (error.response.status === 404) { + history.push(NOT_FOUND_PATH); + } else { + handleAPIError((messages) => actions.setFlashMessages({ error: messages })); + } + }); + }, + initializeFederatedSummary: ({ sourceId }) => { + const route = routes.fritoPieAccountContentSourceFederatedSummaryPath(sourceId); + + http(route) + .then(({ data }) => actions.onUpdateSummary(data.summary)) + .catch(() => { + handleAPIError((messages) => actions.setFlashMessages({ error: messages })); + }); + }, + searchContentSourceDocuments: async ({ sourceId }, breakpoint) => { + await breakpoint(300); + + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationContentSourceDocumentsPath(sourceId) + : routes.fritoPieAccountContentSourceDocumentsPath(sourceId); + + const { + contentFilterValue: query, + contentMeta: { page }, + } = values; + + http + .post(route, { query, page }) + .then(({ data }) => actions.setSearchResults(data)) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + updateContentSource: ({ sourceId, source }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationContentSourceSettingsPath(sourceId) + : routes.fritoPieAccountContentSourceSettingsPath(sourceId); + + http + .patch(route, { content_source: source }) + .then(({ data }) => actions.onUpdateSourceName(data.name)) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + removeContentSource: ({ sourceId, successCallback }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationContentSourcePath(sourceId) + : routes.fritoPieAccountContentSourcePath(sourceId); + + return http + .delete(route) + .then(({ data: { name } }) => { + SourcesLogic.actions.setFlashMessages({ success: [`Successfully deleted ${name}`] }); + successCallback(); + }) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + getSourceConfigData: ({ serviceType }) => { + const route = routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationPath( + serviceType + ); + + http(route) + .then(({ data }) => actions.setSourceConfigData(data)) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + getSourceConnectData: ({ serviceType, successCallback }) => { + const { isOrganization } = AppLogic.values; + const { subdomainValue: subdomain, indexPermissionsValue: indexPermissions } = values; + + const route = isOrganization + ? routes.prepareFritoPieOrganizationContentSourcesPath(serviceType) + : routes.prepareFritoPieAccountContentSourcesPath(serviceType); + + const params = new URLSearchParams(); + if (subdomain) params.append('subdomain', subdomain); + if (indexPermissions) params.append('index_permissions', indexPermissions.toString()); + + return http(`${route}?${params}`) + .then(({ data }) => { + actions.setSourceConnectData(data); + successCallback(data.oauthUrl); + }) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + getSourceReConnectData: ({ serviceType }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationContentSourceReauthPreparePath(serviceType) + : routes.fritoPieAccountContentSourceReauthPreparePath(serviceType); + + return http(route) + .then(({ data }) => actions.setSourceConnectData(data)) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + getPreContentSourceConfigData: ({ preContentSourceId }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.fritoPieOrganizationPreContentSourcePath(preContentSourceId) + : routes.fritoPieAccountPreContentSourcePath(preContentSourceId); + + http(route) + .then(({ data }) => actions.setPreContentSourceConfigData(data)) + .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + }, + saveSourceConfig: ({ isUpdating, successCallback }) => { + const { + sourceConfigData: { serviceType }, + baseUrlValue, + clientIdValue, + clientSecretValue, + sourceConfigData, + } = values; + + const route = isUpdating + ? routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationPath(serviceType) + : routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationsPath(); + + const method = isUpdating ? 'put' : 'post'; + + const params = { + base_url: baseUrlValue || undefined, + client_id: clientIdValue || undefined, + client_secret: clientSecretValue || undefined, + service_type: serviceType, + private_key: sourceConfigData.configuredFields?.privateKey, + public_key: sourceConfigData.configuredFields?.publicKey, + consumer_key: sourceConfigData.configuredFields?.consumerKey, + }; + + return http({ url: route, method, data: params }) + .then(({ data }) => { + if (isUpdating) + actions.setFlashMessages({ success: ['Successfully updated configuration.'] }); + actions.setSourceConfigData(data); + if (successCallback) successCallback(); + }) + .catch( + handleAPIError((messages) => { + actions.setFlashMessages({ error: messages }); + if (!isUpdating) throw new Error(messages[0]); + }) + ); + }, + createContentSource: ({ serviceType, successCallback, errorCallback }) => { + const { isOrganization } = AppLogic.values; + const route = isOrganization + ? routes.formCreateFritoPieOrganizationContentSourcesPath() + : routes.formCreateFritoPieAccountContentSourcesPath(); + + const { + selectedGithubOrganizations: githubOrganizations, + customSourceNameValue, + loginValue, + passwordValue, + indexPermissionsValue, + } = values; + + const params = { + service_type: serviceType, + name: customSourceNameValue || undefined, + login: loginValue || undefined, + password: passwordValue || undefined, + organizations: githubOrganizations.length > 0 ? githubOrganizations : undefined, + indexPermissions: indexPermissionsValue || undefined, + }; + + // Remove undefined values from params + Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); + + return http + .post(route, params) + .then(({ data }) => { + actions.setCustomSourceData(data); + successCallback(); + }) + .catch( + handleAPIError((messages) => { + actions.setFlashMessages({ error: messages }); + if (errorCallback) errorCallback(); + throw new Error('Auth Error'); + }) + ); + }, + }), +}); + +const setPage = (state: IMeta, page: number) => ({ + ...state, + page: { + ...state.page, + current: page, + }, +}); From 82a119545a554f6ba64b371794cf0019059dd404 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 14:39:02 -0600 Subject: [PATCH 02/13] Add types and route --- .../applications/workplace_search/routes.ts | 2 + .../applications/workplace_search/types.ts | 42 +++++++++++++++++++ 2 files changed, 44 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 6099a42e6d7cb..ea0230648bf9c 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 @@ -10,6 +10,8 @@ import { CURRENT_MAJOR_VERSION } from '../../../common/version'; export const SETUP_GUIDE_PATH = '/setup_guide'; +export const NOT_FOUND_PATH = '/404'; + export const LEAVE_FEEDBACK_EMAIL = 'support@elastic.co'; export const LEAVE_FEEDBACK_URL = `mailto:${LEAVE_FEEDBACK_EMAIL}?Subject=Elastic%20Workplace%20Search%20Feedback`; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index 801bcda2a319a..1bd3cabb0227d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -8,6 +8,17 @@ export * from '../../../common/types/workplace_search'; export type SpacerSizeTypes = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'; +export interface MetaPage { + current: number; + size: number; + total_pages: number; + total_results: number; +} + +export interface Meta { + page: MetaPage; +} + export interface Group { id: string; name: string; @@ -89,6 +100,30 @@ export interface ContentSourceDetails extends ContentSource { boost: number; } +interface DescriptionList { + title: string; + description: string; +} + +export interface ContentSourceFullData extends ContentSourceDetails { + activities: object[]; + details: DescriptionList[]; + summary: object[]; + groups: object[]; + custom: boolean; + accessToken: string; + key: string; + urlField: string; + titleField: string; + licenseSupportsPermissions: boolean; + serviceTypeSupportsPermissions: boolean; + indexPermissions: boolean; + hasPermissions: boolean; + urlFieldIsLinkable: boolean; + createdAt: string; + serviceName: string; +} + export interface ContentSourceStatus { id: string; name: string; @@ -121,3 +156,10 @@ export enum FeatureIds { GlobalAccessPermissions = 'GlobalAccessPermissions', DocumentLevelPermissions = 'DocumentLevelPermissions', } + +export interface CustomSource { + accessToken: string; + key: string; + name: string; + id: string; +} From 174d244b8e4dd4841be0c1ac489fdc3271ef52fe Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 14:40:37 -0600 Subject: [PATCH 03/13] Update paths and typings Renamed IMeta -> Meta Used object instead of IObject --- .../views/content_sources/source_logic.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index b135a0a66f380..4650cf732fc34 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -12,13 +12,13 @@ import http from 'shared/http'; import routes from 'workplace_search/routes'; import { handleAPIError } from 'app_search/utils/handleAPIError'; -import { DEFAULT_META } from 'shared/constants/defaultMeta'; -import { IMeta, IFlashMessagesProps } from 'shared/types'; -import { AppLogic } from 'workplace_search/App/AppLogic'; -import { NOT_FOUND_PATH } from 'workplace_search/utils/routePaths'; -import { IObject, ContentSourceFullData, CustomSource } from 'workplace_search/types'; +import { IFlashMessagesProps } from 'shared/types'; +import { DEFAULT_META } from '../../../shared/constants'; +import { AppLogic } from '../../app_logic'; +import { NOT_FOUND_PATH } from '../../routes'; +import { ContentSourceFullData, CustomSource, Meta } from '../../types'; -import { SourcesLogic } from './SourcesLogic'; +import { SourcesLogic } from './sources_logic'; export interface SourceActions { onInitializeSource(contentSource: ContentSourceFullData): ContentSourceFullData; @@ -28,7 +28,7 @@ export interface SourceActions { setFlashMessages(flashMessages: IFlashMessagesProps): { flashMessages: IFlashMessagesProps }; setSearchResults(searchResultsResponse: SearchResultsResponse): SearchResultsResponse; initializeFederatedSummary(sourceId: string): { sourceId: string }; - onUpdateSummary(summary: IObject[]): IObject[]; + onUpdateSummary(summary: object[]): object[]; setContentFilterValue(contentFilterValue: string): string; setActivePage(activePage: number): number; setClientIdValue(clientIdValue: string): string; @@ -61,7 +61,7 @@ export interface SourceActions { isUpdating: boolean, successCallback?: () => void ): { isUpdating: boolean; successCallback?() }; - initializeSource(sourceId: string, history: IObject): { sourceId: string; history: IObject }; + initializeSource(sourceId: string, history: object): { sourceId: string; history: object }; getSourceConfigData(serviceType: string): { serviceType: string }; getSourceConnectData( serviceType: string, @@ -100,8 +100,8 @@ interface SourceValues { dataLoading: boolean; sectionLoading: boolean; buttonLoading: boolean; - contentItems: IObject[]; - contentMeta: IMeta; + contentItems: object[]; + contentMeta: Meta; contentFilterValue: string; customSourceNameValue: string; clientIdValue: string; @@ -116,13 +116,13 @@ interface SourceValues { newCustomSource: CustomSource; currentServiceType: string; githubOrganizations: string[]; - selectedGithubOrganizationsMap: IObject; - selectedGithubOrganizations: IObject; + selectedGithubOrganizationsMap: object; + selectedGithubOrganizations: object; } interface SearchResultsResponse { - results: IObject[]; - meta: IMeta; + results: object[]; + meta: Meta; } interface PreContentSourceResponse { @@ -137,7 +137,7 @@ export const SourceLogic = kea>({ onUpdateSourceName: (name: string) => name, setSourceConfigData: (sourceConfigData: SourceConfigData) => sourceConfigData, setSourceConnectData: (sourceConnectData: SourceConnectData) => sourceConnectData, - onUpdateSummary: (summary: IObject[]) => summary, + onUpdateSummary: (summary: object[]) => summary, setFlashMessages: (flashMessages: IFlashMessagesProps) => ({ flashMessages }), setSearchResults: (searchResultsResponse: SearchResultsResponse) => searchResultsResponse, setContentFilterValue: (contentFilterValue: string) => contentFilterValue, @@ -153,7 +153,7 @@ export const SourceLogic = kea>({ setCustomSourceData: (data: CustomSource) => data, setPreContentSourceConfigData: (data: PreContentSourceResponse) => data, setSelectedGithubOrganizations: (option: string) => option, - initializeSource: (sourceId: string, history: IObject) => ({ sourceId, history }), + initializeSource: (sourceId: string, history: object) => ({ sourceId, history }), initializeFederatedSummary: (sourceId: string) => ({ sourceId }), searchContentSourceDocuments: (sourceId: string) => ({ sourceId }), updateContentSource: (sourceId: string, source: { name: string }) => ({ sourceId, source }), @@ -571,7 +571,7 @@ export const SourceLogic = kea>({ }), }); -const setPage = (state: IMeta, page: number) => ({ +const setPage = (state: Meta, page: number) => ({ ...state, page: { ...state.page, From c5f607635361df8a60144a2368b7427de15c0dc7 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 15:05:34 -0600 Subject: [PATCH 04/13] Remove internal flash messages in favor of globals - All instances of flashAPIErrors(e) are only placeholders until the later commit removing axios. - buttonLoading was set to false when the error flash messages were set. For now I added a `setButtonNotLoading` action to do this manually in a finally block. This will be refactored once axios is removed. - SourcesLogic is no longer needed because we set a queued flash message instead of trying to set it in SourcesLogic, which no longer has local flash messages --- .../views/content_sources/source_logic.ts | 89 +++++++++---------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 4650cf732fc34..9f784b93e163f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -11,21 +11,23 @@ import { kea, MakeLogicType } from 'kea'; import http from 'shared/http'; import routes from 'workplace_search/routes'; -import { handleAPIError } from 'app_search/utils/handleAPIError'; -import { IFlashMessagesProps } from 'shared/types'; +import { + flashAPIErrors, + setSuccessMessage, + setQueuedSuccessMessage, + FlashMessagesLogic, +} from '../../../shared/flash_messages'; + import { DEFAULT_META } from '../../../shared/constants'; import { AppLogic } from '../../app_logic'; import { NOT_FOUND_PATH } from '../../routes'; import { ContentSourceFullData, CustomSource, Meta } from '../../types'; -import { SourcesLogic } from './sources_logic'; - export interface SourceActions { onInitializeSource(contentSource: ContentSourceFullData): ContentSourceFullData; onUpdateSourceName(name: string): string; setSourceConfigData(sourceConfigData: SourceConfigData): SourceConfigData; setSourceConnectData(sourceConnectData: SourceConnectData): SourceConnectData; - setFlashMessages(flashMessages: IFlashMessagesProps): { flashMessages: IFlashMessagesProps }; setSearchResults(searchResultsResponse: SearchResultsResponse): SearchResultsResponse; initializeFederatedSummary(sourceId: string): { sourceId: string }; onUpdateSummary(summary: object[]): object[]; @@ -69,6 +71,7 @@ export interface SourceActions { ): { serviceType: string; successCallback(oauthUrl: string) }; getSourceReConnectData(serviceType: string): { serviceType: string }; getPreContentSourceConfigData(preContentSourceId: string): { preContentSourceId: string }; + setButtonNotLoading(): void; } interface SourceConfigData { @@ -96,7 +99,6 @@ interface SourceConnectData { interface SourceValues { contentSource: ContentSourceFullData; - flashMessages: IFlashMessagesProps; dataLoading: boolean; sectionLoading: boolean; buttonLoading: boolean; @@ -138,7 +140,6 @@ export const SourceLogic = kea>({ setSourceConfigData: (sourceConfigData: SourceConfigData) => sourceConfigData, setSourceConnectData: (sourceConnectData: SourceConnectData) => sourceConnectData, onUpdateSummary: (summary: object[]) => summary, - setFlashMessages: (flashMessages: IFlashMessagesProps) => ({ flashMessages }), setSearchResults: (searchResultsResponse: SearchResultsResponse) => searchResultsResponse, setContentFilterValue: (contentFilterValue: string) => contentFilterValue, setActivePage: (activePage: number) => activePage, @@ -178,6 +179,7 @@ export const SourceLogic = kea>({ errorCallback?: () => void ) => ({ serviceType, successCallback, errorCallback }), resetSourceState: () => true, + setButtonNotLoading: () => false, }, reducers: { contentSource: [ @@ -206,18 +208,6 @@ export const SourceLogic = kea>({ setSourceConnectData: (_, sourceConnectData) => sourceConnectData, }, ], - flashMessages: [ - {}, - { - setFlashMessages: (_, { flashMessages }) => flashMessages, - onUpdateSourceName: (_, name) => ({ success: [`Successfully changed name to ${name}`] }), - resetSourceState: () => ({}), - removeContentSource: () => ({}), - saveSourceConfig: () => ({}), - getSourceConnectData: () => ({}), - createContentSource: () => ({}), - }, - ], dataLoading: [ true, { @@ -230,7 +220,7 @@ export const SourceLogic = kea>({ buttonLoading: [ false, { - setFlashMessages: () => false, + setButtonNotLoading: () => false, setSourceConnectData: () => false, setSourceConfigData: () => false, resetSourceState: () => false, @@ -385,7 +375,7 @@ export const SourceLogic = kea>({ if (error.response.status === 404) { history.push(NOT_FOUND_PATH); } else { - handleAPIError((messages) => actions.setFlashMessages({ error: messages })); + flashAPIErrors(e); } }); }, @@ -395,7 +385,7 @@ export const SourceLogic = kea>({ http(route) .then(({ data }) => actions.onUpdateSummary(data.summary)) .catch(() => { - handleAPIError((messages) => actions.setFlashMessages({ error: messages })); + flashAPIErrors(e); }); }, searchContentSourceDocuments: async ({ sourceId }, breakpoint) => { @@ -414,7 +404,7 @@ export const SourceLogic = kea>({ http .post(route, { query, page }) .then(({ data }) => actions.setSearchResults(data)) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)); }, updateContentSource: ({ sourceId, source }) => { const { isOrganization } = AppLogic.values; @@ -425,9 +415,10 @@ export const SourceLogic = kea>({ http .patch(route, { content_source: source }) .then(({ data }) => actions.onUpdateSourceName(data.name)) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)); }, removeContentSource: ({ sourceId, successCallback }) => { + FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const route = isOrganization ? routes.fritoPieOrganizationContentSourcePath(sourceId) @@ -436,10 +427,11 @@ export const SourceLogic = kea>({ return http .delete(route) .then(({ data: { name } }) => { - SourcesLogic.actions.setFlashMessages({ success: [`Successfully deleted ${name}`] }); + setQueuedSuccessMessage(`Successfully deleted ${name}`); successCallback(); }) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)) + .finally(actions.setButtonNotLoading); }, getSourceConfigData: ({ serviceType }) => { const route = routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationPath( @@ -448,9 +440,10 @@ export const SourceLogic = kea>({ http(route) .then(({ data }) => actions.setSourceConfigData(data)) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)); }, getSourceConnectData: ({ serviceType, successCallback }) => { + FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const { subdomainValue: subdomain, indexPermissionsValue: indexPermissions } = values; @@ -467,7 +460,8 @@ export const SourceLogic = kea>({ actions.setSourceConnectData(data); successCallback(data.oauthUrl); }) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)) + .finally(actions.setButtonNotLoading); }, getSourceReConnectData: ({ serviceType }) => { const { isOrganization } = AppLogic.values; @@ -477,7 +471,7 @@ export const SourceLogic = kea>({ return http(route) .then(({ data }) => actions.setSourceConnectData(data)) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)); }, getPreContentSourceConfigData: ({ preContentSourceId }) => { const { isOrganization } = AppLogic.values; @@ -487,9 +481,10 @@ export const SourceLogic = kea>({ http(route) .then(({ data }) => actions.setPreContentSourceConfigData(data)) - .catch(handleAPIError((messages) => actions.setFlashMessages({ error: messages }))); + .catch(flashAPIErrors(e)); }, saveSourceConfig: ({ isUpdating, successCallback }) => { + FlashMessagesLogic.actions.clearFlashMessages(); const { sourceConfigData: { serviceType }, baseUrlValue, @@ -516,19 +511,18 @@ export const SourceLogic = kea>({ return http({ url: route, method, data: params }) .then(({ data }) => { - if (isUpdating) - actions.setFlashMessages({ success: ['Successfully updated configuration.'] }); + if (isUpdating) setSuccessMessage('Successfully updated configuration.'); actions.setSourceConfigData(data); if (successCallback) successCallback(); }) - .catch( - handleAPIError((messages) => { - actions.setFlashMessages({ error: messages }); - if (!isUpdating) throw new Error(messages[0]); - }) - ); + .catch((e) => { + flashAPIErrors(e); + if (!isUpdating) throw new Error(e); + }) + .finally(actions.setButtonNotLoading); }, createContentSource: ({ serviceType, successCallback, errorCallback }) => { + FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const route = isOrganization ? routes.formCreateFritoPieOrganizationContentSourcesPath() @@ -560,13 +554,18 @@ export const SourceLogic = kea>({ actions.setCustomSourceData(data); successCallback(); }) - .catch( - handleAPIError((messages) => { - actions.setFlashMessages({ error: messages }); - if (errorCallback) errorCallback(); - throw new Error('Auth Error'); - }) - ); + .catch((e) => { + flashAPIErrors(e); + if (errorCallback) errorCallback(); + throw new Error('Auth Error'); + }) + .finally(actions.setButtonNotLoading); + }, + onUpdateSourceName: (name: string) => { + setSuccessMessage(`Successfully changed name to ${name}`); + }, + resetSourceState: () => { + FlashMessagesLogic.actions.clearFlashMessages(); }, }), }); From ddb64a199256fc3126851ad718750e1dccc25a10 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 15:06:33 -0600 Subject: [PATCH 05/13] Add return types to callback definitions --- .../views/content_sources/source_logic.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 9f784b93e163f..51c61d4479e70 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -53,22 +53,22 @@ export interface SourceActions { removeContentSource( sourceId: string, successCallback: () => void - ): { sourceId: string; successCallback() }; + ): { sourceId: string; successCallback(): void }; createContentSource( serviceType: string, successCallback: () => void, errorCallback?: () => void - ): { serviceType: string; successCallback(); errorCallback?() }; + ): { serviceType: string; successCallback(): void; errorCallback?(): void }; saveSourceConfig( isUpdating: boolean, successCallback?: () => void - ): { isUpdating: boolean; successCallback?() }; + ): { isUpdating: boolean; successCallback?(): void }; initializeSource(sourceId: string, history: object): { sourceId: string; history: object }; getSourceConfigData(serviceType: string): { serviceType: string }; getSourceConnectData( serviceType: string, successCallback: (oauthUrl: string) => string - ): { serviceType: string; successCallback(oauthUrl: string) }; + ): { serviceType: string; successCallback(oauthUrl: string): void }; getSourceReConnectData(serviceType: string): { serviceType: string }; getPreContentSourceConfigData(preContentSourceId: string): { preContentSourceId: string }; setButtonNotLoading(): void; From 28b89422bd7dc177fcc6b8ffa6b70706b3d9b697 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 15:36:58 -0600 Subject: [PATCH 06/13] Update routes According to the API info getSourceReConnectData is supposed to send the source ID and not the service type. In the template, we are actually sending the ID but the logic file parameterizes it as serviceType. This is fixed here. Usage: https://github.com/elastic/ent-search/blob/master/app/javascript/workplace_search/ContentSources/components/AddSource/ReAuthenticate.tsx#L38 --- .../views/content_sources/source_logic.ts | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 51c61d4479e70..c04e6199ffd93 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -9,7 +9,6 @@ import { keys, pickBy } from 'lodash'; import { kea, MakeLogicType } from 'kea'; import http from 'shared/http'; -import routes from 'workplace_search/routes'; import { flashAPIErrors, @@ -69,7 +68,7 @@ export interface SourceActions { serviceType: string, successCallback: (oauthUrl: string) => string ): { serviceType: string; successCallback(oauthUrl: string): void }; - getSourceReConnectData(serviceType: string): { serviceType: string }; + getSourceReConnectData(sourceId: string): { sourceId: string }; getPreContentSourceConfigData(preContentSourceId: string): { preContentSourceId: string }; setButtonNotLoading(): void; } @@ -133,6 +132,9 @@ interface PreContentSourceResponse { githubOrganizations: string[]; } +const ACCOUNT_CREATE_SOURCE_ROUTE = '/api/workplace_search/account/create_source'; +const ORG_CREATE_SOURCE_ROUTE = '/api/workplace_search/org/create_source'; + export const SourceLogic = kea>({ actions: { onInitializeSource: (contentSource: ContentSourceFullData) => contentSource, @@ -167,7 +169,7 @@ export const SourceLogic = kea>({ serviceType, successCallback, }), - getSourceReConnectData: (serviceType: string) => ({ serviceType }), + getSourceReConnectData: (sourceId: string) => ({ sourceId }), getPreContentSourceConfigData: (preContentSourceId: string) => ({ preContentSourceId }), saveSourceConfig: (isUpdating: boolean, successCallback?: () => void) => ({ isUpdating, @@ -361,8 +363,8 @@ export const SourceLogic = kea>({ initializeSource: ({ sourceId, history }) => { const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationContentSourcePath(sourceId) - : routes.fritoPieAccountContentSourcePath(sourceId); + ? `/api/workplace_search/org/sources/${sourceId}` + : `/api/workplace_search/account/sources/${sourceId}`; http(route) .then(({ data }) => { @@ -380,7 +382,7 @@ export const SourceLogic = kea>({ }); }, initializeFederatedSummary: ({ sourceId }) => { - const route = routes.fritoPieAccountContentSourceFederatedSummaryPath(sourceId); + const route = `/api/workplace_search/org/sources/${sourceId}/federated_summary`; http(route) .then(({ data }) => actions.onUpdateSummary(data.summary)) @@ -393,8 +395,8 @@ export const SourceLogic = kea>({ const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationContentSourceDocumentsPath(sourceId) - : routes.fritoPieAccountContentSourceDocumentsPath(sourceId); + ? `/api/workplace_search/org/sources/${sourceId}/documents` + : `/api/workplace_search/account/sources/${sourceId}/documents`; const { contentFilterValue: query, @@ -409,8 +411,8 @@ export const SourceLogic = kea>({ updateContentSource: ({ sourceId, source }) => { const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationContentSourceSettingsPath(sourceId) - : routes.fritoPieAccountContentSourceSettingsPath(sourceId); + ? `/api/workplace_search/org/sources/${sourceId}/settings` + : `/api/workplace_search/account/sources/${sourceId}/settings`; http .patch(route, { content_source: source }) @@ -421,8 +423,8 @@ export const SourceLogic = kea>({ FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationContentSourcePath(sourceId) - : routes.fritoPieAccountContentSourcePath(sourceId); + ? `/api/workplace_search/org/sources/${sourceId}` + : `/api/workplace_search/account/sources/${sourceId}`; return http .delete(route) @@ -434,9 +436,7 @@ export const SourceLogic = kea>({ .finally(actions.setButtonNotLoading); }, getSourceConfigData: ({ serviceType }) => { - const route = routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationPath( - serviceType - ); + const route = `/api/workplace_search/org/settings/connectors/${serviceType}`; http(route) .then(({ data }) => actions.setSourceConfigData(data)) @@ -448,8 +448,8 @@ export const SourceLogic = kea>({ const { subdomainValue: subdomain, indexPermissionsValue: indexPermissions } = values; const route = isOrganization - ? routes.prepareFritoPieOrganizationContentSourcesPath(serviceType) - : routes.prepareFritoPieAccountContentSourcesPath(serviceType); + ? `/api/workplace_search/org/sources/${serviceType}/prepare` + : `/api/workplace_search/account/sources/${serviceType}/prepare`; const params = new URLSearchParams(); if (subdomain) params.append('subdomain', subdomain); @@ -463,11 +463,11 @@ export const SourceLogic = kea>({ .catch(flashAPIErrors(e)) .finally(actions.setButtonNotLoading); }, - getSourceReConnectData: ({ serviceType }) => { + getSourceReConnectData: ({ sourceId }) => { const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationContentSourceReauthPreparePath(serviceType) - : routes.fritoPieAccountContentSourceReauthPreparePath(serviceType); + ? `/api/workplace_search/org/sources/${sourceId}/reauth_prepare` + : `/api/workplace_search/account/sources/${sourceId}/reauth_prepare`; return http(route) .then(({ data }) => actions.setSourceConnectData(data)) @@ -476,8 +476,8 @@ export const SourceLogic = kea>({ getPreContentSourceConfigData: ({ preContentSourceId }) => { const { isOrganization } = AppLogic.values; const route = isOrganization - ? routes.fritoPieOrganizationPreContentSourcePath(preContentSourceId) - : routes.fritoPieAccountPreContentSourcePath(preContentSourceId); + ? `/api/workplace_search/org/pre_sources/${preContentSourceId}` + : `/api/workplace_search/account/pre_sources/${preContentSourceId}`; http(route) .then(({ data }) => actions.setPreContentSourceConfigData(data)) @@ -494,8 +494,8 @@ export const SourceLogic = kea>({ } = values; const route = isUpdating - ? routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationPath(serviceType) - : routes.fritoPieOrganizationSettingsContentSourceOauthConfigurationsPath(); + ? `/api/workplace_search/org/settings/connectors/${serviceType}` + : '/api/workplace_search/org/settings/connectors'; const method = isUpdating ? 'put' : 'post'; @@ -524,9 +524,7 @@ export const SourceLogic = kea>({ createContentSource: ({ serviceType, successCallback, errorCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; - const route = isOrganization - ? routes.formCreateFritoPieOrganizationContentSourcesPath() - : routes.formCreateFritoPieAccountContentSourcesPath(); + const route = isOrganization ? ORG_CREATE_SOURCE_ROUTE : ACCOUNT_CREATE_SOURCE_ROUTE; const { selectedGithubOrganizations: githubOrganizations, From e5a39cb5baffabad92bf73db5f3444d88da0b337 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 16:05:03 -0600 Subject: [PATCH 07/13] Replace axios with HttpLogic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also removes using history in favor of KibanaLogic’s navigateToUrl --- .../views/content_sources/source_logic.ts | 194 ++++++++++-------- 1 file changed, 107 insertions(+), 87 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index c04e6199ffd93..5a5d7dba0abe4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -8,7 +8,8 @@ import { keys, pickBy } from 'lodash'; import { kea, MakeLogicType } from 'kea'; -import http from 'shared/http'; +import { HttpLogic } from '../../../shared/http'; +import { KibanaLogic } from '../../../shared/kibana'; import { flashAPIErrors, @@ -360,35 +361,35 @@ export const SourceLogic = kea>({ ], }), listeners: ({ actions, values }) => ({ - initializeSource: ({ sourceId, history }) => { + initializeSource: async ({ sourceId }) => { const { isOrganization } = AppLogic.values; const route = isOrganization ? `/api/workplace_search/org/sources/${sourceId}` : `/api/workplace_search/account/sources/${sourceId}`; - http(route) - .then(({ data }) => { - actions.onInitializeSource(data); - if (data.isFederatedSource) { - actions.initializeFederatedSummary(sourceId); - } - }) - .catch((error) => { - if (error.response.status === 404) { - history.push(NOT_FOUND_PATH); - } else { - flashAPIErrors(e); - } - }); + try { + const response = await HttpLogic.values.http.get(route); + actions.onInitializeSource(response); + if (response.isFederatedSource) { + actions.initializeFederatedSummary(sourceId); + } + } catch (e) { + // TODO: Verify this works once components are there. Not sure if the catch gives a status code. + if (e.response.status === 404) { + KibanaLogic.values.navigateToUrl(NOT_FOUND_PATH); + } else { + flashAPIErrors(e); + } + } }, - initializeFederatedSummary: ({ sourceId }) => { + initializeFederatedSummary: async ({ sourceId }) => { const route = `/api/workplace_search/org/sources/${sourceId}/federated_summary`; - - http(route) - .then(({ data }) => actions.onUpdateSummary(data.summary)) - .catch(() => { - flashAPIErrors(e); - }); + try { + const response = await HttpLogic.values.http.get(route); + actions.onUpdateSummary(response.summary); + } catch (e) { + flashAPIErrors(e); + } }, searchContentSourceDocuments: async ({ sourceId }, breakpoint) => { await breakpoint(300); @@ -403,46 +404,57 @@ export const SourceLogic = kea>({ contentMeta: { page }, } = values; - http - .post(route, { query, page }) - .then(({ data }) => actions.setSearchResults(data)) - .catch(flashAPIErrors(e)); + try { + const response = await HttpLogic.values.http.post(route, { + body: JSON.stringify({ query, page }), + }); + actions.setSearchResults(response); + } catch (e) { + flashAPIErrors(e); + } }, - updateContentSource: ({ sourceId, source }) => { + updateContentSource: async ({ sourceId, source }) => { const { isOrganization } = AppLogic.values; const route = isOrganization ? `/api/workplace_search/org/sources/${sourceId}/settings` : `/api/workplace_search/account/sources/${sourceId}/settings`; - http - .patch(route, { content_source: source }) - .then(({ data }) => actions.onUpdateSourceName(data.name)) - .catch(flashAPIErrors(e)); + try { + const response = await HttpLogic.values.http.patch(route, { + body: JSON.stringify({ content_source: source }), + }); + actions.onUpdateSourceName(response.name); + } catch (e) { + flashAPIErrors(e); + } }, - removeContentSource: ({ sourceId, successCallback }) => { + removeContentSource: async ({ sourceId, successCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const route = isOrganization ? `/api/workplace_search/org/sources/${sourceId}` : `/api/workplace_search/account/sources/${sourceId}`; - return http - .delete(route) - .then(({ data: { name } }) => { - setQueuedSuccessMessage(`Successfully deleted ${name}`); - successCallback(); - }) - .catch(flashAPIErrors(e)) - .finally(actions.setButtonNotLoading); + try { + const response = await HttpLogic.values.http.delete(route); + setQueuedSuccessMessage(`Successfully deleted ${response.name}`); + successCallback(); + } catch (e) { + flashAPIErrors(e); + actions.setButtonNotLoading(); + } }, - getSourceConfigData: ({ serviceType }) => { + getSourceConfigData: async ({ serviceType }) => { const route = `/api/workplace_search/org/settings/connectors/${serviceType}`; - http(route) - .then(({ data }) => actions.setSourceConfigData(data)) - .catch(flashAPIErrors(e)); + try { + const response = await HttpLogic.values.http.get(route); + actions.setSourceConfigData(response); + } catch (e) { + flashAPIErrors(e); + } }, - getSourceConnectData: ({ serviceType, successCallback }) => { + getSourceConnectData: async ({ serviceType, successCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const { subdomainValue: subdomain, indexPermissionsValue: indexPermissions } = values; @@ -455,35 +467,42 @@ export const SourceLogic = kea>({ if (subdomain) params.append('subdomain', subdomain); if (indexPermissions) params.append('index_permissions', indexPermissions.toString()); - return http(`${route}?${params}`) - .then(({ data }) => { - actions.setSourceConnectData(data); - successCallback(data.oauthUrl); - }) - .catch(flashAPIErrors(e)) - .finally(actions.setButtonNotLoading); + try { + const response = await HttpLogic.values.http.get(`${route}?${params}`); + actions.setSourceConnectData(response); + successCallback(response.oauthUrl); + } catch (e) { + flashAPIErrors(e); + actions.setButtonNotLoading(); + } }, - getSourceReConnectData: ({ sourceId }) => { + getSourceReConnectData: async ({ sourceId }) => { const { isOrganization } = AppLogic.values; const route = isOrganization ? `/api/workplace_search/org/sources/${sourceId}/reauth_prepare` : `/api/workplace_search/account/sources/${sourceId}/reauth_prepare`; - return http(route) - .then(({ data }) => actions.setSourceConnectData(data)) - .catch(flashAPIErrors(e)); + try { + const response = await HttpLogic.values.http.get(route); + actions.setSourceConnectData(response); + } catch (e) { + flashAPIErrors(e); + } }, - getPreContentSourceConfigData: ({ preContentSourceId }) => { + getPreContentSourceConfigData: async ({ preContentSourceId }) => { const { isOrganization } = AppLogic.values; const route = isOrganization ? `/api/workplace_search/org/pre_sources/${preContentSourceId}` : `/api/workplace_search/account/pre_sources/${preContentSourceId}`; - http(route) - .then(({ data }) => actions.setPreContentSourceConfigData(data)) - .catch(flashAPIErrors(e)); + try { + const response = await HttpLogic.values.http.get(route); + actions.setPreContentSourceConfigData(response); + } catch (e) { + flashAPIErrors(e); + } }, - saveSourceConfig: ({ isUpdating, successCallback }) => { + saveSourceConfig: async ({ isUpdating, successCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { sourceConfigData: { serviceType }, @@ -497,7 +516,7 @@ export const SourceLogic = kea>({ ? `/api/workplace_search/org/settings/connectors/${serviceType}` : '/api/workplace_search/org/settings/connectors'; - const method = isUpdating ? 'put' : 'post'; + const http = isUpdating ? HttpLogic.values.http.put : HttpLogic.values.http.post; const params = { base_url: baseUrlValue || undefined, @@ -509,19 +528,20 @@ export const SourceLogic = kea>({ consumer_key: sourceConfigData.configuredFields?.consumerKey, }; - return http({ url: route, method, data: params }) - .then(({ data }) => { - if (isUpdating) setSuccessMessage('Successfully updated configuration.'); - actions.setSourceConfigData(data); - if (successCallback) successCallback(); - }) - .catch((e) => { - flashAPIErrors(e); - if (!isUpdating) throw new Error(e); - }) - .finally(actions.setButtonNotLoading); + try { + const response = await http(route, { + body: JSON.stringify({ params }), + }); + if (isUpdating) setSuccessMessage('Successfully updated configuration.'); + actions.setSourceConfigData(response); + if (successCallback) successCallback(); + } catch (e) { + flashAPIErrors(e); + actions.setButtonNotLoading(); + if (!isUpdating) throw new Error(e); + } }, - createContentSource: ({ serviceType, successCallback, errorCallback }) => { + createContentSource: async ({ serviceType, successCallback, errorCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; const route = isOrganization ? ORG_CREATE_SOURCE_ROUTE : ACCOUNT_CREATE_SOURCE_ROUTE; @@ -546,18 +566,18 @@ export const SourceLogic = kea>({ // Remove undefined values from params Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); - return http - .post(route, params) - .then(({ data }) => { - actions.setCustomSourceData(data); - successCallback(); - }) - .catch((e) => { - flashAPIErrors(e); - if (errorCallback) errorCallback(); - throw new Error('Auth Error'); - }) - .finally(actions.setButtonNotLoading); + try { + const response = await HttpLogic.values.http.post(route, { + body: JSON.stringify({ params }), + }); + actions.setCustomSourceData(response); + successCallback(); + } catch (e) { + flashAPIErrors(e); + actions.setButtonNotLoading(); + if (errorCallback) errorCallback(); + throw new Error('Auth Error'); + } }, onUpdateSourceName: (name: string) => { setSuccessMessage(`Successfully changed name to ${name}`); From d9b78dbd88056bbfd9e066ccb3313abaa58dbd86 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 16:14:15 -0600 Subject: [PATCH 08/13] Fix incorrect type This selector is actually an array of strings --- .../workplace_search/views/content_sources/source_logic.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 5a5d7dba0abe4..e1b7a649bc45a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -120,6 +120,7 @@ interface SourceValues { githubOrganizations: string[]; selectedGithubOrganizationsMap: object; selectedGithubOrganizations: object; + selectedGithubOrganizations: string[]; } interface SearchResultsResponse { From 783217957d273c6a14c75d9df21eff3252399ac9 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 16:16:43 -0600 Subject: [PATCH 09/13] Create GenericObject to satisfy TypeScript Previously in `ent-search`, we had a generic `IObject` interface that we could use on keyed objects. It was not migrated over since it uses `any` and Kibana has a generic `object` type we can use in most situations. However, when we are checking for keys in our code, `object` does not work. This commit is an attempt at making a generic interface we can use. --- .../public/applications/workplace_search/types.ts | 6 ++++++ .../views/content_sources/source_logic.ts | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index 1bd3cabb0227d..8b51a64006a2a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -163,3 +163,9 @@ export interface CustomSource { name: string; id: string; } + +export type AnyType = string | number | boolean | object | undefined | null; + +export interface GenericObject { + [key: string]: AnyType | AnyType[]; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index e1b7a649bc45a..26876bd8c99c6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -21,7 +21,7 @@ import { import { DEFAULT_META } from '../../../shared/constants'; import { AppLogic } from '../../app_logic'; import { NOT_FOUND_PATH } from '../../routes'; -import { ContentSourceFullData, CustomSource, Meta } from '../../types'; +import { ContentSourceFullData, CustomSource, Meta, GenericObject } from '../../types'; export interface SourceActions { onInitializeSource(contentSource: ContentSourceFullData): ContentSourceFullData; @@ -118,8 +118,7 @@ interface SourceValues { newCustomSource: CustomSource; currentServiceType: string; githubOrganizations: string[]; - selectedGithubOrganizationsMap: object; - selectedGithubOrganizations: object; + selectedGithubOrganizationsMap: GenericObject; selectedGithubOrganizations: string[]; } @@ -345,13 +344,13 @@ export const SourceLogic = kea>({ }, ], selectedGithubOrganizationsMap: [ - {}, + {} as GenericObject, { - setSelectedGithubOrganizations: (state, option) => ({ + setSelectedGithubOrganizations: (state: GenericObject, option) => ({ ...state, ...{ [option]: !state[option] }, }), - resetSourceState: () => [], + resetSourceState: () => ({}), }, ], }, @@ -562,7 +561,7 @@ export const SourceLogic = kea>({ password: passwordValue || undefined, organizations: githubOrganizations.length > 0 ? githubOrganizations : undefined, indexPermissions: indexPermissionsValue || undefined, - }; + } as GenericObject; // Remove undefined values from params Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); From 3cb5ad38f49d2f4b292b1e306af32b72eedf5d6d Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 16:35:19 -0600 Subject: [PATCH 10/13] More strict object typing Removes GenericObject from last commit and adds stricter local typing --- .../applications/workplace_search/types.ts | 6 ------ .../views/content_sources/source_logic.ts | 16 +++++++++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts index 8b51a64006a2a..1bd3cabb0227d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts @@ -163,9 +163,3 @@ export interface CustomSource { name: string; id: string; } - -export type AnyType = string | number | boolean | object | undefined | null; - -export interface GenericObject { - [key: string]: AnyType | AnyType[]; -} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 26876bd8c99c6..3096ec9e4d2e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -21,7 +21,7 @@ import { import { DEFAULT_META } from '../../../shared/constants'; import { AppLogic } from '../../app_logic'; import { NOT_FOUND_PATH } from '../../routes'; -import { ContentSourceFullData, CustomSource, Meta, GenericObject } from '../../types'; +import { ContentSourceFullData, CustomSource, Meta } from '../../types'; export interface SourceActions { onInitializeSource(contentSource: ContentSourceFullData): ContentSourceFullData; @@ -97,6 +97,10 @@ interface SourceConnectData { serviceType: string; } +interface OrganizationsMap { + [key: string]: string | boolean; +} + interface SourceValues { contentSource: ContentSourceFullData; dataLoading: boolean; @@ -118,7 +122,7 @@ interface SourceValues { newCustomSource: CustomSource; currentServiceType: string; githubOrganizations: string[]; - selectedGithubOrganizationsMap: GenericObject; + selectedGithubOrganizationsMap: OrganizationsMap; selectedGithubOrganizations: string[]; } @@ -344,9 +348,9 @@ export const SourceLogic = kea>({ }, ], selectedGithubOrganizationsMap: [ - {} as GenericObject, + {} as OrganizationsMap, { - setSelectedGithubOrganizations: (state: GenericObject, option) => ({ + setSelectedGithubOrganizations: (state, option) => ({ ...state, ...{ [option]: !state[option] }, }), @@ -561,7 +565,9 @@ export const SourceLogic = kea>({ password: passwordValue || undefined, organizations: githubOrganizations.length > 0 ? githubOrganizations : undefined, indexPermissions: indexPermissionsValue || undefined, - } as GenericObject; + } as { + [key: string]: string | string[] | undefined; + }; // Remove undefined values from params Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); From 70c5731ee4709419433abd6b84ea17a2985aae1b Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Tue, 17 Nov 2020 16:54:00 -0600 Subject: [PATCH 11/13] Add i18n Also added for already-merged SourcesLogic --- .../views/content_sources/source_logic.ts | 33 +++++++++++++++++-- .../views/content_sources/sources_logic.ts | 21 ++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 3096ec9e4d2e3..4e52379854d80 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -8,6 +8,8 @@ import { keys, pickBy } from 'lodash'; import { kea, MakeLogicType } from 'kea'; +import { i18n } from '@kbn/i18n'; + import { HttpLogic } from '../../../shared/http'; import { KibanaLogic } from '../../../shared/kibana'; @@ -441,7 +443,15 @@ export const SourceLogic = kea>({ try { const response = await HttpLogic.values.http.delete(route); - setQueuedSuccessMessage(`Successfully deleted ${response.name}`); + setQueuedSuccessMessage( + i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.flashMessages.contentSourceRemoved', + { + defaultMessage: 'Successfully deleted {sourceName}.', + values: { sourceName: response.name }, + } + ) + ); successCallback(); } catch (e) { flashAPIErrors(e); @@ -536,7 +546,16 @@ export const SourceLogic = kea>({ const response = await http(route, { body: JSON.stringify({ params }), }); - if (isUpdating) setSuccessMessage('Successfully updated configuration.'); + if (isUpdating) { + setSuccessMessage( + i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.flashMessages.contentSourceConfigUpdated', + { + defaultMessage: 'Successfully updated configuration.', + } + ) + ); + } actions.setSourceConfigData(response); if (successCallback) successCallback(); } catch (e) { @@ -586,7 +605,15 @@ export const SourceLogic = kea>({ } }, onUpdateSourceName: (name: string) => { - setSuccessMessage(`Successfully changed name to ${name}`); + setSuccessMessage( + i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.flashMessages.contentSourceNameChanged', + { + defaultMessage: 'Successfully changed name to {sourceName}.', + values: { sourceName: name }, + } + ) + ); }, resetSourceState: () => { FlashMessagesLogic.actions.clearFlashMessages(); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts index eacba312d5da6..5a8da7cd32fa8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts @@ -8,6 +8,8 @@ import { cloneDeep, findIndex } from 'lodash'; import { kea, MakeLogicType } from 'kea'; +import { i18n } from '@kbn/i18n'; + import { HttpLogic } from '../../../shared/http'; import { @@ -208,10 +210,25 @@ export const SourcesLogic = kea>( } }, setAddedSource: ({ addedSourceName, additionalConfiguration }) => { + const successfullyConnectedMessage = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.flashMessages.contentSourceConnected', + { + defaultMessage: 'Successfully connected {sourceName}.', + values: { sourceName: addedSourceName }, + } + ); + + const additionalConfigurationMessage = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sources.flashMessages.additionalConfigurationNeeded', + { + defaultMessage: 'This source requires additional configuration.', + } + ); + setSuccessMessage( [ - `Successfully connected ${addedSourceName}.`, - additionalConfiguration ? 'This source requires additional configuration.' : '', + successfullyConnectedMessage, + additionalConfiguration ? additionalConfigurationMessage : '', ].join(' ') ); }, From 4afbbefccf8e1b0605248e0740c7cd90ea1d21e1 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Wed, 18 Nov 2020 10:24:36 -0600 Subject: [PATCH 12/13] Move button loading action to finally block --- .../views/content_sources/source_logic.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 4e52379854d80..291343b4fb631 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -455,6 +455,7 @@ export const SourceLogic = kea>({ successCallback(); } catch (e) { flashAPIErrors(e); + } finally { actions.setButtonNotLoading(); } }, @@ -487,6 +488,7 @@ export const SourceLogic = kea>({ successCallback(response.oauthUrl); } catch (e) { flashAPIErrors(e); + } finally { actions.setButtonNotLoading(); } }, @@ -560,8 +562,9 @@ export const SourceLogic = kea>({ if (successCallback) successCallback(); } catch (e) { flashAPIErrors(e); - actions.setButtonNotLoading(); if (!isUpdating) throw new Error(e); + } finally { + actions.setButtonNotLoading(); } }, createContentSource: async ({ serviceType, successCallback, errorCallback }) => { @@ -599,9 +602,10 @@ export const SourceLogic = kea>({ successCallback(); } catch (e) { flashAPIErrors(e); - actions.setButtonNotLoading(); if (errorCallback) errorCallback(); throw new Error('Auth Error'); + } finally { + actions.setButtonNotLoading(); } }, onUpdateSourceName: (name: string) => { From 62c7d15aabb5d7519e2b4144948fbf4b4f699618 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Wed, 18 Nov 2020 10:25:37 -0600 Subject: [PATCH 13/13] Move route strings to inline --- .../workplace_search/views/content_sources/source_logic.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts index 291343b4fb631..889519b8a9985 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts @@ -139,9 +139,6 @@ interface PreContentSourceResponse { githubOrganizations: string[]; } -const ACCOUNT_CREATE_SOURCE_ROUTE = '/api/workplace_search/account/create_source'; -const ORG_CREATE_SOURCE_ROUTE = '/api/workplace_search/org/create_source'; - export const SourceLogic = kea>({ actions: { onInitializeSource: (contentSource: ContentSourceFullData) => contentSource, @@ -570,7 +567,9 @@ export const SourceLogic = kea>({ createContentSource: async ({ serviceType, successCallback, errorCallback }) => { FlashMessagesLogic.actions.clearFlashMessages(); const { isOrganization } = AppLogic.values; - const route = isOrganization ? ORG_CREATE_SOURCE_ROUTE : ACCOUNT_CREATE_SOURCE_ROUTE; + const route = isOrganization + ? '/api/workplace_search/org/create_source' + : '/api/workplace_search/account/create_source'; const { selectedGithubOrganizations: githubOrganizations,