Skip to content

Commit a80f1c0

Browse files
Add Finished column to Instance list, replace Health with Error, restore Fleet Price
- Add Finished column to Instance list - Move Price after Backend in Instance list - Replace Health column/field with Error (only shows non-healthy values) - Error field always visible in Instance details (shows - when healthy) - Move Blocks before Hostname in Instance details - Restore Price to Fleet list and Fleet details Made-with: Cursor
1 parent 7fa4cc7 commit a80f1c0

5 files changed

Lines changed: 49 additions & 23 deletions

File tree

frontend/src/locale/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@
634634
"region": "Region",
635635
"spot": "Spot",
636636
"started": "Started",
637-
"finished_at": "Finished at",
637+
"finished_at": "Finished",
638638
"price": "Price",
639639
"termination_reason": "Termination reason",
640640
"health": "Health",

frontend/src/pages/Fleets/Details/FleetDetails/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { format } from 'date-fns';
66
import { Box, ColumnLayout, Container, Header, Loader, NavigateLink, StatusIndicator } from 'components';
77

88
import { DATE_TIME_FORMAT } from 'consts';
9-
import { formatFleetBackend, formatFleetResources, getFleetInstancesLinkText, getFleetStatusIconType } from 'libs/fleet';
9+
import { formatFleetBackend, formatFleetResources, getFleetInstancesLinkText, getFleetPrice, getFleetStatusIconType } from 'libs/fleet';
1010
import { ROUTES } from 'routes';
1111
import { useGetFleetDetailsQuery } from 'services/fleet';
1212

@@ -86,6 +86,11 @@ export const FleetDetails = () => {
8686
<Box variant="awsui-key-label">{t('fleets.instances.created')}</Box>
8787
<div>{format(new Date(data.created_at), DATE_TIME_FORMAT)}</div>
8888
</div>
89+
90+
<div>
91+
<Box variant="awsui-key-label">{t('fleets.instances.price')}</Box>
92+
<div>{(() => { const p = getFleetPrice(data); return typeof p === 'number' ? `$${p}` : '-'; })()}</div>
93+
</div>
8994
</ColumnLayout>
9095
</Container>
9196
)}

frontend/src/pages/Fleets/List/hooks.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Button, ListEmptyMessage, NavigateLink, StatusIndicator, TableProps } f
1010
import { DATE_TIME_FORMAT } from 'consts';
1111
import { useProjectFilter } from 'hooks/useProjectFilter';
1212
import { EMPTY_QUERY, requestParamsToTokens, tokensToRequestParams, tokensToSearchParams } from 'libs/filters';
13-
import { formatFleetBackend, formatFleetResources, getFleetInstancesLinkText, getFleetStatusIconType } from 'libs/fleet';
13+
import { formatFleetBackend, formatFleetResources, getFleetInstancesLinkText, getFleetPrice, getFleetStatusIconType } from 'libs/fleet';
1414
import { ROUTES } from 'routes';
1515

1616
export const useEmptyMessages = ({
@@ -96,6 +96,14 @@ export const useColumnsDefinitions = () => {
9696
header: t('fleets.instances.created'),
9797
cell: (item) => format(new Date(item.created_at), DATE_TIME_FORMAT),
9898
},
99+
{
100+
id: 'price',
101+
header: t('fleets.instances.price'),
102+
cell: (item) => {
103+
const price = getFleetPrice(item);
104+
return typeof price === 'number' ? `$${price}` : '-';
105+
},
106+
},
99107
];
100108

101109
return { columns } as const;

frontend/src/pages/Instances/Details/InstanceDetails/index.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,14 @@ export const InstanceDetails = () => {
7777
</div>
7878

7979
<div>
80-
<Box variant="awsui-key-label">{t('fleets.instances.health')}</Box>
80+
<Box variant="awsui-key-label">{t('projects.run.error')}</Box>
8181
<div>
82-
{data.status === 'idle' || data.status === 'busy' ? (
83-
<StatusIndicator
84-
type={data.unreachable ? 'error' : getHealthStatusIconType(data.health_status)}
85-
/>
82+
{data.unreachable ? (
83+
<StatusIndicator type="error">Unreachable</StatusIndicator>
84+
) : data.health_status !== 'healthy' ? (
85+
<StatusIndicator type={getHealthStatusIconType(data.health_status)}>
86+
{prettyEnumValue(data.health_status)}
87+
</StatusIndicator>
8688
) : (
8789
'-'
8890
)}
@@ -140,17 +142,17 @@ export const InstanceDetails = () => {
140142
<div>{typeof data.price === 'number' ? `$${data.price}` : '-'}</div>
141143
</div>
142144

143-
<div>
144-
<Box variant="awsui-key-label">{t('fleets.instances.hostname')}</Box>
145-
<div>{data.hostname ?? '-'}</div>
146-
</div>
147-
148145
{data.total_blocks !== null && (
149146
<div>
150147
<Box variant="awsui-key-label">{t('fleets.instances.blocks')}</Box>
151148
<div>{data.total_blocks}</div>
152149
</div>
153150
)}
151+
152+
<div>
153+
<Box variant="awsui-key-label">{t('fleets.instances.hostname')}</Box>
154+
<div>{data.hostname ?? '-'}</div>
155+
</div>
154156
</ColumnLayout>
155157
</Container>
156158
)}

frontend/src/pages/Instances/List/hooks/useColumnDefinitions.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Icon, NavigateLink, StatusIndicator, TableProps } from 'components';
66

77
import { DATE_TIME_FORMAT } from 'consts';
88
import { formatBackend, getStatusIconType } from 'libs/fleet';
9-
import { formatInstanceStatusText, getHealthStatusIconType } from 'libs/instance';
9+
import { formatInstanceStatusText, getHealthStatusIconType, prettyEnumValue } from 'libs/instance';
1010
import { formatResources } from 'libs/resources';
1111
import { ROUTES } from 'routes';
1212

@@ -54,12 +54,18 @@ export const useColumnsDefinitions = () => {
5454
),
5555
},
5656
{
57-
id: 'health',
58-
header: t('fleets.instances.health'),
59-
cell: (item) =>
60-
item.status === 'idle' || item.status === 'busy' ? (
61-
<StatusIndicator type={item.unreachable ? 'error' : getHealthStatusIconType(item.health_status)} />
62-
) : null,
57+
id: 'error',
58+
header: t('projects.run.error'),
59+
cell: (item) => {
60+
if (item.unreachable) return <StatusIndicator type="error">Unreachable</StatusIndicator>;
61+
if (item.health_status !== 'healthy')
62+
return (
63+
<StatusIndicator type={getHealthStatusIconType(item.health_status)}>
64+
{prettyEnumValue(item.health_status)}
65+
</StatusIndicator>
66+
);
67+
return null;
68+
},
6369
},
6470
{
6571
id: 'hostname',
@@ -71,6 +77,11 @@ export const useColumnsDefinitions = () => {
7177
header: t('fleets.instances.backend'),
7278
cell: (item) => formatBackend(item.backend),
7379
},
80+
{
81+
id: 'price',
82+
header: t('fleets.instances.price'),
83+
cell: (item) => (typeof item.price === 'number' ? `$${item.price}` : '-'),
84+
},
7485
{
7586
id: 'region',
7687
header: t('fleets.instances.region'),
@@ -97,9 +108,9 @@ export const useColumnsDefinitions = () => {
97108
cell: (item) => format(new Date(item.created), DATE_TIME_FORMAT),
98109
},
99110
{
100-
id: 'price',
101-
header: t('fleets.instances.price'),
102-
cell: (item) => (typeof item.price === 'number' ? `$${item.price}` : '-'),
111+
id: 'finished_at',
112+
header: t('fleets.instances.finished_at'),
113+
cell: (item) => (item.finished_at ? format(new Date(item.finished_at), DATE_TIME_FORMAT) : '-'),
103114
},
104115
];
105116

0 commit comments

Comments
 (0)