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 @@ -112,6 +112,10 @@ export const varsReducer = (
configObject: PackagePolicyConfigRecord,
registryVar: RegistryVarsEntry
): PackagePolicyConfigRecord => {
// section_header vars are decorative only and hold no value
if (registryVar.type === 'section_header') {
return configObject;
}
const configEntry: PackagePolicyConfigRecordEntry = {
value: !registryVar.default && registryVar.multi ? [] : registryVar.default,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ export enum RegistryInputKeys {
deprecated = 'deprecated',
migrate_from = 'migrate_from',
dynamic_signal_types = 'dynamic_signal_types',
show_divider = 'show_divider',
}

export type RegistryInputGroup = 'logs' | 'metrics';
Expand All @@ -347,6 +348,8 @@ export interface RegistryInput {
[RegistryInputKeys.migrate_from]?: string;
/** When true the data stream signal type (logs/metrics/traces) is determined at runtime by the agent. Valid for OTel collector inputs in composable integrations. */
[RegistryInputKeys.dynamic_signal_types]?: boolean;
/** When false, suppresses the automatic horizontal divider rendered after the input-level config section. Defaults to true. */
[RegistryInputKeys.show_divider]?: boolean;
}

export enum RegistryStreamKeys {
Expand Down Expand Up @@ -551,7 +554,8 @@ export type RegistryVarType =
| 'string'
| 'textarea'
| 'duration'
| 'url';
| 'url'
| 'section_header';
export enum RegistryVarsEntryKeys {
name = 'name',
title = 'title',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface RegistryVarGroup {
selector_title: string;
description?: string;
required?: boolean; // When true, all vars in the selected option are treated as required
show_divider?: boolean; // When false, suppresses the automatic horizontal divider rendered after this var_group's stream section
options: RegistryVarGroupOption[];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type {
} from '../../../../../../types';
import type { PackagePolicyConfigValidationResults } from '../../../services';
import { isAdvancedVar, validationHasErrors } from '../../../services';
import { shouldShowVar } from '../../../services/var_group_helpers';
import { shouldShowVar, getVarsControlledByVarGroups } from '../../../services/var_group_helpers';
import type { VarGroupSelection } from '../../../services/var_group_helpers';
import { useAgentless } from '../../../single_page_layout/hooks/setup_technology';

Expand Down Expand Up @@ -72,10 +72,15 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
const [isShowingAdvanced, setIsShowingAdvanced] = useState<boolean>(false);
const { isAgentlessEnabled } = useAgentless();

// Split vars into required and advanced, filtering by var_group visibility and deprecated vars
const [requiredVars, advancedVars] = useMemo(() => {
// Split vars into required and advanced, filtering by var_group visibility and deprecated vars.
// Required vars are further split into pre-group (not controlled by any var_group, rendered
// above var_group selectors) and post-group (controlled by a selected var_group option,
// rendered below var_group selectors) to preserve manifest declaration order intent.
const [preGroupRequiredVars, postGroupRequiredVars, advancedVars] = useMemo(() => {
const _advancedVars: RegistryVarsEntry[] = [];
const _requiredVars: RegistryVarsEntry[] = [];
const _preGroupVars: RegistryVarsEntry[] = [];
const _postGroupVars: RegistryVarsEntry[] = [];
const controlledVars = varGroups?.length ? getVarsControlledByVarGroups(varGroups) : null;
(packageInputVars || []).forEach((varDef) => {
if (!isEditPage && !!varDef.deprecated) {
return;
Expand All @@ -89,11 +94,15 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
}
if (isAdvancedVar(varDef, varGroups, varGroupSelections)) {
_advancedVars.push(varDef);
} else if (controlledVars?.has(varDef.name)) {
// Var is controlled by a var_group option — render after the var_group selector
_postGroupVars.push(varDef);
} else {
_requiredVars.push(varDef);
// Var is independent of var_groups — render before the var_group selector
_preGroupVars.push(varDef);
}
});
return [_requiredVars, _advancedVars];
return [_preGroupVars, _postGroupVars, _advancedVars];
}, [packageInputVars, varGroups, varGroupSelections, isEditPage]);

const allAdvancedVars = useMemo(() => {
Expand Down Expand Up @@ -189,6 +198,36 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
) : null}
<EuiFlexItem>
<EuiFlexGroup direction="column" gutterSize="m">
{preGroupRequiredVars.map((varDef) => {
const { name: varName, type: varType } = varDef;

const value = packagePolicyInput.vars?.[varName]?.value;
const frozen = packagePolicyInput.vars?.[varName]?.frozen;

return (
<EuiFlexItem key={varName}>
<PackagePolicyInputVarField
varDef={varDef}
value={value}
frozen={frozen}
onChange={(newValue: any) => {
updatePackagePolicyInput({
vars: {
...packagePolicyInput.vars,
[varName]: {
type: varType,
value: newValue,
},
},
});
}}
errors={inputValidationResults.vars?.[varName]}
forceShowErrors={forceShowErrors}
isEditPage={isEditPage}
/>
</EuiFlexItem>
);
})}
{varGroups?.map((varGroup) => (
<EuiFlexItem key={varGroup.name}>
<VarGroupSelector
Expand All @@ -199,7 +238,7 @@ export const PackagePolicyInputConfig: React.FunctionComponent<{
/>
</EuiFlexItem>
))}
{requiredVars.map((varDef) => {
{postGroupRequiredVars.map((varDef) => {
const { name: varName, type: varType } = varDef;

const value = packagePolicyInput.vars?.[varName]?.value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,9 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{
showDescriptionColumn={!isSingleInputAndStreams}
streamAdvancedVars={consolidatedStreamAdvancedVars}
/>
{hasInputStreams && !shouldConsolidateAdvancedSections ? (
{hasInputStreams &&
!shouldConsolidateAdvancedSections &&
packageInput.show_divider !== false ? (
<ShortenedHorizontalRule margin="m" />
) : (
<EuiSpacer size="l" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
EuiSwitch,
EuiFieldText,
EuiText,
EuiTitle,
EuiFieldPassword,
EuiCodeBlock,
EuiTextArea,
Expand Down Expand Up @@ -112,6 +113,21 @@ export const PackagePolicyInputVarField: React.FunctionComponent<InputFieldProps
return null;
}

if (type === 'section_header') {
return (
<>
<EuiTitle size="xxs">
<h4>{title || name}</h4>
</EuiTitle>
{description && (
<EuiText size="s" color="subdued">
<ReactMarkdown children={description} />
</EuiText>
)}
</>
);
}

if (name === DATASET_VAR_NAME && packageType === 'input') {
return (
<DatasetComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export const isAdvancedVar = (
varGroups?: RegistryVarGroup[],
varGroupSelections?: VarGroupSelection
): boolean => {
// section_header vars are decorative and always render with required vars, never under "Advanced options"
if (varDef.type === 'section_header') {
return false;
}

// If var is in a selected var_group option, treat as non-advanced (override show_user: false)
if (
varGroups &&
Expand Down
Loading