Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1348,5 +1348,175 @@ describe('PackagePolicyInputPanel', () => {
expect(lastCall?.streams?.[0]?.vars).not.toHaveProperty(USE_APM_VAR_NAME);
});
});

it('hoists the non-GA release badge up to the input header for input-type packages', async () => {
const betaOtelStreams: RegistryStreamWithDataStream[] = [
{
...otelPackageInputStreams[0],
data_stream: {
...otelPackageInputStreams[0].data_stream,
release: 'beta',
},
},
];
const otelPolicyInput = {
id: 'input-1',
type: OTEL_COLLECTOR_INPUT_TYPE,
policy_template: 'otel_template',
enabled: true,
streams: [
{
id: 'otel-stream-1',
data_stream: { type: 'logs', dataset: 'my_otel.data' },
enabled: true,
vars: {},
},
],
} as NewPackagePolicyInput;

renderResult = testRenderer.render(
<PackagePolicyInputPanel
packageInfo={otelPackageInfo}
packageInput={otelPackageInput}
packageInputStreams={betaOtelStreams}
packagePolicyInput={otelPolicyInput}
updatePackagePolicyInput={mockUpdateOtelInput}
inputValidationResults={otelInputValidationResults}
/>
);

await waitFor(() => {
expect(renderResult.getByText('Beta')).toBeInTheDocument();
// Stream-level toggle should not render for input-type packages,
// which is why the badge is hoisted up to the input header instead.
expect(renderResult.queryByTestId('streamOptions.switch')).not.toBeInTheDocument();
});
});
});

describe('Non-GA release badge hoisting', () => {
beforeEach(() => {
jest.spyOn(ExperimentalFeaturesService, 'get').mockReturnValue({
enableVarGroups: true,
} as any);
useAgentlessMock.mockReturnValue({
isAgentlessEnabled: false,
isAgentlessDefault: false,
isAgentlessAgentPolicy: jest.fn(),
getAgentlessStatusForPackage: jest
.fn()
.mockReturnValue({ isAgentless: false, isDefaultDeploymentMode: false }),
isServerless: false,
isCloud: false,
});
});

const singleBetaStream: RegistryStreamWithDataStream[] = [
{
input: 'logfile',
title: 'Stream 1',
template_path: 'stream.yml.hbs',
vars: [
{
name: 'paths',
type: 'text',
title: 'Paths',
multi: false,
required: false,
show_user: true,
},
],
description: 'Test stream',
data_stream: {
...mockPackageInputStreams[0].data_stream,
release: 'beta',
},
},
];

const singleStreamPolicyInput = {
...packagePolicyInput,
streams: [packagePolicyInput.streams[0]],
} as NewPackagePolicyInput;

it('hoists the release badge to the input header when there is a single stream', async () => {
renderResult = testRenderer.render(
<PackagePolicyInputPanel
packageInfo={mockPackageInfo}
packageInput={mockPackageInput}
packageInputStreams={singleBetaStream}
packagePolicyInput={singleStreamPolicyInput}
updatePackagePolicyInput={mockUpdatePackagePolicyInput}
inputValidationResults={inputValidationResults}
/>
);
await waitFor(() => {
expect(renderResult.getByText('Beta')).toBeInTheDocument();
// Single-stream rows don't render their own toggle, so the badge
// would otherwise float alone - here we expect it at the input header.
expect(renderResult.queryByTestId('streamOptions.switch')).not.toBeInTheDocument();
});
});

it('renders the release badge at the stream row for multi-stream integrations', async () => {
const multiStreamsWithBeta: RegistryStreamWithDataStream[] = [
{
input: 'logfile',
title: 'Stream 1',
template_path: 'stream.yml.hbs',
vars: [
{
name: 'paths',
type: 'text',
title: 'Paths',
multi: false,
required: false,
show_user: true,
},
],
description: 'Test stream 1',
data_stream: {
...mockPackageInputStreams[0].data_stream,
release: 'beta',
},
},
{
input: 'logfile',
title: 'Stream 2',
template_path: 'stream.yml.hbs',
vars: [
{
name: 'paths',
type: 'text',
title: 'Paths',
multi: false,
required: false,
show_user: true,
},
],
description: 'Test stream 2',
data_stream: {
...mockPackageInputStreams[1].data_stream,
},
},
];

renderResult = testRenderer.render(
<PackagePolicyInputPanel
packageInfo={mockPackageInfo}
packageInput={mockPackageInput}
packageInputStreams={multiStreamsWithBeta}
packagePolicyInput={packagePolicyInput}
updatePackagePolicyInput={mockUpdatePackagePolicyInput}
inputValidationResults={inputValidationResults}
/>
);
await waitFor(() => {
expect(renderResult.getByText('Beta')).toBeInTheDocument();
// Multi-stream integrations show per-stream toggles, so the badge
// stays at the stream row - no need to hoist.
expect(renderResult.getAllByTestId('streamOptions.switch').length).toBeGreaterThan(0);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import React, { useState, Fragment, memo, useMemo, useCallback } from 'react';
import React, { useState, memo, useMemo, useCallback } from 'react';
import ReactMarkdown from 'react-markdown';
import styled from 'styled-components';
import { FormattedMessage } from '@kbn/i18n-react';
Expand Down Expand Up @@ -40,7 +40,9 @@ import {
DATA_STREAM_USE_APM_VAR,
shouldIncludeUseAPMVar,
hasDynamicSignalTypes,
mapPackageReleaseToIntegrationCardRelease,
} from '../../../../../../../../../common/services';
import { InlineReleaseBadge } from '../../../../../../components';
import {
DATA_STREAM_TYPE_VAR_NAME,
USE_APM_VAR_NAME,
Expand Down Expand Up @@ -234,11 +236,6 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
const errorCount = inputValidationResults && countValidationErrors(inputValidationResults);
const hasErrors = forceShowErrors && errorCount;

const hasInputStreams = useMemo(
() => packageInputStreams.length > 0,
[packageInputStreams.length]
);

const inputStreams = useMemo(
() =>
packageInputStreams
Expand All @@ -254,6 +251,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
.filter((stream) => Boolean(stream.packagePolicyInputStream)),
[packageInputStreamShouldBeVisible, packageInputStreams, packagePolicyInput.streams]
);
const hasInputStreams = useMemo(() => inputStreams.length > 0, [inputStreams.length]);
const showTopLevelDescription = inputStreams.length === 1;

const dynamicSignalTypes = useMemo(
Expand Down Expand Up @@ -345,6 +343,27 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
defaultMessage: 'This input is deprecated.',
});

// Whether the individual stream rows will render their own toggle switch.
// When they won't (input-type package or single visible stream), we hoist
// the non-GA release badge up to the input header so it doesn't float alone.
const hasStreamToggle = packageInfo.type !== 'input' && inputStreams.length > 1;

const inputReleaseBadge = useMemo(() => {
if (hasStreamToggle) return null;
const preReleaseStream = inputStreams.find(
({ packageInputStream }) =>
packageInputStream.data_stream.release && packageInputStream.data_stream.release !== 'ga'
);
if (!preReleaseStream?.packageInputStream.data_stream.release) return null;
return (
<InlineReleaseBadge
release={mapPackageReleaseToIntegrationCardRelease(
preReleaseStream.packageInputStream.data_stream.release
)}
/>
);
}, [hasStreamToggle, inputStreams]);

// Check if any vars or streams in this input are deprecated
const hasDeprecatedFeatures = useMemo(() => {
const inputVarsDeprecated = (packageInput.vars || []).some((v) => !!v.deprecated);
Expand Down Expand Up @@ -382,6 +401,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
</h3>
</EuiTitle>
</EuiFlexItem>
{inputReleaseBadge && <EuiFlexItem grow={false}>{inputReleaseBadge}</EuiFlexItem>}
{migrationTooltip}
</EuiFlexGroup>
<EuiSpacer size="s" />
Expand All @@ -407,6 +427,9 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
</h3>
</EuiTitle>
</EuiFlexItem>
{inputReleaseBadge && (
<EuiFlexItem grow={false}>{inputReleaseBadge}</EuiFlexItem>
)}
{migrationTooltip}
{isDeprecatedInput && (
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -505,11 +528,16 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
</EuiFlexItem>
</EuiFlexGroup>

{/* Header rule break */}
{isShowingStreams ? <EuiSpacer size="l" /> : null}
{/* Spacing if we are showing rest of content */}
{isShowingStreams &&
hasInputStreams &&
((packageInput.vars && packageInput.vars.length) || !shouldConsolidateAdvancedSections) ? (
<EuiSpacer size="m" />
) : null}

{/* Input level policy */}
{isShowingStreams && packageInput.vars && packageInput.vars.length ? (
<Fragment>
<>
<PackagePolicyInputConfig
data-test-subj="PackagePolicy.InputConfig"
hasInputStreams={hasInputStreams}
Expand All @@ -531,13 +559,13 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
packageInput.show_divider !== false ? (
<ShortenedHorizontalRule margin="m" />
) : (
<EuiSpacer size="l" />
<EuiSpacer size="m" />
)}
</Fragment>
</>
) : null}

{/* Per-stream policy */}
{isShowingStreams && !shouldConsolidateAdvancedSections ? (
{isShowingStreams && hasInputStreams && !shouldConsolidateAdvancedSections ? (
<EuiFlexGroup direction="column" data-test-subj="PackagePolicy.InputConfig.streams">
{inputStreams.map(({ packageInputStream, packagePolicyInputStream }, index) => {
return (
Expand All @@ -546,7 +574,7 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
data-test-subj="PackagePolicy.InputStreamConfig"
packageInfo={packageInfo}
packageInputStream={packageInputStream}
totalStreams={inputStreams.length}
hasStreamToggle={hasStreamToggle}
packagePolicyInputStream={packagePolicyInputStream!}
inputPolicyTemplate={packagePolicyInput.policy_template}
showDescriptionColumn={!isSingleInputAndStreams}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ describe('PackagePolicyInputStreamConfig', () => {
updatePackagePolicyInputStream={mockUpdatePackagePolicyInputStream}
inputStreamValidationResults={{ vars: {} }}
forceShowErrors={false}
totalStreams={2}
hasStreamToggle={true}
inputPolicyTemplate={inputPolicyTemplate}
/>
);
Expand Down Expand Up @@ -297,7 +297,7 @@ describe('PackagePolicyInputStreamConfig', () => {
updatePackagePolicyInputStream={mockUpdatePackagePolicyInputStream}
inputStreamValidationResults={{ vars: {} }}
forceShowErrors={false}
totalStreams={2}
hasStreamToggle={true}
/>
);

Expand Down
Loading
Loading