feat: Lightsail + svg animation

This commit is contained in:
Zakaria
2026-10-11 14:19:00 -04:00
parent 0036ef7e51
commit ca1e845cb6
40 changed files with 1887 additions and 34 deletions
@@ -3,6 +3,7 @@ import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
import {useEffect, useState} from 'react'
import {getLoadBalancingDependencies, listFlatItems, putFlatItem, deleteFlatItem} from '@/api/cloudProxyClient'
import {useAccountId} from '@/lib/accountStore'
import {LoadBalancingProgress} from '@/components/LoadBalancingProgress'
import type {CloudResource} from '@/types/resource'
type Props = {
@@ -37,7 +38,21 @@ export function TargetGroupPanel({resource, runtimeReachable}: Props) {
void Promise.all([dependenciesQuery.refetch(), healthQuery.refetch()])
}
const registerMutation = useMutation({
mutationFn: () => putFlatItem('aws', 'targetgroups', resource?.id ?? '', {id: instanceId, port: Number(port)}),
mutationFn: async () => {
const startedAt = Date.now()
await putFlatItem('aws', 'targetgroups', resource?.id ?? '', {id: instanceId, port: Number(port)})
while (true) {
const health = await listFlatItems('aws', 'targetgroups', resource?.id ?? '')
const target = health.items.find((item) => stringValue(item.body.id) === instanceId && Number(item.body.port) === Number(port))
const state = stringValue(target?.body.state).toLowerCase()
if (state === 'healthy' || state === 'unhealthy') {
const remaining = 5_000 - (Date.now() - startedAt)
if (remaining > 0) await new Promise<void>((resolve) => setTimeout(resolve, remaining))
return
}
await new Promise<void>((resolve) => setTimeout(resolve, 500))
}
},
onSuccess: () => queryClient.invalidateQueries({queryKey: ['target-group-health', accountId, resource?.id]}),
})
const deregisterMutation = useMutation({
@@ -63,6 +78,7 @@ export function TargetGroupPanel({resource, runtimeReachable}: Props) {
<label className="dynamic-field"><span>Target port</span><input className="input" type="number" min="1" max="65535" value={port} onChange={(event) => setPort(event.target.value)} disabled={registerMutation.isPending}/></label>
<div style={{alignSelf: 'end'}}><button className="button primary" type="submit" disabled={!runtimeReachable || !instanceId || !validPort || registerMutation.isPending}>{registerMutation.isPending ? 'Registering' : 'Register target'}</button></div>
{instances.length === 0 && dependenciesQuery.isSuccess && <p className="muted">No running instances are available in this account.</p>}
{registerMutation.isPending && <div className="dynamic-field--span"><LoadBalancingProgress kind="target" description="Waiting for the target health check to become healthy or unhealthy."/></div>}
</form>
{error instanceof Error && <p className="error-text compact-text" role="alert">{error.message}</p>}
{healthQuery.isLoading && <div className="muted padded">Loading target health</div>}