Enhance canvas functionality with new node types and validation

- Added support for new canvas node types: curves, color-adjust, light-adjust, detail-adjust, and render.
- Implemented validation for adjustment nodes to restrict incoming edges to one.
- Updated canvas connection validation to improve user feedback on invalid connections.
- Enhanced node creation and rendering logic to accommodate new node types and their properties.
- Refactored related components and utilities for better maintainability and performance.
This commit is contained in:
Matthias
2026-04-02 11:39:05 +02:00
parent 9bab9bb93d
commit f3c5c2d8f1
52 changed files with 5755 additions and 44 deletions

View File

@@ -1,7 +1,36 @@
import { query, mutation } from "./_generated/server";
import { query, mutation, type MutationCtx } from "./_generated/server";
import { v } from "convex/values";
import { requireAuth } from "./helpers";
import type { Id } from "./_generated/dataModel";
import type { Doc, Id } from "./_generated/dataModel";
import { isAdjustmentNodeType } from "../lib/canvas-node-types";
async function assertTargetAllowsIncomingEdge(
ctx: MutationCtx,
args: {
targetNodeId: Id<"nodes">;
edgeIdToIgnore?: Id<"edges">;
},
): Promise<void> {
const targetNode = await ctx.db.get(args.targetNodeId);
if (!targetNode) {
throw new Error("Target node not found");
}
if (!isAdjustmentNodeType(targetNode.type)) {
return;
}
const incomingEdges = await ctx.db
.query("edges")
.withIndex("by_target", (q) => q.eq("targetNodeId", args.targetNodeId))
.collect();
const existingIncoming = incomingEdges.filter(
(edge: Doc<"edges">) => edge._id !== args.edgeIdToIgnore,
);
if (existingIncoming.length >= 1) {
throw new Error("Adjustment nodes allow only one incoming edge.");
}
}
// ============================================================================
// Queries
@@ -89,6 +118,10 @@ export const create = mutation({
throw new Error("Cannot connect a node to itself");
}
await assertTargetAllowsIncomingEdge(ctx, {
targetNodeId: args.targetNodeId,
});
const edgeId = await ctx.db.insert("edges", {
canvasId: args.canvasId,
sourceNodeId: args.sourceNodeId,