diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx
index cd5b997d9c788..9a1c943763bd8 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx
@@ -267,6 +267,29 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
);
const extensionView = useUIExtension(packagePolicy.package?.name ?? '', 'package-policy-create');
+ const replaceDefineStepView = useUIExtension(
+ packagePolicy.package?.name ?? '',
+ 'package-policy-replace-define-step'
+ );
+
+ if (replaceDefineStepView && extensionView) {
+ throw new Error(
+ "'package-policy-create' and 'package-policy-replace-define-step' cannot both be registered as UI extensions"
+ );
+ }
+
+ const replaceStepConfigurePackagePolicy = replaceDefineStepView && packageInfo?.name && (
+
+
+
+ );
const stepConfigurePackagePolicy = useMemo(
() =>
@@ -329,7 +352,7 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({
defaultMessage: 'Configure integration',
}),
'data-test-subj': 'dataCollectionSetupStep',
- children: stepConfigurePackagePolicy,
+ children: replaceStepConfigurePackagePolicy || stepConfigurePackagePolicy,
},
{
title: i18n.translate('xpack.fleet.createPackagePolicy.stepSelectAgentPolicyTitle', {
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.test.tsx
index c295cdd41cecb..303629a99bb69 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.test.tsx
@@ -331,11 +331,42 @@ describe('edit package policy page', () => {
expect(useStartServices().application.navigateToUrl).not.toHaveBeenCalled();
});
- it('should show ready for upgrade if package useLatestPackageVersion and no conflicts', async () => {
- (useUIExtension as MockFn).mockReturnValue({
- useLatestPackageVersion: true,
- Component: TestComponent,
+ it("throws when both 'package-policy-edit' and 'package-policy-replace-define-step' are defined", async () => {
+ (useUIExtension as MockFn)
+ .mockReturnValueOnce({
+ view: 'package-policy-edit',
+ Component: TestComponent,
+ })
+ .mockReturnValueOnce({
+ view: 'package-policy-replace-define-step',
+ Component: TestComponent,
+ })
+ .mockReturnValueOnce({
+ view: 'package-policy-edit-tabs',
+ Component: TestComponent,
+ });
+
+ render();
+
+ await waitFor(() => {
+ expect(renderResult.getByTestId('euiErrorBoundary')).toBeVisible();
});
+ });
+
+ it('should show ready for upgrade if package useLatestPackageVersion and no conflicts', async () => {
+ (useUIExtension as MockFn)
+ .mockReturnValueOnce({
+ view: 'package-policy-edit',
+ useLatestPackageVersion: true,
+ Component: TestComponent,
+ })
+ .mockReturnValueOnce(undefined)
+ .mockReturnValueOnce({
+ view: 'package-policy-edit-tabs',
+ useLatestPackageVersion: true,
+ Component: TestComponent,
+ });
+
(sendUpgradePackagePolicyDryRun as MockFn).mockResolvedValue({
data: [
{
@@ -357,10 +388,19 @@ describe('edit package policy page', () => {
});
it('should show review field conflicts if package useLatestPackageVersion and has conflicts', async () => {
- (useUIExtension as MockFn).mockReturnValue({
- useLatestPackageVersion: true,
- Component: TestComponent,
- });
+ (useUIExtension as MockFn)
+ .mockReturnValueOnce({
+ view: 'package-policy-edit',
+ useLatestPackageVersion: true,
+ Component: TestComponent,
+ })
+ .mockReturnValueOnce(undefined)
+ .mockReturnValueOnce({
+ view: 'package-policy-edit-tabs',
+ useLatestPackageVersion: true,
+ Component: TestComponent,
+ });
+
(sendUpgradePackagePolicyDryRun as MockFn).mockResolvedValue({
data: [
{
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
index afab7a48ebb76..b066457b0aa2e 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx
@@ -35,7 +35,7 @@ import {
} from '../../../../integrations/hooks';
import {
Loading,
- Error,
+ Error as ErrorComponent,
ExtensionWrapper,
EuiButtonWithTooltip,
DevtoolsRequestFlyoutButton,
@@ -240,10 +240,21 @@ export const EditPackagePolicyForm = memo<{
};
const extensionView = useUIExtension(packagePolicy.package?.name ?? '', 'package-policy-edit');
+ const replaceDefineStepView = useUIExtension(
+ packagePolicy.package?.name ?? '',
+ 'package-policy-replace-define-step'
+ );
const extensionTabsView = useUIExtension(
packagePolicy.package?.name ?? '',
'package-policy-edit-tabs'
);
+
+ if (replaceDefineStepView && extensionView) {
+ throw new Error(
+ "'package-policy-create' and 'package-policy-replace-define-step' cannot both be registered as UI extensions"
+ );
+ }
+
const tabsViews = extensionTabsView?.tabs;
const [selectedTab, setSelectedTab] = useState(0);
@@ -339,6 +350,20 @@ export const EditPackagePolicyForm = memo<{
]
);
+ const replaceConfigurePackage = replaceDefineStepView && originalPackagePolicy && packageInfo && (
+
+
+
+ );
+
const { showDevtoolsRequest: isShowDevtoolRequestExperimentEnabled } =
ExperimentalFeaturesService.get();
@@ -361,7 +386,7 @@ export const EditPackagePolicyForm = memo<{
{isLoadingData ? (
) : loadingError || !agentPolicy || !packageInfo ? (
-
>
)}
- {configurePackage}
+ {replaceConfigurePackage || configurePackage}
{/* Extra space to accomodate the EuiBottomBar height */}
diff --git a/x-pack/plugins/fleet/public/types/ui_extensions.ts b/x-pack/plugins/fleet/public/types/ui_extensions.ts
index fc8726e7b813a..53ae5322f0d9d 100644
--- a/x-pack/plugins/fleet/public/types/ui_extensions.ts
+++ b/x-pack/plugins/fleet/public/types/ui_extensions.ts
@@ -10,7 +10,9 @@ import type { ComponentType, LazyExoticComponent } from 'react';
import type { FleetServerAgentComponentUnit } from '../../common/types/models/agent';
-import type { Agent, NewPackagePolicy, PackageInfo, PackagePolicy } from '.';
+import type { PackagePolicyValidationResults } from '../services';
+
+import type { Agent, AgentPolicy, NewPackagePolicy, PackageInfo, PackagePolicy } from '.';
/** Register a Fleet UI extension */
export type UIExtensionRegistrationCallback = (extensionPoint: UIExtensionPoint) => void;
@@ -20,6 +22,22 @@ export interface UIExtensionsStorage {
[key: string]: Partial>;
}
+/**
+ * UI Component Extension is used to replace the Define Step on
+ * the pages displaying the ability to edit/create an Integration Policy
+ */
+export type PackagePolicyReplaceDefineStepExtensionComponent =
+ ComponentType;
+
+export type PackagePolicyReplaceDefineStepExtensionComponentProps = (
+ | (PackagePolicyEditExtensionComponentProps & { isEditPage: true })
+ | (PackagePolicyCreateExtensionComponentProps & { isEditPage: false })
+) & {
+ validationResults?: PackagePolicyValidationResults;
+ agentPolicy?: AgentPolicy;
+ packageInfo: PackageInfo;
+};
+
/**
* UI Component Extension is used on the pages displaying the ability to edit an
* Integration Policy
@@ -73,6 +91,12 @@ export interface PackageGenericErrorsListProps {
packageErrors: FleetServerAgentComponentUnit[];
}
+export interface PackagePolicyReplaceDefineStepExtension {
+ package: string;
+ view: 'package-policy-replace-define-step';
+ Component: LazyExoticComponent;
+}
+
/** Extension point registration contract for Integration Policy Edit views */
export interface PackagePolicyEditExtension {
package: string;
@@ -184,6 +208,7 @@ export interface AgentEnrollmentFlyoutFinalStepExtension {
/** Fleet UI Extension Point */
export type UIExtensionPoint =
+ | PackagePolicyReplaceDefineStepExtension
| PackagePolicyEditExtension
| PackagePolicyResponseExtension
| PackagePolicyEditTabsExtension