Skip to content

Commit

Permalink
[Fleet + Integrations UI] Migrate Fleet UI to new tabbed layout (#101828
Browse files Browse the repository at this point in the history
) (#102393)

* WIP: Migrate fleet to new page layout system

* Add 'Add Agent' button to agents table

* Fix flyout import in search and filter bar

* Place settings/feedback in header

* Move actions to top nav

* Fix i18n + types + unit test failures

* Remove unused props in DefaultLayout

* Fix background height in Fleet layout

This is fixed through a hack for now, because Kibana's layout doesn't
allow apps to flex the top-level wrapper via `flex: 1`. The same
behavior reported in the original issue (#101781) is present in all
other Kibana apps.

Fixes #101781

* Use euiHeaderHeightCompensation for min-height calc

* Move settings portal to app component

* Fix agent details URL in failing unit test

* Remove unreferenced overview files + update functional tests

* Remove unneeded fragment

* Remove beta badges in Fleet + Integrations

Fixes #100731

* Fix i18n

* Fix page path reference

* Fix failing tests

* Re-fix i18n post merge

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	x-pack/plugins/translations/translations/ja-JP.json
#	x-pack/plugins/translations/translations/zh-CN.json
  • Loading branch information
kpollich committed Jun 16, 2021
1 parent 5482a70 commit 49cc723
Show file tree
Hide file tree
Showing 44 changed files with 421 additions and 1,242 deletions.
10 changes: 2 additions & 8 deletions x-pack/plugins/fleet/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@
"server": true,
"ui": true,
"configPath": ["xpack", "fleet"],
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects"],
"optionalPlugins": [
"security",
"features",
"cloud",
"usageCollection",
"home"
],
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation"],
"optionalPlugins": ["security", "features", "cloud", "usageCollection", "home"],
"extraPublicDirs": ["common"],
"requiredBundles": ["kibanaReact", "esUiShared", "home", "infra", "kibanaUtils"]
}
129 changes: 88 additions & 41 deletions x-pack/plugins/fleet/public/applications/fleet/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React, { memo, useEffect, useState } from 'react';
import type { AppMountParameters } from 'kibana/public';
import { EuiCode, EuiEmptyPrompt, EuiErrorBoundary, EuiPanel } from '@elastic/eui';
import { EuiCode, EuiEmptyPrompt, EuiErrorBoundary, EuiPanel, EuiPortal } from '@elastic/eui';
import type { History } from 'history';
import { createHashHistory } from 'history';
import { Router, Redirect, Route, Switch } from 'react-router-dom';
Expand All @@ -16,11 +16,13 @@ import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
import useObservable from 'react-use/lib/useObservable';

import type { TopNavMenuData } from 'src/plugins/navigation/public';

import type { FleetConfigType, FleetStartServices } from '../../plugin';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
import { EuiThemeProvider } from '../../../../../../src/plugins/kibana_react/common';

import { PackageInstallProvider } from '../integrations/hooks';
import { PackageInstallProvider, useUrlModal } from '../integrations/hooks';

import {
ConfigContext,
Expand All @@ -30,25 +32,25 @@ import {
sendGetPermissionsCheck,
sendSetup,
useBreadcrumbs,
useConfig,
useStartServices,
UIExtensionsContext,
} from './hooks';
import { Error, Loading } from './components';
import { Error, Loading, SettingFlyout } from './components';
import type { UIExtensionsStorage } from './types';

import { FLEET_ROUTING_PATHS } from './constants';
import { DefaultLayout, WithoutHeaderLayout } from './layouts';
import { AgentPolicyApp } from './sections/agent_policy';
import { DataStreamApp } from './sections/data_stream';
import { FleetApp } from './sections/agents';
import { IngestManagerOverview } from './sections/overview';
import { ProtectedRoute } from './index';
import { AgentsApp } from './sections/agents';
import { CreatePackagePolicyPage } from './sections/agent_policy/create_package_policy_page';
import { EnrollmentTokenListPage } from './sections/agents/enrollment_token_list_page';

const FEEDBACK_URL = 'https://ela.st/fleet-feedback';

const ErrorLayout = ({ children }: { children: JSX.Element }) => (
<EuiErrorBoundary>
<DefaultLayout showSettings={false}>
<DefaultLayout>
<WithoutHeaderLayout>{children}</WithoutHeaderLayout>
</DefaultLayout>
</EuiErrorBoundary>
Expand Down Expand Up @@ -233,37 +235,82 @@ export const FleetAppContext: React.FC<{
}
);

export const AppRoutes = memo(() => {
const { agents } = useConfig();
const FleetTopNav = memo(
({ setHeaderActionMenu }: { setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'] }) => {
const { getModalHref } = useUrlModal();
const services = useStartServices();

return (
<Switch>
<Route path={FLEET_ROUTING_PATHS.policies}>
<DefaultLayout section="agent_policy">
<AgentPolicyApp />
</DefaultLayout>
</Route>
<Route path={FLEET_ROUTING_PATHS.data_streams}>
<DefaultLayout section="data_stream">
<DataStreamApp />
</DefaultLayout>
</Route>
<ProtectedRoute path={FLEET_ROUTING_PATHS.fleet} isAllowed={agents.enabled}>
<DefaultLayout section="fleet">
<FleetApp />
</DefaultLayout>
</ProtectedRoute>
<Route exact path={FLEET_ROUTING_PATHS.overview}>
<DefaultLayout section="overview">
<IngestManagerOverview />
</DefaultLayout>
</Route>
<Route path={FLEET_ROUTING_PATHS.add_integration_to_policy}>
<DefaultLayout showNav={false}>
<CreatePackagePolicyPage />
</DefaultLayout>
</Route>
<Redirect to="/" />
</Switch>
);
});
const { TopNavMenu } = services.navigation.ui;

const topNavConfig: TopNavMenuData[] = [
{
label: i18n.translate('xpack.fleet.appNavigation.sendFeedbackButton', {
defaultMessage: 'Send Feedback',
}),
iconType: 'popout',
run: () => window.open(FEEDBACK_URL),
},

{
label: i18n.translate('xpack.fleet.appNavigation.settingsButton', {
defaultMessage: 'Fleet settings',
}),
iconType: 'gear',
run: () => (window.location.href = getModalHref('settings')),
},
];
return (
<TopNavMenu
appName={i18n.translate('xpack.fleet.appTitle', { defaultMessage: 'Fleet' })}
config={topNavConfig}
setMenuMountPoint={setHeaderActionMenu}
/>
);
}
);

export const AppRoutes = memo(
({ setHeaderActionMenu }: { setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'] }) => {
const { modal, setModal } = useUrlModal();

return (
<>
<FleetTopNav setHeaderActionMenu={setHeaderActionMenu} />

{modal === 'settings' && (
<EuiPortal>
<SettingFlyout
onClose={() => {
setModal(null);
}}
/>
</EuiPortal>
)}

<Switch>
<Route path={FLEET_ROUTING_PATHS.agents}>
<AgentsApp />
</Route>
<Route path={FLEET_ROUTING_PATHS.policies}>
<AgentPolicyApp />
</Route>
<Route path={FLEET_ROUTING_PATHS.enrollment_tokens}>
<EnrollmentTokenListPage />
</Route>
<Route path={FLEET_ROUTING_PATHS.data_streams}>
<DataStreamApp />
</Route>

{/* TODO: Move this route to the Integrations app */}
<Route path={FLEET_ROUTING_PATHS.add_integration_to_policy}>
<DefaultLayout>
<CreatePackagePolicyPage />
</DefaultLayout>
</Route>

<Redirect to={FLEET_ROUTING_PATHS.agents} />
</Switch>
</>
);
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface AdditionalBreadcrumbOptions {
type Breadcrumb = ChromeBreadcrumb & Partial<AdditionalBreadcrumbOptions>;

const BASE_BREADCRUMB: Breadcrumb = {
href: pagePathGetters.overview()[1],
href: pagePathGetters.base()[1],
text: i18n.translate('xpack.fleet.breadcrumbs.appTitle', {
defaultMessage: 'Fleet',
}),
Expand All @@ -38,15 +38,6 @@ const breadcrumbGetters: {
[key in Page]?: (values: DynamicPagePathValues) => Breadcrumb[];
} = {
base: () => [BASE_BREADCRUMB],
overview: () => [
BASE_BREADCRUMB,
{
text: i18n.translate('xpack.fleet.breadcrumbs.overviewPageTitle', {
defaultMessage: 'Overview',
}),
},
],

policies: () => [
BASE_BREADCRUMB,
{
Expand Down Expand Up @@ -122,40 +113,26 @@ const breadcrumbGetters: {
}),
},
],
fleet: () => [
BASE_BREADCRUMB,
{
text: i18n.translate('xpack.fleet.breadcrumbs.agentsPageTitle', {
defaultMessage: 'Agents',
}),
},
],
fleet_agent_list: () => [
agent_list: () => [
BASE_BREADCRUMB,
{
text: i18n.translate('xpack.fleet.breadcrumbs.agentsPageTitle', {
defaultMessage: 'Agents',
}),
},
],
fleet_agent_details: ({ agentHost }) => [
agent_details: ({ agentHost }) => [
BASE_BREADCRUMB,
{
href: pagePathGetters.fleet()[1],
href: pagePathGetters.agent_list({})[1],
text: i18n.translate('xpack.fleet.breadcrumbs.agentsPageTitle', {
defaultMessage: 'Agents',
}),
},
{ text: agentHost },
],
fleet_enrollment_tokens: () => [
enrollment_tokens: () => [
BASE_BREADCRUMB,
{
href: pagePathGetters.fleet()[1],
text: i18n.translate('xpack.fleet.breadcrumbs.agentsPageTitle', {
defaultMessage: 'Agents',
}),
},
{
text: i18n.translate('xpack.fleet.breadcrumbs.enrollmentTokensPageTitle', {
defaultMessage: 'Enrollment tokens',
Expand Down
7 changes: 5 additions & 2 deletions x-pack/plugins/fleet/public/applications/fleet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface FleetAppProps {
history: AppMountParameters['history'];
kibanaVersion: string;
extensions: UIExtensionsStorage;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
}
const FleetApp = ({
basepath,
Expand All @@ -45,6 +46,7 @@ const FleetApp = ({
history,
kibanaVersion,
extensions,
setHeaderActionMenu,
}: FleetAppProps) => {
return (
<FleetAppContext
Expand All @@ -56,15 +58,15 @@ const FleetApp = ({
extensions={extensions}
>
<WithPermissionsAndSetup>
<AppRoutes />
<AppRoutes setHeaderActionMenu={setHeaderActionMenu} />
</WithPermissionsAndSetup>
</FleetAppContext>
);
};

export function renderApp(
startServices: FleetStartServices,
{ element, appBasePath, history }: AppMountParameters,
{ element, appBasePath, history, setHeaderActionMenu }: AppMountParameters,
config: FleetConfigType,
kibanaVersion: string,
extensions: UIExtensionsStorage
Expand All @@ -77,6 +79,7 @@ export function renderApp(
history={history}
kibanaVersion={kibanaVersion}
extensions={extensions}
setHeaderActionMenu={setHeaderActionMenu}
/>,
element
);
Expand Down
Loading

0 comments on commit 49cc723

Please sign in to comment.