Skip to content

Commit

Permalink
[Enterprise Search] Add Workplace Search side navigation (#74894)
Browse files Browse the repository at this point in the history
* Add routes

* Add version for use in doc link

* Set up basic router layout + WorkplaceSearchNav

* Update views to account for Layout

* Move version to common folder

* Fix version path

* Remove product button

No longer needed since we have all top-level app links in Kibana as a part of this PR

* You know, for search

* Remove comment

* Remove unused i18n properties from JSON

Tests were failing after removing component:
https://kibana-ci.elastic.co/job/elastic+kibana+pipeline-pull-request/67797/execution/node/382/log/

* Revert button and i18n copy  removal

This reverts commit ba05351.

* Move Overview out of layout to hide nav

For now, the route for groups was added to avoid having comment out the code. Will add the groups component in a future PR

* Revert layout changes to Overview

Since there is no nav, the padding was missing and the view looked off. Reverting to the 7.9, centered column view

* Remove extra Overview component

Was causing tests to fail

* Revert error state to use EuiPage

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
scottybollinger and elasticmachine authored Aug 14, 2020
1 parent 1626490 commit ac04e05
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 11 deletions.
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}`;

0 comments on commit ac04e05

Please sign in to comment.