// 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 {Region} from '../../types/base' import {ClusterName, ComputeFleetStatus} from '../../types/clusters' import {InstanceState, Instance, NodeType} from '../../types/instances' import React from 'react' import {useTranslation} from 'react-i18next' import {GetClusterInstances, Ec2Action} from '../../model' import {useState, getState, consoleDomain} from '../../store' import { Button, Header, Link, Pagination, SpaceBetween, Table, TextFilter, } from '@cloudscape-design/components' import {useCollection} from '@cloudscape-design/collection-hooks' import {InstanceStatusIndicator} from '../../components/Status' import EmptyState from '../../components/EmptyState' import DateView from '../../components/date/DateView' import {extendCollectionsOptions} from '../../shared/extendCollectionsOptions' function InstanceActions({instance}: {instance?: Instance}) { const {t} = useTranslation() const clusterName = useState(['app', 'clusters', 'selected']) const fleetStatus: ComputeFleetStatus = useState([ 'clusters', 'index', clusterName, 'computeFleetStatus', ]) const [startPending, setStartPending] = React.useState(false) const [stopPending, setStopPending] = React.useState(false) const resetPending = () => { setStopPending(false) setStartPending(false) } const refresh = React.useCallback(() => { const clusterName = getState(['app', 'clusters', 'selected']) clusterName && GetClusterInstances(clusterName, resetPending) }, []) const stopInstance = React.useCallback(() => { setStopPending(true) Ec2Action(instance!.instanceId, 'stop_instances', refresh) }, [instance, refresh]) const startInstance = React.useCallback(() => { setStartPending(true) Ec2Action(instance!.instanceId, 'start_instances', refresh) }, [instance, refresh]) const isComputeFleetStopped = fleetStatus === ComputeFleetStatus.Stopped const isHeadNodeRunning = instance?.nodeType === NodeType.HeadNode && instance?.state === InstanceState.Running const isHeadNodeStopped = instance?.nodeType === NodeType.HeadNode && instance?.state === InstanceState.Stopped return ( ) } export default function ClusterInstances() { let defaultRegion = useState(['aws', 'region']) || '' const region: Region = useState(['app', 'selectedRegion']) || defaultRegion const {t} = useTranslation() const clusterName: ClusterName = useState(['app', 'clusters', 'selected']) const instances: Instance[] | null = useState([ 'clusters', 'index', clusterName, 'instances', ]) const [selectedInstanceId, setSelectedInstanceId] = React.useState() const selectedInstances: Instance[] = instances ? instances.filter(instance => instance.instanceId === selectedInstanceId) : [] const onSelectionChangeCallback = React.useCallback(({detail}) => { setSelectedInstanceId(detail.selectedItems[0].instanceId) }, []) React.useEffect(() => { const tick = () => { const clusterName = getState(['app', 'clusters', 'selected']) clusterName && GetClusterInstances(clusterName) } tick() const timerId = setInterval(tick, 10000) return () => { clearInterval(timerId) } }, []) const { items, actions, filteredItemsCount, collectionProps, filterProps, paginationProps, } = useCollection( instances || [], extendCollectionsOptions({ filtering: { empty: ( ), noMatch: ( actions.setFiltering('')}> {t('cluster.instances.filtering.clearFilter')} } /> ), }, sorting: { defaultState: { sortingColumn: { sortingField: 'instanceId', }, }, }, selection: {}, }), ) return ( } > {t('cluster.instances.title')} } trackBy="instanceId" columnDefinitions={[ { id: 'id', header: t('cluster.instances.id'), cell: instance => ( {instance.instanceId} ), sortingField: 'instanceId', }, { id: 'instance-type', header: t('cluster.instances.instance'), cell: instance => instance.instanceType, sortingField: 'instanceType', }, { id: 'launch-time', header: t('cluster.instances.launchedTime'), cell: instance => , sortingField: 'launchTime', }, { id: 'node-type', header: t('cluster.instances.type'), cell: instance => instance.nodeType, sortingField: 'nodeType', }, { id: 'private-ip', header: t('cluster.instances.privateIp'), cell: instance => instance.privateIpAddress, sortingField: 'privateIpAddress', }, { id: 'public-ip', header: t('cluster.instances.publicIp'), cell: instance => instance.publicIpAddress, sortingField: 'publicIpAddress', }, { id: 'state', header: t('cluster.instances.state'), cell: instance => , sortingField: 'state', }, ]} selectionType="single" selectedItems={selectedInstances} onSelectionChange={onSelectionChangeCallback} loading={instances === null} items={items} loadingText={t('cluster.instances.loadingText')} pagination={} filter={ } /> ) }