/*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ import { Alert, Button, DeleteConfirmationDialog, Heading, KeyValuePair, Link, LoadingIndicator, Stack, StatusIndicator, Text, } from 'aws-northstar'; import { LLSafeHtmlString, useI18nContext } from '$strings'; import { PageLayout, useNotificationContext } from '$northstar-plus'; import { TearDownDetails } from '@ada/api'; import { apiHooks } from '$api'; import { awsConsoleCloudFormationUrl } from '$common/utils'; import { parse as parseArn } from '@aws-sdk/util-arn-parser'; import React, { Fragment, useCallback, useState } from 'react'; import copyToClipboard from 'clipboard-copy'; export const TeardownPage: React.FC = () => { const { LL } = useI18nContext(); const { addSuccess, addError, addBrief } = useNotificationContext(); const [strategy, setStrategy] = useState<'destroyData' | 'retainData'>(); const isDestroyData = strategy === 'destroyData'; const [showConfirm, setShowConfirm] = useState(false); const [isProcessing, setIsProcessing] = useState(false); const [details, setDetails] = useState(); const onError = useCallback( (error) => { setIsProcessing(false); addError({ header: LL.VIEW.ADMIN.Teardown.notify.error.header(), content: error.message, }); }, [strategy], ); const onSuccess = useCallback( (result: TearDownDetails) => { setDetails(result); setIsProcessing(false); addSuccess({ header: LL.VIEW.ADMIN.Teardown.notify.success.header(), content: LL.VIEW.ADMIN.Teardown.notify.success.content(), dismissible: false, }); }, [strategy], ); const [startTeardownWithRetainData] = apiHooks.useDeleteAdministrationStartTearDownRetainData({ onError, onSuccess, }); const [startTeardownWithDestroyData] = apiHooks.useDeleteAdministrationStartTearDownDestroyData({ onError, onSuccess, }); const retainData = useCallback(() => { setStrategy('retainData'); setShowConfirm(true); }, []); const destroyData = useCallback(() => { setStrategy('destroyData'); setShowConfirm(true); }, []); const cancelHandler = useCallback(() => { setStrategy(undefined); setShowConfirm(false); }, []); const deleteHandler = useCallback(() => { setIsProcessing(true); setShowConfirm(false); switch (strategy) { case 'retainData': startTeardownWithRetainData({}); break; case 'destroyData': startTeardownWithDestroyData({}); break; } }, [strategy]); const copyDetails = useCallback(() => { if (details == null) { return; } copyToClipboard( JSON.stringify( { ...details, stackLink: awsConsoleCloudFormationUrl(details.coreStackId), }, null, 2, ), ); addBrief({ type: 'success', header: LL.VIEW.notify.brief.clipboard.success(), }); }, [details]); return ( {isProcessing && } {!details && !isProcessing && ( {LL.VIEW.ADMIN.Teardown.strategy.retainData.heading()} {LL.VIEW.ADMIN.Teardown.strategy.destroyData.heading()} )} {details && ( {LL.VIEW.ADMIN.Teardown.success.heading()} {details.coreStackId} } /> {details.retainedResources && ( {details.retainedResources.map((arn) => ( ))} } /> )} {strategy && LL.VIEW.ADMIN.Teardown.success.details.dataIndicator[strategy]()} )} {strategy && showConfirm && ( } onCancelClicked={cancelHandler} onDeleteClicked={deleteHandler} > )} ); }; const ArnResourceLink: React.FC<{ arn: string }> = ({ arn }) => { const { region, resource, service } = parseArn(arn); switch (service) { case 's3': { return (
  • S3 Bucket:
     {resource}
  • ); } case 'kms': { const [type, id] = resource.split('/'); if (type === 'key') { return (
  • KMS Key:
     {id}
  • ); } return null; } case 'logs': { // https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoncloudwatchlogs.html#amazoncloudwatchlogs-resources-for-iam-policies // arn:${Partition}:logs:${Region}:${Account}:log-group:${LogGroupName}:log-stream:${LogStreamName} // arn:${Partition}:logs:${Region}:${Account}:log-group:${LogGroupName} // arn:${Partition}:logs:${Region}:${Account}:destination:${DestinationName} const [type, logGroupName, logStreamType, logStreamName] = resource.split(':'); if (type === 'log-group') { if (logStreamType == null) { return (
  • Log Group:
     {logGroupName}
  • ); } else { return (
  • Log Stream:
     {logStreamName}
  • ); } } return null; } default: { return (
  • {arn}
  • ); } } };