first commit

This commit is contained in:
Zakaria
2026-09-22 16:13:21 -04:00
commit 7e49be27f1
297 changed files with 63162 additions and 0 deletions
@@ -0,0 +1,89 @@
import {Cloud} from 'lucide-react'
import {Navigate, useNavigate, useParams, useSearchParams} from 'react-router-dom'
import {CloudSelector} from '@/components/CloudSelector'
import {
ProviderBanner,
RuntimeFlow,
ServiceGrid,
SummarySection,
} from '@/features/cloud-console/CloudConsoleSections'
import {useCloudConsoleHomeData} from '@/features/cloud-console/useCloudConsoleHomeData'
import type {CloudProvider} from '@/types/cloud'
export function CloudConsoleHomePage() {
const navigate = useNavigate()
const params = useParams()
const [searchParams] = useSearchParams()
const search = (searchParams.get('search') ?? '').trim().toLowerCase()
const routeCloud = normalizeCloud(params.cloud)
const cloud = routeCloud ?? 'aws'
const data = useCloudConsoleHomeData(cloud)
if (!routeCloud) return <Navigate to="/console/aws" replace/>
const filteredServices = search
? data.serviceCards.filter((s) =>
s.label.toLowerCase().includes(search) ||
s.id.toLowerCase().includes(search) ||
s.meta?.toLowerCase().includes(search)
)
: data.serviceCards
return (
<>
<div className="page-header cloud-explorer-header">
<div className="page-title">
<Cloud size={20}/>
<div>
<h1>Console Home</h1>
<p className="muted">Cloud-aware local runtime overview</p>
</div>
</div>
<div className="cloud-header-selectors">
<label>
<span>Cloud</span>
<CloudSelector
clouds={data.cloudsQuery.data ?? []}
selected={cloud}
onSelect={(nextCloud) => navigate(`/console/${nextCloud}`)}
/>
</label>
</div>
</div>
<div className="content cloud-console-home">
<ProviderBanner
cloud={cloud}
runtimeClass={data.runtimeClass}
runtimeReachable={data.status?.runtime === 'reachable'}
onOpenStorage={() => navigate(`/cloud-explorer/${cloud}/storage`)}
/>
<SummarySection
cloud={cloud}
runtimeLabel={data.runtimeLabel}
runtimeState={data.runtimeState}
runtimeClass={data.runtimeClass}
runtimeDetail={data.runtimeDetail}
activeServices={data.activeServices}
activeServicesDetail={data.activeServicesDetail}
resourceCount={data.resourceCount}
resourceDetail={data.resourceDetail}
/>
<RuntimeFlow cloud={cloud} status={data.status}/>
<ServiceGrid
services={filteredServices}
searchQuery={search}
runtimeReachable={data.status?.runtime === 'reachable'}
onNavigate={(route) => navigate(route)}
/>
</div>
</>
)
}
function normalizeCloud(value?: string): CloudProvider | null {
return value === 'aws' || value === 'azure' || value === 'gcp' ? value : null
}
@@ -0,0 +1,305 @@
import {useMemo, useState} from 'react'
import {Cloud, X} from 'lucide-react'
import {Navigate, useNavigate, useParams} from 'react-router-dom'
import {useQuery} from '@tanstack/react-query'
import {Link} from 'react-router-dom'
import {getServiceSchema} from '@/api/cloudProxyClient'
import {useCloudServicesQuery, useCloudStatusQuery, useCloudsQuery} from '@/api/queries/cloudQueries'
import {CloudSelector} from '@/components/CloudSelector'
import {DynamicResourceView} from '@/components/DynamicResourceView'
import {EmptyState} from '@/components/EmptyState'
import {normalizeCapabilities, withRuntimeState, withServiceAvailability} from '@/lib/capabilities'
import type {CloudProvider, CloudServiceDescriptor, CloudServiceType, CloudStatus} from '@/types/cloud'
import type {ServiceSchema} from '@/types/schema'
export function CloudExplorerPage() {
const navigate = useNavigate()
const params = useParams()
const routeCloud = normalizeCloud(params.cloud)
const cloud = routeCloud ?? 'aws'
const service = params.service ?? ''
const [infoOpen, setInfoOpen] = useState(false)
const cloudsQuery = useCloudsQuery()
const servicesQuery = useCloudServicesQuery(cloud)
const statusQuery = useCloudStatusQuery(cloud)
const schemaQuery = useQuery({
queryKey: ['cloud-schema', cloud, service],
queryFn: ({signal}) => getServiceSchema(cloud, service, signal),
enabled: Boolean(service),
})
const selectedService = useMemo(
() => servicesQuery.data?.find((item) => item.service === service),
[service, servicesQuery.data],
)
// Until the catalog resolves, availability is unknown — not "coming soon".
// Treating it as unknown keeps a registered service from flashing the
// adapter-coming-soon notice on every load.
const catalogPending = servicesQuery.isPending
if (!routeCloud) {
return <Navigate to="/cloud-explorer/aws/storage" replace/>
}
// Never redirect while the catalog is still loading: doing so silently sent
// any unknown or slow-loading service to storage.
if (servicesQuery.isSuccess && !selectedService) {
return <UnknownServiceNotice cloud={cloud} service={service} services={servicesQuery.data}/>
}
return (
<>
<div className="page-header cloud-explorer-header">
<div className="page-title">
<Cloud size={20}/>
<div>
<h1>Cloud Explorer</h1>
<p className="muted">Unified local runtime console</p>
</div>
</div>
<div className="cloud-header-selectors">
<label>
<span>Service</span>
<div className="service-selector-readonly">{selectedService?.displayName ?? service}</div>
</label>
<label>
<span>Cloud</span>
<CloudSelector
clouds={cloudsQuery.data ?? []}
selected={cloud}
onSelect={(nextCloud) => navigate(`/cloud-explorer/${nextCloud}/storage`)}
/>
</label>
</div>
</div>
<div className="content cloud-explorer">
<DynamicResourceView
cloud={cloud}
service={service}
serviceAvailability={selectedService?.availability}
serviceReason={selectedService?.reason}
cloudStatus={statusQuery.data}
statusLoading={statusQuery.isLoading || catalogPending}
onOpenInfo={() => setInfoOpen(true)}
/>
</div>
{infoOpen && (
<ServiceInfoDialog
cloud={cloud}
service={service}
descriptor={selectedService}
status={statusQuery.data}
statusLoading={statusQuery.isLoading}
schema={schemaQuery.data}
onClose={() => setInfoOpen(false)}
/>
)}
</>
)
}
function normalizeCloud(value?: string): CloudProvider | null {
return value === 'aws' || value === 'azure' || value === 'gcp' ? value : null
}
function ServiceInfoDialog({
cloud,
service,
descriptor,
status,
statusLoading,
schema,
onClose,
}: {
cloud: CloudProvider
service: CloudServiceType
descriptor?: CloudServiceDescriptor
status?: CloudStatus
statusLoading: boolean
schema?: ServiceSchema
onClose: () => void
}) {
const capabilityList = schema?.capabilities
? withServiceAvailability(
withRuntimeState(
normalizeCapabilities([
...(schema.capabilities.resourceActions ?? []),
...(schema.capabilities.objectActions ?? []),
...(schema.capabilities.kubernetesActions ?? []),
...(schema.capabilities.databaseActions ?? []),
]),
status?.runtime === 'reachable',
),
descriptor?.availability ?? 'coming_soon',
)
: []
const actionFallback = schema?.actions.join(', ') ?? 'Loading actions'
return (
<div className="modal-overlay" onClick={onClose}>
<div className="service-info-dialog" onClick={(event) => event.stopPropagation()}>
<div className="service-info-header">
<div>
<p className="eyebrow">Service Information</p>
<h3>{schema?.displayName ?? descriptor?.displayName ?? service}</h3>
</div>
<button className="icon-btn" type="button" onClick={onClose} aria-label="Close" title="Close">
<X size={14} aria-hidden="true"/>
</button>
</div>
<div className="service-info-grid">
<InfoCard label="Proxy API" value={`/api/clouds/${cloud}/services/${service}`} detail="Single entry point used by the UI"/>
<InfoCard label="Service" value={descriptor?.displayName ?? service} detail={serviceAvailability(descriptor)}/>
<InfoCard label="Runtime" value={runtimeValue(status)} detail={runtimeDetail(status, statusLoading)} state={runtimeState(status, statusLoading)}/>
<InfoCard label="Adapter" value={adapterValue(cloud, status)} detail={adapterDetail(status, statusLoading)} state={adapterState(cloud, status)}/>
<InfoCard label="Connection" value={connectionValue(status, statusLoading)} detail={status?.endpoint ?? 'No runtime endpoint'} state={runtimeState(status, statusLoading)}/>
<InfoCard label="Normalized Contract" value={schema?.columns.length ? `${schema.columns.length} columns · ${schema.filters.length} filters` : 'Loading schema'} detail="Shared table and resource inspector"/>
</div>
<div className="service-info-section">
<p className="eyebrow">Supported Actions</p>
{capabilityList.length ? (
<div className="capability-strip">
{capabilityList.map((capability) => (
<span
key={capability.name}
className={`capability-pill ${capability.status}`}
title={capability.reason}
>
{capability.label}
</span>
))}
</div>
) : (
<p className="service-info-copy">{actionFallback}</p>
)}
</div>
{descriptor?.reason && (
<div className="service-info-section">
<p className="eyebrow">Availability</p>
<p className="service-info-copy">{descriptor.reason}</p>
</div>
)}
</div>
</div>
)
}
function InfoCard({
label,
value,
detail,
state,
}: {
label: string
value: string
detail: string
state?: 'ready' | 'pending' | 'unavailable'
}) {
return (
<div className={`service-info-card ${state ?? ''}`}>
<span>{label}</span>
<strong>{value}</strong>
<small>{detail}</small>
</div>
)
}
function serviceAvailability(service?: CloudServiceDescriptor): string {
if (!service) return 'Loading service schema'
return service.availability === 'available' ? 'Schema available' : 'Coming soon'
}
function runtimeValue(status?: CloudStatus): string {
return status?.endpoint?.replace(/^https?:\/\//, '') ?? 'Unknown'
}
function runtimeDetail(status?: CloudStatus, loading?: boolean): string {
if (loading) return 'Checking runtime'
if (!status) return 'Status unavailable'
if (status.runtime === 'reachable') return 'Runtime reachable'
if (status.runtime === 'unavailable') return status.error ?? 'Runtime unavailable'
return 'Runtime coming soon'
}
function runtimeState(status?: CloudStatus, loading?: boolean): 'ready' | 'pending' | 'unavailable' {
if (loading || !status || status.runtime === 'coming_soon') return 'pending'
return status.runtime === 'reachable' ? 'ready' : 'unavailable'
}
function adapterValue(cloud: CloudProvider, status?: CloudStatus): string {
if (cloud === 'gcp') return 'GCP Adapter'
if (status?.adapterRegistered === false) return 'Not registered'
return `${cloud.toUpperCase()} Adapter`
}
function adapterDetail(status?: CloudStatus, loading?: boolean): string {
if (loading) return 'Checking adapter'
if (!status) return 'Adapter status unknown'
return status.adapterRegistered ? 'Adapter ready' : 'Coming soon'
}
function adapterState(_cloud: CloudProvider, status?: CloudStatus): 'ready' | 'pending' | 'unavailable' {
if (!status || !status.adapterRegistered) return 'pending'
return 'ready'
}
function connectionValue(status?: CloudStatus, loading?: boolean): string {
if (loading) return 'Checking'
if (!status) return 'Unknown'
if (status.runtime === 'reachable') return 'Connected'
if (status.runtime === 'unavailable') return 'Not connected'
return 'Coming soon'
}
/**
* A slug that is not in the server's catalog. Previously this silently redirected
* to storage, so a typo or a stale bookmark looked like a working page.
*/
function UnknownServiceNotice({
cloud,
service,
services,
}: {
cloud: CloudProvider
service: string
services?: CloudServiceDescriptor[]
}) {
const available = (services ?? []).filter((item) => item.availability === 'available')
return (
<>
<div className="page-header cloud-explorer-header">
<div className="page-title">
<Cloud size={20}/>
<div>
<h1>Cloud Explorer</h1>
<p className="muted">Unified local runtime console</p>
</div>
</div>
</div>
<div className="content cloud-explorer">
<EmptyState
icon={Cloud}
title={service ? `${cloud.toUpperCase()} has no service called "${service}"` : 'No service selected'}
description="Pick one of the services this runtime exposes."
/>
<div className="unknown-service-links">
{available.map((item) => (
<Link
className="button compact"
key={item.service}
to={item.route.startsWith('/') ? item.route : `/cloud-explorer/${cloud}/${item.route}`}
>
{item.displayName}
</Link>
))}
<Link className="button compact" to={`/console/${cloud}`}>Console Home</Link>
</div>
</div>
</>
)
}
@@ -0,0 +1,89 @@
import {ArrowLeft, Database} from 'lucide-react'
import {Link, useParams, useSearchParams} from 'react-router-dom'
import {useQuery} from '@tanstack/react-query'
import {getCloudResource} from '@/api/cloudProxyClient'
import {HttpError} from '@/api/HttpClient'
import {useCloudServicesQuery, useCloudStatusQuery} from '@/api/queries/cloudQueries'
import {AzureSqlPanel} from '@/components/AzureSqlPanel'
import {CosmosNoSqlPanel} from '@/components/CosmosNoSqlPanel'
import {DynamoDbTableExplorer} from '@/components/DynamoDbTableExplorer'
import {useAccountId} from '@/lib/accountStore'
import {dataExplorerKind} from '@/lib/dataExplorer'
import type {CloudProvider} from '@/types/cloud'
export function DatabaseDataPage() {
const {cloud, service, resourceId} = useParams()
const accountId = useAccountId()
if ((cloud !== 'aws' && cloud !== 'azure' && cloud !== 'gcp') || !service || !resourceId) {
return <div className="content"><DataNotice title="Invalid data workspace" detail="Check the cloud, service, and resource in this link."/>
<Link to="/console/aws">Console Home</Link></div>
}
return <DatabaseDataWorkspace key={`${accountId}:${cloud}:${service}:${resourceId}`} cloud={cloud} service={service} resourceId={resourceId}/>
}
function DatabaseDataWorkspace({cloud, service, resourceId}: {cloud: CloudProvider; service: string; resourceId: string}) {
const accountId = useAccountId()
const [searchParams, setSearchParams] = useSearchParams()
const servicesQuery = useCloudServicesQuery(cloud)
const statusQuery = useCloudStatusQuery(cloud)
const descriptor = servicesQuery.data?.find((item) => item.service === service)
const resourceQuery = useQuery({
queryKey: ['cloud-data-resource', accountId, cloud, service, resourceId],
queryFn: ({signal}) => getCloudResource(cloud, service, resourceId, signal),
enabled: descriptor?.availability === 'available' && statusQuery.data?.runtime === 'reachable',
})
const resource = resourceQuery.data
const kind = resource && dataExplorerKind(resource)
const containerId = searchParams.get('container') || undefined
function retry() {
void servicesQuery.refetch()
void statusQuery.refetch()
if (descriptor?.availability === 'available' && statusQuery.data?.runtime === 'reachable') void resourceQuery.refetch()
}
function selectContainer(id: string | undefined) {
setSearchParams((previous) => {
const next = new URLSearchParams(previous)
if (id) next.set('container', id)
else next.delete('container')
return next
})
}
function renderWorkspace() {
if (servicesQuery.isPending || statusQuery.isPending) return <DataNotice title="Loading workspace" detail="Checking service availability and runtime connection."/>
if (servicesQuery.isError || statusQuery.isError) return <DataNotice title="Unable to load workspace" detail={(servicesQuery.error ?? statusQuery.error)?.message} onRetry={retry}/>
if (!descriptor) return <DataNotice title="Unknown service" detail={`No ${service} service exists for ${cloud.toUpperCase()}.`}/>
if (descriptor.availability !== 'available') return <DataNotice title="Service unavailable" detail={descriptor.reason ?? 'This service has no available adapter.'}/>
if (statusQuery.data?.runtime !== 'reachable') return <DataNotice title="Runtime unavailable" detail={statusQuery.data?.error ?? 'Start the selected runtime to explore data.'} onRetry={retry}/>
if (resourceQuery.isError) return <DataNotice title={resourceQuery.error instanceof HttpError && resourceQuery.error.status === 404 ? 'Resource not found' : 'Unable to load resource'} detail={resourceQuery.error.message} onRetry={retry}/>
if (!resource) return <DataNotice title="Loading resource" detail="Reading resource details from the runtime."/>
if (kind === 'dynamodb') return <DynamoDbTableExplorer cloud={cloud} resource={resource} runtimeReachable/>
if (kind === 'cosmos') return <CosmosNoSqlPanel key={containerId ?? ''} cloud={cloud} resource={resource} runtimeReachable selectedContainerId={containerId} onSelectContainer={selectContainer}/>
if (kind === 'sql') return <AzureSqlPanel cloud={cloud} resource={resource} runtimeReachable/>
return <DataNotice title="Data exploration unavailable" detail="This resource supports management operations only."/>
}
return (
<div className="database-data-page">
<header className="page-header data-workspace-header">
<Link className="button compact" to={`/cloud-explorer/${cloud}/${service}`}><ArrowLeft size={14}/>Back to {descriptor?.displayName ?? service}</Link>
<div className="page-title">
<Database size={20}/>
<div>
<h1>{resource?.name ?? resourceId}</h1>
<p className="muted">{cloud.toUpperCase()} · {descriptor?.displayName ?? service} · Explore data</p>
</div>
</div>
</header>
<div className="data-workspace">{renderWorkspace()}</div>
</div>
)
}
function DataNotice({title, detail, onRetry}: {title: string; detail?: string; onRetry?: () => void}) {
return <div className="runtime-notice" role="status"><h3>{title}</h3>{detail && <p>{detail}</p>}
{onRetry && <button className="button" type="button" onClick={onRetry}>Retry</button>}
</div>
}