mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[fleet] Adjust unified integration view to have better UI controls (#114692)
* [fleet] Adjust Package Cards to horizontal layout * Fix responsive shifting * Addressing feedback * cleanup layout for integrations view * i18n * Fix type errors Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Dave Snider <dave.snider@gmail.com> Co-authored-by: Josh Dover <1813008+joshdover@users.noreply.github.com>
This commit is contained in:
parent
56a2e788ca
commit
864e6f1a74
10 changed files with 132 additions and 161 deletions
|
@ -42,6 +42,12 @@
|
|||
#app-fixed-viewport {
|
||||
top: $headerHeight;
|
||||
}
|
||||
|
||||
.kbnStickyMenu {
|
||||
position: sticky;
|
||||
max-height: calc(100vh - #{$headerHeight + $euiSize});
|
||||
top: $headerHeight + $euiSize;
|
||||
}
|
||||
}
|
||||
|
||||
.kbnBody {
|
||||
|
|
|
@ -5,20 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React, { memo } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiSpacer, EuiText, EuiLink } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import styled, { useTheme } from 'styled-components';
|
||||
|
||||
import type { EuiTheme } from 'src/plugins/kibana_react/common';
|
||||
|
||||
import { useLink } from '../../../hooks';
|
||||
import type { Section } from '../sections';
|
||||
|
||||
import { useLinks, useStartServices } from '../hooks';
|
||||
|
||||
import { WithHeaderLayout } from './';
|
||||
|
||||
interface Props {
|
||||
|
@ -26,45 +18,11 @@ interface Props {
|
|||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Illustration = styled(EuiImage)`
|
||||
margin-bottom: -77px;
|
||||
position: relative;
|
||||
top: -16px;
|
||||
width: 395px;
|
||||
`;
|
||||
|
||||
const Hero = styled.div`
|
||||
text-align: right;
|
||||
`;
|
||||
|
||||
const HeroImage = memo(() => {
|
||||
const { toSharedAssets } = useLinks();
|
||||
const theme = useTheme() as EuiTheme;
|
||||
const IS_DARK_THEME = theme.darkMode;
|
||||
|
||||
return (
|
||||
<Hero>
|
||||
<Illustration
|
||||
alt={i18n.translate('xpack.fleet.epm.illustrationAltText', {
|
||||
defaultMessage: 'Illustration of an integration',
|
||||
})}
|
||||
url={
|
||||
IS_DARK_THEME
|
||||
? toSharedAssets('illustration_integrations_darkmode.svg')
|
||||
: toSharedAssets('illustration_integrations_lightmode.svg')
|
||||
}
|
||||
/>
|
||||
</Hero>
|
||||
);
|
||||
});
|
||||
|
||||
export const DefaultLayout: React.FunctionComponent<Props> = memo(({ section, children }) => {
|
||||
const { getHref } = useLink();
|
||||
const { docLinks } = useStartServices();
|
||||
|
||||
return (
|
||||
<WithHeaderLayout
|
||||
rightColumn={<HeroImage />}
|
||||
leftColumn={
|
||||
<EuiFlexGroup direction="column" gutterSize="none" justifyContent="center">
|
||||
<EuiText>
|
||||
|
@ -79,20 +37,11 @@ export const DefaultLayout: React.FunctionComponent<Props> = memo(({ section, ch
|
|||
<EuiSpacer size="s" />
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="m" color="subdued">
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.epm.pageSubtitle"
|
||||
defaultMessage="Collect data from popular applications and services. To learn more about Integrations, view {link}"
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink target="_blank" href={docLinks.links.elasticStackGetStarted}>
|
||||
{i18n.translate('xpack.fleet.epm.pageSubtitleLinkText', {
|
||||
defaultMessage: 'Getting started with Elastic Stack',
|
||||
})}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
defaultMessage="Choose an integration to start collecting and analyzing your data"
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
|
|
@ -22,7 +22,7 @@ export default {
|
|||
type Args = Omit<PackageCardProps, 'status'> & { width: number };
|
||||
|
||||
const args: Args = {
|
||||
width: 250,
|
||||
width: 280,
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
name: 'beats',
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { EuiCard } from '@elastic/eui';
|
||||
import { EuiCard, EuiFlexItem, EuiBadge, EuiToolTip, EuiSpacer } from '@elastic/eui';
|
||||
|
||||
import { CardIcon } from '../../../../../components/package_icon';
|
||||
import type { IntegrationCardItem } from '../../../../../../common/types/models/epm';
|
||||
|
@ -16,10 +16,10 @@ import { RELEASE_BADGE_DESCRIPTION, RELEASE_BADGE_LABEL } from './release_badge'
|
|||
|
||||
export type PackageCardProps = IntegrationCardItem;
|
||||
|
||||
// adding the `href` causes EuiCard to use a `a` instead of a `button`
|
||||
// `a` tags use `euiLinkColor` which results in blueish Badge text
|
||||
// Min-height is roughly 3 lines of content.
|
||||
// This keeps the cards from looking overly unbalanced because of content differences.
|
||||
const Card = styled(EuiCard)`
|
||||
color: inherit;
|
||||
min-height: 127px;
|
||||
`;
|
||||
|
||||
export function PackageCard({
|
||||
|
@ -32,14 +32,28 @@ export function PackageCard({
|
|||
url,
|
||||
release,
|
||||
}: PackageCardProps) {
|
||||
const betaBadgeLabel = release && release !== 'ga' ? RELEASE_BADGE_LABEL[release] : undefined;
|
||||
const betaBadgeLabelTooltipContent =
|
||||
release && release !== 'ga' ? RELEASE_BADGE_DESCRIPTION[release] : undefined;
|
||||
let releaseBadge: React.ReactNode | null = null;
|
||||
|
||||
if (release && release !== 'ga') {
|
||||
releaseBadge = (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="xs" />
|
||||
<span>
|
||||
<EuiToolTip display="inlineBlock" content={RELEASE_BADGE_DESCRIPTION[release]}>
|
||||
<EuiBadge color="hollow">{RELEASE_BADGE_LABEL[release]}</EuiBadge>
|
||||
</EuiToolTip>
|
||||
</span>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
layout="horizontal"
|
||||
title={title || ''}
|
||||
titleSize="xs"
|
||||
description={description}
|
||||
hasBorder
|
||||
icon={
|
||||
<CardIcon
|
||||
icons={icons}
|
||||
|
@ -50,9 +64,9 @@ export function PackageCard({
|
|||
/>
|
||||
}
|
||||
href={url}
|
||||
betaBadgeLabel={betaBadgeLabel}
|
||||
betaBadgeTooltipContent={betaBadgeLabelTooltipContent}
|
||||
target={url.startsWith('http') || url.startsWith('https') ? '_blank' : undefined}
|
||||
/>
|
||||
>
|
||||
{releaseBadge}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { Fragment, useCallback, useState } from 'react';
|
||||
import type { ReactNode, FunctionComponent } from 'react';
|
||||
import React, { useCallback, useState, useRef, useEffect } from 'react';
|
||||
import {
|
||||
EuiFlexGrid,
|
||||
EuiFlexGroup,
|
||||
|
@ -20,7 +20,6 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { useStartServices } from '../../../../../hooks';
|
||||
import { Loading } from '../../../components';
|
||||
import { useLocalSearch, searchIdField } from '../../../hooks';
|
||||
|
||||
|
@ -31,7 +30,7 @@ import { PackageCard } from './package_card';
|
|||
export interface Props {
|
||||
isLoading?: boolean;
|
||||
controls?: ReactNode | ReactNode[];
|
||||
title: string;
|
||||
title?: string;
|
||||
list: IntegrationCardItem[];
|
||||
initialSearch?: string;
|
||||
setSelectedCategory: (category: string) => void;
|
||||
|
@ -40,7 +39,7 @@ export interface Props {
|
|||
callout?: JSX.Element | null;
|
||||
}
|
||||
|
||||
export function PackageListGrid({
|
||||
export const PackageListGrid: FunctionComponent<Props> = ({
|
||||
isLoading,
|
||||
controls,
|
||||
title,
|
||||
|
@ -50,9 +49,23 @@ export function PackageListGrid({
|
|||
setSelectedCategory,
|
||||
showMissingIntegrationMessage = false,
|
||||
callout,
|
||||
}: Props) {
|
||||
}) => {
|
||||
const [searchTerm, setSearchTerm] = useState(initialSearch || '');
|
||||
const localSearchRef = useLocalSearch(list);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
const [isSticky, setIsSticky] = useState(false);
|
||||
const [windowScrollY] = useState(window.scrollY);
|
||||
|
||||
useEffect(() => {
|
||||
const menuRefCurrent = menuRef.current;
|
||||
const onScroll = () => {
|
||||
if (menuRefCurrent) {
|
||||
setIsSticky(menuRefCurrent?.getBoundingClientRect().top < 110);
|
||||
}
|
||||
};
|
||||
window.addEventListener('scroll', onScroll);
|
||||
return () => window.removeEventListener('scroll', onScroll);
|
||||
}, [windowScrollY, isSticky]);
|
||||
|
||||
const onQueryChange = ({
|
||||
queryText: userInput,
|
||||
|
@ -71,7 +84,7 @@ export function PackageListGrid({
|
|||
setSearchTerm('');
|
||||
};
|
||||
|
||||
const controlsContent = <ControlsColumn title={title} controls={controls} />;
|
||||
const controlsContent = <ControlsColumn title={title} controls={controls} sticky={isSticky} />;
|
||||
let gridContent: JSX.Element;
|
||||
|
||||
if (isLoading || !localSearchRef.current) {
|
||||
|
@ -93,58 +106,68 @@ export function PackageListGrid({
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiFlexGroup alignItems="flexStart">
|
||||
<EuiFlexItem grow={1}>{controlsContent}</EuiFlexItem>
|
||||
<EuiFlexItem grow={3}>
|
||||
<EuiSearchBar
|
||||
query={searchTerm || undefined}
|
||||
box={{
|
||||
placeholder: i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', {
|
||||
defaultMessage: 'Search for integrations',
|
||||
}),
|
||||
incremental: true,
|
||||
}}
|
||||
onChange={onQueryChange}
|
||||
/>
|
||||
{callout ? (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
{callout}
|
||||
</>
|
||||
) : null}
|
||||
<EuiSpacer />
|
||||
{gridContent}
|
||||
{showMissingIntegrationMessage && (
|
||||
<>
|
||||
<EuiSpacer size="xxl" />
|
||||
<MissingIntegrationContent
|
||||
resetQuery={resetQuery}
|
||||
setSelectedCategory={setSelectedCategory}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<div ref={menuRef}>
|
||||
<EuiFlexGroup alignItems="flexStart" gutterSize="xl">
|
||||
<EuiFlexItem grow={1} className={isSticky ? 'kbnStickyMenu' : ''}>
|
||||
{controlsContent}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={5}>
|
||||
<EuiSearchBar
|
||||
query={searchTerm || undefined}
|
||||
box={{
|
||||
placeholder: i18n.translate('xpack.fleet.epmList.searchPackagesPlaceholder', {
|
||||
defaultMessage: 'Search for integrations',
|
||||
}),
|
||||
incremental: true,
|
||||
}}
|
||||
onChange={onQueryChange}
|
||||
/>
|
||||
{callout ? (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
{callout}
|
||||
</>
|
||||
) : null}
|
||||
<EuiSpacer />
|
||||
{gridContent}
|
||||
{showMissingIntegrationMessage && (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
<MissingIntegrationContent
|
||||
resetQuery={resetQuery}
|
||||
setSelectedCategory={setSelectedCategory}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
interface ControlsColumnProps {
|
||||
controls: ReactNode;
|
||||
title: string;
|
||||
title: string | undefined;
|
||||
sticky: boolean;
|
||||
}
|
||||
|
||||
function ControlsColumn({ controls, title }: ControlsColumnProps) {
|
||||
function ControlsColumn({ controls, title, sticky }: ControlsColumnProps) {
|
||||
let titleContent;
|
||||
if (title) {
|
||||
titleContent = (
|
||||
<>
|
||||
<EuiTitle size="s">
|
||||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="l" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiTitle size="s">
|
||||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={4}>{controls}</EuiFlexItem>
|
||||
<EuiFlexItem grow={1} />
|
||||
</EuiFlexGroup>
|
||||
</Fragment>
|
||||
<EuiFlexGroup direction="column" className={sticky ? 'kbnStickyMenu' : ''} gutterSize="none">
|
||||
{titleContent}
|
||||
{controls}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -196,20 +219,17 @@ function MissingIntegrationContent({
|
|||
resetQuery,
|
||||
setSelectedCategory,
|
||||
}: MissingIntegrationContentProps) {
|
||||
const {
|
||||
application: { getUrlForApp },
|
||||
} = useStartServices();
|
||||
const handleCustomInputsLinkClick = useCallback(() => {
|
||||
resetQuery();
|
||||
setSelectedCategory('custom');
|
||||
}, [resetQuery, setSelectedCategory]);
|
||||
|
||||
return (
|
||||
<EuiText>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.integrations.missing"
|
||||
defaultMessage="Don't see an integration? Collect any logs or metrics using our {customInputsLink}, or add data using {beatsTutorialLink}. Request new integrations using our {discussForumLink}."
|
||||
defaultMessage="Don't see an integration? Collect any logs or metrics using our {customInputsLink}. Request new integrations using our {discussForumLink}."
|
||||
values={{
|
||||
customInputsLink: (
|
||||
<EuiLink onClick={handleCustomInputsLinkClick}>
|
||||
|
@ -227,14 +247,6 @@ function MissingIntegrationContent({
|
|||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
beatsTutorialLink: (
|
||||
<EuiLink href={getUrlForApp('home', { path: '#/tutorial_directory' })}>
|
||||
<FormattedMessage
|
||||
id="xpack.fleet.integrations.beatsModulesLink"
|
||||
defaultMessage="Beats modules"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
import React, { memo, useMemo, useState } from 'react';
|
||||
import { useLocation, useHistory, useParams } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import _ from 'lodash';
|
||||
import { EuiHorizontalRule } from '@elastic/eui';
|
||||
import { EuiHorizontalRule, EuiFlexItem } from '@elastic/eui';
|
||||
|
||||
import { pagePathGetters } from '../../../../constants';
|
||||
import {
|
||||
|
@ -93,10 +92,6 @@ const packageListToIntegrationsList = (packages: PackageList): PackageList => {
|
|||
}, []);
|
||||
};
|
||||
|
||||
const title = i18n.translate('xpack.fleet.epmList.allTitle', {
|
||||
defaultMessage: 'Browse by category',
|
||||
});
|
||||
|
||||
// TODO: clintandrewhall - this component is hard to test due to the hooks, particularly those that use `http`
|
||||
// or `location` to load data. Ideally, we'll split this into "connected" and "pure" components.
|
||||
export const AvailablePackages: React.FC = memo(() => {
|
||||
|
@ -121,9 +116,7 @@ export const AvailablePackages: React.FC = memo(() => {
|
|||
|
||||
function setSearchTerm(search: string) {
|
||||
// Use .replace so the browser's back button is not tied to single keystroke
|
||||
history.replace(
|
||||
pagePathGetters.integrations_all({ category: selectedCategory, searchTerm: search })[1]
|
||||
);
|
||||
history.replace(pagePathGetters.integrations_all({ searchTerm: search })[1]);
|
||||
}
|
||||
|
||||
const { data: eprPackages, isLoading: isLoadingAllPackages } = useGetPackages({
|
||||
|
@ -186,20 +179,26 @@ export const AvailablePackages: React.FC = memo(() => {
|
|||
}
|
||||
|
||||
let controls = [
|
||||
<EuiHorizontalRule />,
|
||||
<IntegrationPreference initialType={preference} onChange={setPreference} />,
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
<IntegrationPreference initialType={preference} onChange={setPreference} />,
|
||||
</EuiFlexItem>,
|
||||
];
|
||||
|
||||
if (categories) {
|
||||
controls = [
|
||||
<CategoryFacets
|
||||
isLoading={isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations}
|
||||
categories={categories}
|
||||
selectedCategory={selectedCategory}
|
||||
onCategoryChange={({ id }) => {
|
||||
setSelectedCategory(id);
|
||||
}}
|
||||
/>,
|
||||
<EuiFlexItem className="eui-yScrollWithShadows">
|
||||
<CategoryFacets
|
||||
isLoading={
|
||||
isLoadingCategories || isLoadingAllPackages || isLoadingAppendCustomIntegrations
|
||||
}
|
||||
categories={categories}
|
||||
selectedCategory={selectedCategory}
|
||||
onCategoryChange={({ id }) => {
|
||||
setSelectedCategory(id);
|
||||
}}
|
||||
/>
|
||||
</EuiFlexItem>,
|
||||
...controls,
|
||||
];
|
||||
}
|
||||
|
@ -214,7 +213,6 @@ export const AvailablePackages: React.FC = memo(() => {
|
|||
return (
|
||||
<PackageListGrid
|
||||
isLoading={isLoadingAllPackages}
|
||||
title={title}
|
||||
controls={controls}
|
||||
initialSearch={searchParam}
|
||||
list={filteredCards}
|
||||
|
|
|
@ -21,7 +21,7 @@ export interface CategoryFacet {
|
|||
export const ALL_CATEGORY = {
|
||||
id: '',
|
||||
title: i18n.translate('xpack.fleet.epmList.allPackagesFilterLinkText', {
|
||||
defaultMessage: 'All',
|
||||
defaultMessage: 'All categories',
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ export const CardIcon: React.FunctionComponent<UsePackageIconType & Omit<EuiIcon
|
|||
) => {
|
||||
const { icons } = props;
|
||||
if (icons && icons.length === 1 && icons[0].type === 'eui') {
|
||||
return <EuiIcon size={'xl'} type={icons[0].src} />;
|
||||
return <EuiIcon size={'xl'} type={icons[0].src} {...props} />;
|
||||
} else if (icons && icons.length === 1 && icons[0].type === 'svg') {
|
||||
return <EuiIcon size={'xl'} type={icons[0].src} />;
|
||||
return <EuiIcon size={'xl'} type={icons[0].src} {...props} />;
|
||||
} else {
|
||||
return <PackageIcon {...props} />;
|
||||
}
|
||||
|
|
|
@ -10720,7 +10720,6 @@
|
|||
"xpack.fleet.epm.detailsTitle": "詳細",
|
||||
"xpack.fleet.epm.errorLoadingNotice": "NOTICE.txtの読み込みエラー",
|
||||
"xpack.fleet.epm.featuresLabel": "機能",
|
||||
"xpack.fleet.epm.illustrationAltText": "統合の例",
|
||||
"xpack.fleet.epm.install.packageInstallError": "{pkgName} {pkgVersion}のインストールエラー",
|
||||
"xpack.fleet.epm.install.packageUpdateError": "{pkgName} {pkgVersion}の更新エラー",
|
||||
"xpack.fleet.epm.licenseLabel": "ライセンス",
|
||||
|
@ -10755,7 +10754,6 @@
|
|||
"xpack.fleet.epm.usedByLabel": "エージェントポリシー",
|
||||
"xpack.fleet.epm.versionLabel": "バージョン",
|
||||
"xpack.fleet.epmList.allPackagesFilterLinkText": "すべて",
|
||||
"xpack.fleet.epmList.allTitle": "カテゴリで参照",
|
||||
"xpack.fleet.epmList.installedTitle": "インストールされている統合",
|
||||
"xpack.fleet.epmList.missingIntegrationPlaceholder": "検索用語と一致する統合が見つかりませんでした。別のキーワードを試すか、左側のカテゴリを使用して参照してください。",
|
||||
"xpack.fleet.epmList.noPackagesFoundPlaceholder": "パッケージが見つかりません",
|
||||
|
@ -10829,12 +10827,10 @@
|
|||
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注:",
|
||||
"xpack.fleet.hostsInput.addRow": "行の追加",
|
||||
"xpack.fleet.initializationErrorMessageTitle": "Fleet を初期化できません",
|
||||
"xpack.fleet.integrations.beatsModulesLink": "Beatsモジュール",
|
||||
"xpack.fleet.integrations.customInputsLink": "カスタム入力",
|
||||
"xpack.fleet.integrations.discussForumLink": "ディスカッションフォーラム",
|
||||
"xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "{title} アセットをインストールしています",
|
||||
"xpack.fleet.integrations.installPackage.installPackageButtonLabel": "{title}アセットをインストール",
|
||||
"xpack.fleet.integrations.missing": "統合が表示されない場合{customInputsLink}を使用してログまたはメトリックを収集するか、{beatsTutorialLink}を使用してデータを追加してください。{discussForumLink}を使用して新しい統合を要求してください。",
|
||||
"xpack.fleet.integrations.packageInstallErrorDescription": "このパッケージのインストール中に問題が発生しました。しばらくたってから再試行してください。",
|
||||
"xpack.fleet.integrations.packageInstallErrorTitle": "{title}パッケージをインストールできませんでした",
|
||||
"xpack.fleet.integrations.packageInstallSuccessDescription": "正常に{title}をインストールしました",
|
||||
|
|
|
@ -10834,7 +10834,6 @@
|
|||
"xpack.fleet.epm.detailsTitle": "详情",
|
||||
"xpack.fleet.epm.errorLoadingNotice": "加载 NOTICE.txt 时出错",
|
||||
"xpack.fleet.epm.featuresLabel": "功能",
|
||||
"xpack.fleet.epm.illustrationAltText": "集成的图示",
|
||||
"xpack.fleet.epm.install.packageInstallError": "安装 {pkgName} {pkgVersion} 时出错",
|
||||
"xpack.fleet.epm.install.packageUpdateError": "将 {pkgName} 更新到 {pkgVersion} 时出错",
|
||||
"xpack.fleet.epm.licenseLabel": "许可证",
|
||||
|
@ -10869,7 +10868,6 @@
|
|||
"xpack.fleet.epm.usedByLabel": "代理策略",
|
||||
"xpack.fleet.epm.versionLabel": "版本",
|
||||
"xpack.fleet.epmList.allPackagesFilterLinkText": "全部",
|
||||
"xpack.fleet.epmList.allTitle": "按类别浏览",
|
||||
"xpack.fleet.epmList.installedTitle": "已安装集成",
|
||||
"xpack.fleet.epmList.missingIntegrationPlaceholder": "我们未找到任何匹配搜索词的集成。请重试其他关键字,或使用左侧的类别浏览。",
|
||||
"xpack.fleet.epmList.noPackagesFoundPlaceholder": "未找到任何软件包",
|
||||
|
@ -10943,12 +10941,10 @@
|
|||
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注意:",
|
||||
"xpack.fleet.hostsInput.addRow": "添加行",
|
||||
"xpack.fleet.initializationErrorMessageTitle": "无法初始化 Fleet",
|
||||
"xpack.fleet.integrations.beatsModulesLink": "Beats 模板",
|
||||
"xpack.fleet.integrations.customInputsLink": "定制输入",
|
||||
"xpack.fleet.integrations.discussForumLink": "讨论论坛",
|
||||
"xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "正在安装 {title} 资产",
|
||||
"xpack.fleet.integrations.installPackage.installPackageButtonLabel": "安装 {title} 资产",
|
||||
"xpack.fleet.integrations.missing": "未看到集成?使用我们的{customInputsLink}收集任何日志或指标或使用 {beatsTutorialLink} 添加数据。使用{discussForumLink}请求新的集成。",
|
||||
"xpack.fleet.integrations.packageInstallErrorDescription": "尝试安装此软件包时出现问题。请稍后重试。",
|
||||
"xpack.fleet.integrations.packageInstallErrorTitle": "无法安装 {title} 软件包",
|
||||
"xpack.fleet.integrations.packageInstallSuccessDescription": "已成功安装 {title}",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue