[Stack Management] Converted to use KibanaPageTemplate (sort of) (#101335)

* Just replace the old wrapper and uses the `solutionNav` prop
* Examples of: Empty Page, Error state, Page Header, and Split Panel
This commit is contained in:
Caroline Horn 2021-06-08 11:25:52 -04:00 committed by GitHub
parent 08ff557ca6
commit 51e2da9630
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 793 additions and 820 deletions

View file

@ -598,7 +598,7 @@
"section": "def-public.ImAType",
"text": "ImAType"
},
", e?: string | undefined) => ",
", e: string | undefined) => ",
{
"pluginId": "pluginA",
"scope": "public",

View file

@ -28,3 +28,9 @@
.euiBody--collapsibleNavIsDocked .euiBottomBar {
margin-left: $euiCollapsibleNavWidth;
}
// Temporary fix for EuiPageHeader with a bottom border but no tabs or padding
// Will fix in EUI -- @cchaos
.euiPageHeader--bottomBorder:not(.euiPageHeader--tabsAtBottom):not([class*='euiPageHeader--padding']) {
padding-bottom: $euiSizeL;
}

View file

@ -269,6 +269,7 @@ export class AdvancedSettings extends Component<AdvancedSettingsProps, AdvancedS
dockLinks={this.props.dockLinks}
toasts={this.props.toasts}
trackUiMetric={this.props.trackUiMetric}
queryText={query.text}
/>
<PageFooter
toasts={this.props.toasts}

View file

@ -11,16 +11,16 @@ import React, { PureComponent, Fragment } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiForm,
EuiSplitPanel,
EuiLink,
EuiPanel,
EuiCallOut,
EuiSpacer,
EuiText,
EuiTextColor,
EuiBottomBar,
EuiButton,
EuiToolTip,
EuiButtonEmpty,
EuiTitle,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { isEmpty } from 'lodash';
@ -47,6 +47,7 @@ interface FormProps {
dockLinks: DocLinksStart['links'];
toasts: ToastsStart;
trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void;
queryText?: string;
}
interface FormState {
@ -241,17 +242,18 @@ export class Form extends PureComponent<FormProps> {
renderCategory(category: Category, settings: FieldSetting[], totalSettings: number) {
return (
<Fragment key={category}>
<EuiPanel paddingSize="l">
<EuiForm>
<EuiText>
<EuiFlexGroup alignItems="baseline">
<EuiFlexItem grow={false}>
<EuiSplitPanel.Outer hasBorder>
<EuiSplitPanel.Inner color="subdued">
<EuiFlexGroup alignItems="baseline">
<EuiFlexItem grow={false}>
<EuiTitle>
<h2>{getCategoryName(category)}</h2>
</EuiFlexItem>
{this.renderClearQueryLink(totalSettings, settings.length)}
</EuiFlexGroup>
</EuiText>
<EuiSpacer size="m" />
</EuiTitle>
</EuiFlexItem>
{this.renderClearQueryLink(totalSettings, settings.length)}
</EuiFlexGroup>
</EuiSplitPanel.Inner>
<EuiSplitPanel.Inner>
{settings.map((setting) => {
return (
<Field
@ -266,8 +268,8 @@ export class Form extends PureComponent<FormProps> {
/>
);
})}
</EuiForm>
</EuiPanel>
</EuiSplitPanel.Inner>
</EuiSplitPanel.Outer>
<EuiSpacer size="l" />
</Fragment>
);
@ -276,22 +278,28 @@ export class Form extends PureComponent<FormProps> {
maybeRenderNoSettings(clearQuery: FormProps['clearQuery']) {
if (this.props.showNoResultsMessage) {
return (
<EuiPanel paddingSize="l">
<FormattedMessage
id="advancedSettings.form.noSearchResultText"
defaultMessage="No settings found {clearSearch}"
values={{
clearSearch: (
<EuiLink onClick={clearQuery}>
<FormattedMessage
id="advancedSettings.form.clearNoSearchResultText"
defaultMessage="(clear search)"
/>
</EuiLink>
),
}}
/>
</EuiPanel>
<EuiCallOut
color="danger"
title={
<>
<FormattedMessage
id="advancedSettings.form.noSearchResultText"
defaultMessage="No settings found for {queryText} {clearSearch}"
values={{
clearSearch: (
<EuiLink onClick={clearQuery}>
<FormattedMessage
id="advancedSettings.form.clearNoSearchResultText"
defaultMessage="(clear search)"
/>
</EuiLink>
),
queryText: <strong>{this.props.queryText}</strong>,
}}
/>
</>
}
/>
);
}
return null;

View file

@ -8,15 +8,7 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiHorizontalRule,
EuiIcon,
EuiPageContent,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { EuiEmptyPrompt, EuiHorizontalRule, EuiPageContent } from '@elastic/eui';
interface ManagementLandingPageProps {
version: string;
@ -27,39 +19,37 @@ export const ManagementLandingPage = ({ version, setBreadcrumbs }: ManagementLan
setBreadcrumbs();
return (
<EuiPageContent horizontalPosition="center" data-test-subj="managementHome">
<div>
<div className="eui-textCenter">
<EuiIcon type="managementApp" size="xxl" />
<EuiSpacer />
<EuiTitle>
<h1>
<EuiPageContent verticalPosition="center" horizontalPosition="center" color="subdued">
<EuiEmptyPrompt
data-test-subj="managementHome"
iconType="managementApp"
title={
<h1>
<FormattedMessage
id="management.landing.header"
defaultMessage="Welcome to Stack Management {version}"
values={{ version }}
/>
</h1>
}
body={
<>
<p>
<FormattedMessage
id="management.landing.header"
defaultMessage="Welcome to Stack Management {version}"
values={{ version }}
id="management.landing.subhead"
defaultMessage="Manage your indices, index patterns, saved objects, Kibana settings, and more."
/>
</h1>
</EuiTitle>
<EuiText>
<FormattedMessage
id="management.landing.subhead"
defaultMessage="Manage your indices, index patterns, saved objects, Kibana settings, and more."
/>
</EuiText>
</div>
<EuiHorizontalRule />
<EuiText color="subdued" size="s" textAlign="center">
<p>
<FormattedMessage
id="management.landing.text"
defaultMessage="A complete list of apps is in the menu on the left."
/>
</p>
</EuiText>
</div>
</p>
<EuiHorizontalRule />
<p>
<FormattedMessage
id="management.landing.text"
defaultMessage="A complete list of apps is in the menu on the left."
/>
</p>
</>
}
/>
</EuiPageContent>
);
};

View file

@ -5,20 +5,23 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import './management_app.scss';
import React, { useState, useEffect, useCallback } from 'react';
import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from 'kibana/public';
import { I18nProvider } from '@kbn/i18n/react';
import { EuiPage } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { ManagementSection, MANAGEMENT_BREADCRUMB } from '../../utils';
import { ManagementRouter } from './management_router';
import { ManagementSidebarNav } from '../management_sidebar_nav';
import { reactRouterNavigate } from '../../../../kibana_react/public';
import { managementSidebarNav } from '../management_sidebar_nav/management_sidebar_nav';
import {
KibanaPageTemplate,
KibanaPageTemplateProps,
reactRouterNavigate,
} from '../../../../kibana_react/public';
import { SectionsServiceStart } from '../../types';
import './management_app.scss';
interface ManagementAppProps {
appBasePath: string;
history: AppMountParameters['history'];
@ -64,10 +67,30 @@ export const ManagementApp = ({ dependencies, history }: ManagementAppProps) =>
return null;
}
const solution: KibanaPageTemplateProps['solutionNav'] = {
name: i18n.translate('management.nav.label', {
defaultMessage: 'Management',
}),
icon: 'managementApp',
'data-test-subj': 'mgtSideBarNav',
items: managementSidebarNav({
selectedId,
sections,
history,
}),
};
return (
<I18nProvider>
<EuiPage>
<ManagementSidebarNav selectedId={selectedId} sections={sections} history={history} />
<KibanaPageTemplate
restrictWidth={false}
// EUI TODO
// The different template options need to be manually recreated by the individual pages.
// These classes help enforce the layouts.
pageContentProps={{ className: 'kbnAppWrapper' }}
pageContentBodyProps={{ className: 'kbnAppWrapper' }}
solutionNav={solution}
>
<ManagementRouter
history={history}
setBreadcrumbs={setBreadcrumbsScoped}
@ -75,7 +98,7 @@ export const ManagementApp = ({ dependencies, history }: ManagementAppProps) =>
sections={sections}
dependencies={dependencies}
/>
</EuiPage>
</KibanaPageTemplate>
</I18nProvider>
);
};

View file

@ -8,7 +8,6 @@
import React, { memo } from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { EuiPageBody } from '@elastic/eui';
import { AppMountParameters, ChromeBreadcrumb, ScopedHistory } from 'kibana/public';
import { ManagementAppWrapper } from '../management_app_wrapper';
import { ManagementLandingPage } from '../landing';
@ -26,36 +25,34 @@ interface ManagementRouterProps {
export const ManagementRouter = memo(
({ dependencies, history, setBreadcrumbs, onAppMounted, sections }: ManagementRouterProps) => (
<Router history={history}>
<EuiPageBody restrictWidth={false} className="mgtPage__body">
<Switch>
{sections.map((section) =>
section
.getAppsEnabled()
.map((app) => (
<Route
path={`${app.basePath}`}
component={() => (
<ManagementAppWrapper
app={app}
setBreadcrumbs={setBreadcrumbs}
onAppMounted={onAppMounted}
history={history}
/>
)}
/>
))
)}
<Route
path={'/'}
component={() => (
<ManagementLandingPage
version={dependencies.kibanaVersion}
setBreadcrumbs={setBreadcrumbs}
<Switch>
{sections.map((section) =>
section
.getAppsEnabled()
.map((app) => (
<Route
path={`${app.basePath}`}
component={() => (
<ManagementAppWrapper
app={app}
setBreadcrumbs={setBreadcrumbs}
onAppMounted={onAppMounted}
history={history}
/>
)}
/>
)}
/>
</Switch>
</EuiPageBody>
))
)}
<Route
path={'/'}
component={() => (
<ManagementLandingPage
version={dependencies.kibanaVersion}
setBreadcrumbs={setBreadcrumbs}
/>
)}
/>
</Switch>
</Router>
)
);

View file

@ -9,8 +9,10 @@
import React, { createRef, Component } from 'react';
import { ChromeBreadcrumb, AppMountParameters, ScopedHistory } from 'kibana/public';
import classNames from 'classnames';
import { ManagementApp } from '../../utils';
import { Unmount } from '../../types';
import { APP_WRAPPER_CLASS } from '../../../../../../src/core/public';
interface ManagementSectionWrapperProps {
app: ManagementApp;
@ -53,6 +55,12 @@ export class ManagementAppWrapper extends Component<ManagementSectionWrapperProp
}
render() {
return <div ref={this.mountElementRef} />;
return (
<div
// The following classes are a stop-gap for this element that wraps children of KibanaPageTemplate
className={classNames('euiPageContentBody', APP_WRAPPER_CLASS)}
ref={this.mountElementRef}
/>
);
}
}

View file

@ -6,4 +6,4 @@
* Side Public License, v 1.
*/
export { ManagementSidebarNav } from './management_sidebar_nav';
export { managementSidebarNav } from './management_sidebar_nav';

View file

@ -6,24 +6,13 @@
* Side Public License, v 1.
*/
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { sortBy } from 'lodash';
import {
EuiIcon,
EuiSideNav,
EuiScreenReaderOnly,
EuiSideNavItemType,
EuiFlexGroup,
EuiFlexItem,
EuiToolTip,
} from '@elastic/eui';
import { EuiIcon, EuiSideNavItemType, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { AppMountParameters } from 'kibana/public';
import { ManagementApp, ManagementSection } from '../../utils';
import './management_sidebar_nav.scss';
import { ManagementItem } from '../../utils/management_item';
import { reactRouterNavigate } from '../../../../kibana_react/public';
@ -33,24 +22,12 @@ interface ManagementSidebarNavProps {
selectedId: string;
}
const headerLabel = i18n.translate('management.nav.label', {
defaultMessage: 'Management',
});
const navMenuLabel = i18n.translate('management.nav.menu', {
defaultMessage: 'Management menu',
});
/** @internal **/
export const ManagementSidebarNav = ({
export const managementSidebarNav = ({
selectedId,
sections,
history,
}: ManagementSidebarNavProps) => {
const HEADER_ID = 'stack-management-nav-header';
const [isSideNavOpenOnMobile, setIsSideNavOpenOnMobile] = useState(false);
const toggleOpenOnMobile = () => setIsSideNavOpenOnMobile(!isSideNavOpenOnMobile);
const sectionsToNavItems = (managementSections: ManagementSection[]) => {
const sortedManagementSections = sortBy(managementSections, 'order');
@ -83,11 +60,11 @@ export const ManagementSidebarNav = ({
const TooltipWrapper = ({ text, tip }: TooltipWrapperProps) => (
<EuiToolTip content={tip} position="right">
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
<EuiFlexGroup alignItems="center" gutterSize="xs" responsive={false}>
<EuiFlexItem grow={false}>{text}</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiIcon type="questionInCircle" />
<EuiIcon color="subdued" size="s" type="questionInCircle" />
</EuiFlexItem>
</EuiFlexGroup>
</EuiToolTip>
@ -109,19 +86,5 @@ export const ManagementSidebarNav = ({
};
};
return (
<>
<EuiScreenReaderOnly>
<h2 id={HEADER_ID}>{headerLabel}</h2>
</EuiScreenReaderOnly>
<EuiSideNav
aria-labelledby={HEADER_ID}
mobileTitle={navMenuLabel}
toggleOpenOnMobile={toggleOpenOnMobile}
isOpenOnMobile={isSideNavOpenOnMobile}
items={sectionsToNavItems(sections)}
className="mgtSideBarNav"
/>
</>
);
return sectionsToNavItems(sections);
};

View file

@ -13,7 +13,7 @@ export class ManagementMenuService extends FtrService {
public async getSections() {
const sectionsElements = await this.find.allByCssSelector(
'.mgtSideBarNav > .euiSideNav__content > .euiSideNavItem'
'.kbnPageTemplateSolutionNav .euiSideNavItem--root'
);
const sections = [];

View file

@ -8,17 +8,7 @@
import React, { useEffect } from 'react';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiPageBody,
EuiPageContent,
EuiSpacer,
EuiTab,
EuiTabs,
EuiTitle,
} from '@elastic/eui';
import { EuiButtonEmpty, EuiPageHeader, EuiSpacer } from '@elastic/eui';
import { documentationService } from '../../services/documentation';
import { DataStreamList } from './data_stream_list';
import { IndexList } from './index_list';
@ -93,73 +83,59 @@ export const IndexManagementHome: React.FunctionComponent<RouteComponentProps<Ma
}, []);
return (
<EuiPageBody>
<EuiPageContent>
<EuiTitle size="l">
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={true}>
<h1 data-test-subj="appTitle">
<FormattedMessage
id="xpack.idxMgmt.home.appTitle"
defaultMessage="Index Management"
/>
</h1>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
href={documentationService.getIdxMgmtDocumentationLink()}
target="_blank"
iconType="help"
data-test-subj="documentationLink"
>
<FormattedMessage
id="xpack.idxMgmt.home.idxMgmtDocsLinkText"
defaultMessage="Index Management docs"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiTitle>
<>
<EuiPageHeader
pageTitle={
<span data-test-subj="appTitle">
<FormattedMessage id="xpack.idxMgmt.home.appTitle" defaultMessage="Index Management" />
</span>
}
bottomBorder
rightSideItems={[
<EuiButtonEmpty
href={documentationService.getIdxMgmtDocumentationLink()}
target="_blank"
iconType="help"
data-test-subj="documentationLink"
>
<FormattedMessage
id="xpack.idxMgmt.home.idxMgmtDocsLinkText"
defaultMessage="Index Management docs"
/>
</EuiButtonEmpty>,
]}
tabs={tabs.map((tab) => ({
onClick: () => onSectionChange(tab.id),
isSelected: tab.id === section,
key: tab.id,
'data-test-subj': `${tab.id}Tab`,
label: tab.name,
}))}
/>
<EuiSpacer size="m" />
<EuiSpacer size="l" />
<EuiTabs>
{tabs.map((tab) => (
<EuiTab
onClick={() => onSectionChange(tab.id)}
isSelected={tab.id === section}
key={tab.id}
data-test-subj={`${tab.id}Tab`}
>
{tab.name}
</EuiTab>
))}
</EuiTabs>
<EuiSpacer size="m" />
<Switch>
<Route
exact
path={[`/${Section.DataStreams}`, `/${Section.DataStreams}/:dataStreamName?`]}
component={DataStreamList}
/>
<Route exact path={`/${Section.Indices}`} component={IndexList} />
<Route
exact
path={[`/${Section.IndexTemplates}`, `/${Section.IndexTemplates}/:templateName?`]}
component={TemplateList}
/>
<Route
exact
path={[
`/${Section.ComponentTemplates}`,
`/${Section.ComponentTemplates}/:componentTemplateName?`,
]}
component={ComponentTemplateList}
/>
</Switch>
</EuiPageContent>
</EuiPageBody>
<Switch>
<Route
exact
path={[`/${Section.DataStreams}`, `/${Section.DataStreams}/:dataStreamName?`]}
component={DataStreamList}
/>
<Route exact path={`/${Section.Indices}`} component={IndexList} />
<Route
exact
path={[`/${Section.IndexTemplates}`, `/${Section.IndexTemplates}/:templateName?`]}
component={TemplateList}
/>
<Route
exact
path={[
`/${Section.ComponentTemplates}`,
`/${Section.ComponentTemplates}/:componentTemplateName?`,
]}
component={ComponentTemplateList}
/>
</Switch>
</>
);
};

View file

@ -34,6 +34,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import type { PublicMethodsOf } from '@kbn/utility-types';
import type { NotificationsStart } from 'src/core/public';
import { APP_WRAPPER_CLASS } from '../../../../../../../src/core/public';
import { SectionLoading } from '../../../../../../../src/plugins/es_ui_shared/public';
import { reactRouterNavigate } from '../../../../../../../src/plugins/kibana_react/public';
import type { ApiKey, ApiKeyToInvalidate } from '../../../../common/model';
@ -88,7 +89,7 @@ export class APIKeysGridPage extends Component<Props, State> {
public render() {
return (
<div>
<div className={APP_WRAPPER_CLASS}>
<Route path="/create">
<Breadcrumb
text={i18n.translate('xpack.security.management.apiKeys.createBreadcrumb', {
@ -157,7 +158,7 @@ export class APIKeysGridPage extends Component<Props, State> {
if (!areApiKeysEnabled) {
return (
<EuiPageContent>
<EuiPageContent verticalPosition="center" horizontalPosition="center" color="danger">
<NotEnabled />
</EuiPageContent>
);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { EuiEmptyPrompt, EuiLink } from '@elastic/eui';
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
@ -15,30 +15,35 @@ import { useKibana } from '../../../../../../../../src/plugins/kibana_react/publ
export const NotEnabled: React.FunctionComponent = () => {
const docLinks = useKibana().services.docLinks!;
return (
<EuiCallOut
<EuiEmptyPrompt
title={
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
defaultMessage="API keys not enabled in Elasticsearch"
/>
<h2>
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle"
defaultMessage="API keys not enabled in Elasticsearch"
/>
</h2>
}
color="danger"
iconType="alert"
>
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
values={{
link: (
<EuiLink href={`${docLinks.links.security.apiKeyServiceSettings}`} target="_blank">
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
defaultMessage="docs"
/>
</EuiLink>
),
}}
/>
</EuiCallOut>
body={
<p>
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription"
defaultMessage="Contact your system administrator and refer to the {link} to enable API keys."
values={{
link: (
<EuiLink href={`${docLinks.links.security.apiKeyServiceSettings}`} target="_blank">
<FormattedMessage
id="xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText"
defaultMessage="docs"
/>
</EuiLink>
),
}}
/>
</p>
}
/>
);
};

View file

@ -4,7 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
EuiButton,
EuiButtonIcon,
@ -14,15 +13,11 @@ import {
EuiInMemoryTable,
EuiLink,
EuiPageContent,
EuiPageContentBody,
EuiPageContentHeader,
EuiPageContentHeaderSection,
EuiPageHeader,
EuiSpacer,
EuiText,
EuiTitle,
EuiToolTip,
} from '@elastic/eui';
import React, { Component, Fragment } from 'react';
import React, { Component } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@ -129,49 +124,42 @@ export class RoleMappingsGridPage extends Component<Props, State> {
if (loadState === 'finished' && roleMappings && roleMappings.length === 0) {
return (
<EuiPageContent>
<EuiPageContent verticalPosition="center" horizontalPosition="center" color="subdued">
<EmptyPrompt history={this.props.history} />
</EuiPageContent>
);
}
return (
<EuiPageContent>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h2>
<FormattedMessage
id="xpack.security.management.roleMappings.roleMappingTitle"
defaultMessage="Role Mappings"
/>
</h2>
</EuiTitle>
<EuiText color="subdued" size="s">
<p>
<FormattedMessage
id="xpack.security.management.roleMappings.roleMappingDescription"
defaultMessage="Role mappings define which roles are assigned to users from an external identity provider. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink
href={this.props.docLinks.links.security.mappingRoles}
external={true}
target="_blank"
>
<FormattedMessage
id="xpack.security.management.roleMappings.learnMoreLinkText"
defaultMessage="Learn more."
/>
</EuiLink>
),
}}
/>
</p>
</EuiText>
</EuiPageContentHeaderSection>
<EuiPageContentHeaderSection>
<>
<EuiPageHeader
bottomBorder
pageTitle={
<FormattedMessage
id="xpack.security.management.roleMappings.roleMappingTitle"
defaultMessage="Role Mappings"
/>
}
description={
<FormattedMessage
id="xpack.security.management.roleMappings.roleMappingDescription"
defaultMessage="Role mappings define which roles are assigned to users from an external identity provider. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink href={this.props.docLinks.links.security.mappingRoles} external={true}>
<FormattedMessage
id="xpack.security.management.roleMappings.learnMoreLinkText"
defaultMessage="Learn more."
/>
</EuiLink>
),
}}
/>
}
rightSideItems={[
<EuiButton
fill
iconType="plusInCircleFilled"
data-test-subj="createRoleMappingButton"
{...reactRouterNavigate(this.props.history, EDIT_ROLE_MAPPING_PATH)}
>
@ -179,21 +167,20 @@ export class RoleMappingsGridPage extends Component<Props, State> {
id="xpack.security.management.roleMappings.createRoleMappingButtonLabel"
defaultMessage="Create role mapping"
/>
</EuiButton>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageContentBody>
<Fragment>
{!this.state.hasCompatibleRealms && (
<>
<NoCompatibleRealms />
<EuiSpacer />
</>
)}
{this.renderTable()}
</Fragment>
</EuiPageContentBody>
</EuiPageContent>
</EuiButton>,
]}
/>
<EuiSpacer size="l" />
{!this.state.hasCompatibleRealms && (
<>
<NoCompatibleRealms />
<EuiSpacer />
</>
)}
{this.renderTable()}
</>
);
}

View file

@ -114,7 +114,6 @@
"advancedSettings.form.cancelButtonLabel": "変更をキャンセル",
"advancedSettings.form.clearNoSearchResultText": " (検索結果を消去) ",
"advancedSettings.form.clearSearchResultText": " (検索結果を消去) ",
"advancedSettings.form.noSearchResultText": "設定が見つかりませんでした {clearSearch}",
"advancedSettings.form.requiresPageReloadToastButtonLabel": "ページを再読み込み",
"advancedSettings.form.requiresPageReloadToastDescription": "設定を有効にするためにページの再読み込みが必要です。",
"advancedSettings.form.saveButtonLabel": "変更を保存",
@ -3248,7 +3247,6 @@
"management.landing.subhead": "インデックス、インデックスパターン、保存されたオブジェクト、Kibanaの設定、その他を管理します。",
"management.landing.text": "アプリの一覧は左側のメニューにあります。",
"management.nav.label": "管理",
"management.nav.menu": "管理メニュー",
"management.sections.dataTip": "クラスターデータとバックアップを管理します",
"management.sections.dataTitle": "データ",
"management.sections.ingestTip": "データを変換し、クラスターに読み込む方法を管理します",
@ -4915,17 +4913,6 @@
"visTypeVislib.heatmap.metricTitle": "値",
"visTypeVislib.heatmap.segmentTitle": "X 軸",
"visTypeVislib.heatmap.splitTitle": "チャートを分割",
"visTypePie.pie.metricTitle": "スライスサイズ",
"visTypePie.pie.pieDescription": "全体に対する比率でデータを比較します。",
"visTypePie.pie.pieTitle": "円",
"visTypePie.pie.segmentTitle": "スライスの分割",
"visTypePie.pie.splitTitle": "チャートを分割",
"visTypePie.editors.pie.donutLabel": "ドーナッツ",
"visTypePie.editors.pie.labelsSettingsTitle": "ラベル設定",
"visTypePie.editors.pie.pieSettingsTitle": "パイ設定",
"visTypePie.editors.pie.showLabelsLabel": "ラベルを表示",
"visTypePie.editors.pie.showTopLevelOnlyLabel": "トップレベルのみ表示",
"visTypePie.editors.pie.showValuesLabel": "値を表示",
"visTypeVislib.vislib.errors.noResultsFoundTitle": "結果が見つかりませんでした",
"visTypeVislib.vislib.heatmap.maxBucketsText": "定義された数列が多すぎます ({nr}) 。構成されている最大値は {max} です。",
"visTypeVislib.vislib.legend.filterForValueButtonAriaLabel": "値 {legendDataLabel} でフィルタリング",
@ -4937,8 +4924,56 @@
"visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}、トグルオプション",
"visTypeVislib.vislib.tooltip.fieldLabel": "フィールド",
"visTypeVislib.vislib.tooltip.valueLabel": "値",
"visTypePie.pie.metricTitle": "スライスサイズ",
"visTypePie.pie.pieDescription": "全体に対する比率でデータを比較します。",
"visTypePie.pie.pieTitle": "円",
"visTypePie.pie.segmentTitle": "スライスの分割",
"visTypePie.pie.splitTitle": "チャートを分割",
"visTypePie.editors.pie.donutLabel": "ドーナッツ",
"visTypePie.editors.pie.labelsSettingsTitle": "ラベル設定",
"visTypePie.editors.pie.pieSettingsTitle": "パイ設定",
"visTypePie.editors.pie.showLabelsLabel": "ラベルを表示",
"visTypePie.editors.pie.showTopLevelOnlyLabel": "トップレベルのみ表示",
"visTypePie.editors.pie.showValuesLabel": "値を表示",
"visualizations.advancedSettings.visualization.legacyChartsLibrary.description": "Visualizeでエリア、折れ線、棒グラフのレガシーグラフライブラリを有効にします。",
"visualizations.advancedSettings.visualization.legacyChartsLibrary.name": "レガシーグラフライブラリ",
"visualizations.advancedSettings.visualizeEnableLabsText": "ユーザーが実験的なビジュアライゼーションを作成、表示、編集できるようになります。無効の場合、\n ユーザーは本番準備が整ったビジュアライゼーションのみを利用できます。",
"visualizations.advancedSettings.visualizeEnableLabsTitle": "実験的なビジュアライゼーションを有効にする",
"visualizations.disabledLabVisualizationLink": "ドキュメンテーションを表示",
"visualizations.disabledLabVisualizationMessage": "ラボビジュアライゼーションを表示するには、高度な設定でラボモードをオンにしてください。",
"visualizations.disabledLabVisualizationTitle": "{title} はラボビジュアライゼーションです。",
"visualizations.displayName": "ビジュアライゼーション",
"visualizations.embeddable.placeholderTitle": "プレースホルダータイトル",
"visualizations.function.range.from.help": "範囲の開始",
"visualizations.function.range.help": "範囲オブジェクトを生成します",
"visualizations.function.range.to.help": "範囲の終了",
"visualizations.function.visDimension.accessor.help": "使用するデータセット内の列 (列インデックスまたは列名) ",
"visualizations.function.visDimension.error.accessor": "入力された列名は無効です。",
"visualizations.function.visDimension.format.help": "フォーマット",
"visualizations.function.visDimension.formatParams.help": "フォーマットパラメーター",
"visualizations.function.visDimension.help": "visConfig ディメンションオブジェクトを生成します",
"visualizations.initializeWithoutIndexPatternErrorMessage": "インデックスパターンなしで集約を初期化しようとしています",
"visualizations.newVisWizard.aggBasedGroupDescription": "クラシック Visualize ライブラリを使用して、アグリゲーションに基づいてグラフを作成します。",
"visualizations.newVisWizard.aggBasedGroupTitle": "アグリゲーションに基づく",
"visualizations.newVisWizard.chooseSourceTitle": "ソースの選択",
"visualizations.newVisWizard.experimentalTitle": "実験的",
"visualizations.newVisWizard.experimentalTooltip": "このビジュアライゼーションは今後のリリースで変更または削除される可能性があり、SLA のサポート対象になりません。",
"visualizations.newVisWizard.exploreOptionLinkText": "探索オプション",
"visualizations.newVisWizard.filterVisTypeAriaLabel": "ビジュアライゼーションのタイプでフィルタリング",
"visualizations.newVisWizard.goBackLink": "別のビジュアライゼーションを選択",
"visualizations.newVisWizard.helpTextAriaLabel": "タイプを選択してビジュアライゼーションの作成を始めましょう。ESC を押してこのモーダルを閉じます。Tab キーを押して次に進みます。",
"visualizations.newVisWizard.learnMoreText": "詳細について",
"visualizations.newVisWizard.newVisTypeTitle": "新規 {visTypeName}",
"visualizations.newVisWizard.readDocumentationLink": "ドキュメンテーションを表示",
"visualizations.newVisWizard.searchSelection.notFoundLabel": "一致インデックスまたは保存した検索が見つかりません。",
"visualizations.newVisWizard.searchSelection.savedObjectType.indexPattern": "インデックスパターン",
"visualizations.newVisWizard.searchSelection.savedObjectType.search": "保存検索",
"visualizations.newVisWizard.title": "新規ビジュアライゼーション",
"visualizations.newVisWizard.toolsGroupTitle": "ツール",
"visualizations.noResultsFoundTitle": "結果が見つかりませんでした",
"visualizations.savedObjectName": "ビジュアライゼーション",
"visualizations.savingVisualizationFailed.errorMsg": "ビジュアライゼーションの保存が失敗しました",
"visualizations.visualizationTypeInvalidMessage": "無効なビジュアライゼーションタイプ \"{visType}\"",
"visTypeXy.aggResponse.allDocsTitle": "すべてのドキュメント",
"visTypeXy.area.areaDescription": "軸と線の間のデータを強調します。",
"visTypeXy.area.areaTitle": "エリア",
@ -5060,43 +5095,6 @@
"visTypeXy.thresholdLine.style.dashedText": "鎖線",
"visTypeXy.thresholdLine.style.dotdashedText": "点線",
"visTypeXy.thresholdLine.style.fullText": "完全",
"visualizations.advancedSettings.visualizeEnableLabsText": "ユーザーが実験的なビジュアライゼーションを作成、表示、編集できるようになります。無効の場合、\n ユーザーは本番準備が整ったビジュアライゼーションのみを利用できます。",
"visualizations.advancedSettings.visualizeEnableLabsTitle": "実験的なビジュアライゼーションを有効にする",
"visualizations.disabledLabVisualizationLink": "ドキュメンテーションを表示",
"visualizations.disabledLabVisualizationMessage": "ラボビジュアライゼーションを表示するには、高度な設定でラボモードをオンにしてください。",
"visualizations.disabledLabVisualizationTitle": "{title} はラボビジュアライゼーションです。",
"visualizations.displayName": "ビジュアライゼーション",
"visualizations.embeddable.placeholderTitle": "プレースホルダータイトル",
"visualizations.function.range.from.help": "範囲の開始",
"visualizations.function.range.help": "範囲オブジェクトを生成します",
"visualizations.function.range.to.help": "範囲の終了",
"visualizations.function.visDimension.accessor.help": "使用するデータセット内の列 (列インデックスまたは列名) ",
"visualizations.function.visDimension.error.accessor": "入力された列名は無効です。",
"visualizations.function.visDimension.format.help": "フォーマット",
"visualizations.function.visDimension.formatParams.help": "フォーマットパラメーター",
"visualizations.function.visDimension.help": "visConfig ディメンションオブジェクトを生成します",
"visualizations.initializeWithoutIndexPatternErrorMessage": "インデックスパターンなしで集約を初期化しようとしています",
"visualizations.newVisWizard.aggBasedGroupDescription": "クラシック Visualize ライブラリを使用して、アグリゲーションに基づいてグラフを作成します。",
"visualizations.newVisWizard.aggBasedGroupTitle": "アグリゲーションに基づく",
"visualizations.newVisWizard.chooseSourceTitle": "ソースの選択",
"visualizations.newVisWizard.experimentalTitle": "実験的",
"visualizations.newVisWizard.experimentalTooltip": "このビジュアライゼーションは今後のリリースで変更または削除される可能性があり、SLA のサポート対象になりません。",
"visualizations.newVisWizard.exploreOptionLinkText": "探索オプション",
"visualizations.newVisWizard.filterVisTypeAriaLabel": "ビジュアライゼーションのタイプでフィルタリング",
"visualizations.newVisWizard.goBackLink": "別のビジュアライゼーションを選択",
"visualizations.newVisWizard.helpTextAriaLabel": "タイプを選択してビジュアライゼーションの作成を始めましょう。ESC を押してこのモーダルを閉じます。Tab キーを押して次に進みます。",
"visualizations.newVisWizard.learnMoreText": "詳細について",
"visualizations.newVisWizard.newVisTypeTitle": "新規 {visTypeName}",
"visualizations.newVisWizard.readDocumentationLink": "ドキュメンテーションを表示",
"visualizations.newVisWizard.searchSelection.notFoundLabel": "一致インデックスまたは保存した検索が見つかりません。",
"visualizations.newVisWizard.searchSelection.savedObjectType.indexPattern": "インデックスパターン",
"visualizations.newVisWizard.searchSelection.savedObjectType.search": "保存検索",
"visualizations.newVisWizard.title": "新規ビジュアライゼーション",
"visualizations.newVisWizard.toolsGroupTitle": "ツール",
"visualizations.noResultsFoundTitle": "結果が見つかりませんでした",
"visualizations.savedObjectName": "ビジュアライゼーション",
"visualizations.savingVisualizationFailed.errorMsg": "ビジュアライゼーションの保存が失敗しました",
"visualizations.visualizationTypeInvalidMessage": "無効なビジュアライゼーションタイプ \"{visType}\"",
"visualize.badge.readOnly.text": "読み取り専用",
"visualize.badge.readOnly.tooltip": "ビジュアライゼーションをライブラリに保存できません",
"visualize.byValue_pageHeading": "{originatingApp}アプリに埋め込まれた{chartType}タイプのビジュアライゼーション",

View file

@ -115,7 +115,6 @@
"advancedSettings.form.clearNoSearchResultText": " (清除搜索) ",
"advancedSettings.form.clearSearchResultText": " (清除搜索) ",
"advancedSettings.form.countOfSettingsChanged": "{unsavedCount} 个未保存{unsavedCount, plural, other {设置} }{hiddenCount, plural, =0 {} other {# 个已隐藏} }",
"advancedSettings.form.noSearchResultText": "未找到设置{clearSearch}",
"advancedSettings.form.requiresPageReloadToastButtonLabel": "重新加载页面",
"advancedSettings.form.requiresPageReloadToastDescription": "一个或多个设置需要您重新加载页面才能生效。",
"advancedSettings.form.saveButtonLabel": "保存更改",
@ -3270,7 +3269,6 @@
"management.landing.subhead": "管理您的索引、索引模式、已保存对象、Kibana 设置等等。",
"management.landing.text": "应用的完整列表位于左侧菜单中。",
"management.nav.label": "管理",
"management.nav.menu": "管理菜单",
"management.sections.dataTip": "管理您的集群数据和备份",
"management.sections.dataTitle": "数据",
"management.sections.ingestTip": "管理如何转换数据并将其加载到集群中",
@ -4942,17 +4940,6 @@
"visTypeVislib.heatmap.metricTitle": "值",
"visTypeVislib.heatmap.segmentTitle": "X 轴",
"visTypeVislib.heatmap.splitTitle": "拆分图表",
"visTypePie.pie.metricTitle": "切片大小",
"visTypePie.pie.pieDescription": "以整体的比例比较数据。",
"visTypePie.pie.pieTitle": "饼图",
"visTypePie.pie.segmentTitle": "拆分切片",
"visTypePie.pie.splitTitle": "拆分图表",
"visTypePie.editors.pie.donutLabel": "圆环图",
"visTypePie.editors.pie.labelsSettingsTitle": "标签设置",
"visTypePie.editors.pie.pieSettingsTitle": "饼图设置",
"visTypePie.editors.pie.showLabelsLabel": "显示标签",
"visTypePie.editors.pie.showTopLevelOnlyLabel": "仅显示顶级",
"visTypePie.editors.pie.showValuesLabel": "显示值",
"visTypeVislib.vislib.errors.noResultsFoundTitle": "找不到结果",
"visTypeVislib.vislib.heatmap.maxBucketsText": "定义了过多的序列 ({nr})。配置的最大值为 {max}。",
"visTypeVislib.vislib.legend.filterForValueButtonAriaLabel": "筛留值 {legendDataLabel}",
@ -4964,8 +4951,57 @@
"visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}, 切换选项",
"visTypeVislib.vislib.tooltip.fieldLabel": "字段",
"visTypeVislib.vislib.tooltip.valueLabel": "值",
"visTypePie.pie.metricTitle": "切片大小",
"visTypePie.pie.pieDescription": "以整体的比例比较数据。",
"visTypePie.pie.pieTitle": "饼图",
"visTypePie.pie.segmentTitle": "拆分切片",
"visTypePie.pie.splitTitle": "拆分图表",
"visTypePie.editors.pie.donutLabel": "圆环图",
"visTypePie.editors.pie.labelsSettingsTitle": "标签设置",
"visTypePie.editors.pie.pieSettingsTitle": "饼图设置",
"visTypePie.editors.pie.showLabelsLabel": "显示标签",
"visTypePie.editors.pie.showTopLevelOnlyLabel": "仅显示顶级",
"visTypePie.editors.pie.showValuesLabel": "显示值",
"visualizations.advancedSettings.visualization.legacyChartsLibrary.description": "在 Visualize 中启用面积图、折线图和条形图的旧版图表库。",
"visualizations.advancedSettings.visualization.legacyChartsLibrary.name": "旧版图表库",
"visualizations.advancedSettings.visualizeEnableLabsText": "允许用户创建、查看和编辑实验性可视化。如果禁用,\n 仅被视为生产就绪的可视化可供用户使用。",
"visualizations.advancedSettings.visualizeEnableLabsTitle": "启用实验性可视化",
"visualizations.disabledLabVisualizationLink": "阅读文档",
"visualizations.disabledLabVisualizationMessage": "请在高级设置中打开实验模式,以查看实验性可视化。",
"visualizations.disabledLabVisualizationTitle": "{title} 为实验室可视化。",
"visualizations.displayName": "可视化",
"visualizations.embeddable.placeholderTitle": "占位符标题",
"visualizations.function.range.from.help": "范围起始",
"visualizations.function.range.help": "生成范围对象",
"visualizations.function.range.to.help": "范围结束",
"visualizations.function.visDimension.accessor.help": "要使用的数据集列 (列索引或列名称) ",
"visualizations.function.visDimension.error.accessor": "提供的列名称无效",
"visualizations.function.visDimension.format.help": "格式",
"visualizations.function.visDimension.formatParams.help": "格式参数",
"visualizations.function.visDimension.help": "生成 visConfig 维度对象",
"visualizations.initializeWithoutIndexPatternErrorMessage": "正在尝试在不使用索引模式的情况下初始化聚合",
"visualizations.newVisWizard.aggBasedGroupDescription": "使用我们的经典可视化库,基于聚合创建图表。",
"visualizations.newVisWizard.aggBasedGroupTitle": "基于聚合",
"visualizations.newVisWizard.chooseSourceTitle": "选择源",
"visualizations.newVisWizard.experimentalTitle": "实验性",
"visualizations.newVisWizard.experimentalTooltip": "未来版本可能会更改或删除此可视化,其不受支持 SLA 的约束。",
"visualizations.newVisWizard.exploreOptionLinkText": "浏览选项",
"visualizations.newVisWizard.filterVisTypeAriaLabel": "筛留可视化类型",
"visualizations.newVisWizard.goBackLink": "选择不同的可视化",
"visualizations.newVisWizard.helpTextAriaLabel": "通过为该可视化选择类型,开始创建您的可视化。按 Esc 键关闭此模式。按 Tab 键继续。",
"visualizations.newVisWizard.learnMoreText": "希望了解详情?",
"visualizations.newVisWizard.newVisTypeTitle": "新建{visTypeName}",
"visualizations.newVisWizard.readDocumentationLink": "阅读文档",
"visualizations.newVisWizard.resultsFound": "{resultCount, plural, other {类型}}已找到",
"visualizations.newVisWizard.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。",
"visualizations.newVisWizard.searchSelection.savedObjectType.indexPattern": "索引模式",
"visualizations.newVisWizard.searchSelection.savedObjectType.search": "已保存搜索",
"visualizations.newVisWizard.title": "新建可视化",
"visualizations.newVisWizard.toolsGroupTitle": "工具",
"visualizations.noResultsFoundTitle": "找不到结果",
"visualizations.savedObjectName": "可视化",
"visualizations.savingVisualizationFailed.errorMsg": "保存可视化失败",
"visualizations.visualizationTypeInvalidMessage": "无效的可视化类型“{visType}”",
"visTypeXy.aggResponse.allDocsTitle": "所有文档",
"visTypeXy.area.areaDescription": "突出轴与线之间的数据。",
"visTypeXy.area.areaTitle": "面积图",
@ -5087,44 +5123,6 @@
"visTypeXy.thresholdLine.style.dashedText": "虚线",
"visTypeXy.thresholdLine.style.dotdashedText": "点虚线",
"visTypeXy.thresholdLine.style.fullText": "实线",
"visualizations.advancedSettings.visualizeEnableLabsText": "允许用户创建、查看和编辑实验性可视化。如果禁用,\n 仅被视为生产就绪的可视化可供用户使用。",
"visualizations.advancedSettings.visualizeEnableLabsTitle": "启用实验性可视化",
"visualizations.disabledLabVisualizationLink": "阅读文档",
"visualizations.disabledLabVisualizationMessage": "请在高级设置中打开实验模式,以查看实验性可视化。",
"visualizations.disabledLabVisualizationTitle": "{title} 为实验室可视化。",
"visualizations.displayName": "可视化",
"visualizations.embeddable.placeholderTitle": "占位符标题",
"visualizations.function.range.from.help": "范围起始",
"visualizations.function.range.help": "生成范围对象",
"visualizations.function.range.to.help": "范围结束",
"visualizations.function.visDimension.accessor.help": "要使用的数据集列 (列索引或列名称) ",
"visualizations.function.visDimension.error.accessor": "提供的列名称无效",
"visualizations.function.visDimension.format.help": "格式",
"visualizations.function.visDimension.formatParams.help": "格式参数",
"visualizations.function.visDimension.help": "生成 visConfig 维度对象",
"visualizations.initializeWithoutIndexPatternErrorMessage": "正在尝试在不使用索引模式的情况下初始化聚合",
"visualizations.newVisWizard.aggBasedGroupDescription": "使用我们的经典可视化库,基于聚合创建图表。",
"visualizations.newVisWizard.aggBasedGroupTitle": "基于聚合",
"visualizations.newVisWizard.chooseSourceTitle": "选择源",
"visualizations.newVisWizard.experimentalTitle": "实验性",
"visualizations.newVisWizard.experimentalTooltip": "未来版本可能会更改或删除此可视化,其不受支持 SLA 的约束。",
"visualizations.newVisWizard.exploreOptionLinkText": "浏览选项",
"visualizations.newVisWizard.filterVisTypeAriaLabel": "筛留可视化类型",
"visualizations.newVisWizard.goBackLink": "选择不同的可视化",
"visualizations.newVisWizard.helpTextAriaLabel": "通过为该可视化选择类型,开始创建您的可视化。按 Esc 键关闭此模式。按 Tab 键继续。",
"visualizations.newVisWizard.learnMoreText": "希望了解详情?",
"visualizations.newVisWizard.newVisTypeTitle": "新建{visTypeName}",
"visualizations.newVisWizard.readDocumentationLink": "阅读文档",
"visualizations.newVisWizard.resultsFound": "{resultCount, plural, other {类型}}已找到",
"visualizations.newVisWizard.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。",
"visualizations.newVisWizard.searchSelection.savedObjectType.indexPattern": "索引模式",
"visualizations.newVisWizard.searchSelection.savedObjectType.search": "已保存搜索",
"visualizations.newVisWizard.title": "新建可视化",
"visualizations.newVisWizard.toolsGroupTitle": "工具",
"visualizations.noResultsFoundTitle": "找不到结果",
"visualizations.savedObjectName": "可视化",
"visualizations.savingVisualizationFailed.errorMsg": "保存可视化失败",
"visualizations.visualizationTypeInvalidMessage": "无效的可视化类型“{visType}”",
"visualize.badge.readOnly.text": "只读",
"visualize.badge.readOnly.tooltip": "无法将可视化保存到库",
"visualize.byValue_pageHeading": "已嵌入到 {originatingApp} 应用中的 {chartType} 类型可视化",