[Fleet] Create a new UIExtensionPoint to replace the integration define step (#149653)

This commit is contained in:
Or Ouziel 2023-02-01 18:28:44 +02:00 committed by GitHub
parent 0a6edd8501
commit f002889cca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 126 additions and 13 deletions

View file

@ -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 && (
<ExtensionWrapper>
<replaceDefineStepView.Component
agentPolicy={agentPolicy}
packageInfo={packageInfo}
newPolicy={packagePolicy}
onChange={handleExtensionViewOnChange}
validationResults={validationResults}
isEditPage={false}
/>
</ExtensionWrapper>
);
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', {

View file

@ -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: [
{

View file

@ -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 && (
<ExtensionWrapper>
<replaceDefineStepView.Component
agentPolicy={agentPolicy}
packageInfo={packageInfo}
policy={originalPackagePolicy}
newPolicy={packagePolicy}
onChange={handleExtensionViewOnChange}
validationResults={validationResults}
isEditPage={true}
/>
</ExtensionWrapper>
);
const { showDevtoolsRequest: isShowDevtoolRequestExperimentEnabled } =
ExperimentalFeaturesService.get();
@ -361,7 +386,7 @@ export const EditPackagePolicyForm = memo<{
{isLoadingData ? (
<Loading />
) : loadingError || !agentPolicy || !packageInfo ? (
<Error
<ErrorComponent
title={
<FormattedMessage
id="xpack.fleet.editPackagePolicy.errorLoadingDataTitle"
@ -399,7 +424,7 @@ export const EditPackagePolicyForm = memo<{
<EuiSpacer size="xxl" />
</>
)}
{configurePackage}
{replaceConfigurePackage || configurePackage}
{/* Extra space to accomodate the EuiBottomBar height */}
<EuiSpacer size="xxl" />
<EuiSpacer size="xxl" />

View file

@ -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<Record<UIExtensionPoint['view'], UIExtensionPoint>>;
}
/**
* 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<PackagePolicyReplaceDefineStepExtensionComponentProps>;
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<PackagePolicyReplaceDefineStepExtensionComponent>;
}
/** 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