From be0ae160be73b66ee39744c32f5183f6d5206140 Mon Sep 17 00:00:00 2001 From: leonardcser <73912641+leonardcser@users.noreply.github.com> Date: Tue, 30 Sep 2025 11:50:08 +0200 Subject: [PATCH 1/4] refactor: remove public executions --- apps/api/src/cron.ts | 1 - apps/api/src/db/queries.ts | 128 -------------- apps/api/src/db/schema/index.ts | 7 - apps/api/src/email.ts | 1 - apps/api/src/index.ts | 2 - apps/api/src/routes/deployments.ts | 1 - apps/api/src/routes/executions.ts | 86 --------- apps/api/src/routes/objects.ts | 17 +- apps/api/src/routes/public.ts | 166 ------------------ apps/api/src/routes/workflows.ts | 3 - apps/api/src/runtime/runtime.ts | 3 - apps/api/src/utils/og-image-generator.ts | 66 ------- .../executions/execution-info-card.tsx | 23 --- apps/web/src/pages/docs/api-page.tsx | 1 - apps/web/src/pages/execution-detail-page.tsx | 86 +-------- apps/web/src/pages/executions-page.tsx | 30 +--- apps/web/src/pages/home-page.tsx | 11 +- apps/web/src/routes.tsx | 34 ---- apps/web/src/services/execution-service.ts | 85 +-------- apps/web/src/services/workflow-service.ts | 4 - packages/types/src/execution.ts | 8 - packages/types/src/workflow.ts | 1 - 22 files changed, 14 insertions(+), 750 deletions(-) delete mode 100644 apps/api/src/routes/public.ts delete mode 100644 apps/api/src/utils/og-image-generator.ts diff --git a/apps/api/src/cron.ts b/apps/api/src/cron.ts index a0314066..458af3b4 100644 --- a/apps/api/src/cron.ts +++ b/apps/api/src/cron.ts @@ -73,7 +73,6 @@ async function executeWorkflow( userId: "cron_trigger", organizationId: workflowInfo.organizationId, status: "executing" as ExecutionStatusType, - visibility: "private", nodeExecutions, createdAt: new Date(), updatedAt: new Date(), diff --git a/apps/api/src/db/queries.ts b/apps/api/src/db/queries.ts index cdaf3e20..a5d098bc 100644 --- a/apps/api/src/db/queries.ts +++ b/apps/api/src/db/queries.ts @@ -86,7 +86,6 @@ export type SaveExecutionRecord = { organizationId: string; status: ExecutionStatusType; nodeExecutions: NodeExecution[]; - visibility: "public" | "private"; error?: string; createdAt?: Date; updatedAt?: Date; @@ -481,7 +480,6 @@ export async function saveExecution( status: record.status as WorkflowExecutionStatus, nodeExecutions, error: record.error, - visibility: record.visibility, startedAt: record.startedAt, endedAt: record.endedAt, }; @@ -914,25 +912,6 @@ export async function listExecutions( return results.map((item) => item.executions); } -/** - * Get a public execution by ID - * - * @param db Database instance - * @param id Execution ID - * @returns Execution record or undefined if not found or not public - */ -export async function getPublicExecution( - db: ReturnType, - id: string -): Promise { - const [execution] = await db - .select() - .from(executions) - .where(and(eq(executions.id, id), eq(executions.visibility, "public"))); - - return execution; -} - /** * Get workflow names by their IDs * @@ -977,113 +956,6 @@ export async function getWorkflowName( return workflow?.name; } -/** - * Update execution visibility to public - * - * @param db Database instance - * @param executionId Execution ID - * @param organizationId Organization ID - * @returns The updated execution record - */ -export async function updateExecutionToPublic( - db: ReturnType, - executionId: string, - organizationId: string -): Promise { - const [execution] = await db - .update(executions) - .set({ visibility: "public", updatedAt: new Date() }) - .where( - and( - eq(executions.id, executionId), - eq(executions.organizationId, organizationId) - ) - ) - .returning(); - - return execution; -} - -/** - * Update execution visibility to private - * - * @param db Database instance - * @param executionId Execution ID - * @param organizationId Organization ID - * @returns The updated execution record - */ -export async function updateExecutionToPrivate( - db: ReturnType, - executionId: string, - organizationId: string -): Promise { - const [execution] = await db - .update(executions) - .set({ visibility: "private", updatedAt: new Date() }) - .where( - and( - eq(executions.id, executionId), - eq(executions.organizationId, organizationId) - ) - ) - .returning(); - - return execution; -} - -/** - * Update execution OG image generation status - * - * @param db Database instance - * @param executionId Execution ID - * @returns The updated execution record - */ -export async function updateExecutionOgImageStatus( - db: ReturnType, - executionId: string -): Promise { - const [execution] = await db - .update(executions) - .set({ ogImageGenerated: true, updatedAt: new Date() }) - .where(eq(executions.id, executionId)) - .returning(); - - return execution; -} - -/** - * Get execution with visibility check - * - * @param db Database instance - * @param executionId Execution ID - * @param organizationId Organization ID - * @returns The execution record with visibility status - */ -export async function getExecutionWithVisibility( - db: ReturnType, - executionId: string, - organizationId: string -): Promise< - | { id: string; organizationId: string; ogImageGenerated: boolean | null } - | undefined -> { - const [execution] = await db - .select({ - id: executions.id, - organizationId: executions.organizationId, - ogImageGenerated: executions.ogImageGenerated, - }) - .from(executions) - .where( - and( - eq(executions.id, executionId), - eq(executions.organizationId, organizationId) - ) - ); - - return execution; -} - /** * Get a cron trigger. * diff --git a/apps/api/src/db/schema/index.ts b/apps/api/src/db/schema/index.ts index 5f0c0062..1f308b6d 100644 --- a/apps/api/src/db/schema/index.ts +++ b/apps/api/src/db/schema/index.ts @@ -284,16 +284,10 @@ export const executions = sqliteTable( .$type() .notNull(), error: text("error"), - visibility: text("visibility", { enum: ["public", "private"] }) - .notNull() - .default("private"), startedAt: integer("started_at", { mode: "timestamp" }), endedAt: integer("ended_at", { mode: "timestamp" }), createdAt: createCreatedAt(), updatedAt: createUpdatedAt(), - ogImageGenerated: integer("og_image_generated", { - mode: "boolean", - }).default(false), }, (table) => [ index("executions_workflow_id_idx").on(table.workflowId), @@ -303,7 +297,6 @@ export const executions = sqliteTable( index("executions_created_at_idx").on(table.createdAt), index("executions_started_at_idx").on(table.startedAt), index("executions_ended_at_idx").on(table.endedAt), - index("executions_visibility_idx").on(table.visibility), // Composite indexes for common query patterns index("executions_organization_id_status_idx").on( table.organizationId, diff --git a/apps/api/src/email.ts b/apps/api/src/email.ts index e3d76546..b3139172 100644 --- a/apps/api/src/email.ts +++ b/apps/api/src/email.ts @@ -186,7 +186,6 @@ export async function handleIncomingEmail( userId: "email", organizationId: workflow.organizationId, status: ExecutionStatus.EXECUTING, - visibility: "private", nodeExecutions, createdAt: new Date(), updatedAt: new Date(), diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 3a1dc23c..c260d8f5 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -16,7 +16,6 @@ import llmsRoutes from "./routes/llms"; import objectRoutes from "./routes/objects"; import organizationRoutes from "./routes/organizations"; import profileRoutes from "./routes/profile"; -import publicRoutes from "./routes/public"; import robotsRoutes from "./routes/robots"; import secretRoutes from "./routes/secrets"; import typeRoutes from "./routes/types"; @@ -55,7 +54,6 @@ app.route("/robots.txt", robotsRoutes); app.route("/llms.txt", llmsRoutes); // Public routes -app.route("/public", publicRoutes); app.route("/types", typeRoutes); app.route("/:organizationIdOrHandle/api-keys", apiKeyRoutes); diff --git a/apps/api/src/routes/deployments.ts b/apps/api/src/routes/deployments.ts index c2eb3450..56ee2214 100644 --- a/apps/api/src/routes/deployments.ts +++ b/apps/api/src/routes/deployments.ts @@ -364,7 +364,6 @@ deploymentRoutes.post( userId, organizationId, status: executingStatus, - visibility: "private", nodeExecutions, createdAt: new Date(), updatedAt: new Date(), diff --git a/apps/api/src/routes/executions.ts b/apps/api/src/routes/executions.ts index ef3c2ce9..512d0b67 100644 --- a/apps/api/src/routes/executions.ts +++ b/apps/api/src/routes/executions.ts @@ -2,7 +2,6 @@ import { GetExecutionResponse, ListExecutionsRequest, ListExecutionsResponse, - UpdateExecutionVisibilityResponse, WorkflowExecution, WorkflowExecutionStatus, } from "@dafthunk/types"; @@ -13,15 +12,10 @@ import { ApiContext } from "../context"; import { createDatabase, getExecution, - getExecutionWithVisibility, getWorkflowName, getWorkflowNames, listExecutions, - updateExecutionOgImageStatus, - updateExecutionToPrivate, - updateExecutionToPublic, } from "../db"; -import { generateExecutionOgImage } from "../utils/og-image-generator"; const executionRoutes = new Hono(); @@ -53,7 +47,6 @@ executionRoutes.get("/:id", apiKeyOrJwtMiddleware, async (c) => { status: execution.status as WorkflowExecutionStatus, nodeExecutions: executionData.nodeExecutions || [], error: execution.error || undefined, - visibility: execution.visibility, startedAt: execution.startedAt ?? executionData.startedAt, endedAt: execution.endedAt ?? executionData.endedAt, }; @@ -102,7 +95,6 @@ executionRoutes.get("/", jwtMiddleware, async (c) => { status: execution.status as WorkflowExecutionStatus, nodeExecutions: executionData.nodeExecutions || [], error: execution.error || undefined, - visibility: execution.visibility, startedAt: execution.startedAt ?? executionData.startedAt, endedAt: execution.endedAt ?? executionData.endedAt, }; @@ -112,82 +104,4 @@ executionRoutes.get("/", jwtMiddleware, async (c) => { return c.json(response); }); -executionRoutes.patch("/:id/share/public", jwtMiddleware, async (c) => { - const executionId = c.req.param("id"); - const db = createDatabase(c.env.DB); - const organizationId = c.get("organizationId")!; - - try { - const execution = await getExecutionWithVisibility( - db, - executionId, - organizationId - ); - - if (!execution) { - return c.json({ error: "Execution not found" }, 404); - } - - await updateExecutionToPublic(db, executionId, organizationId); - - if (!execution.ogImageGenerated && c.env.BROWSER) { - try { - await generateExecutionOgImage({ - env: c.env, - executionId: executionId, - organizationId: organizationId, - }); - - await updateExecutionOgImageStatus(db, executionId); - console.log( - `Execution ${executionId} updated with OG image generation status.` - ); - } catch (error) { - console.error( - `OG image generation step failed for execution ${executionId}, but execution is now public. Error: ${error}` - ); - } - } - - const response: UpdateExecutionVisibilityResponse = { - success: true, - message: "Execution set to public", - }; - return c.json(response); - } catch (error) { - console.error("Error setting execution to public:", error); - return c.json({ error: "Failed to set execution to public" }, 500); - } -}); - -executionRoutes.patch("/:id/share/private", jwtMiddleware, async (c) => { - const id = c.req.param("id"); - const db = createDatabase(c.env.DB); - - const organizationId = c.get("organizationId")!; - - try { - const execution = await getExecution(db, id, organizationId); - - if (!execution) { - return c.json({ error: "Execution not found" }, 404); - } - - // The check execution.organizationId !== orgId is implicitly handled by getExecutionById - // if it correctly filters by organizationId. If not, this check might be needed here. - // However, getExecutionById already takes orgId, so it should be fine. - - await updateExecutionToPrivate(db, id, organizationId); - - const response: UpdateExecutionVisibilityResponse = { - success: true, - message: "Execution set to private", - }; - return c.json(response); - } catch (error) { - console.error("Error setting execution to private:", error); - return c.json({ error: "Failed to set execution to private" }, 500); - } -}); - export default executionRoutes; diff --git a/apps/api/src/routes/objects.ts b/apps/api/src/routes/objects.ts index 3d5399f6..ad7f6a76 100644 --- a/apps/api/src/routes/objects.ts +++ b/apps/api/src/routes/objects.ts @@ -48,7 +48,6 @@ objectRoutes.get("/", apiKeyOrJwtMiddleware, async (c) => { const db = createDatabase(c.env.DB); const [execution] = await db .select({ - visibility: executionsTable.visibility, organizationId: executionsTable.organizationId, }) .from(executionsTable) @@ -58,17 +57,13 @@ objectRoutes.get("/", apiKeyOrJwtMiddleware, async (c) => { return c.text("Object not found or linked to invalid execution", 404); } - if (execution.visibility === "private") { - // For private executions, the execution's organization must match the requesting organization - if (execution.organizationId !== requestingOrganizationId) { - return c.text( - "Forbidden: You do not have access to this object via its execution", - 403 - ); - } + // For private executions, the execution's organization must match the requesting organization + if (execution.organizationId !== requestingOrganizationId) { + return c.text( + "Forbidden: You do not have access to this object via its execution", + 403 + ); } - // If execution is public, access is allowed for any authenticated entity (JWT user or API key). - // No further check against requestingOrganizationId is needed here for public executions. } else { // Object not linked to an execution, check its own organizationId if (metadata?.organizationId !== requestingOrganizationId) { diff --git a/apps/api/src/routes/public.ts b/apps/api/src/routes/public.ts deleted file mode 100644 index 510dd0b7..00000000 --- a/apps/api/src/routes/public.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - GetPublicExecutionResponse, - ObjectReference, - PublicExecutionWithStructure, - Workflow, - WorkflowExecution, - WorkflowExecutionStatus, -} from "@dafthunk/types"; -import { eq } from "drizzle-orm"; -import { Hono } from "hono"; - -import { ApiContext } from "../context"; -import { createDatabase } from "../db"; -import { - executions as executionsTable, - getPublicExecution, - getWorkflow, -} from "../db"; -import { ObjectStore } from "../runtime/object-store"; - -const publicRoutes = new Hono(); - -// Public Objects Route -publicRoutes.get("/objects", async (c) => { - const objectId = c.req.query("id"); - const mimeType = c.req.query("mimeType"); - - if (!objectId || !mimeType) { - return c.text("Missing required parameters: id and mimeType", 400); - } - - try { - const objectStore = new ObjectStore(c.env.RESSOURCES); - const reference: ObjectReference = { id: objectId, mimeType }; - const result = await objectStore.readObject(reference); - - if (!result) { - return c.text("Object not found", 404); - } - - const { data, metadata } = result; - - if (!metadata?.executionId) { - return c.text("Object is not linked to an execution", 404); - } - - const db = createDatabase(c.env.DB); - const [execution] = await db - .select({ - visibility: executionsTable.visibility, - organizationId: executionsTable.organizationId, - }) - .from(executionsTable) - .where(eq(executionsTable.id, metadata.executionId)); - - if (!execution) { - return c.text("Object not found or linked to invalid execution", 404); - } - - if (execution.visibility !== "public") { - return c.text( - "Forbidden: You do not have access to this object via its execution", - 403 - ); - } - - return c.body(data, { - headers: { - "content-type": mimeType, - "Cache-Control": "public, max-age=31536000", - }, - }); - } catch (error) { - console.error("Object retrieval error:", error); - if (error instanceof Error && error.message.startsWith("Forbidden")) { - return c.text(error.message, 403); - } - return c.text("Object not found or error retrieving object", 404); - } -}); - -// Public Executions Route -publicRoutes.get("/executions/:id", async (c) => { - const id = c.req.param("id"); - const db = createDatabase(c.env.DB); - - try { - const executionRecord = await getPublicExecution(db, id); - - if (!executionRecord) { - return c.json({ error: "Execution not found or not public" }, 404); - } - - let workflowNodes: Workflow["nodes"] = []; - let workflowEdges: Workflow["edges"] = []; - let workflowName = "Unknown Workflow"; - - const workflowRecord = await getWorkflow( - db, - executionRecord.workflowId, - executionRecord.organizationId - ); - - if (workflowRecord) { - const workflowDataFromDb = workflowRecord.data as Workflow; - workflowNodes = workflowDataFromDb.nodes || []; - workflowEdges = workflowDataFromDb.edges || []; - workflowName = workflowRecord.name || workflowName; - } - - const executionData = executionRecord.data as WorkflowExecution; - const responseExecution: PublicExecutionWithStructure = { - id: executionRecord.id, - workflowId: executionRecord.workflowId, - workflowName: workflowName, - deploymentId: executionRecord.deploymentId ?? undefined, - status: executionRecord.status as WorkflowExecutionStatus, - nodeExecutions: executionData.nodeExecutions || [], - error: executionRecord.error || undefined, - visibility: executionRecord.visibility, - startedAt: executionRecord.startedAt ?? executionData.startedAt, - endedAt: executionRecord.endedAt ?? executionData.endedAt, - nodes: workflowNodes, - edges: workflowEdges, - }; - - const response: GetPublicExecutionResponse = { - execution: responseExecution, - }; - return c.json(response); - } catch (error) { - console.error("Error retrieving public execution:", error); - return c.json({ error: "Failed to retrieve public execution" }, 500); - } -}); - -// Public Images Route -publicRoutes.get("/images/:key", async (c) => { - const key = c.req.param("key"); - - try { - const object = await c.env.RESSOURCES.get("images/" + key); - const mimeType = object?.httpMetadata?.contentType; - - if (!object || !mimeType) { - return c.text("Image not found", 404); - } - - const image = new Uint8Array(await object.arrayBuffer()); - - return c.body(image, { - headers: { - "content-type": mimeType, - "Cache-Control": "public, max-age=31536000", - }, - }); - } catch (error) { - console.error("Object retrieval error:", error); - if (error instanceof Error && error.message.startsWith("Forbidden")) { - return c.text(error.message, 403); - } - return c.text("Object not found or error retrieving object", 404); - } -}); - -export default publicRoutes; diff --git a/apps/api/src/routes/workflows.ts b/apps/api/src/routes/workflows.ts index 5e0a38b9..e5683536 100644 --- a/apps/api/src/routes/workflows.ts +++ b/apps/api/src/routes/workflows.ts @@ -681,7 +681,6 @@ workflowRoutes.post( userId, organizationId: organizationId, status: ExecutionStatus.EXECUTING, - visibility: "private", nodeExecutions, createdAt: new Date(), updatedAt: new Date(), @@ -741,7 +740,6 @@ workflowRoutes.post( status: ExecutionStatus.CANCELLED, nodeExecutions: execution.data.nodeExecutions || [], error: execution.error ?? "Execution cancelled by user", - visibility: execution.visibility, updatedAt: now, endedAt: now, startedAt: execution.startedAt ?? undefined, @@ -767,7 +765,6 @@ workflowRoutes.post( status: ExecutionStatus.CANCELLED, nodeExecutions: execution.data.nodeExecutions || [], error: execution.error ?? "Execution cancelled by user", - visibility: execution.visibility, updatedAt: now, endedAt: now, startedAt: execution.startedAt ?? undefined, diff --git a/apps/api/src/runtime/runtime.ts b/apps/api/src/runtime/runtime.ts index 6de4bbe8..bb43f6c7 100644 --- a/apps/api/src/runtime/runtime.ts +++ b/apps/api/src/runtime/runtime.ts @@ -204,7 +204,6 @@ export class Runtime extends WorkflowEntrypoint { deploymentId: event.payload.deploymentId, status: "submitted", nodeExecutions: [], - visibility: "private", startedAt: undefined, endedAt: undefined, } as WorkflowExecution; @@ -1244,7 +1243,6 @@ export class Runtime extends WorkflowEntrypoint { status: executionStatus as ExecutionStatusType, nodeExecutions: nodeExecutionList, error: errorMsg, - visibility: "private", updatedAt: new Date(), startedAt, endedAt, @@ -1260,7 +1258,6 @@ export class Runtime extends WorkflowEntrypoint { status: executionStatus, nodeExecutions: nodeExecutionList, error: errorMsg, - visibility: "private", startedAt, endedAt, }; diff --git a/apps/api/src/utils/og-image-generator.ts b/apps/api/src/utils/og-image-generator.ts deleted file mode 100644 index 2de7f828..00000000 --- a/apps/api/src/utils/og-image-generator.ts +++ /dev/null @@ -1,66 +0,0 @@ -import puppeteer from "@cloudflare/puppeteer"; - -import { type Bindings } from "../context"; - -const OG_IMAGE_WIDTH = 1200; -const OG_IMAGE_HEIGHT = 630; - -interface OgImageGeneratorParams { - env: Pick; - executionId: string; - organizationId: string; - sharedExecutionPath?: string; -} - -/** - * Generates an OG image for a given execution, saves it to R2, and returns the R2 key. - * Throws an error if any step fails. - */ -export async function generateExecutionOgImage({ - env, - executionId, - organizationId, - sharedExecutionPath = "/public/executions/", -}: OgImageGeneratorParams): Promise { - let browser = null; - console.log( - `[ogImageGenerator] Starting OG image generation for execution ID: ${executionId}` - ); - - try { - browser = await puppeteer.launch(env.BROWSER as any); - const page = await browser.newPage(); - - const targetUrl = `${env.WEB_HOST}${sharedExecutionPath}${executionId}?fullscreen&theme=light`; - - await page.setViewport({ width: OG_IMAGE_WIDTH, height: OG_IMAGE_HEIGHT }); - await page.goto(targetUrl, { waitUntil: "networkidle0" }); - - const screenshotBuffer = await page.screenshot({ - type: "jpeg", - quality: 80, - }); - - const key = `images/og-execution-${executionId}.jpeg`; - await env.RESSOURCES.put(key, screenshotBuffer, { - httpMetadata: { - contentType: "image/jpeg", - cacheControl: "public, max-age=31536000", - }, - customMetadata: { - executionId, - organizationId, - }, - }); - } catch (error) { - console.error( - `[ogImageGenerator] Error during OG image generation for ${executionId}: ${error}` - ); - // Re-throw the error to be handled by the caller - throw error; - } finally { - if (browser) { - await browser.close(); - } - } -} diff --git a/apps/web/src/components/executions/execution-info-card.tsx b/apps/web/src/components/executions/execution-info-card.tsx index 047a49f4..8e7beea7 100644 --- a/apps/web/src/components/executions/execution-info-card.tsx +++ b/apps/web/src/components/executions/execution-info-card.tsx @@ -16,15 +16,11 @@ import { CardTitle, } from "@/components/ui/card"; import { useOrgUrl } from "@/hooks/use-org-url"; -import { cn } from "@/utils/utils"; - -import { Badge } from "../ui/badge"; import { ExecutionStatusBadge } from "./execution-status-badge"; interface ExecutionInfoCardProps { id: string; status: WorkflowExecutionStatus; - visibility: "public" | "private"; startedAt?: Date; endedAt?: Date; workflowId: string; @@ -38,7 +34,6 @@ interface ExecutionInfoCardProps { export function ExecutionInfoCard({ id, status, - visibility, startedAt, endedAt, workflowId, @@ -82,24 +77,6 @@ export function ExecutionInfoCard({ {description}
- {visibility && ( - - {visibility === "public" ? ( - - ) : ( - - )} - {visibility} - - )}
diff --git a/apps/web/src/pages/docs/api-page.tsx b/apps/web/src/pages/docs/api-page.tsx index 9328f02c..31f48ffe 100644 --- a/apps/web/src/pages/docs/api-page.tsx +++ b/apps/web/src/pages/docs/api-page.tsx @@ -160,7 +160,6 @@ export function DocsApiPage() { } } ], - "visibility": "private", "startedAt": "2024-01-15T10:30:00.000Z", "endedAt": "2024-01-15T10:31:23.000Z" } diff --git a/apps/web/src/pages/execution-detail-page.tsx b/apps/web/src/pages/execution-detail-page.tsx index e6168593..0a758768 100644 --- a/apps/web/src/pages/execution-detail-page.tsx +++ b/apps/web/src/pages/execution-detail-page.tsx @@ -1,18 +1,12 @@ import type { NodeExecution, WorkflowExecution } from "@dafthunk/types"; -import Eye from "lucide-react/icons/eye"; -import EyeOff from "lucide-react/icons/eye-off"; -import Share2 from "lucide-react/icons/share-2"; import { useEffect, useMemo, useState } from "react"; -import { Link, useParams } from "react-router"; +import { useParams } from "react-router"; import { toast } from "sonner"; -import { useAuth } from "@/components/auth-context"; import { ExecutionInfoCard } from "@/components/executions/execution-info-card"; import { InsetError } from "@/components/inset-error"; import { InsetLoading } from "@/components/inset-loading"; import { InsetLayout } from "@/components/layouts/inset-layout"; -import { Button } from "@/components/ui/button"; -import { LoadingButton } from "@/components/ui/loading-button"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { WorkflowBuilder } from "@/components/workflow/workflow-builder"; import type { @@ -22,11 +16,7 @@ import type { import { useOrgUrl } from "@/hooks/use-org-url"; import { usePageBreadcrumbs } from "@/hooks/use-page"; import { useDeploymentVersion } from "@/services/deployment-service"; -import { - setExecutionPrivate, - setExecutionPublic, - useExecution, -} from "@/services/execution-service"; +import { useExecution } from "@/services/execution-service"; import { useObjectService } from "@/services/object-service"; import { convertToReactFlowEdges, @@ -37,14 +27,12 @@ import { export function ExecutionDetailPage() { const { executionId } = useParams<{ executionId: string }>(); const { setBreadcrumbs } = usePageBreadcrumbs([]); - const { organization } = useAuth(); const { getOrgUrl } = useOrgUrl(); const { execution, executionError: executionDetailsError, isExecutionLoading: isExecutionDetailsLoading, - mutateExecution: mutateExecutionDetails, } = useExecution(executionId || null); const { createObjectUrl } = useObjectService(); @@ -96,8 +84,6 @@ export function ExecutionDetailPage() { const [reactFlowNodes, setReactFlowNodes] = useState([]); const [reactFlowEdges, setReactFlowEdges] = useState([]); - const [isVisibilityUpdating, setIsVisibilityUpdating] = useState(false); - useEffect(() => { if (executionId) { setBreadcrumbs([ @@ -182,39 +168,6 @@ export function ExecutionDetailPage() { [reactFlowEdges] ); - const handleToggleVisibility = async () => { - if (!execution || !executionId || !organization?.handle) return; - - setIsVisibilityUpdating(true); - const newVisibility = - execution.visibility === "public" ? "private" : "public"; - - try { - let success = false; - - if (newVisibility === "public") { - success = await setExecutionPublic(executionId, organization.handle); - } else { - success = await setExecutionPrivate(executionId, organization.handle); - } - - if (success) { - toast.success(`Execution successfully made ${newVisibility}.`); - mutateExecutionDetails(); - } else { - toast.error(`Failed to update visibility.`); - } - } catch (error) { - toast.error( - `Failed to update visibility: ${ - error instanceof Error ? error.message : String(error) - }` - ); - } - - setIsVisibilityUpdating(false); - }; - if (isExecutionDetailsLoading || isStructureOverallLoading) { return ; } else if (executionDetailsError) { @@ -245,45 +198,12 @@ export function ExecutionDetailPage() { Status Visualization - {execution && ( -
- {execution.visibility === "public" && executionId && ( - - )} - - ) : ( - - ) - } - > - {execution.visibility === "public" - ? "Make Private" - : "Make Public"} - -
- )} + {execution &&
} ; }, }, - { - accessorKey: "visibility", - header: "Visibility", - cell: ({ row }) => { - const visibility = row.getValue( - "visibility" - ) as WorkflowExecution["visibility"]; - return ( - - {visibility === "public" ? ( - - ) : ( - - )} - {visibility} - - ); - }, - }, + { accessorKey: "startedAt", header: "Started At", diff --git a/apps/web/src/pages/home-page.tsx b/apps/web/src/pages/home-page.tsx index 9887821c..cbfe09a6 100644 --- a/apps/web/src/pages/home-page.tsx +++ b/apps/web/src/pages/home-page.tsx @@ -11,7 +11,6 @@ import { Link, Navigate } from "react-router"; import { useAuth } from "@/components/auth-context"; import { HomeFooter } from "@/components/layouts/home-footer"; import { HomeHeader } from "@/components/layouts/home-header"; -import { useTheme } from "@/components/theme-provider"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardHeader, CardTitle } from "@/components/ui/card"; @@ -67,11 +66,8 @@ const features = [ export function HomePage() { const { user, isAuthenticated } = useAuth(); - const { theme } = useTheme(); const { getOrgUrl } = useOrgUrl(); - const homepagePublicExecutionUrl = `${import.meta.env.VITE_WEBSITE_URL}/public/executions/${import.meta.env.VITE_HOMEPAGE_PUBLIC_EXECUTION_ID}?fullscreen`; - if (isAuthenticated && user) { return ; } @@ -133,10 +129,9 @@ export function HomePage() {
-