diff --git a/x-pack/plugins/enterprise_search/common/version.ts b/x-pack/plugins/enterprise_search/common/version.ts new file mode 100644 index 00000000000000..e29ad8a9f866b9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/common/version.ts @@ -0,0 +1,11 @@ +/* + * 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 { SemVer } from 'semver'; +import pkg from '../../../../package.json'; + +export const CURRENT_VERSION = new SemVer(pkg.version as string); +export const CURRENT_MAJOR_VERSION = CURRENT_VERSION.major; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx index e1114986d22446..53f3a7a274429e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +// TODO: Remove EuiPage & EuiPageBody before exposing full app + import React from 'react'; import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/index.ts new file mode 100644 index 00000000000000..41861a8ee2dc50 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/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 { WorkplaceSearchNav } from './nav'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx new file mode 100644 index 00000000000000..0e85d8467cff0d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx @@ -0,0 +1,22 @@ +/* + * 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 '../../../__mocks__/shallow_usecontext.mock'; +import React from 'react'; +import { shallow } from 'enzyme'; + +import { SideNav, SideNavLink } from '../../../shared/layout'; +import { WorkplaceSearchNav } from './'; + +describe('WorkplaceSearchNav', () => { + it('renders', () => { + const wrapper = shallow(); + + expect(wrapper.find(SideNav)).toHaveLength(1); + expect(wrapper.find(SideNavLink).first().prop('to')).toEqual('/'); + expect(wrapper.find(SideNavLink).last().prop('to')).toEqual('http://localhost:3002/ws/search'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx new file mode 100644 index 00000000000000..8f8edc61620ab6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx @@ -0,0 +1,74 @@ +/* + * 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, { useContext } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { EuiSpacer } from '@elastic/eui'; + +import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; +import { KibanaContext, IKibanaContext } from '../../../index'; +import { SideNav, SideNavLink } from '../../../shared/layout'; + +import { + ORG_SOURCES_PATH, + SOURCES_PATH, + SECURITY_PATH, + ROLE_MAPPINGS_PATH, + GROUPS_PATH, + ORG_SETTINGS_PATH, +} from '../../routes'; + +export const WorkplaceSearchNav: React.FC = () => { + const { enterpriseSearchUrl } = useContext(KibanaContext) as IKibanaContext; + const legacyUrl = (path: string) => `${enterpriseSearchUrl}/ws#${path}`; + + // TODO: icons + return ( + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.overview', { + defaultMessage: 'Overview', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.sources', { + defaultMessage: 'Sources', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.groups', { + defaultMessage: 'Groups', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.roleMappings', { + defaultMessage: 'Role Mappings', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.security', { + defaultMessage: 'Security', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.settings', { + defaultMessage: 'Settings', + })} + + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.personalDashboard', { + defaultMessage: 'View my personal dashboard', + })} + + + {i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.search', { + defaultMessage: 'Go to search application', + })} + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx index 2c3e78b404d42a..b816eb29732079 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +// TODO: Remove EuiPage & EuiPageBody before exposing full app + import React, { useContext, useEffect } from 'react'; import { EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx index 743080d965c36c..a4af405247f835 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx @@ -15,7 +15,7 @@ import { Overview } from './components/overview'; import { WorkplaceSearch } from './'; -describe('Workplace Search Routes', () => { +describe('Workplace Search', () => { describe('/', () => { it('redirects to Setup Guide when enterpriseSearchUrl is not set', () => { (useContext as jest.Mock).mockImplementationOnce(() => ({ enterpriseSearchUrl: '' })); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index cfa70ea29eca84..6470a3b78c5f1e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -5,7 +5,7 @@ */ import React, { useContext } from 'react'; -import { Route, Redirect } from 'react-router-dom'; +import { Route, Redirect, Switch } from 'react-router-dom'; import { Provider } from 'react-redux'; import { Store } from 'redux'; import { getContext, resetContext } from 'kea'; @@ -15,6 +15,8 @@ resetContext({ createStore: true }); const store = getContext().store as Store; import { KibanaContext, IKibanaContext } from '../index'; +import { Layout } from '../shared/layout'; +import { WorkplaceSearchNav } from './components/layout/nav'; import { SETUP_GUIDE_PATH } from './routes'; @@ -23,14 +25,39 @@ import { Overview } from './components/overview'; export const WorkplaceSearch: React.FC = () => { const { enterpriseSearchUrl } = useContext(KibanaContext) as IKibanaContext; + if (!enterpriseSearchUrl) + return ( + + + + + + + {/* Kibana displays a blank page on redirect if this isn't included */} + + + ); + return ( - - {!enterpriseSearchUrl ? : } - - - - + + + + + + + + + }> + + + {/* Will replace with groups component subsequent PR */} +
+ + + + + ); }; 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 d9798d1f30cfcc..993a1a378e7385 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 @@ -4,9 +4,107 @@ * you may not use this file except in compliance with the Elastic License. */ -export const ORG_SOURCES_PATH = '/org/sources'; -export const USERS_PATH = '/org/users'; -export const ORG_SETTINGS_PATH = '/org/settings'; +import { CURRENT_MAJOR_VERSION } from '../../../common/version'; + export const SETUP_GUIDE_PATH = '/setup_guide'; +export const LEAVE_FEEDBACK_EMAIL = 'support@elastic.co'; +export const LEAVE_FEEDBACK_URL = `mailto:${LEAVE_FEEDBACK_EMAIL}?Subject=Elastic%20Workplace%20Search%20Feedback`; + +export const DOCS_PREFIX = `https://www.elastic.co/guide/en/workplace-search/${CURRENT_MAJOR_VERSION}`; +export const ENT_SEARCH_DOCS_PREFIX = `https://www.elastic.co/guide/en/enterprise-search/${CURRENT_MAJOR_VERSION}`; +export const DOCUMENT_PERMISSIONS_DOCS_URL = `${DOCS_PREFIX}/workplace-search-sources-document-permissions.html`; +export const DOCUMENT_PERMISSIONS_SYNC_DOCS_URL = `${DOCUMENT_PERMISSIONS_DOCS_URL}#sources-permissions-synchronizing`; +export const PRIVATE_SOURCES_DOCS_URL = `${DOCUMENT_PERMISSIONS_DOCS_URL}#sources-permissions-org-private`; +export const EXTERNAL_IDENTITIES_DOCS_URL = `${DOCS_PREFIX}/workplace-search-external-identities-api.html`; +export const SECURITY_DOCS_URL = `${DOCS_PREFIX}/workplace-search-security.html`; +export const SMTP_DOCS_URL = `${DOCS_PREFIX}/workplace-search-smtp-mailer.html`; +export const CONFLUENCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-confluence-cloud-connector.html`; +export const CONFLUENCE_SERVER_DOCS_URL = `${DOCS_PREFIX}/workplace-search-confluence-server-connector.html`; +export const DROPBOX_DOCS_URL = `${DOCS_PREFIX}/workplace-search-dropbox-connector.html`; +export const GITHUB_DOCS_URL = `${DOCS_PREFIX}/workplace-search-github-connector.html`; +export const GITHUB_ENTERPRISE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-github-connector.html`; +export const GMAIL_DOCS_URL = `${DOCS_PREFIX}/workplace-search-gmail-connector.html`; +export const GOOGLE_DRIVE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-google-drive-connector.html`; +export const JIRA_DOCS_URL = `${DOCS_PREFIX}/workplace-search-jira-cloud-connector.html`; +export const JIRA_SERVER_DOCS_URL = `${DOCS_PREFIX}/workplace-search-jira-server-connector.html`; +export const ONE_DRIVE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-onedrive-connector.html`; +export const SALESFORCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-salesforce-connector.html`; +export const SERVICE_NOW_DOCS_URL = `${DOCS_PREFIX}/workplace-search-servicenow-connector.html`; +export const SHARE_POINT_DOCS_URL = `${DOCS_PREFIX}/workplace-search-sharepoint-online-connector.html`; +export const SLACK_DOCS_URL = `${DOCS_PREFIX}/workplace-search-slack-connector.html`; +export const ZENDESK_DOCS_URL = `${DOCS_PREFIX}/workplace-search-zendesk-connector.html`; +export const CUSTOM_SOURCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-api-sources.html`; +export const CUSTOM_API_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-sources-api.html`; +export const CUSTOM_API_DOCUMENT_PERMISSIONS_DOCS_URL = `${CUSTOM_SOURCE_DOCS_URL}#custom-api-source-document-level-access-control`; +export const ENT_SEARCH_LICENSE_MANAGEMENT = `${ENT_SEARCH_DOCS_PREFIX}/license-management.html`; + +export const ORG_PATH = '/org'; + +export const ROLE_MAPPINGS_PATH = `${ORG_PATH}/role-mappings`; +export const ROLE_MAPPING_PATH = `${ROLE_MAPPINGS_PATH}/:roleId`; +export const ROLE_MAPPING_NEW_PATH = `${ROLE_MAPPINGS_PATH}/new`; + +export const USERS_PATH = `${ORG_PATH}/users`; +export const SECURITY_PATH = `${ORG_PATH}/security`; + +export const GROUPS_PATH = `${ORG_PATH}/groups`; +export const GROUP_PATH = `${GROUPS_PATH}/:groupId`; +export const GROUP_SOURCE_PRIORITIZATION_PATH = `${GROUPS_PATH}/:groupId/source-prioritization`; + +export const SOURCES_PATH = '/sources'; +export const ORG_SOURCES_PATH = `${ORG_PATH}${SOURCES_PATH}`; + +export const SOURCE_ADDED_PATH = `${SOURCES_PATH}/added`; +export const ADD_SOURCE_PATH = `${SOURCES_PATH}/add`; +export const ADD_CONFLUENCE_PATH = `${SOURCES_PATH}/add/confluence-cloud`; +export const ADD_CONFLUENCE_SERVER_PATH = `${SOURCES_PATH}/add/confluence-server`; +export const ADD_DROPBOX_PATH = `${SOURCES_PATH}/add/dropbox`; +export const ADD_GITHUB_ENTERPRISE_PATH = `${SOURCES_PATH}/add/github-enterprise-server`; +export const ADD_GITHUB_PATH = `${SOURCES_PATH}/add/github`; +export const ADD_GMAIL_PATH = `${SOURCES_PATH}/add/gmail`; +export const ADD_GOOGLE_DRIVE_PATH = `${SOURCES_PATH}/add/google-drive`; +export const ADD_JIRA_PATH = `${SOURCES_PATH}/add/jira-cloud`; +export const ADD_JIRA_SERVER_PATH = `${SOURCES_PATH}/add/jira-server`; +export const ADD_ONE_DRIVE_PATH = `${SOURCES_PATH}/add/one-drive`; +export const ADD_SALESFORCE_PATH = `${SOURCES_PATH}/add/salesforce`; +export const ADD_SERVICE_NOW_PATH = `${SOURCES_PATH}/add/service-now`; +export const ADD_SHARE_POINT_PATH = `${SOURCES_PATH}/add/share-point`; +export const ADD_SLACK_PATH = `${SOURCES_PATH}/add/slack`; +export const ADD_ZENDESK_PATH = `${SOURCES_PATH}/add/zendesk`; +export const ADD_CUSTOM_PATH = `${SOURCES_PATH}/add/custom`; + +export const PERSONAL_SETTINGS_PATH = '/settings'; + +export const SOURCE_DETAILS_PATH = `${SOURCES_PATH}/:sourceId`; +export const SOURCE_CONTENT_PATH = `${SOURCES_PATH}/:sourceId/content`; +export const SOURCE_SCHEMAS_PATH = `${SOURCES_PATH}/:sourceId/schemas`; +export const SOURCE_DISPLAY_SETTINGS_PATH = `${SOURCES_PATH}/:sourceId/display-settings`; +export const SOURCE_SETTINGS_PATH = `${SOURCES_PATH}/:sourceId/settings`; +export const REINDEX_JOB_PATH = `${SOURCES_PATH}/:sourceId/schema-errors/:activeReindexJobId`; + +export const DISPLAY_SETTINGS_SEARCH_RESULT_PATH = `${SOURCE_DISPLAY_SETTINGS_PATH}/`; +export const DISPLAY_SETTINGS_RESULT_DETAIL_PATH = `${SOURCE_DISPLAY_SETTINGS_PATH}/result-detail`; + +export const ORG_SETTINGS_PATH = `${ORG_PATH}/settings`; +export const ORG_SETTINGS_CUSTOMIZE_PATH = `${ORG_SETTINGS_PATH}/customize`; +export const ORG_SETTINGS_CONNECTORS_PATH = `${ORG_SETTINGS_PATH}/connectors`; +export const ORG_SETTINGS_OAUTH_APPLICATION_PATH = `${ORG_SETTINGS_PATH}/oauth`; +export const EDIT_CONFLUENCE_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/confluence-cloud/edit`; +export const EDIT_CONFLUENCE_SERVER_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/confluence-server/edit`; +export const EDIT_DROPBOX_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/dropbox/edit`; +export const EDIT_GITHUB_ENTERPRISE_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/github-enterprise-server/edit`; +export const EDIT_GITHUB_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/github/edit`; +export const EDIT_GMAIL_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/gmail/edit`; +export const EDIT_GOOGLE_DRIVE_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/google-drive/edit`; +export const EDIT_JIRA_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/jira-cloud/edit`; +export const EDIT_JIRA_SERVER_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/jira-server/edit`; +export const EDIT_ONE_DRIVE_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/one-drive/edit`; +export const EDIT_SALESFORCE_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/salesforce/edit`; +export const EDIT_SERVICE_NOW_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/service-now/edit`; +export const EDIT_SHARE_POINT_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/share-point/edit`; +export const EDIT_SLACK_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/slack/edit`; +export const EDIT_ZENDESK_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/zendesk/edit`; +export const EDIT_CUSTOM_PATH = `${ORG_SETTINGS_CONNECTORS_PATH}/custom/edit`; + export const getSourcePath = (sourceId: string): string => `${ORG_SOURCES_PATH}/${sourceId}`;