Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enterprise Search] Add Workplace Search side navigation #74894

Merged
merged 17 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions x-pack/plugins/enterprise_search/common/version.ts
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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(<WorkplaceSearchNav />);

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');
});
});
Original file line number Diff line number Diff line change
@@ -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 (
<SideNav product={WORKPLACE_SEARCH_PLUGIN}>
<SideNavLink to="/" isRoot>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.overview', {
defaultMessage: 'Overview',
})}
</SideNavLink>
<SideNavLink isExternal to={legacyUrl(ORG_SOURCES_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.sources', {
defaultMessage: 'Sources',
})}
</SideNavLink>
<SideNavLink isExternal to={legacyUrl(GROUPS_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.groups', {
defaultMessage: 'Groups',
})}
</SideNavLink>
<SideNavLink isExternal to={legacyUrl(ROLE_MAPPINGS_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.roleMappings', {
defaultMessage: 'Role Mappings',
})}
</SideNavLink>
<SideNavLink isExternal to={legacyUrl(SECURITY_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.security', {
defaultMessage: 'Security',
})}
</SideNavLink>
<SideNavLink isExternal to={legacyUrl(ORG_SETTINGS_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.settings', {
defaultMessage: 'Settings',
})}
</SideNavLink>
<EuiSpacer />
<SideNavLink isExternal to={legacyUrl(SOURCES_PATH)}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.personalDashboard', {
defaultMessage: 'View my personal dashboard',
})}
</SideNavLink>
<SideNavLink isExternal to={`${enterpriseSearchUrl}/ws/search`}>
{i18n.translate('xpack.enterpriseSearch.workplaceSearch.nav.search', {
defaultMessage: 'Go to search application',
})}
</SideNavLink>
</SideNav>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: '' }));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';

Expand All @@ -23,14 +25,39 @@ import { Overview } from './components/overview';

export const WorkplaceSearch: React.FC = () => {
const { enterpriseSearchUrl } = useContext(KibanaContext) as IKibanaContext;
if (!enterpriseSearchUrl)
return (
<Switch>
<Route exact path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route>
<Redirect to={SETUP_GUIDE_PATH} />
<SetupGuide /> {/* Kibana displays a blank page on redirect if this isn't included */}
</Route>
</Switch>
);

return (
<Provider store={store}>
<Route exact path="/">
{!enterpriseSearchUrl ? <Redirect to={SETUP_GUIDE_PATH} /> : <Overview />}
</Route>
<Route path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Switch>
<Route path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route exact path="/">
<Overview />
</Route>
<Route>
<Layout navigation={<WorkplaceSearchNav />}>
<Switch>
<Route exact path="/groups">
{/* Will replace with groups component subsequent PR */}
<div />
</Route>
</Switch>
</Layout>
</Route>
</Switch>
</Provider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;