Skip to content

Commit

Permalink
[Fleet] Hide Config and API reference tabs if they are not needed (
Browse files Browse the repository at this point in the history
…elastic#182518)

## Summary

Resolves [elastic#180547](elastic#180547).

This PR hides the `Config` tab for integrations with no inputs, which
are primarily asset-only integrations such as Elastic Agent, Prebuilt
Security Detection Rules, Elastic Synthetics Dashboard, and ML solution
packages.

I took the opportunity to also hide `API references` tab in a similar
way.

### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
  • Loading branch information
jen-huang authored May 3, 2024
1 parent 3e32e01 commit 66ab2c3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
EuiSpacer,
EuiText,
EuiLink,
EuiCallOut,
} from '@elastic/eui';
import type { EuiInMemoryTableProps } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
Expand All @@ -34,8 +35,38 @@ interface Props {
integration?: string | null;
}

const getInputs = ({ packageInfo, integration }: Props) => {
return packageInfo.policy_templates?.reduce((acc, policyTemplate) => {
if (integration && policyTemplate.name !== integration) {
return acc;
}
if ('inputs' in policyTemplate && policyTemplate.inputs) {
return [
...acc,
...policyTemplate.inputs.map((input) => ({
key: `${policyTemplate.name}-${input.type}`,
...input,
streams: getStreamsForInputType(input.type, packageInfo, []),
})),
];
}
return acc;
}, [] as RegistryInputWithStreams[]);
};

export const hasDocumentation = ({ packageInfo, integration }: Props) => {
if (packageInfo.vars && packageInfo.vars.length > 0) {
return true;
}

if ((getInputs({ packageInfo, integration }) || []).length > 0) {
return true;
}
};

export const DocumentationPage: React.FunctionComponent<Props> = ({ packageInfo, integration }) => {
const { docLinks } = useStartServices();
const showDocumentation = hasDocumentation({ packageInfo, integration });

const content = (
<>
Expand All @@ -47,7 +78,7 @@ export const DocumentationPage: React.FunctionComponent<Props> = ({ packageInfo,
defaultMessage="This documents all the inputs, streams, and variables available to use this integration programmatically via the Fleet Kibana API. {learnMore}"
values={{
learnMore: (
<EuiLink href={docLinks.links.fleet.api}>
<EuiLink href={docLinks.links.fleet.api} external={true}>
<FormattedMessage
id="xpack.fleet.epm.packageDetails.apiReference.learnMoreLink"
defaultMessage="Learn more"
Expand All @@ -60,9 +91,21 @@ export const DocumentationPage: React.FunctionComponent<Props> = ({ packageInfo,
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<PackageVars vars={packageInfo.vars} />

<Inputs packageInfo={packageInfo} integration={integration} />
{showDocumentation ? (
<>
<PackageVars vars={packageInfo.vars} />
<Inputs packageInfo={packageInfo} integration={integration} />
</>
) : (
<EuiCallOut
title={
<FormattedMessage
id="xpack.fleet.epm.packageDetails.apiReference.noDocumentationMessage"
defaultMessage="This integration has no references available."
/>
}
/>
)}
<EuiSpacer size="m" />
</>
);
Expand Down Expand Up @@ -127,26 +170,7 @@ const Inputs: React.FunctionComponent<{
packageInfo: PackageInfo;
integration?: string | null;
}> = ({ packageInfo, integration }) => {
const inputs = useMemo(
() =>
packageInfo.policy_templates?.reduce((acc, policyTemplate) => {
if (integration && policyTemplate.name !== integration) {
return acc;
}
if ('inputs' in policyTemplate && policyTemplate.inputs) {
return [
...acc,
...policyTemplate.inputs.map((input) => ({
key: `${policyTemplate.name}-${input.type}`,
...input,
streams: getStreamsForInputType(input.type, packageInfo, []),
})),
];
}
return acc;
}, [] as RegistryInputWithStreams[]),
[packageInfo, integration]
);
const inputs = useMemo(() => getInputs({ packageInfo, integration }), [packageInfo, integration]);
return (
<>
<EuiSpacer size="m" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
getPackageReleaseLabel,
isPackagePrerelease,
splitPkgKey,
packageToPackagePolicyInputs,
} from '../../../../../../../common/services';
import { HIDDEN_API_REFERENCE_PACKAGES } from '../../../../../../../common/constants';

Expand Down Expand Up @@ -82,7 +83,7 @@ import { OverviewPage } from './overview';
import { PackagePoliciesPage } from './policies';
import { SettingsPage } from './settings';
import { CustomViewPage } from './custom';
import { DocumentationPage } from './documentation';
import { DocumentationPage, hasDocumentation } from './documentation';
import { Configs } from './configs';

import './index.scss';
Expand Down Expand Up @@ -266,6 +267,15 @@ export function Detail() {
const showCustomTab =
useUIExtension(packageInfoData?.item?.name ?? '', 'package-detail-custom') !== undefined;

// Only show config tab if package has `inputs`
const showConfigTab = packageInfo ? packageToPackagePolicyInputs(packageInfo).length > 0 : false;

// Only show API references tab if it is allowed & has documentation to show
const showDocumentationTab =
!HIDDEN_API_REFERENCE_PACKAGES.includes(pkgName) &&
packageInfo &&
hasDocumentation({ packageInfo, integration });

// Track install status state
useEffect(() => {
if (packageInfoIsFetchedAfterMount && packageInfoData?.item) {
Expand Down Expand Up @@ -637,7 +647,7 @@ export function Detail() {
});
}

if (canReadPackageSettings) {
if (canReadPackageSettings && showConfigTab) {
tabs.push({
id: 'configs',
name: (
Expand Down Expand Up @@ -673,7 +683,7 @@ export function Detail() {
});
}

if (!HIDDEN_API_REFERENCE_PACKAGES.includes(packageInfo.name)) {
if (showDocumentationTab) {
tabs.push({
id: 'api-reference',
name: (
Expand All @@ -698,11 +708,13 @@ export function Detail() {
getHref,
integration,
canReadIntegrationPolicies,
numOfDeferredInstallations,
isInstalled,
CustomAssets,
canReadPackageSettings,
showConfigTab,
showCustomTab,
showDocumentationTab,
numOfDeferredInstallations,
]);

const securityCallout = missingSecurityConfiguration ? (
Expand Down

0 comments on commit 66ab2c3

Please sign in to comment.