The `import/order` rule isn't enough to sort import within a single import group alphabetically. This adds `sort-imports` rule that handles the sorting within groups.
204 lines
5.9 KiB
TypeScript
204 lines
5.9 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
|
|
import {
|
|
Button,
|
|
DropdownItem,
|
|
DropdownList,
|
|
Flex,
|
|
FlexItem,
|
|
MenuToggleAction,
|
|
Modal,
|
|
ModalBody,
|
|
ModalFooter,
|
|
ModalHeader,
|
|
Spinner,
|
|
} from '@patternfly/react-core';
|
|
import useChrome from '@redhat-cloud-services/frontend-components/useChrome';
|
|
import { ChromeUser } from '@redhat-cloud-services/types';
|
|
|
|
import { AMPLITUDE_MODULE_NAME } from '../../../../../constants';
|
|
import {
|
|
useComposeBPWithNotification as useComposeBlueprintMutation,
|
|
useCreateBPWithNotification as useCreateBlueprintMutation,
|
|
} from '../../../../../Hooks';
|
|
import { setBlueprintId } from '../../../../../store/BlueprintSlice';
|
|
import { useAppDispatch, useAppSelector } from '../../../../../store/hooks';
|
|
import {
|
|
CreateBlueprintRequest,
|
|
CreateBlueprintResponse,
|
|
} from '../../../../../store/imageBuilderApi';
|
|
import { selectPackages } from '../../../../../store/wizardSlice';
|
|
import { createAnalytics } from '../../../../../Utilities/analytics';
|
|
|
|
type CreateDropdownProps = {
|
|
getBlueprintPayload: () => Promise<'' | CreateBlueprintRequest | undefined>;
|
|
setIsOpen: (isOpen: boolean) => void;
|
|
isDisabled: boolean;
|
|
};
|
|
|
|
export const CreateSaveAndBuildBtn = ({
|
|
getBlueprintPayload,
|
|
setIsOpen,
|
|
isDisabled,
|
|
}: CreateDropdownProps) => {
|
|
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
|
|
|
const { analytics, auth, isBeta } = useChrome();
|
|
useEffect(() => {
|
|
(async () => {
|
|
const data = await auth?.getUser();
|
|
setUserData(data);
|
|
})();
|
|
}, [auth]);
|
|
const packages = useAppSelector(selectPackages);
|
|
|
|
const { trigger: buildBlueprint } = useComposeBlueprintMutation();
|
|
const { trigger: createBlueprint } = useCreateBlueprintMutation({
|
|
fixedCacheKey: 'createBlueprintKey',
|
|
});
|
|
const dispatch = useAppDispatch();
|
|
const onSaveAndBuild = async () => {
|
|
const requestBody = await getBlueprintPayload();
|
|
setIsOpen(false);
|
|
|
|
if (!process.env.IS_ON_PREMISE && requestBody) {
|
|
const analyticsData = createAnalytics(requestBody, packages, isBeta);
|
|
analytics.track(`${AMPLITUDE_MODULE_NAME} - Blueprint Created`, {
|
|
...analyticsData,
|
|
type: 'createBlueprintAndBuildImages',
|
|
account_id: userData?.identity.internal?.account_id || 'Not found',
|
|
});
|
|
analytics.track(`${AMPLITUDE_MODULE_NAME} - Image Requested`, {
|
|
module: AMPLITUDE_MODULE_NAME,
|
|
trigger: 'blueprint_created',
|
|
image_request_types: requestBody.image_requests.map(
|
|
(req) => req.image_type
|
|
),
|
|
});
|
|
}
|
|
if (requestBody) {
|
|
const blueprint = (await createBlueprint({
|
|
createBlueprintRequest: requestBody,
|
|
})) as CreateBlueprintResponse;
|
|
|
|
buildBlueprint({ id: blueprint.id, body: {} });
|
|
dispatch(setBlueprintId(blueprint.id));
|
|
}
|
|
};
|
|
|
|
return (
|
|
<DropdownList>
|
|
<DropdownItem onClick={onSaveAndBuild} isDisabled={isDisabled}>
|
|
Create blueprint and build image(s)
|
|
</DropdownItem>
|
|
</DropdownList>
|
|
);
|
|
};
|
|
|
|
export const CreateSaveButton = ({
|
|
setIsOpen,
|
|
getBlueprintPayload,
|
|
isDisabled,
|
|
}: CreateDropdownProps) => {
|
|
const { analytics, auth, isBeta } = useChrome();
|
|
const [userData, setUserData] = useState<ChromeUser | void>(undefined);
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
const data = await auth?.getUser();
|
|
setUserData(data);
|
|
})();
|
|
}, [auth]);
|
|
const packages = useAppSelector(selectPackages);
|
|
|
|
const { trigger: createBlueprint, isLoading } = useCreateBlueprintMutation({
|
|
fixedCacheKey: 'createBlueprintKey',
|
|
});
|
|
const dispatch = useAppDispatch();
|
|
const [showModal, setShowModal] = useState(false);
|
|
const wasModalSeen = window.localStorage.getItem(
|
|
'imageBuilder.saveAndBuildModalSeen'
|
|
);
|
|
|
|
const SaveAndBuildImagesModal = () => {
|
|
const handleClose = () => {
|
|
setShowModal(false);
|
|
};
|
|
|
|
return (
|
|
<Modal isOpen={showModal} onClose={handleClose} width="50%">
|
|
<ModalHeader title="Save time by building images" />
|
|
<ModalBody>
|
|
Building blueprints and images doesn't need to be a two step
|
|
process. To build images simultaneously, use the dropdown arrow to the
|
|
right side of this button.
|
|
</ModalBody>
|
|
<ModalFooter>
|
|
<Button
|
|
key="back"
|
|
variant="primary"
|
|
data-testid="close-button-saveandbuild-modal"
|
|
onClick={handleClose}
|
|
>
|
|
Close
|
|
</Button>
|
|
</ModalFooter>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
const onClick = () => {
|
|
if (!wasModalSeen) {
|
|
setShowModal(true);
|
|
window.localStorage.setItem('imageBuilder.saveAndBuildModalSeen', 'true');
|
|
} else {
|
|
onSave();
|
|
}
|
|
};
|
|
|
|
const onSave = async () => {
|
|
const requestBody = await getBlueprintPayload();
|
|
setIsOpen(false);
|
|
|
|
if (!process.env.IS_ON_PREMISE && requestBody) {
|
|
const analyticsData = createAnalytics(requestBody, packages, isBeta);
|
|
analytics.track(`${AMPLITUDE_MODULE_NAME} - Blueprint Created`, {
|
|
...analyticsData,
|
|
type: 'createBlueprint',
|
|
account_id: userData?.identity.internal?.account_id || 'Not found',
|
|
});
|
|
}
|
|
if (requestBody) {
|
|
const blueprint = (await createBlueprint({
|
|
createBlueprintRequest: requestBody,
|
|
})) as CreateBlueprintResponse;
|
|
dispatch(setBlueprintId(blueprint.id));
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{showModal && <SaveAndBuildImagesModal />}
|
|
<MenuToggleAction
|
|
onClick={onClick}
|
|
id="wizard-create-save-btn"
|
|
isDisabled={isDisabled}
|
|
>
|
|
<Flex display={{ default: 'inlineFlex' }}>
|
|
{isLoading && (
|
|
<FlexItem>
|
|
<Spinner
|
|
style={
|
|
{ '--pf-v6-c-spinner--Color': '#fff' } as React.CSSProperties
|
|
}
|
|
isInline
|
|
size="md"
|
|
/>
|
|
</FlexItem>
|
|
)}
|
|
<FlexItem>Create blueprint</FlexItem>
|
|
</Flex>
|
|
</MenuToggleAction>
|
|
</>
|
|
);
|
|
};
|