Add the provisioning Button
This commit is contained in:
parent
03421acc74
commit
357401ecfa
5 changed files with 210 additions and 118 deletions
53
package-lock.json
generated
53
package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
|||
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
||||
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
||||
"@reduxjs/toolkit": "^1.8.5",
|
||||
"@scalprum/react-core": "^0.2.8",
|
||||
"classnames": "2.3.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
|
|
@ -3288,6 +3289,19 @@
|
|||
"react-router-dom": ">=4.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@redhat-cloud-services/frontend-components/node_modules/@scalprum/react-core": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
||||
"dependencies": {
|
||||
"@scalprum/core": "^0.1.2",
|
||||
"lodash": "^4.17.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0 || >=17.0.0",
|
||||
"react-dom": ">=16.8.0 || >=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redhat-cloud-services/rbac-client": {
|
||||
"version": "1.0.106",
|
||||
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.0.106.tgz",
|
||||
|
|
@ -3340,11 +3354,11 @@
|
|||
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
||||
},
|
||||
"node_modules/@scalprum/react-core": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
|
||||
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
|
||||
"dependencies": {
|
||||
"@scalprum/core": "^0.1.2",
|
||||
"@scalprum/core": "^0.2.3",
|
||||
"lodash": "^4.17.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
@ -3352,6 +3366,11 @@
|
|||
"react-dom": ">=16.8.0 || >=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@scalprum/react-core/node_modules/@scalprum/core": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/core/-/core-0.2.3.tgz",
|
||||
"integrity": "sha512-bL7YjXWSgtAw44ha+goEF/cCWUu1BELB0qo4Y8hlfmn0+FMnoIHcY0gD1OOotz7Oy74r5+DRxi5Wra40DTG8Qg=="
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "5.30.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz",
|
||||
|
|
@ -19400,6 +19419,17 @@
|
|||
"@scalprum/core": "^0.1.1",
|
||||
"@scalprum/react-core": "^0.1.7",
|
||||
"sanitize-html": "^2.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scalprum/react-core": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
||||
"requires": {
|
||||
"@scalprum/core": "^0.1.2",
|
||||
"lodash": "^4.17.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@redhat-cloud-services/frontend-components-config": {
|
||||
|
|
@ -19661,12 +19691,19 @@
|
|||
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
||||
},
|
||||
"@scalprum/react-core": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
|
||||
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
|
||||
"requires": {
|
||||
"@scalprum/core": "^0.1.2",
|
||||
"@scalprum/core": "^0.2.3",
|
||||
"lodash": "^4.17.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scalprum/core": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@scalprum/core/-/core-0.2.3.tgz",
|
||||
"integrity": "sha512-bL7YjXWSgtAw44ha+goEF/cCWUu1BELB0qo4Y8hlfmn0+FMnoIHcY0gD1OOotz7Oy74r5+DRxi5Wra40DTG8Qg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/browser": {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
||||
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
||||
"@reduxjs/toolkit": "^1.8.5",
|
||||
"@scalprum/react-core": "^0.2.8",
|
||||
"classnames": "2.3.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
|
|
|
|||
|
|
@ -1,126 +1,49 @@
|
|||
import React from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Popover,
|
||||
Text,
|
||||
TextContent,
|
||||
TextVariants,
|
||||
} from '@patternfly/react-core';
|
||||
import { DownloadIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
|
||||
import { Button } from '@patternfly/react-core';
|
||||
import { useLoadModule, useScalprum } from '@scalprum/react-core';
|
||||
import ImageLinkDirect from './ImageLinkDirect';
|
||||
|
||||
const ImageLink = (props) => {
|
||||
const fileExtensions = {
|
||||
vsphere: '.vmdk',
|
||||
'guest-image': '.qcow2',
|
||||
'image-installer': '.iso',
|
||||
};
|
||||
const scalprum = useScalprum();
|
||||
const hasProvisionig = scalprum.initialized && scalprum.config?.provisioning;
|
||||
if (hasProvisionig && props.imageType === 'ami') {
|
||||
const [wizardOpen, openWizard] = React.useState(false);
|
||||
const [{ default: ProvisioningWizard }, error] = useLoadModule(
|
||||
{
|
||||
appName: 'provisioning', // optional
|
||||
scope: 'provisioning',
|
||||
module: './ProvisioningWizard',
|
||||
// processor: (val) => val, // optional
|
||||
},
|
||||
{},
|
||||
{}
|
||||
);
|
||||
|
||||
const uploadStatus = props.imageStatus
|
||||
? props.imageStatus.upload_status
|
||||
: undefined;
|
||||
if (uploadStatus) {
|
||||
if (uploadStatus.type === 'aws') {
|
||||
const url =
|
||||
'https://console.aws.amazon.com/ec2/v2/home?region=' +
|
||||
uploadStatus.options.region +
|
||||
'#LaunchInstanceWizard:ami=' +
|
||||
uploadStatus.options.ami;
|
||||
if (!error) {
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={url}
|
||||
>
|
||||
Launch instance
|
||||
</Button>
|
||||
);
|
||||
} else if (uploadStatus.type === 'azure') {
|
||||
const url =
|
||||
'https://portal.azure.com/#@' +
|
||||
props.uploadOptions.tenant_id +
|
||||
'/resource/subscriptions/' +
|
||||
props.uploadOptions.subscription_id +
|
||||
'/resourceGroups/' +
|
||||
props.uploadOptions.resource_group +
|
||||
'/providers/Microsoft.Compute/images/' +
|
||||
uploadStatus.options.image_name;
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={url}
|
||||
>
|
||||
View uploaded image
|
||||
</Button>
|
||||
);
|
||||
} else if (uploadStatus.type === 'gcp') {
|
||||
return (
|
||||
<Popover
|
||||
aria-label="Popover with google cloud platform image details"
|
||||
maxWidth="30rem"
|
||||
headerContent={'GCP image details'}
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text component={TextVariants.p}>
|
||||
To use an Image Builder created Google Cloud Platform (GCP)
|
||||
image in your project, specify the project ID and image name in
|
||||
your templates and configurations.
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Project ID</strong>
|
||||
<br />
|
||||
{uploadStatus.options.project_id}
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Image Name</strong>
|
||||
<br />
|
||||
{uploadStatus.options.image_name}
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Shared with</strong>
|
||||
<br />
|
||||
{/* the account the image is shared with is stored in the form type:account so this extracts the account */}
|
||||
{props.uploadOptions.share_with_accounts[0].split(':')[1]}
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<Button component="a" target="_blank" variant="link" isInline>
|
||||
Image details
|
||||
<Suspense fallback="loading">
|
||||
<Button variant="link" isInline onClick={() => openWizard(true)}>
|
||||
Launch
|
||||
</Button>
|
||||
</Popover>
|
||||
);
|
||||
} else if (uploadStatus.type === 'aws.s3') {
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<DownloadIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={uploadStatus.options.url}
|
||||
>
|
||||
Download {fileExtensions[props.imageType]}
|
||||
</Button>
|
||||
{wizardOpen && (
|
||||
<ProvisioningWizard
|
||||
isOpen
|
||||
onClose={() => openWizard(false)}
|
||||
image={{ name: props.imageName, id: props.imageId }}
|
||||
/>
|
||||
)}
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return <ImageLinkDirect {...props} />;
|
||||
};
|
||||
|
||||
ImageLink.propTypes = {
|
||||
imageId: PropTypes.string.isRequired,
|
||||
imageName: PropTypes.string.isRequired,
|
||||
imageStatus: PropTypes.object,
|
||||
imageType: PropTypes.string,
|
||||
uploadOptions: PropTypes.object,
|
||||
|
|
|
|||
129
src/Components/ImagesTable/ImageLinkDirect.js
Normal file
129
src/Components/ImagesTable/ImageLinkDirect.js
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Popover,
|
||||
Text,
|
||||
TextContent,
|
||||
TextVariants,
|
||||
} from '@patternfly/react-core';
|
||||
import { DownloadIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
|
||||
|
||||
const ImageLinkDirect = (props) => {
|
||||
const fileExtensions = {
|
||||
vsphere: '.vmdk',
|
||||
'guest-image': '.qcow2',
|
||||
'image-installer': '.iso',
|
||||
};
|
||||
|
||||
const uploadStatus = props.imageStatus
|
||||
? props.imageStatus.upload_status
|
||||
: undefined;
|
||||
if (uploadStatus) {
|
||||
if (uploadStatus.type === 'aws') {
|
||||
const url =
|
||||
'https://console.aws.amazon.com/ec2/v2/home?region=' +
|
||||
uploadStatus.options.region +
|
||||
'#LaunchInstanceWizard:ami=' +
|
||||
uploadStatus.options.ami;
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={url}
|
||||
>
|
||||
Launch instance
|
||||
</Button>
|
||||
);
|
||||
} else if (uploadStatus.type === 'azure') {
|
||||
const url =
|
||||
'https://portal.azure.com/#@' +
|
||||
props.uploadOptions.tenant_id +
|
||||
'/resource/subscriptions/' +
|
||||
props.uploadOptions.subscription_id +
|
||||
'/resourceGroups/' +
|
||||
props.uploadOptions.resource_group +
|
||||
'/providers/Microsoft.Compute/images/' +
|
||||
uploadStatus.options.image_name;
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<ExternalLinkAltIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={url}
|
||||
>
|
||||
View uploaded image
|
||||
</Button>
|
||||
);
|
||||
} else if (uploadStatus.type === 'gcp') {
|
||||
return (
|
||||
<Popover
|
||||
aria-label="Popover with google cloud platform image details"
|
||||
maxWidth="30rem"
|
||||
headerContent={'GCP image details'}
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text component={TextVariants.p}>
|
||||
To use an Image Builder created Google Cloud Platform (GCP)
|
||||
image in your project, specify the project ID and image name in
|
||||
your templates and configurations.
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Project ID</strong>
|
||||
<br />
|
||||
{uploadStatus.options.project_id}
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Image Name</strong>
|
||||
<br />
|
||||
{uploadStatus.options.image_name}
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Shared with</strong>
|
||||
<br />
|
||||
{/* the account the image is shared with is stored in the form type:account so this extracts the account */}
|
||||
{props.uploadOptions.share_with_accounts[0].split(':')[1]}
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<Button component="a" target="_blank" variant="link" isInline>
|
||||
Image details
|
||||
</Button>
|
||||
</Popover>
|
||||
);
|
||||
} else if (uploadStatus.type === 'aws.s3') {
|
||||
return (
|
||||
<Button
|
||||
component="a"
|
||||
target="_blank"
|
||||
variant="link"
|
||||
icon={<DownloadIcon />}
|
||||
iconPosition="right"
|
||||
isInline
|
||||
href={uploadStatus.options.url}
|
||||
>
|
||||
Download {fileExtensions[props.imageType]}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
ImageLinkDirect.propTypes = {
|
||||
imageStatus: PropTypes.object,
|
||||
imageType: PropTypes.string,
|
||||
uploadOptions: PropTypes.object,
|
||||
};
|
||||
|
||||
export default ImageLinkDirect;
|
||||
|
|
@ -265,6 +265,8 @@ const ImagesTable = () => {
|
|||
</Td>
|
||||
<Td dataLabel="Instance">
|
||||
<ImageLink
|
||||
imageId={id}
|
||||
imageName={compose.request.image_name || id}
|
||||
imageStatus={compose.image_status}
|
||||
imageType={
|
||||
compose.request.image_requests[0].image_type
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue