// 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 {Ec2AmiState, ImageInfoSummary} from '../../types/images' import React, {useMemo} from 'react' import {useSelector} from 'react-redux' import {ListCustomImages, DescribeCustomImage} from '../../model' import {setState, useState, getState, clearState} from '../../store' import {useCollection} from '@cloudscape-design/collection-hooks' // Components import EmptyState from '../../components/EmptyState' import ImageBuildDialog from './ImageBuildDialog' import CustomImageDetails from './CustomImageDetails' // UI Elements import { Button, Header, Link, Pagination, Select, SpaceBetween, SplitPanel, Table, TextFilter, } from '@cloudscape-design/components' import Layout from '../Layout' import {useHelpPanel} from '../../components/help-panel/HelpPanel' import {TFunction, Trans, useTranslation} from 'react-i18next' import InfoLink from '../../components/InfoLink' import TitleDescriptionHelpPanel from '../../components/help-panel/TitleDescriptionHelpPanel' const imageBuildPath = ['app', 'customImages', 'imageBuild'] // selectors const selectCustomImagesList = (state: any): ImageInfoSummary[] => state.customImages.list function CustomImagesList() { const {t} = useTranslation() const images = useSelector(selectCustomImagesList) const [selected, setSelected] = React.useState([]) const imageStatus = useState(['app', 'customImages', 'selectedImageStatus']) let select = (image: ImageInfoSummary) => { setSelected([image]) DescribeCustomImage(image.imageId) setState(['app', 'customImages', 'selected'], image.imageId) } const buildImage = () => { setState([...imageBuildPath, 'dialog'], true) } const refreshImages = () => { clearState(['customImages', 'list']) clearState(['app', 'customImages', 'selected']) ListCustomImages(imageStatus || 'AVAILABLE') } const { items, actions, filteredItemsCount, collectionProps, filterProps, paginationProps, } = useCollection(images || [], { filtering: { empty: ( {t('customImages.list.filtering.empty.action')} } /> ), noMatch: ( actions.setFiltering('')}> {t('customImages.list.filtering.noMatch.action')} } /> ), }, pagination: {pageSize: 10}, sorting: {}, selection: {}, }) return ( } />} description={ } counter={images && `(${images.length})`} actions={ } > {t('customImages.header.title')} } columnDefinitions={[ { id: 'name', header: t('customImages.list.columns.name'), cell: image => image.imageId, sortingField: 'imageId', }, { id: 'ami-id', header: t('customImages.list.columns.amiId'), cell: image => (image.ec2AmiInfo ? image.ec2AmiInfo.amiId : ''), }, { id: 'status', header: t('customImages.list.columns.status'), cell: image => image.imageBuildStatus || '-', sortingField: 'imageBuildStatus', }, { id: 'region', header: t('customImages.list.columns.region'), cell: image => image.region || '-', sortingField: 'region', }, { id: 'version', header: t('customImages.list.columns.version'), cell: image => image.version || '-', }, ]} loading={!images} items={items} selectionType="single" loadingText={t('customImages.list.filtering.loadingText')} pagination={} filter={ } selectedItems={selected} onSelectionChange={e => { select(e.detail.selectedItems[0]) }} /> ) } type Status = Ec2AmiState.Available | Ec2AmiState.Pending | Ec2AmiState.Failed function statusToOption(t: TFunction, status: Status) { switch (status) { case Ec2AmiState.Available: return { label: t('customImages.actions.statusSelect.available'), value: Ec2AmiState.Available, } case Ec2AmiState.Pending: return { label: t('customImages.actions.statusSelect.pending'), value: Ec2AmiState.Pending, } case Ec2AmiState.Failed: return { label: t('customImages.actions.statusSelect.failed'), value: Ec2AmiState.Failed, } } } function StatusSelect() { const {t} = useTranslation() const defaultStatus = statusToOption(t, Ec2AmiState.Available) const [status, setStatus] = React.useState(defaultStatus) return (