// 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={
}
/>
)
}