import React, { useEffect, useState } from 'react';
import {
Alert,
Button,
ClipboardCopy,
DescriptionList,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
Popover,
Skeleton,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import useChrome from '@redhat-cloud-services/frontend-components/useChrome';
import { ChromeUser } from '@redhat-cloud-services/types';
import ClonesTable from './ClonesTable';
import { AMPLITUDE_MODULE_NAME } from '../../constants';
import { useGetComposeStatusQuery } from '../../store/backendApi';
import { extractProvisioningList } from '../../store/helpers';
import {
ComposesResponseItem,
GcpUploadRequestOptions,
} from '../../store/imageBuilderApi';
import { useGetSourceListQuery } from '../../store/provisioningApi';
import {
isAwsUploadRequestOptions,
isAzureUploadRequestOptions,
isAzureUploadStatus,
isGcpUploadRequestOptions,
isGcpUploadStatus,
isOciUploadStatus,
} from '../../store/typeGuards';
const SourceNotFoundPopover = () => {
return (
The information about the source cannot be loaded. Please check the
source was not removed and try again later.
}
iconPosition="right"
isInline
href={'settings/sources'}
>
Manage sources here
>
}
>
);
};
type AzureSourceNamePropTypes = {
id: string;
};
const AzureSourceName = ({ id }: AzureSourceNamePropTypes) => {
const { data: rawSources, isSuccess } = useGetSourceListQuery({
provider: 'azure',
});
if (!isSuccess) {
return ;
}
const sources = extractProvisioningList(rawSources);
const sourcename = sources?.find((source) => source?.id === id);
if (sourcename) {
return
{sourcename.name}
;
}
return ;
};
type AwsSourceNamePropTypes = {
id: string;
};
const AwsSourceName = ({ id }: AwsSourceNamePropTypes) => {
const { data: rawSources, isSuccess } = useGetSourceListQuery({
provider: 'aws',
});
if (!isSuccess) {
return ;
}
const sources = extractProvisioningList(rawSources);
const sourcename = sources?.find((source) => source?.id === id);
if (sourcename) {
return {sourcename.name}
;
}
return ;
};
const parseGcpSharedWith = (
sharedWith: GcpUploadRequestOptions['share_with_accounts']
) => {
if (sharedWith) {
const splitGCPSharedWith = sharedWith[0].split(':');
return splitGCPSharedWith[1];
}
};
type AwsDetailsPropTypes = {
compose: ComposesResponseItem;
};
export const AwsDetails = ({ compose }: AwsDetailsPropTypes) => {
const options = compose.request.image_requests[0].upload_request.options;
const [userData, setUserData] = useState(undefined);
const { analytics, auth } = useChrome();
useEffect(() => {
(async () => {
const data = await auth?.getUser();
setUserData(data);
})();
}, [auth]);
if (!isAwsUploadRequestOptions(options)) {
throw TypeError(
`Error: options must be of type AwsUploadRequestOptions, not ${typeof options}.`
);
}
return (
<>
Build Information
UUID
{
analytics.track(`${AMPLITUDE_MODULE_NAME} - Copy UUID`, {
module: AMPLITUDE_MODULE_NAME,
link_name: compose.id,
current_path: window.location.pathname,
account_id:
userData?.identity.internal?.account_id || 'Not found',
});
}}
>
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
{options.share_with_sources?.[0] && (
Source
)}
{options.share_with_accounts?.[0] && (
Shared with
}
iconPosition="right"
isInline
// the format of an account link is taken from
// https://docs.aws.amazon.com/signin/latest/userguide/sign-in-urls-defined.html
href={`https://${options.share_with_accounts[0]}.signin.aws.amazon.com/console/`}
onClick={() => {
analytics.track(`${AMPLITUDE_MODULE_NAME} - Link Clicked`, {
module: AMPLITUDE_MODULE_NAME,
link_name: options.share_with_accounts
? options.share_with_accounts[0]
: '',
current_path: window.location.pathname,
account_id:
userData?.identity.internal?.account_id || 'Not found',
});
}}
>
{options.share_with_accounts[0]}
)}
<>
Cloud Provider Identifiers
>
>
);
};
type AzureDetailsPropTypes = {
compose: ComposesResponseItem;
};
export const AzureDetails = ({ compose }: AzureDetailsPropTypes) => {
const { data: composeStatus } = useGetComposeStatusQuery({
composeId: compose.id,
});
const options = compose.request.image_requests[0].upload_request.options;
if (!isAzureUploadRequestOptions(options)) {
throw TypeError(
`Error: options must be of type AzureUploadRequestOptions, not ${typeof options}.`
);
}
const sourceId = options.source_id;
const resourceGroup = options.resource_group;
const uploadStatus = composeStatus?.image_status.upload_status?.options;
if (uploadStatus && !isAzureUploadStatus(uploadStatus)) {
throw TypeError(
`Error: uploadStatus must be of type AzureUploadStatus, not ${typeof uploadStatus}.`
);
}
return (
<>
Build Information
UUID
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
{sourceId && (
Source
)}
Resource Group
{resourceGroup}
Cloud Provider Identifiers
Image name
{composeStatus?.image_status.status === 'success' && (
{uploadStatus?.image_name || ''}
)}
>
);
};
type GcpDetailsPropTypes = {
compose: ComposesResponseItem;
};
export const GcpDetails = ({ compose }: GcpDetailsPropTypes) => {
const { data: composeStatus } = useGetComposeStatusQuery({
composeId: compose.id,
});
const options = compose.request.image_requests[0].upload_request.options;
if (!isGcpUploadRequestOptions(options)) {
throw TypeError(
`Error: options must be of type GcpUploadRequestOptions, not ${typeof options}.`
);
}
const uploadStatus = composeStatus?.image_status.upload_status?.options;
if (uploadStatus && !isGcpUploadStatus(uploadStatus)) {
throw TypeError(
`Error: uploadStatus must be of type GcpUploadStatus, not ${typeof uploadStatus}.`
);
}
return (
<>
Build Information
UUID
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
{composeStatus?.image_status.status === 'success' && (
Project ID
{uploadStatus?.project_id}
)}
{options.share_with_accounts && (
Shared with
{parseGcpSharedWith(options.share_with_accounts)}
)}
Cloud Provider Identifiers
Image name
{composeStatus?.image_status.status === 'success' && (
{uploadStatus?.image_name || ''}
)}
>
);
};
type OciDetailsPropTypes = {
compose: ComposesResponseItem;
};
export const OciDetails = ({ compose }: OciDetailsPropTypes) => {
const { data: composeStatus } = useGetComposeStatusQuery({
composeId: compose.id,
});
const options = composeStatus?.image_status.upload_status?.options;
if (options && !isOciUploadStatus(options)) {
throw TypeError(
`Error: uploadStatus must be of type OciUploadStatus, not ${typeof options}.`
);
}
return (
<>
Build Information
UUID
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
Cloud Provider Identifiers
Object Storage URL
{composeStatus?.image_status.status === 'success' && (
{options?.url || ''}
)}
>
);
};
type AwsS3DetailsPropTypes = {
compose: ComposesResponseItem;
};
export const AwsS3Details = ({ compose }: AwsS3DetailsPropTypes) => {
return (
<>
Build Information
UUID
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
>
);
};
type LocalDetailsPropTypes = {
compose: ComposesResponseItem;
};
export const LocalDetails = ({ compose }: LocalDetailsPropTypes) => {
return (
<>
Build Information
UUID
{compose.id}
Architecture
{compose.request.image_requests[0].architecture}
>
);
};