feat: Cloudformation + RDS
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { ChevronDown, ChevronUp, Info, Loader2, Plus, RefreshCw, Trash2, X } from "lucide-react";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
@@ -49,6 +49,10 @@ import { ApiGatewayRoutePanel } from "@/components/ApiGatewayRoutePanel";
|
||||
import { S3LambdaTriggerPanel } from "@/components/S3LambdaTriggerPanel";
|
||||
import { ScheduledLambdaTriggerPanel } from "@/components/ScheduledLambdaTriggerPanel";
|
||||
import { SqsLambdaTriggerPanel } from "@/components/SqsLambdaTriggerPanel";
|
||||
import { SqsQueuePanel } from "@/components/SqsQueuePanel";
|
||||
import { CloudFormationStackPanel } from "@/components/CloudFormationStackPanel";
|
||||
import { CloudFormationCreatePanel } from "@/components/CloudFormationCreatePanel";
|
||||
import { CloudFormationUpdatePanel } from "@/components/CloudFormationUpdatePanel";
|
||||
import { EventBridgeRulePanel } from "@/components/EventBridgeRulePanel";
|
||||
import { LambdaInvocationHistoryPanel } from "@/components/LambdaInvocationHistoryPanel";
|
||||
import { LambdaCreatePanel } from "@/components/LambdaCreatePanel";
|
||||
@@ -62,7 +66,7 @@ import { WorkflowExecutionDebugger } from "@/components/WorkflowExecutionDebugge
|
||||
import {WorkflowCreatePanel} from "@/components/WorkflowCreatePanel";
|
||||
import {workflowCreationDestinationPath, type WorkflowCreationDestination} from "@/lib/workflowCreate";
|
||||
import {workflowStudioPath} from "@/lib/workflowStudio";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
||||
|
||||
interface DynamicResourceViewProps {
|
||||
cloud: CloudProvider;
|
||||
@@ -90,6 +94,7 @@ export function DynamicResourceView({
|
||||
onOpenInfo,
|
||||
}: DynamicResourceViewProps) {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const qc = useQueryClient();
|
||||
const [search, setSearch] = useState("");
|
||||
const [state, setState] = useState("");
|
||||
@@ -105,6 +110,7 @@ export function DynamicResourceView({
|
||||
const [deleteConfirm, setDeleteConfirm] = useState(false);
|
||||
const [bulkDeleteError, setBulkDeleteError] = useState<string | null>(null);
|
||||
const [deleteWarning, setDeleteWarning] = useState<string | null>(null);
|
||||
const openedResourceRef = useRef<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (cloud === "aws" && service === "compute") {
|
||||
@@ -139,6 +145,16 @@ export function DynamicResourceView({
|
||||
cloudStatus?.runtime === "reachable",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const resourceId = searchParams.get("resource");
|
||||
if (!resourceId || !resourcesQuery.data) return;
|
||||
const key = `${cloud}:${service}:${resourceId}`;
|
||||
if (openedResourceRef.current === key) return;
|
||||
const resource = resourcesQuery.data.find((candidate) => candidate.id === resourceId);
|
||||
if (resource) setSelected(resource);
|
||||
openedResourceRef.current = key;
|
||||
}, [cloud, resourcesQuery.data, searchParams, service]);
|
||||
|
||||
// Automatically reconcile selected items when resources query data changes
|
||||
useEffect(() => {
|
||||
setSelectedItems((prev) => {
|
||||
@@ -284,6 +300,10 @@ export function DynamicResourceView({
|
||||
const warning = bucketDeleteWarning(contents);
|
||||
if (warning) throw new Error(warning);
|
||||
}
|
||||
if (cloud === "aws" && service === "iac") {
|
||||
const current = await getCloudResource(cloud, service, resource.id);
|
||||
if (current?.metadata.enableTerminationProtection === true) throw new Error("Termination protection is enabled. Disable it from Stack actions before deleting this stack.");
|
||||
}
|
||||
await deleteCloudResource(cloud, service, resource.id);
|
||||
},
|
||||
onSuccess: (_, resource) => {
|
||||
@@ -797,13 +817,20 @@ export function DynamicResourceView({
|
||||
onCancel={() => setCreateOpen(false)}
|
||||
onSubmit={(values) => createMut.mutate({values})}
|
||||
/>
|
||||
) : service === "workflows" && cloud === "aws" ? (
|
||||
) : service === "workflows" && cloud === "aws" ? (
|
||||
<WorkflowCreatePanel
|
||||
isSubmitting={createMut.isPending}
|
||||
submitError={createMut.error instanceof Error ? createMut.error.message : null}
|
||||
onCancel={() => setCreateOpen(false)}
|
||||
onSubmit={(submission) => createMut.mutate(submission)}
|
||||
/>
|
||||
) : service === "iac" && cloud === "aws" ? (
|
||||
<CloudFormationCreatePanel
|
||||
isSubmitting={createMut.isPending}
|
||||
submitError={createMut.error instanceof Error ? createMut.error.message : null}
|
||||
onCancel={() => setCreateOpen(false)}
|
||||
onSubmit={(values) => createMut.mutate({values})}
|
||||
/>
|
||||
) : (
|
||||
<DynamicFormRenderer
|
||||
key={`${cloud}:${service}:create`}
|
||||
@@ -886,6 +913,8 @@ export function DynamicResourceView({
|
||||
{cloud === "aws" && <S3BucketWebsitePanel resource={selected} runtimeReachable={canUseRuntime} />}
|
||||
</>
|
||||
)}
|
||||
{service === "messaging" && cloud === "aws" && <SqsQueuePanel resource={activeSelected} runtimeReachable={canUseRuntime} />}
|
||||
{service === "iac" && cloud === "aws" && <CloudFormationStackPanel resource={activeSelected} />}
|
||||
{service === "ecr" && cloud === "aws" && (
|
||||
<EcrImageBrowser resource={activeSelected} runtimeReachable={canUseRuntime} />
|
||||
)}
|
||||
@@ -1015,7 +1044,7 @@ export function DynamicResourceView({
|
||||
onCancel={() => setEditingResource(null)}
|
||||
onSubmit={handleEditSubmit}
|
||||
/>
|
||||
) : <DynamicFormRenderer
|
||||
) : service === "iac" && cloud === "aws" ? <CloudFormationUpdatePanel initialTemplate={String(initialEditValues.templateBody ?? '')} isSubmitting={updateMut.isPending} submitError={updateError} onCancel={() => setEditingResource(null)} onSubmit={handleEditSubmit}/> : <DynamicFormRenderer
|
||||
key={editingResource.id}
|
||||
schema={schema}
|
||||
fields={schema.updateFields}
|
||||
|
||||
Reference in New Issue
Block a user