// 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' // UI Elements import { Button, Header, Link, Pagination, Select, SpaceBetween, Table, TextFilter, } from '@cloudscape-design/components' 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' import {extendCollectionsOptions} from '../../../shared/extendCollectionsOptions' import {CustomImageStatusIndicator} from '../../../components/Status' 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 = () => { setSelected([]) clearState(['customImages', 'list']) clearState(['app', 'customImages', 'selected']) ListCustomImages(imageStatus || 'AVAILABLE') } const imagesCount = (images || []).length const { items, actions, filteredItemsCount, collectionProps, filterProps, paginationProps, } = useCollection( images || [], extendCollectionsOptions({ filtering: { empty: ( {t('customImages.list.filtering.empty.action')} } /> ), noMatch: ( actions.setFiltering('')}> {t('customImages.list.filtering.noMatch.action')} } /> ), }, sorting: { defaultState: { sortingColumn: { sortingField: 'imageId', }, }, }, selection: {}, }), ) return ( } />} description={ } counter={`(${imagesCount})`} 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 => ( ), 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 (