// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance // with the License. A copy of the License is located at // // http://aws.amazon.com/apache2.0/ // // or in the "LICENSE.txt" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES // OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and // limitations under the License. import * as React from 'react' import {BuildImage} from '../../../model' // UI Elements import { Box, Button, Flashbar, FlashbarProps, FormField, Header, Input, Modal, SpaceBetween, } from '@cloudscape-design/components' import FileUploadButton from '../../../components/FileChooser' // State import {setState, useState, getState, clearState} from '../../../store' import ConfigView from '../../../components/ConfigView' import {useTranslation} from 'react-i18next' import {AxiosError} from 'axios' import {errorsToFlashbarItems} from '../../Configure/errorsToFlashbarItems' const buildImageErrorsPath = ['app', 'buildImage', 'errors'] // Constants const imageBuildPath = ['app', 'customImages', 'imageBuild'] function buildImageValidate(errorMessage: string) { let valid = true const imageId = getState([...imageBuildPath, 'imageId']) setState([...buildImageErrorsPath, 'validated'], true) if (!imageId || imageId === '') { setState([...buildImageErrorsPath, 'imageId'], errorMessage) valid = false } else { clearState([...buildImageErrorsPath, 'imageId']) } return valid } export default function ImageBuildDialog() { const {t} = useTranslation() const open = useState([...imageBuildPath, 'dialog']) const imageConfig = useState([...imageBuildPath, 'config']) || '' const errors = useState([...imageBuildPath, 'errors']) const imageId = useState([...imageBuildPath, 'imageId']) const pending = useState([...imageBuildPath, 'pending']) let validated = useState([...buildImageErrorsPath, 'validated']) let imageIdError = useState([...buildImageErrorsPath, 'imageId']) const missingImageIdError = t('customImages.dialogs.buildImage.imageIdError') React.useEffect(() => { setFlashbarItems(errorsToFlashbarItems(errors, setFlashbarItems)) }, [errors]) const [flashbarItems, setFlashbarItems] = React.useState< FlashbarProps.MessageDefinition[] >([]) const handleClose = () => { setState([...imageBuildPath, 'dialog'], false) clearState([...imageBuildPath, 'errors']) } const handleBuild = async () => { clearState([...imageBuildPath, 'errors']) setState([...imageBuildPath, 'pending'], true) if (buildImageValidate(missingImageIdError)) { try { await BuildImage(imageId, imageConfig) handleClose() } catch (error: unknown) { if ((error as AxiosError).response) { setState( [...imageBuildPath, 'errors'], (error as AxiosError).response?.data, ) } } setState([...imageBuildPath, 'pending'], false) } } const setImageId = (newImageId: any) => { if (newImageId !== imageId) { setState([...imageBuildPath, 'imageId'], newImageId) if (validated) buildImageValidate(missingImageIdError) } } const descriptionElementRef = React.useRef(null) React.useEffect(() => { if (open) { const {current: descriptionElement} = descriptionElementRef if (descriptionElement !== null) { ;(descriptionElement as any).focus() } } }, [open]) return ( { setState([...imageBuildPath, 'config'], data) }} /> } > {t('customImages.dialogs.buildImage.title')} } footer={ } > { setImageId(detail.value) }} /> { { setState([...imageBuildPath, 'config'], detail.value) }} /> } ) }