feat: add share page settings dialog + add org id to deployment as well
This commit is contained in:
		
							parent
							
								
									b2690ab2c5
								
							
						
					
					
						commit
						30ec7d3105
					
				
							
								
								
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								web/drizzle/0029_large_frightful_four.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								web/drizzle/0029_large_frightful_four.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					ALTER TABLE "comfyui_deploy"."deployments" ADD COLUMN "description" text;--> statement-breakpoint
 | 
				
			||||||
 | 
					ALTER TABLE "comfyui_deploy"."deployments" ADD COLUMN "showcase_media" jsonb;
 | 
				
			||||||
							
								
								
									
										1
									
								
								web/drizzle/0030_kind_doorman.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/drizzle/0030_kind_doorman.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					ALTER TABLE "comfyui_deploy"."deployments" ADD COLUMN "org_id" text;
 | 
				
			||||||
							
								
								
									
										750
									
								
								web/drizzle/meta/0029_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										750
									
								
								web/drizzle/meta/0029_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,750 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "id": "a7d6a8dd-0e15-4165-98a2-de2a334455dc",
 | 
				
			||||||
 | 
					  "prevId": "7bdeb193-ee27-40cc-8252-59ddaf505ab8",
 | 
				
			||||||
 | 
					  "version": "5",
 | 
				
			||||||
 | 
					  "dialect": "pg",
 | 
				
			||||||
 | 
					  "tables": {
 | 
				
			||||||
 | 
					    "api_keys": {
 | 
				
			||||||
 | 
					      "name": "api_keys",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "key": {
 | 
				
			||||||
 | 
					          "name": "key",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "revoked": {
 | 
				
			||||||
 | 
					          "name": "revoked",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "api_keys_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "api_keys_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "api_keys",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {
 | 
				
			||||||
 | 
					        "api_keys_key_unique": {
 | 
				
			||||||
 | 
					          "name": "api_keys_key_unique",
 | 
				
			||||||
 | 
					          "nullsNotDistinct": false,
 | 
				
			||||||
 | 
					          "columns": [
 | 
				
			||||||
 | 
					            "key"
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "deployments": {
 | 
				
			||||||
 | 
					      "name": "deployments",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_version_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_version_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "machine_id": {
 | 
				
			||||||
 | 
					          "name": "machine_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "description": {
 | 
				
			||||||
 | 
					          "name": "description",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "showcase_media": {
 | 
				
			||||||
 | 
					          "name": "showcase_media",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "environment": {
 | 
				
			||||||
 | 
					          "name": "environment",
 | 
				
			||||||
 | 
					          "type": "deployment_environment",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "deployments_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_versions",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_version_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "no action",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_machine_id_machines_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_machine_id_machines_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "machines",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "machine_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "no action",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machines": {
 | 
				
			||||||
 | 
					      "name": "machines",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "endpoint": {
 | 
				
			||||||
 | 
					          "name": "endpoint",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "disabled": {
 | 
				
			||||||
 | 
					          "name": "disabled",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "auth_token": {
 | 
				
			||||||
 | 
					          "name": "auth_token",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "type": {
 | 
				
			||||||
 | 
					          "name": "type",
 | 
				
			||||||
 | 
					          "type": "machine_type",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'classic'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "status": {
 | 
				
			||||||
 | 
					          "name": "status",
 | 
				
			||||||
 | 
					          "type": "machine_status",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'ready'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "snapshot": {
 | 
				
			||||||
 | 
					          "name": "snapshot",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "models": {
 | 
				
			||||||
 | 
					          "name": "models",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "gpu": {
 | 
				
			||||||
 | 
					          "name": "gpu",
 | 
				
			||||||
 | 
					          "type": "machine_gpu",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "build_machine_instance_id": {
 | 
				
			||||||
 | 
					          "name": "build_machine_instance_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "build_log": {
 | 
				
			||||||
 | 
					          "name": "build_log",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "machines_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "machines_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "machines",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "users": {
 | 
				
			||||||
 | 
					      "name": "users",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "username": {
 | 
				
			||||||
 | 
					          "name": "username",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {},
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_outputs": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_outputs",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "run_id": {
 | 
				
			||||||
 | 
					          "name": "run_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "data": {
 | 
				
			||||||
 | 
					          "name": "data",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_run_outputs",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_runs",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "run_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_runs": {
 | 
				
			||||||
 | 
					      "name": "workflow_runs",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_version_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_version_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_inputs": {
 | 
				
			||||||
 | 
					          "name": "workflow_inputs",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "machine_id": {
 | 
				
			||||||
 | 
					          "name": "machine_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "origin": {
 | 
				
			||||||
 | 
					          "name": "origin",
 | 
				
			||||||
 | 
					          "type": "workflow_run_origin",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'api'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "status": {
 | 
				
			||||||
 | 
					          "name": "status",
 | 
				
			||||||
 | 
					          "type": "workflow_run_status",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'not-started'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "ended_at": {
 | 
				
			||||||
 | 
					          "name": "ended_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_versions",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_version_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "set null",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_runs_machine_id_machines_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "machines",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "machine_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "set null",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflows": {
 | 
				
			||||||
 | 
					      "name": "workflows",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflows_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflows_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflows",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_versions": {
 | 
				
			||||||
 | 
					      "name": "workflow_versions",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow": {
 | 
				
			||||||
 | 
					          "name": "workflow",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_api": {
 | 
				
			||||||
 | 
					          "name": "workflow_api",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "version": {
 | 
				
			||||||
 | 
					          "name": "version",
 | 
				
			||||||
 | 
					          "type": "integer",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "snapshot": {
 | 
				
			||||||
 | 
					          "name": "snapshot",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_versions",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "enums": {
 | 
				
			||||||
 | 
					    "deployment_environment": {
 | 
				
			||||||
 | 
					      "name": "deployment_environment",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "staging": "staging",
 | 
				
			||||||
 | 
					        "production": "production",
 | 
				
			||||||
 | 
					        "public-share": "public-share"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_gpu": {
 | 
				
			||||||
 | 
					      "name": "machine_gpu",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "T4": "T4",
 | 
				
			||||||
 | 
					        "A10G": "A10G",
 | 
				
			||||||
 | 
					        "A100": "A100"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_status": {
 | 
				
			||||||
 | 
					      "name": "machine_status",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "ready": "ready",
 | 
				
			||||||
 | 
					        "building": "building",
 | 
				
			||||||
 | 
					        "error": "error"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_type": {
 | 
				
			||||||
 | 
					      "name": "machine_type",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "classic": "classic",
 | 
				
			||||||
 | 
					        "runpod-serverless": "runpod-serverless",
 | 
				
			||||||
 | 
					        "modal-serverless": "modal-serverless",
 | 
				
			||||||
 | 
					        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_origin": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_origin",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "manual": "manual",
 | 
				
			||||||
 | 
					        "api": "api",
 | 
				
			||||||
 | 
					        "public-share": "public-share"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_status": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_status",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "not-started": "not-started",
 | 
				
			||||||
 | 
					        "running": "running",
 | 
				
			||||||
 | 
					        "uploading": "uploading",
 | 
				
			||||||
 | 
					        "success": "success",
 | 
				
			||||||
 | 
					        "failed": "failed"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "schemas": {
 | 
				
			||||||
 | 
					    "comfyui_deploy": "comfyui_deploy"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "_meta": {
 | 
				
			||||||
 | 
					    "schemas": {},
 | 
				
			||||||
 | 
					    "tables": {},
 | 
				
			||||||
 | 
					    "columns": {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										756
									
								
								web/drizzle/meta/0030_snapshot.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										756
									
								
								web/drizzle/meta/0030_snapshot.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,756 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "id": "db06ea66-92c2-4ebe-93c1-6cb8a90ccd8b",
 | 
				
			||||||
 | 
					  "prevId": "a7d6a8dd-0e15-4165-98a2-de2a334455dc",
 | 
				
			||||||
 | 
					  "version": "5",
 | 
				
			||||||
 | 
					  "dialect": "pg",
 | 
				
			||||||
 | 
					  "tables": {
 | 
				
			||||||
 | 
					    "api_keys": {
 | 
				
			||||||
 | 
					      "name": "api_keys",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "key": {
 | 
				
			||||||
 | 
					          "name": "key",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "revoked": {
 | 
				
			||||||
 | 
					          "name": "revoked",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "api_keys_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "api_keys_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "api_keys",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {
 | 
				
			||||||
 | 
					        "api_keys_key_unique": {
 | 
				
			||||||
 | 
					          "name": "api_keys_key_unique",
 | 
				
			||||||
 | 
					          "nullsNotDistinct": false,
 | 
				
			||||||
 | 
					          "columns": [
 | 
				
			||||||
 | 
					            "key"
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "deployments": {
 | 
				
			||||||
 | 
					      "name": "deployments",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_version_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_version_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "machine_id": {
 | 
				
			||||||
 | 
					          "name": "machine_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "description": {
 | 
				
			||||||
 | 
					          "name": "description",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "showcase_media": {
 | 
				
			||||||
 | 
					          "name": "showcase_media",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "environment": {
 | 
				
			||||||
 | 
					          "name": "environment",
 | 
				
			||||||
 | 
					          "type": "deployment_environment",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "deployments_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_workflow_version_id_workflow_versions_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_workflow_version_id_workflow_versions_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_versions",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_version_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "no action",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "deployments_machine_id_machines_id_fk": {
 | 
				
			||||||
 | 
					          "name": "deployments_machine_id_machines_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "deployments",
 | 
				
			||||||
 | 
					          "tableTo": "machines",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "machine_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "no action",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machines": {
 | 
				
			||||||
 | 
					      "name": "machines",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "endpoint": {
 | 
				
			||||||
 | 
					          "name": "endpoint",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "disabled": {
 | 
				
			||||||
 | 
					          "name": "disabled",
 | 
				
			||||||
 | 
					          "type": "boolean",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "auth_token": {
 | 
				
			||||||
 | 
					          "name": "auth_token",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "type": {
 | 
				
			||||||
 | 
					          "name": "type",
 | 
				
			||||||
 | 
					          "type": "machine_type",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'classic'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "status": {
 | 
				
			||||||
 | 
					          "name": "status",
 | 
				
			||||||
 | 
					          "type": "machine_status",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'ready'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "snapshot": {
 | 
				
			||||||
 | 
					          "name": "snapshot",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "models": {
 | 
				
			||||||
 | 
					          "name": "models",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "gpu": {
 | 
				
			||||||
 | 
					          "name": "gpu",
 | 
				
			||||||
 | 
					          "type": "machine_gpu",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "build_machine_instance_id": {
 | 
				
			||||||
 | 
					          "name": "build_machine_instance_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "build_log": {
 | 
				
			||||||
 | 
					          "name": "build_log",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "machines_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "machines_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "machines",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "users": {
 | 
				
			||||||
 | 
					      "name": "users",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "username": {
 | 
				
			||||||
 | 
					          "name": "username",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {},
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_outputs": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_outputs",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "run_id": {
 | 
				
			||||||
 | 
					          "name": "run_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "data": {
 | 
				
			||||||
 | 
					          "name": "data",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_run_outputs_run_id_workflow_runs_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_run_outputs_run_id_workflow_runs_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_run_outputs",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_runs",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "run_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_runs": {
 | 
				
			||||||
 | 
					      "name": "workflow_runs",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_version_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_version_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_inputs": {
 | 
				
			||||||
 | 
					          "name": "workflow_inputs",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "machine_id": {
 | 
				
			||||||
 | 
					          "name": "machine_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "origin": {
 | 
				
			||||||
 | 
					          "name": "origin",
 | 
				
			||||||
 | 
					          "type": "workflow_run_origin",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'api'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "status": {
 | 
				
			||||||
 | 
					          "name": "status",
 | 
				
			||||||
 | 
					          "type": "workflow_run_status",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "'not-started'"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "ended_at": {
 | 
				
			||||||
 | 
					          "name": "ended_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_runs_workflow_version_id_workflow_versions_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "workflow_versions",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_version_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "set null",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_runs_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_runs_machine_id_machines_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_runs_machine_id_machines_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_runs",
 | 
				
			||||||
 | 
					          "tableTo": "machines",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "machine_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "set null",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflows": {
 | 
				
			||||||
 | 
					      "name": "workflows",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "user_id": {
 | 
				
			||||||
 | 
					          "name": "user_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "org_id": {
 | 
				
			||||||
 | 
					          "name": "org_id",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "name": {
 | 
				
			||||||
 | 
					          "name": "name",
 | 
				
			||||||
 | 
					          "type": "text",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflows_user_id_users_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflows_user_id_users_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflows",
 | 
				
			||||||
 | 
					          "tableTo": "users",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "user_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_versions": {
 | 
				
			||||||
 | 
					      "name": "workflow_versions",
 | 
				
			||||||
 | 
					      "schema": "comfyui_deploy",
 | 
				
			||||||
 | 
					      "columns": {
 | 
				
			||||||
 | 
					        "workflow_id": {
 | 
				
			||||||
 | 
					          "name": "workflow_id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "id": {
 | 
				
			||||||
 | 
					          "name": "id",
 | 
				
			||||||
 | 
					          "type": "uuid",
 | 
				
			||||||
 | 
					          "primaryKey": true,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "gen_random_uuid()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow": {
 | 
				
			||||||
 | 
					          "name": "workflow",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "workflow_api": {
 | 
				
			||||||
 | 
					          "name": "workflow_api",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "version": {
 | 
				
			||||||
 | 
					          "name": "version",
 | 
				
			||||||
 | 
					          "type": "integer",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "snapshot": {
 | 
				
			||||||
 | 
					          "name": "snapshot",
 | 
				
			||||||
 | 
					          "type": "jsonb",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": false
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "created_at": {
 | 
				
			||||||
 | 
					          "name": "created_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "updated_at": {
 | 
				
			||||||
 | 
					          "name": "updated_at",
 | 
				
			||||||
 | 
					          "type": "timestamp",
 | 
				
			||||||
 | 
					          "primaryKey": false,
 | 
				
			||||||
 | 
					          "notNull": true,
 | 
				
			||||||
 | 
					          "default": "now()"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "indexes": {},
 | 
				
			||||||
 | 
					      "foreignKeys": {
 | 
				
			||||||
 | 
					        "workflow_versions_workflow_id_workflows_id_fk": {
 | 
				
			||||||
 | 
					          "name": "workflow_versions_workflow_id_workflows_id_fk",
 | 
				
			||||||
 | 
					          "tableFrom": "workflow_versions",
 | 
				
			||||||
 | 
					          "tableTo": "workflows",
 | 
				
			||||||
 | 
					          "columnsFrom": [
 | 
				
			||||||
 | 
					            "workflow_id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "columnsTo": [
 | 
				
			||||||
 | 
					            "id"
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					          "onDelete": "cascade",
 | 
				
			||||||
 | 
					          "onUpdate": "no action"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "compositePrimaryKeys": {},
 | 
				
			||||||
 | 
					      "uniqueConstraints": {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "enums": {
 | 
				
			||||||
 | 
					    "deployment_environment": {
 | 
				
			||||||
 | 
					      "name": "deployment_environment",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "staging": "staging",
 | 
				
			||||||
 | 
					        "production": "production",
 | 
				
			||||||
 | 
					        "public-share": "public-share"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_gpu": {
 | 
				
			||||||
 | 
					      "name": "machine_gpu",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "T4": "T4",
 | 
				
			||||||
 | 
					        "A10G": "A10G",
 | 
				
			||||||
 | 
					        "A100": "A100"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_status": {
 | 
				
			||||||
 | 
					      "name": "machine_status",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "ready": "ready",
 | 
				
			||||||
 | 
					        "building": "building",
 | 
				
			||||||
 | 
					        "error": "error"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "machine_type": {
 | 
				
			||||||
 | 
					      "name": "machine_type",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "classic": "classic",
 | 
				
			||||||
 | 
					        "runpod-serverless": "runpod-serverless",
 | 
				
			||||||
 | 
					        "modal-serverless": "modal-serverless",
 | 
				
			||||||
 | 
					        "comfy-deploy-serverless": "comfy-deploy-serverless"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_origin": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_origin",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "manual": "manual",
 | 
				
			||||||
 | 
					        "api": "api",
 | 
				
			||||||
 | 
					        "public-share": "public-share"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "workflow_run_status": {
 | 
				
			||||||
 | 
					      "name": "workflow_run_status",
 | 
				
			||||||
 | 
					      "values": {
 | 
				
			||||||
 | 
					        "not-started": "not-started",
 | 
				
			||||||
 | 
					        "running": "running",
 | 
				
			||||||
 | 
					        "uploading": "uploading",
 | 
				
			||||||
 | 
					        "success": "success",
 | 
				
			||||||
 | 
					        "failed": "failed"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "schemas": {
 | 
				
			||||||
 | 
					    "comfyui_deploy": "comfyui_deploy"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "_meta": {
 | 
				
			||||||
 | 
					    "schemas": {},
 | 
				
			||||||
 | 
					    "tables": {},
 | 
				
			||||||
 | 
					    "columns": {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -204,6 +204,20 @@
 | 
				
			|||||||
      "when": 1705642345817,
 | 
					      "when": 1705642345817,
 | 
				
			||||||
      "tag": "0028_futuristic_lady_deathstrike",
 | 
					      "tag": "0028_futuristic_lady_deathstrike",
 | 
				
			||||||
      "breakpoints": true
 | 
					      "breakpoints": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "idx": 29,
 | 
				
			||||||
 | 
					      "version": "5",
 | 
				
			||||||
 | 
					      "when": 1705662714161,
 | 
				
			||||||
 | 
					      "tag": "0029_large_frightful_four",
 | 
				
			||||||
 | 
					      "breakpoints": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "idx": 30,
 | 
				
			||||||
 | 
					      "version": "5",
 | 
				
			||||||
 | 
					      "when": 1705716303820,
 | 
				
			||||||
 | 
					      "tag": "0030_kind_doorman",
 | 
				
			||||||
 | 
					      "breakpoints": true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -60,6 +60,7 @@
 | 
				
			|||||||
    "dayjs": "^1.11.10",
 | 
					    "dayjs": "^1.11.10",
 | 
				
			||||||
    "drizzle-orm": "^0.29.1",
 | 
					    "drizzle-orm": "^0.29.1",
 | 
				
			||||||
    "drizzle-zod": "^0.5.1",
 | 
					    "drizzle-zod": "^0.5.1",
 | 
				
			||||||
 | 
					    "embla-carousel-react": "^8.0.0-rc19",
 | 
				
			||||||
    "fast-glob": "^3.3.2",
 | 
					    "fast-glob": "^3.3.2",
 | 
				
			||||||
    "flexsearch": "^0.7.31",
 | 
					    "flexsearch": "^0.7.31",
 | 
				
			||||||
    "framer-motion": "^10.16.16",
 | 
					    "framer-motion": "^10.16.16",
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import { SharePageSettings } from "@/components/SharePageSettings";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function Page({
 | 
				
			||||||
 | 
					  params,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  params: { share_id: string };
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  return <SharePageSettings deployment_id={params.share_id} />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								web/src/app/(app)/@modal/default.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								web/src/app/(app)/@modal/default.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					import type { FC } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Default: FC = () => {
 | 
				
			||||||
 | 
					  return null;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Default;
 | 
				
			||||||
@ -27,8 +27,10 @@ export const metadata: Metadata = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export default function RootLayout({
 | 
					export default function RootLayout({
 | 
				
			||||||
  children,
 | 
					  children,
 | 
				
			||||||
 | 
					  modal,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  children: React.ReactNode;
 | 
					  children: React.ReactNode;
 | 
				
			||||||
 | 
					  modal: React.ReactNode;
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <html lang="en">
 | 
					    <html lang="en">
 | 
				
			||||||
@ -51,6 +53,7 @@ export default function RootLayout({
 | 
				
			|||||||
                {children}
 | 
					                {children}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <Toaster richColors />
 | 
					              <Toaster richColors />
 | 
				
			||||||
 | 
					              {modal}
 | 
				
			||||||
            </main>
 | 
					            </main>
 | 
				
			||||||
          </body>
 | 
					          </body>
 | 
				
			||||||
        </TooltipProvider>
 | 
					        </TooltipProvider>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,6 @@
 | 
				
			|||||||
import { ButtonActionMenu } from "@/components/ButtonActionLoader";
 | 
					import { ButtonActionMenu } from "@/components/ButtonActionLoader";
 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  PublicRunOutputs,
 | 
					 | 
				
			||||||
} from "@/components/VersionSelect";
 | 
					 | 
				
			||||||
import { RunWorkflowInline } from "@/components/RunWorkflowInline";
 | 
					import { RunWorkflowInline } from "@/components/RunWorkflowInline";
 | 
				
			||||||
 | 
					import { PublicRunOutputs } from "@/components/VersionSelect";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Card,
 | 
					  Card,
 | 
				
			||||||
  CardContent,
 | 
					  CardContent,
 | 
				
			||||||
@ -89,6 +87,11 @@ export default async function Page({
 | 
				
			|||||||
        </CardHeader>
 | 
					        </CardHeader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <CardContent>
 | 
					        <CardContent>
 | 
				
			||||||
 | 
					          <div>
 | 
				
			||||||
 | 
					            {sharedDeployment?.description && (
 | 
				
			||||||
 | 
					              <>{sharedDeployment?.description}</>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
          <RunWorkflowInline
 | 
					          <RunWorkflowInline
 | 
				
			||||||
            inputs={inputs}
 | 
					            inputs={inputs}
 | 
				
			||||||
            machine_id={sharedDeployment.machine_id}
 | 
					            machine_id={sharedDeployment.machine_id}
 | 
				
			||||||
@ -102,7 +105,7 @@ export default async function Page({
 | 
				
			|||||||
        </CardHeader>
 | 
					        </CardHeader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <CardContent>
 | 
					        <CardContent>
 | 
				
			||||||
          <PublicRunOutputs />
 | 
					          <PublicRunOutputs preview={sharedDeployment.showcase_media} />
 | 
				
			||||||
        </CardContent>
 | 
					        </CardContent>
 | 
				
			||||||
      </Card>
 | 
					      </Card>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								web/src/app/(app)/share/[share_id]/settings/page.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								web/src/app/(app)/share/[share_id]/settings/page.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import { SharePageSettings } from "@/components/SharePageSettings";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function Page({
 | 
				
			||||||
 | 
					  params,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  params: { share_id: string };
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  return <SharePageSettings deployment_id={params.share_id} />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -17,7 +17,7 @@ export default async function Page({
 | 
				
			|||||||
      <CardHeader className="relative">
 | 
					      <CardHeader className="relative">
 | 
				
			||||||
        <CardTitle>Run</CardTitle>
 | 
					        <CardTitle>Run</CardTitle>
 | 
				
			||||||
        <div className="absolute right-6 top-6">
 | 
					        <div className="absolute right-6 top-6">
 | 
				
			||||||
          <RouteRefresher interval={5000} />
 | 
					          <RouteRefresher interval={5000} autoRefresh={false} />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </CardHeader>
 | 
					      </CardHeader>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
  DropdownMenuItem,
 | 
					  DropdownMenuItem,
 | 
				
			||||||
  DropdownMenuTrigger,
 | 
					  DropdownMenuTrigger,
 | 
				
			||||||
} from "@/components/ui/dropdown-menu";
 | 
					} from "@/components/ui/dropdown-menu";
 | 
				
			||||||
 | 
					import { useAuth, useClerk } from "@clerk/nextjs";
 | 
				
			||||||
import { MoreVertical } from "lucide-react";
 | 
					import { MoreVertical } from "lucide-react";
 | 
				
			||||||
import { useRouter } from "next/navigation";
 | 
					import { useRouter } from "next/navigation";
 | 
				
			||||||
import { useState } from "react";
 | 
					import { useState } from "react";
 | 
				
			||||||
@ -49,7 +50,9 @@ export function ButtonActionMenu(props: {
 | 
				
			|||||||
    action: () => Promise<any>;
 | 
					    action: () => Promise<any>;
 | 
				
			||||||
  }[];
 | 
					  }[];
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
 | 
					  const user = useAuth();
 | 
				
			||||||
  const [isLoading, setIsLoading] = useState(false);
 | 
					  const [isLoading, setIsLoading] = useState(false);
 | 
				
			||||||
 | 
					  const clerk = useClerk();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <DropdownMenu>
 | 
					    <DropdownMenu>
 | 
				
			||||||
@ -64,6 +67,13 @@ export function ButtonActionMenu(props: {
 | 
				
			|||||||
          <DropdownMenuItem
 | 
					          <DropdownMenuItem
 | 
				
			||||||
            key={action.title}
 | 
					            key={action.title}
 | 
				
			||||||
            onClick={async () => {
 | 
					            onClick={async () => {
 | 
				
			||||||
 | 
					              if (!user.isSignedIn) {
 | 
				
			||||||
 | 
					                clerk.openSignIn({
 | 
				
			||||||
 | 
					                  redirectUrl: window.location.href,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              setIsLoading(true);
 | 
					              setIsLoading(true);
 | 
				
			||||||
              await callServerPromise(action.action());
 | 
					              await callServerPromise(action.action());
 | 
				
			||||||
              setIsLoading(false);
 | 
					              setIsLoading(false);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
import { ButtonAction } from "@/components/ButtonActionLoader";
 | 
					import { DeploymentRow } from "./DeploymentRow";
 | 
				
			||||||
import { CodeBlock } from "@/components/CodeBlock";
 | 
					import { CodeBlock } from "@/components/CodeBlock";
 | 
				
			||||||
import { Button } from "@/components/ui/button";
 | 
					 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Dialog,
 | 
					  Dialog,
 | 
				
			||||||
  DialogContent,
 | 
					  DialogContent,
 | 
				
			||||||
@ -10,15 +9,9 @@ import {
 | 
				
			|||||||
  DialogTrigger,
 | 
					  DialogTrigger,
 | 
				
			||||||
} from "@/components/ui/dialog";
 | 
					} from "@/components/ui/dialog";
 | 
				
			||||||
import { ScrollArea } from "@/components/ui/scroll-area";
 | 
					import { ScrollArea } from "@/components/ui/scroll-area";
 | 
				
			||||||
import { TableCell, TableRow } from "@/components/ui/table";
 | 
					 | 
				
			||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
 | 
					import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
 | 
				
			||||||
import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
 | 
					import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
 | 
				
			||||||
import { getRelativeTime } from "@/lib/getRelativeTime";
 | 
					 | 
				
			||||||
import { removePublicShareDeployment } from "@/server/curdDeploments";
 | 
					 | 
				
			||||||
import type { findAllDeployments } from "@/server/findAllRuns";
 | 
					import type { findAllDeployments } from "@/server/findAllRuns";
 | 
				
			||||||
import { ExternalLink } from "lucide-react";
 | 
					 | 
				
			||||||
import { headers } from "next/headers";
 | 
					 | 
				
			||||||
import Link from "next/link";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const curlTemplate = `
 | 
					const curlTemplate = `
 | 
				
			||||||
curl --request POST \
 | 
					curl --request POST \
 | 
				
			||||||
@ -90,33 +83,21 @@ const run = await client.getRun(run_id);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function DeploymentDisplay({
 | 
					export function DeploymentDisplay({
 | 
				
			||||||
  deployment,
 | 
					  deployment,
 | 
				
			||||||
 | 
					  domain,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  deployment: Awaited<ReturnType<typeof findAllDeployments>>[0];
 | 
					  deployment: Awaited<ReturnType<typeof findAllDeployments>>[0];
 | 
				
			||||||
 | 
					  domain: string;
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const headersList = headers();
 | 
					 | 
				
			||||||
  const host = headersList.get("host") || "";
 | 
					 | 
				
			||||||
  const protocol = headersList.get("x-forwarded-proto") || "";
 | 
					 | 
				
			||||||
  const domain = `${protocol}://${host}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const workflowInput = getInputsFromWorkflow(deployment.version);
 | 
					  const workflowInput = getInputsFromWorkflow(deployment.version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (deployment.environment == "public-share") {
 | 
				
			||||||
 | 
					    return <DeploymentRow deployment={deployment} />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Dialog>
 | 
					    <Dialog>
 | 
				
			||||||
      <DialogTrigger asChild className="appearance-none hover:cursor-pointer">
 | 
					      <DialogTrigger asChild className="appearance-none hover:cursor-pointer">
 | 
				
			||||||
        <TableRow>
 | 
					        <DeploymentRow deployment={deployment} />
 | 
				
			||||||
          <TableCell className="capitalize truncate">
 | 
					 | 
				
			||||||
            {deployment.environment}
 | 
					 | 
				
			||||||
          </TableCell>
 | 
					 | 
				
			||||||
          <TableCell className="font-medium truncate">
 | 
					 | 
				
			||||||
            {deployment.version?.version}
 | 
					 | 
				
			||||||
          </TableCell>
 | 
					 | 
				
			||||||
          <TableCell className="font-medium truncate">
 | 
					 | 
				
			||||||
            {deployment.machine?.name}
 | 
					 | 
				
			||||||
          </TableCell>
 | 
					 | 
				
			||||||
          <TableCell className="text-right truncate">
 | 
					 | 
				
			||||||
            {getRelativeTime(deployment.updated_at)}
 | 
					 | 
				
			||||||
          </TableCell>
 | 
					 | 
				
			||||||
        </TableRow>
 | 
					 | 
				
			||||||
      </DialogTrigger>
 | 
					      </DialogTrigger>
 | 
				
			||||||
      <DialogContent className="max-w-3xl">
 | 
					      <DialogContent className="max-w-3xl">
 | 
				
			||||||
        <DialogHeader>
 | 
					        <DialogHeader>
 | 
				
			||||||
@ -126,105 +107,79 @@ export function DeploymentDisplay({
 | 
				
			|||||||
          <DialogDescription>Code for your deployment client</DialogDescription>
 | 
					          <DialogDescription>Code for your deployment client</DialogDescription>
 | 
				
			||||||
        </DialogHeader>
 | 
					        </DialogHeader>
 | 
				
			||||||
        <ScrollArea className="max-h-[600px] pr-4">
 | 
					        <ScrollArea className="max-h-[600px] pr-4">
 | 
				
			||||||
          {deployment.environment !== "public-share" ? (
 | 
					          <Tabs defaultValue="client" className="w-full gap-2 text-sm">
 | 
				
			||||||
            <Tabs defaultValue="client" className="w-full gap-2 text-sm">
 | 
					            <TabsList className="grid w-fit grid-cols-3 mb-2">
 | 
				
			||||||
              <TabsList className="grid w-fit grid-cols-3 mb-2">
 | 
					              <TabsTrigger value="client">Server Client</TabsTrigger>
 | 
				
			||||||
                <TabsTrigger value="client">Server Client</TabsTrigger>
 | 
					              <TabsTrigger value="js">NodeJS Fetch</TabsTrigger>
 | 
				
			||||||
                <TabsTrigger value="js">NodeJS Fetch</TabsTrigger>
 | 
					              <TabsTrigger value="curl">CURL</TabsTrigger>
 | 
				
			||||||
                <TabsTrigger value="curl">CURL</TabsTrigger>
 | 
					            </TabsList>
 | 
				
			||||||
              </TabsList>
 | 
					            <TabsContent className="flex flex-col gap-2 !mt-0" value="client">
 | 
				
			||||||
              <TabsContent className="flex flex-col gap-2 !mt-0" value="client">
 | 
					              <div>
 | 
				
			||||||
                <div>
 | 
					                Copy and paste the ComfyDeployClient form 
 | 
				
			||||||
                  Copy and paste the ComfyDeployClient form 
 | 
					                <a
 | 
				
			||||||
                  <a
 | 
					                  href="https://github.com/BennyKok/comfyui-deploy-next-example/blob/main/src/lib/comfy-deploy.ts"
 | 
				
			||||||
                    href="https://github.com/BennyKok/comfyui-deploy-next-example/blob/main/src/lib/comfy-deploy.ts"
 | 
					                  className="text-blue-500 hover:underline"
 | 
				
			||||||
                    className="text-blue-500 hover:underline"
 | 
					                  target="_blank"
 | 
				
			||||||
                    target="_blank"
 | 
					 | 
				
			||||||
                  >
 | 
					 | 
				
			||||||
                    here
 | 
					 | 
				
			||||||
                  </a>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="js"
 | 
					 | 
				
			||||||
                  code={formatCode(
 | 
					 | 
				
			||||||
                    domain == "https://www.comfydeploy.com"
 | 
					 | 
				
			||||||
                      ? jsClientSetupTemplateHostedVersion
 | 
					 | 
				
			||||||
                      : jsClientSetupTemplate,
 | 
					 | 
				
			||||||
                    deployment,
 | 
					 | 
				
			||||||
                    domain,
 | 
					 | 
				
			||||||
                    workflowInput
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
                Create a run via deployment id
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="js"
 | 
					 | 
				
			||||||
                  code={formatCode(
 | 
					 | 
				
			||||||
                    workflowInput && workflowInput.length > 0
 | 
					 | 
				
			||||||
                      ? jsClientCreateRunTemplate
 | 
					 | 
				
			||||||
                      : jsClientCreateRunNoInputsTemplate,
 | 
					 | 
				
			||||||
                    deployment,
 | 
					 | 
				
			||||||
                    domain,
 | 
					 | 
				
			||||||
                    workflowInput
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
                Check the status of the run, and retrieve the outputs
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="js"
 | 
					 | 
				
			||||||
                  code={formatCode(
 | 
					 | 
				
			||||||
                    clientTemplate_checkStatus,
 | 
					 | 
				
			||||||
                    deployment,
 | 
					 | 
				
			||||||
                    domain
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              </TabsContent>
 | 
					 | 
				
			||||||
              <TabsContent className="flex flex-col gap-2 !mt-0" value="js">
 | 
					 | 
				
			||||||
                Trigger the workflow
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="js"
 | 
					 | 
				
			||||||
                  code={formatCode(
 | 
					 | 
				
			||||||
                    jsTemplate,
 | 
					 | 
				
			||||||
                    deployment,
 | 
					 | 
				
			||||||
                    domain,
 | 
					 | 
				
			||||||
                    workflowInput
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
                Check the status of the run, and retrieve the outputs
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="js"
 | 
					 | 
				
			||||||
                  code={formatCode(jsTemplate_checkStatus, deployment, domain)}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              </TabsContent>
 | 
					 | 
				
			||||||
              <TabsContent className="flex flex-col gap-2 !mt-2" value="curl">
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="bash"
 | 
					 | 
				
			||||||
                  code={formatCode(curlTemplate, deployment, domain)}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
                <CodeBlock
 | 
					 | 
				
			||||||
                  lang="bash"
 | 
					 | 
				
			||||||
                  code={formatCode(
 | 
					 | 
				
			||||||
                    curlTemplate_checkStatus,
 | 
					 | 
				
			||||||
                    deployment,
 | 
					 | 
				
			||||||
                    domain
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              </TabsContent>
 | 
					 | 
				
			||||||
            </Tabs>
 | 
					 | 
				
			||||||
          ) : (
 | 
					 | 
				
			||||||
            <div className="w-full justify-end flex gap-2 py-1">
 | 
					 | 
				
			||||||
              <Button asChild className="gap-2" variant="outline" type="submit">
 | 
					 | 
				
			||||||
                <ButtonAction
 | 
					 | 
				
			||||||
                  action={removePublicShareDeployment.bind(null, deployment.id)}
 | 
					 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  Remove
 | 
					                  here
 | 
				
			||||||
                </ButtonAction>
 | 
					                </a>
 | 
				
			||||||
              </Button>
 | 
					              </div>
 | 
				
			||||||
              <Button asChild className="gap-2">
 | 
					              <CodeBlock
 | 
				
			||||||
                <Link href={`/share/${deployment.id}`} target="_blank">
 | 
					                lang="js"
 | 
				
			||||||
                  View Share Page <ExternalLink size={14} />
 | 
					                code={formatCode(
 | 
				
			||||||
                </Link>
 | 
					                  domain == "https://www.comfydeploy.com"
 | 
				
			||||||
              </Button>
 | 
					                    ? jsClientSetupTemplateHostedVersion
 | 
				
			||||||
            </div>
 | 
					                    : jsClientSetupTemplate,
 | 
				
			||||||
          )}
 | 
					                  deployment,
 | 
				
			||||||
 | 
					                  domain,
 | 
				
			||||||
 | 
					                  workflowInput
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					              Create a run via deployment id
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="js"
 | 
				
			||||||
 | 
					                code={formatCode(
 | 
				
			||||||
 | 
					                  workflowInput && workflowInput.length > 0
 | 
				
			||||||
 | 
					                    ? jsClientCreateRunTemplate
 | 
				
			||||||
 | 
					                    : jsClientCreateRunNoInputsTemplate,
 | 
				
			||||||
 | 
					                  deployment,
 | 
				
			||||||
 | 
					                  domain,
 | 
				
			||||||
 | 
					                  workflowInput
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					              Check the status of the run, and retrieve the outputs
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="js"
 | 
				
			||||||
 | 
					                code={formatCode(
 | 
				
			||||||
 | 
					                  clientTemplate_checkStatus,
 | 
				
			||||||
 | 
					                  deployment,
 | 
				
			||||||
 | 
					                  domain
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </TabsContent>
 | 
				
			||||||
 | 
					            <TabsContent className="flex flex-col gap-2 !mt-0" value="js">
 | 
				
			||||||
 | 
					              Trigger the workflow
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="js"
 | 
				
			||||||
 | 
					                code={formatCode(jsTemplate, deployment, domain, workflowInput)}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					              Check the status of the run, and retrieve the outputs
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="js"
 | 
				
			||||||
 | 
					                code={formatCode(jsTemplate_checkStatus, deployment, domain)}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </TabsContent>
 | 
				
			||||||
 | 
					            <TabsContent className="flex flex-col gap-2 !mt-2" value="curl">
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="bash"
 | 
				
			||||||
 | 
					                code={formatCode(curlTemplate, deployment, domain)}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					              <CodeBlock
 | 
				
			||||||
 | 
					                lang="bash"
 | 
				
			||||||
 | 
					                code={formatCode(curlTemplate_checkStatus, deployment, domain)}
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </TabsContent>
 | 
				
			||||||
 | 
					          </Tabs>
 | 
				
			||||||
        </ScrollArea>
 | 
					        </ScrollArea>
 | 
				
			||||||
      </DialogContent>
 | 
					      </DialogContent>
 | 
				
			||||||
    </Dialog>
 | 
					    </Dialog>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										37
									
								
								web/src/components/DeploymentRow.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/src/components/DeploymentRow.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { TableCell, TableRow } from "@/components/ui/table";
 | 
				
			||||||
 | 
					import { getRelativeTime } from "@/lib/getRelativeTime";
 | 
				
			||||||
 | 
					import type { findAllDeployments } from "@/server/findAllRuns";
 | 
				
			||||||
 | 
					import { useRouter } from "next/navigation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function DeploymentRow({
 | 
				
			||||||
 | 
					  deployment,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  deployment: Awaited<ReturnType<typeof findAllDeployments>>[0];
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  const router = useRouter();
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <TableRow
 | 
				
			||||||
 | 
					      className="appearance-none hover:cursor-pointer"
 | 
				
			||||||
 | 
					      onClick={() => {
 | 
				
			||||||
 | 
					        if (deployment.environment == "public-share") {
 | 
				
			||||||
 | 
					          router.push(`/share/${deployment.id}/settings`);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <TableCell className="capitalize truncate">
 | 
				
			||||||
 | 
					        {deployment.environment}
 | 
				
			||||||
 | 
					      </TableCell>
 | 
				
			||||||
 | 
					      <TableCell className="font-medium truncate">
 | 
				
			||||||
 | 
					        {deployment.version?.version}
 | 
				
			||||||
 | 
					      </TableCell>
 | 
				
			||||||
 | 
					      <TableCell className="font-medium truncate">
 | 
				
			||||||
 | 
					        {deployment.machine?.name}
 | 
				
			||||||
 | 
					      </TableCell>
 | 
				
			||||||
 | 
					      <TableCell className="text-right truncate">
 | 
				
			||||||
 | 
					        {getRelativeTime(deployment.updated_at)}
 | 
				
			||||||
 | 
					      </TableCell>
 | 
				
			||||||
 | 
					    </TableRow>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -11,6 +11,7 @@ import {
 | 
				
			|||||||
  DialogDescription,
 | 
					  DialogDescription,
 | 
				
			||||||
  DialogHeader,
 | 
					  DialogHeader,
 | 
				
			||||||
  DialogTitle,
 | 
					  DialogTitle,
 | 
				
			||||||
 | 
					  DialogTrigger,
 | 
				
			||||||
} from "@/components/ui/dialog";
 | 
					} from "@/components/ui/dialog";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Tooltip,
 | 
					  Tooltip,
 | 
				
			||||||
@ -106,12 +107,14 @@ export function UpdateModal<
 | 
				
			|||||||
  Y extends UnknownKeysParam,
 | 
					  Y extends UnknownKeysParam,
 | 
				
			||||||
  Z extends ZodObject<K, Y>
 | 
					  Z extends ZodObject<K, Y>
 | 
				
			||||||
>(props: {
 | 
					>(props: {
 | 
				
			||||||
  open: boolean;
 | 
					  open?: boolean;
 | 
				
			||||||
  setOpen: (open: boolean) => void;
 | 
					  setOpen?: (open: boolean) => void;
 | 
				
			||||||
  title: string;
 | 
					  title: string;
 | 
				
			||||||
  description: string;
 | 
					  description: string;
 | 
				
			||||||
  dialogClassName?: string;
 | 
					  dialogClassName?: string;
 | 
				
			||||||
  data: z.infer<Z>;
 | 
					  data: z.infer<Z> & {
 | 
				
			||||||
 | 
					    id: string;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  serverAction: (
 | 
					  serverAction: (
 | 
				
			||||||
    data: z.infer<Z> & {
 | 
					    data: z.infer<Z> & {
 | 
				
			||||||
      id: string;
 | 
					      id: string;
 | 
				
			||||||
@ -119,8 +122,13 @@ export function UpdateModal<
 | 
				
			|||||||
  ) => Promise<unknown>;
 | 
					  ) => Promise<unknown>;
 | 
				
			||||||
  formSchema: Z;
 | 
					  formSchema: Z;
 | 
				
			||||||
  fieldConfig?: FieldConfig<z.infer<Z>>;
 | 
					  fieldConfig?: FieldConfig<z.infer<Z>>;
 | 
				
			||||||
 | 
					  trigger?: React.ReactNode;
 | 
				
			||||||
 | 
					  extraButtons?: React.ReactNode;
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  // const [open, setOpen] = React.useState(false);
 | 
					  const [_open, _setOpen] = React.useState(false);
 | 
				
			||||||
 | 
					  const open = props.open ?? _open;
 | 
				
			||||||
 | 
					  const setOpen = props.setOpen ?? _setOpen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [values, setValues] = useState<Partial<z.infer<Z>>>({});
 | 
					  const [values, setValues] = useState<Partial<z.infer<Z>>>({});
 | 
				
			||||||
  const [isLoading, setIsLoading] = React.useState(false);
 | 
					  const [isLoading, setIsLoading] = React.useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -129,10 +137,18 @@ export function UpdateModal<
 | 
				
			|||||||
  }, [props.data]);
 | 
					  }, [props.data]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Dialog open={props.open} onOpenChange={props.setOpen}>
 | 
					    <Dialog open={open} onOpenChange={setOpen}>
 | 
				
			||||||
      {/* <DialogTrigger asChild>
 | 
					      {props.trigger ?? (
 | 
				
			||||||
        <DropdownMenuItem>{props.title}</DropdownMenuItem>
 | 
					        <DialogTrigger
 | 
				
			||||||
      </DialogTrigger> */}
 | 
					          className="appearance-none hover:cursor-pointer"
 | 
				
			||||||
 | 
					          asChild
 | 
				
			||||||
 | 
					          onClick={() => {
 | 
				
			||||||
 | 
					            setOpen(true);
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {props.trigger}
 | 
				
			||||||
 | 
					        </DialogTrigger>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
      <DialogContent className={cn("sm:max-w-[425px]", props.dialogClassName)}>
 | 
					      <DialogContent className={cn("sm:max-w-[425px]", props.dialogClassName)}>
 | 
				
			||||||
        <DialogHeader>
 | 
					        <DialogHeader>
 | 
				
			||||||
          <DialogTitle>{props.title}</DialogTitle>
 | 
					          <DialogTitle>{props.title}</DialogTitle>
 | 
				
			||||||
@ -152,13 +168,14 @@ export function UpdateModal<
 | 
				
			|||||||
              })
 | 
					              })
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            setIsLoading(false);
 | 
					            setIsLoading(false);
 | 
				
			||||||
            props.setOpen(false);
 | 
					            setOpen(false);
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div className="flex justify-end">
 | 
					          <div className="flex justify-end flex-wrap gap-2">
 | 
				
			||||||
 | 
					            {props.extraButtons}
 | 
				
			||||||
            <AutoFormSubmit>
 | 
					            <AutoFormSubmit>
 | 
				
			||||||
              Save Changes
 | 
					              Save Changes
 | 
				
			||||||
              <span className="ml-2">{isLoading && <LoadingIcon />}</span>
 | 
					              {isLoading && <LoadingIcon />}
 | 
				
			||||||
            </AutoFormSubmit>
 | 
					            </AutoFormSubmit>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </AutoForm>
 | 
					        </AutoForm>
 | 
				
			||||||
 | 
				
			|||||||
@ -69,7 +69,7 @@ export default async function Main() {
 | 
				
			|||||||
            </Section.Announcement>
 | 
					            </Section.Announcement>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <Section.Title className="text-left">
 | 
					            <Section.Title className="text-left">
 | 
				
			||||||
              <span className="text-6xl md:text-7xl pb-2 inline-flex animate-background-shine bg-[linear-gradient(110deg,#1e293b,45%,#939393,55%,#1e293b)] bg-[length:250%_100%] bg-clip-text text-transparent">
 | 
					              <span className="text-5xl sm:text-6xl md:text-7xl pb-2 inline-flex animate-background-shine bg-[linear-gradient(110deg,#1e293b,45%,#939393,55%,#1e293b)] bg-[length:250%_100%] bg-clip-text text-transparent">
 | 
				
			||||||
                {meta.tagline}
 | 
					                {meta.tagline}
 | 
				
			||||||
              </span>
 | 
					              </span>
 | 
				
			||||||
            </Section.Title>
 | 
					            </Section.Title>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										52
									
								
								web/src/components/OutputPreviews.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								web/src/components/OutputPreviews.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					import { Card, CardContent } from "@/components/ui/card";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Carousel,
 | 
				
			||||||
 | 
					  CarouselContent,
 | 
				
			||||||
 | 
					  CarouselItem,
 | 
				
			||||||
 | 
					  CarouselNext,
 | 
				
			||||||
 | 
					  CarouselPrevious,
 | 
				
			||||||
 | 
					  type CarouselApi,
 | 
				
			||||||
 | 
					} from "@/components/ui/carousel";
 | 
				
			||||||
 | 
					import * as React from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function OutputPreview() {
 | 
				
			||||||
 | 
					  const [api, setApi] = React.useState<CarouselApi>();
 | 
				
			||||||
 | 
					  const [current, setCurrent] = React.useState(0);
 | 
				
			||||||
 | 
					  const [count, setCount] = React.useState(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  React.useEffect(() => {
 | 
				
			||||||
 | 
					    if (!api) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setCount(api.scrollSnapList().length);
 | 
				
			||||||
 | 
					    setCurrent(api.selectedScrollSnap() + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    api.on("select", () => {
 | 
				
			||||||
 | 
					      setCurrent(api.selectedScrollSnap() + 1);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }, [api]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <Carousel setApi={setApi} className="w-full max-w-xs">
 | 
				
			||||||
 | 
					        <CarouselContent>
 | 
				
			||||||
 | 
					          {Array.from({ length: 5 }).map((_, index) => (
 | 
				
			||||||
 | 
					            <CarouselItem key={index}>
 | 
				
			||||||
 | 
					              <Card>
 | 
				
			||||||
 | 
					                <CardContent className="flex aspect-square items-center justify-center p-6">
 | 
				
			||||||
 | 
					                  <span className="text-4xl font-semibold">{index + 1}</span>
 | 
				
			||||||
 | 
					                </CardContent>
 | 
				
			||||||
 | 
					              </Card>
 | 
				
			||||||
 | 
					            </CarouselItem>
 | 
				
			||||||
 | 
					          ))}
 | 
				
			||||||
 | 
					        </CarouselContent>
 | 
				
			||||||
 | 
					        <CarouselPrevious />
 | 
				
			||||||
 | 
					        <CarouselNext />
 | 
				
			||||||
 | 
					      </Carousel>
 | 
				
			||||||
 | 
					      <div className="py-2 text-center text-sm text-muted-foreground">
 | 
				
			||||||
 | 
					        Slide {current} of {count}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,14 +1,21 @@
 | 
				
			|||||||
"use client";
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { LoadingIcon } from "@/components/LoadingIcon";
 | 
					import { LoadingIcon } from "@/components/LoadingIcon";
 | 
				
			||||||
 | 
					import { Button } from "@/components/ui/button";
 | 
				
			||||||
 | 
					import { RefreshCcw } from "lucide-react";
 | 
				
			||||||
import { useRouter } from "next/navigation";
 | 
					import { useRouter } from "next/navigation";
 | 
				
			||||||
import { useEffect, useTransition } from "react";
 | 
					import { useEffect, useTransition } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function RouteRefresher(props: { interval: number }) {
 | 
					export function RouteRefresher(props: {
 | 
				
			||||||
 | 
					  interval: number;
 | 
				
			||||||
 | 
					  autoRefresh: boolean;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
  const [isPending, startTransition] = useTransition();
 | 
					  const [isPending, startTransition] = useTransition();
 | 
				
			||||||
  const router = useRouter();
 | 
					  const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (!props.autoRefresh) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let timeout: NodeJS.Timeout;
 | 
					    let timeout: NodeJS.Timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const refresh = () => {
 | 
					    const refresh = () => {
 | 
				
			||||||
@ -35,7 +42,24 @@ export function RouteRefresher(props: { interval: number }) {
 | 
				
			|||||||
      clearTimeout(timeout);
 | 
					      clearTimeout(timeout);
 | 
				
			||||||
      window.removeEventListener("visibilitychange", handleVisibilityChange);
 | 
					      window.removeEventListener("visibilitychange", handleVisibilityChange);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }, [props.interval, router]);
 | 
					  }, [props.interval, router, props.autoRefresh]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <div>{isPending && <LoadingIcon />}</div>;
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      {isPending && <LoadingIcon />}
 | 
				
			||||||
 | 
					      {!isPending && !props.autoRefresh && (
 | 
				
			||||||
 | 
					        <Button
 | 
				
			||||||
 | 
					          className="p-0 h-min"
 | 
				
			||||||
 | 
					          variant="ghost"
 | 
				
			||||||
 | 
					          onClick={() => {
 | 
				
			||||||
 | 
					            startTransition(() => {
 | 
				
			||||||
 | 
					              router.refresh();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <RefreshCcw size={14} />
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,9 @@ export async function RunDisplay({
 | 
				
			|||||||
          </TableCell>
 | 
					          </TableCell>
 | 
				
			||||||
          <TableCell>{run.version?.version}</TableCell>
 | 
					          <TableCell>{run.version?.version}</TableCell>
 | 
				
			||||||
          <TableCell>
 | 
					          <TableCell>
 | 
				
			||||||
            <Badge variant="outline">{run.origin}</Badge>
 | 
					            <Badge variant="outline" className="truncate">
 | 
				
			||||||
 | 
					              {run.origin}
 | 
				
			||||||
 | 
					            </Badge>
 | 
				
			||||||
          </TableCell>
 | 
					          </TableCell>
 | 
				
			||||||
          <LiveStatus run={run} />
 | 
					          <LiveStatus run={run} />
 | 
				
			||||||
        </TableRow>
 | 
					        </TableRow>
 | 
				
			||||||
 | 
				
			|||||||
@ -40,13 +40,10 @@ export function RunWorkflowInline({
 | 
				
			|||||||
  } = publicRunStore();
 | 
					  } = publicRunStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const runWorkflow = async () => {
 | 
					  const runWorkflow = async () => {
 | 
				
			||||||
    console.log();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!user.isSignedIn) {
 | 
					    if (!user.isSignedIn) {
 | 
				
			||||||
      clerk.openSignIn({
 | 
					      clerk.openSignIn({
 | 
				
			||||||
        redirectUrl: window.location.href,
 | 
					        redirectUrl: window.location.href,
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      console.log("hi");
 | 
					 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    console.log(values);
 | 
					    console.log(values);
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@ import {
 | 
				
			|||||||
  TableRow,
 | 
					  TableRow,
 | 
				
			||||||
} from "@/components/ui/table";
 | 
					} from "@/components/ui/table";
 | 
				
			||||||
import { parseAsInteger } from "next-usequerystate";
 | 
					import { parseAsInteger } from "next-usequerystate";
 | 
				
			||||||
 | 
					import { headers } from "next/headers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const itemPerPage = 6;
 | 
					const itemPerPage = 6;
 | 
				
			||||||
const pageParser = parseAsInteger.withDefault(1);
 | 
					const pageParser = parseAsInteger.withDefault(1);
 | 
				
			||||||
@ -69,8 +70,14 @@ export async function RunsTable(props: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export async function DeploymentsTable(props: { workflow_id: string }) {
 | 
					export async function DeploymentsTable(props: { workflow_id: string }) {
 | 
				
			||||||
  const allRuns = await findAllDeployments(props.workflow_id);
 | 
					  const allRuns = await findAllDeployments(props.workflow_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const headersList = headers();
 | 
				
			||||||
 | 
					  const host = headersList.get("host") || "";
 | 
				
			||||||
 | 
					  const protocol = headersList.get("x-forwarded-proto") || "";
 | 
				
			||||||
 | 
					  const domain = `${protocol}://${host}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="overflow-auto h-fit  w-full">
 | 
					    <div className="overflow-auto h-fit w-full">
 | 
				
			||||||
      <Table className="">
 | 
					      <Table className="">
 | 
				
			||||||
        <TableCaption>A list of your deployments</TableCaption>
 | 
					        <TableCaption>A list of your deployments</TableCaption>
 | 
				
			||||||
        <TableHeader className="bg-background top-0 sticky">
 | 
					        <TableHeader className="bg-background top-0 sticky">
 | 
				
			||||||
@ -83,7 +90,7 @@ export async function DeploymentsTable(props: { workflow_id: string }) {
 | 
				
			|||||||
        </TableHeader>
 | 
					        </TableHeader>
 | 
				
			||||||
        <TableBody>
 | 
					        <TableBody>
 | 
				
			||||||
          {allRuns.map((run) => (
 | 
					          {allRuns.map((run) => (
 | 
				
			||||||
            <DeploymentDisplay deployment={run} key={run.id} />
 | 
					            <DeploymentDisplay deployment={run} key={run.id} domain={domain} />
 | 
				
			||||||
          ))}
 | 
					          ))}
 | 
				
			||||||
        </TableBody>
 | 
					        </TableBody>
 | 
				
			||||||
      </Table>
 | 
					      </Table>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,33 +1,37 @@
 | 
				
			|||||||
import { Button, buttonVariants } from '@/components/ui/button';
 | 
					 | 
				
			||||||
type ButtonProps = React.ComponentProps<typeof Button>;
 | 
					 | 
				
			||||||
type LinkProps = React.ComponentProps<typeof Link>;
 | 
					 | 
				
			||||||
import { Card as BaseCard } from '@/components/ui/card';
 | 
					 | 
				
			||||||
type CardProps = React.ComponentProps<typeof BaseCard>;
 | 
					 | 
				
			||||||
import { Tabs, TabsTrigger as Tab, TabsList } from '@/components/ui/tabs';
 | 
					 | 
				
			||||||
type TabsProps = React.ComponentProps<typeof Tabs>;
 | 
					 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Accordion,
 | 
					  Accordion,
 | 
				
			||||||
  AccordionItem,
 | 
					  AccordionItem,
 | 
				
			||||||
  AccordionContent,
 | 
					  AccordionContent,
 | 
				
			||||||
  AccordionTrigger,
 | 
					  AccordionTrigger,
 | 
				
			||||||
} from '@/components/ui/accordion';
 | 
					} from "@/components/ui/accordion";
 | 
				
			||||||
type AccordionProps = React.ComponentProps<typeof Accordion>;
 | 
					import { Badge as Chip } from "@/components/ui/badge";
 | 
				
			||||||
import { Badge as Chip } from '@/components/ui/badge';
 | 
					import { Button, buttonVariants } from "@/components/ui/button";
 | 
				
			||||||
type ChipProps = React.ComponentProps<typeof Chip>;
 | 
					import { Card as BaseCard } from "@/components/ui/card";
 | 
				
			||||||
 | 
					import { Tabs, TabsTrigger as Tab, TabsList } from "@/components/ui/tabs";
 | 
				
			||||||
import Link from 'next/link';
 | 
					// import { PiCheckCircleDuotone } from 'react-icons/pi';
 | 
				
			||||||
 | 
					import { cn } from "@/lib/utils";
 | 
				
			||||||
 | 
					import { ChevronRight as MdChevronRight } from "lucide-react";
 | 
				
			||||||
 | 
					import { CheckCircle as PiCheckCircleDuotone } from "lucide-react";
 | 
				
			||||||
 | 
					import Link from "next/link";
 | 
				
			||||||
import type {
 | 
					import type {
 | 
				
			||||||
  HTMLAttributeAnchorTarget,
 | 
					  HTMLAttributeAnchorTarget,
 | 
				
			||||||
  HTMLAttributes,
 | 
					  HTMLAttributes,
 | 
				
			||||||
  ReactNode,
 | 
					  ReactNode,
 | 
				
			||||||
} from 'react';
 | 
					} from "react";
 | 
				
			||||||
import { twMerge } from 'tailwind-merge';
 | 
					 | 
				
			||||||
import { ChevronRight as MdChevronRight} from 'lucide-react'
 | 
					 | 
				
			||||||
// import { MdChevronRight } from 'react-icons/md';
 | 
					// import { MdChevronRight } from 'react-icons/md';
 | 
				
			||||||
import React from 'react';
 | 
					import React from "react";
 | 
				
			||||||
import { CheckCircle as PiCheckCircleDuotone } from 'lucide-react'
 | 
					import { twMerge } from "tailwind-merge";
 | 
				
			||||||
// import { PiCheckCircleDuotone } from 'react-icons/pi';
 | 
					
 | 
				
			||||||
import { cn } from '@/lib/utils';
 | 
					type ButtonProps = React.ComponentProps<typeof Button>;
 | 
				
			||||||
 | 
					type LinkProps = React.ComponentProps<typeof Link>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CardProps = React.ComponentProps<typeof BaseCard>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TabsProps = React.ComponentProps<typeof Tabs>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AccordionProps = React.ComponentProps<typeof Accordion>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ChipProps = React.ComponentProps<typeof Chip>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Section({
 | 
					function Section({
 | 
				
			||||||
  className,
 | 
					  className,
 | 
				
			||||||
@ -41,8 +45,8 @@ function Section({
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <section
 | 
					    <section
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'flex min-h-[400px] w-full max-w-6xl flex-col justify-center gap-2 rounded-lg px-10 py-10 md:px-20',
 | 
					        "flex min-h-[400px] w-full max-w-6xl flex-col justify-center gap-2 rounded-lg px-2 sm:px-10 py-10 md:px-20",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -64,12 +68,12 @@ function Title({
 | 
				
			|||||||
    <h1
 | 
					    <h1
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'text-center text-4xl font-bold md:text-6xl',
 | 
					        "text-center text-4xl font-bold md:text-6xl",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      style={{
 | 
					      style={{
 | 
				
			||||||
        // @ts-ignore
 | 
					        // @ts-ignore
 | 
				
			||||||
        textWrap: 'balance',
 | 
					        textWrap: "balance",
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {children}
 | 
					      {children}
 | 
				
			||||||
@ -86,12 +90,12 @@ function Subtitle({
 | 
				
			|||||||
    <h2
 | 
					    <h2
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'text text-center overflow-hidden text-ellipsis text-xl',
 | 
					        "text text-center overflow-hidden text-ellipsis text-xl",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      style={{
 | 
					      style={{
 | 
				
			||||||
        // @ts-ignore
 | 
					        // @ts-ignore
 | 
				
			||||||
        textWrap: 'balance',
 | 
					        textWrap: "balance",
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {children}
 | 
					      {children}
 | 
				
			||||||
@ -103,7 +107,7 @@ function Announcement({
 | 
				
			|||||||
  className,
 | 
					  className,
 | 
				
			||||||
  children,
 | 
					  children,
 | 
				
			||||||
  href,
 | 
					  href,
 | 
				
			||||||
  target = '_blank',
 | 
					  target = "_blank",
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: ChipProps & {
 | 
					}: ChipProps & {
 | 
				
			||||||
  href?: string; //string | UrlObject;
 | 
					  href?: string; //string | UrlObject;
 | 
				
			||||||
@ -112,8 +116,8 @@ function Announcement({
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Chip
 | 
					    <Chip
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'w-fit group bg-foreground-50 text-center transition-colors hover:bg-gray-200',
 | 
					        "w-fit group bg-foreground-50 text-center transition-colors hover:bg-gray-200",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      variant="outline"
 | 
					      variant="outline"
 | 
				
			||||||
      // href={href}
 | 
					      // href={href}
 | 
				
			||||||
@ -127,13 +131,13 @@ function Announcement({
 | 
				
			|||||||
      // }
 | 
					      // }
 | 
				
			||||||
      style={{
 | 
					      style={{
 | 
				
			||||||
        // @ts-ignore
 | 
					        // @ts-ignore
 | 
				
			||||||
        textWrap: 'balance',
 | 
					        textWrap: "balance",
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <a href={href} target={target}>
 | 
					      <a href={href} target={target}>
 | 
				
			||||||
        {children}
 | 
					        {children}
 | 
				
			||||||
      </a>{' '}
 | 
					      </a>{" "}
 | 
				
			||||||
      <MdChevronRight
 | 
					      <MdChevronRight
 | 
				
			||||||
        size={20}
 | 
					        size={20}
 | 
				
			||||||
        className="pr-1 transition-transform group-hover:translate-x-[2px]"
 | 
					        className="pr-1 transition-transform group-hover:translate-x-[2px]"
 | 
				
			||||||
@ -143,14 +147,14 @@ function Announcement({
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ActionProps = ButtonProps & {
 | 
					type ActionProps = ButtonProps & {
 | 
				
			||||||
  be: 'button';
 | 
					  be: "button";
 | 
				
			||||||
  hideArrow?: boolean;
 | 
					  hideArrow?: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ActionLinkProps = LinkProps & {
 | 
					type ActionLinkProps = LinkProps & {
 | 
				
			||||||
  be?: 'a';
 | 
					  be?: "a";
 | 
				
			||||||
  hideArrow?: boolean;
 | 
					  hideArrow?: boolean;
 | 
				
			||||||
  variant?: ButtonProps['variant'];
 | 
					  variant?: ButtonProps["variant"];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function PrimaryAction({
 | 
					function PrimaryAction({
 | 
				
			||||||
@ -160,15 +164,15 @@ function PrimaryAction({
 | 
				
			|||||||
  hideArrow,
 | 
					  hideArrow,
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: ActionLinkProps | ActionProps) {
 | 
					}: ActionLinkProps | ActionProps) {
 | 
				
			||||||
  if (props.be === 'button') {
 | 
					  if (props.be === "button") {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Button
 | 
					      <Button
 | 
				
			||||||
        className={cn(
 | 
					        className={cn(
 | 
				
			||||||
          buttonVariants({
 | 
					          buttonVariants({
 | 
				
			||||||
            variant: variant,
 | 
					            variant: variant,
 | 
				
			||||||
          }),
 | 
					          }),
 | 
				
			||||||
          'group',
 | 
					          "group",
 | 
				
			||||||
          className,
 | 
					          className
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
        {...props}
 | 
					        {...props}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
@ -186,8 +190,8 @@ function PrimaryAction({
 | 
				
			|||||||
        buttonVariants({
 | 
					        buttonVariants({
 | 
				
			||||||
          variant: variant,
 | 
					          variant: variant,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        'group',
 | 
					        "group",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -206,17 +210,17 @@ function SecondaryAction({
 | 
				
			|||||||
  hideArrow,
 | 
					  hideArrow,
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: ActionLinkProps | ActionProps) {
 | 
					}: ActionLinkProps | ActionProps) {
 | 
				
			||||||
  if (props.be === 'button') {
 | 
					  if (props.be === "button") {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Button
 | 
					      <Button
 | 
				
			||||||
        className={cn(
 | 
					        className={cn(
 | 
				
			||||||
          buttonVariants({
 | 
					          buttonVariants({
 | 
				
			||||||
            variant: variant,
 | 
					            variant: variant,
 | 
				
			||||||
          }),
 | 
					          }),
 | 
				
			||||||
          'group',
 | 
					          "group",
 | 
				
			||||||
          className,
 | 
					          className
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
        variant={'ghost'}
 | 
					        variant="ghost"
 | 
				
			||||||
        {...props}
 | 
					        {...props}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {children}
 | 
					        {children}
 | 
				
			||||||
@ -231,10 +235,10 @@ function SecondaryAction({
 | 
				
			|||||||
    <Link
 | 
					    <Link
 | 
				
			||||||
      className={cn(
 | 
					      className={cn(
 | 
				
			||||||
        buttonVariants({
 | 
					        buttonVariants({
 | 
				
			||||||
          variant: 'ghost',
 | 
					          variant: "ghost",
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        'group',
 | 
					        "group",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -249,31 +253,31 @@ function PricingCard({
 | 
				
			|||||||
  className,
 | 
					  className,
 | 
				
			||||||
  children,
 | 
					  children,
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: Omit<CardProps, 'children'> & {
 | 
					}: Omit<CardProps, "children"> & {
 | 
				
			||||||
  children:
 | 
					  children:
 | 
				
			||||||
    | ReactNode
 | 
					    | ReactNode
 | 
				
			||||||
    | ReactNode[]
 | 
					    | ReactNode[]
 | 
				
			||||||
    | ((pricingType: PricingType) => ReactNode | ReactNode[]);
 | 
					    | ((pricingType: PricingType) => ReactNode | ReactNode[]);
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  // const { pricingType } = usePricingContext();
 | 
					  // const { pricingType } = usePricingContext();
 | 
				
			||||||
  if (typeof children === 'function')
 | 
					  if (typeof children === "function")
 | 
				
			||||||
    children = (children('month') as React.ReactElement).props.children as
 | 
					    children = (children("month") as React.ReactElement).props.children as
 | 
				
			||||||
      | ReactNode
 | 
					      | ReactNode
 | 
				
			||||||
      | ReactNode[];
 | 
					      | ReactNode[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // extract the title and subtitle from the children
 | 
					  // extract the title and subtitle from the children
 | 
				
			||||||
  // const cardTitleStyles =
 | 
					  // const cardTitleStyles =
 | 
				
			||||||
  const title = getChildComponent(children, Title, {
 | 
					  const title = getChildComponent(children, Title, {
 | 
				
			||||||
    className: 'text-2xl md:text-2xl text-start font-bold',
 | 
					    className: "text-2xl md:text-2xl text-start font-bold",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const subTitle = getChildComponent(children, Subtitle, {
 | 
					  const subTitle = getChildComponent(children, Subtitle, {
 | 
				
			||||||
    className: 'text-md text-start text-foreground-500 mt-4',
 | 
					    className: "text-md text-start text-foreground-500 mt-4",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const priceTags = getChildComponents(children, PriceTag, {
 | 
					  const priceTags = getChildComponents(children, PriceTag, {
 | 
				
			||||||
    className: 'text-4xl font-bold',
 | 
					    className: "text-4xl font-bold",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const primaryAction = getChildComponent(children, PrimaryAction, {
 | 
					  const primaryAction = getChildComponent(children, PrimaryAction, {
 | 
				
			||||||
    className: 'w-full',
 | 
					    className: "w-full",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -281,8 +285,8 @@ function PricingCard({
 | 
				
			|||||||
      // shadow="sm"
 | 
					      // shadow="sm"
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'flex flex-col min-h-[400px] w-full max-w-full items-start justify-between gap-2 p-8 text-sm',
 | 
					        "flex flex-col min-h-[400px] w-full max-w-full items-start justify-between gap-2 p-8 text-sm",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
@ -320,7 +324,7 @@ function PricingCard({
 | 
				
			|||||||
//   setPricingType: (pricingType: PricingType) => {},
 | 
					//   setPricingType: (pricingType: PricingType) => {},
 | 
				
			||||||
// });
 | 
					// });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PricingTypeValue = ['month', 'year'] as const;
 | 
					const PricingTypeValue = ["month", "year"] as const;
 | 
				
			||||||
export type PricingType = (typeof PricingTypeValue)[number];
 | 
					export type PricingType = (typeof PricingTypeValue)[number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// // an helper function to useContext
 | 
					// // an helper function to useContext
 | 
				
			||||||
@ -350,7 +354,7 @@ function PricingOption({ className, ...props }: TabsProps) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Tabs
 | 
					    <Tabs
 | 
				
			||||||
      className={twMerge('w-fit', className)}
 | 
					      className={twMerge("w-fit", className)}
 | 
				
			||||||
      defaultValue="month"
 | 
					      defaultValue="month"
 | 
				
			||||||
      aria-label="Pricing Options"
 | 
					      aria-label="Pricing Options"
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
@ -384,10 +388,10 @@ function PriceTag({
 | 
				
			|||||||
  pricingType,
 | 
					  pricingType,
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: HTMLAttributes<HTMLHeadingElement> & {
 | 
					}: HTMLAttributes<HTMLHeadingElement> & {
 | 
				
			||||||
  pricingType?: 'month' | 'year' | string;
 | 
					  pricingType?: "month" | "year" | string;
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  // const { pricingType: currentPricingType } = usePricingContext();
 | 
					  // const { pricingType: currentPricingType } = usePricingContext();
 | 
				
			||||||
  let currentPricingType = 'month';
 | 
					  const currentPricingType = "month";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pricingType != undefined && currentPricingType !== pricingType)
 | 
					  if (pricingType != undefined && currentPricingType !== pricingType)
 | 
				
			||||||
    return <></>;
 | 
					    return <></>;
 | 
				
			||||||
@ -399,10 +403,10 @@ function Card({ className, children, ...props }: CardProps) {
 | 
				
			|||||||
  // extract the title and subtitle from the children
 | 
					  // extract the title and subtitle from the children
 | 
				
			||||||
  // const cardTitleStyles =
 | 
					  // const cardTitleStyles =
 | 
				
			||||||
  const title = getChildComponent(children, Title, {
 | 
					  const title = getChildComponent(children, Title, {
 | 
				
			||||||
    className: 'text-2xl md:text-2xl font-normal text-center',
 | 
					    className: "text-2xl md:text-2xl font-normal text-center",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const subTitle = getChildComponent(children, Subtitle, {
 | 
					  const subTitle = getChildComponent(children, Subtitle, {
 | 
				
			||||||
    className: 'text-md text-center',
 | 
					    className: "text-md text-center",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const image = getChildComponent(children, ImageArea);
 | 
					  const image = getChildComponent(children, ImageArea);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -411,8 +415,8 @@ function Card({ className, children, ...props }: CardProps) {
 | 
				
			|||||||
      // shadow="sm"
 | 
					      // shadow="sm"
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
      className={twMerge(
 | 
					      className={twMerge(
 | 
				
			||||||
        'flex min-h-[280px] w-full max-w-full items-center justify-center gap-2 p-4 text-sm flex-col',
 | 
					        "flex min-h-[280px] w-full max-w-full items-center justify-center gap-2 p-4 text-sm flex-col",
 | 
				
			||||||
        className,
 | 
					        className
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {image}
 | 
					      {image}
 | 
				
			||||||
@ -431,7 +435,7 @@ function ImageArea({
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      {...props}
 | 
					      {...props}
 | 
				
			||||||
      className={twMerge('aspect-square w-14 bg-foreground-300', className)}
 | 
					      className={twMerge("aspect-square w-14 bg-foreground-300", className)}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      {children}
 | 
					      {children}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -442,11 +446,11 @@ function ImageArea({
 | 
				
			|||||||
function getChildComponent<T extends (...args: any[]) => React.JSX.Element>(
 | 
					function getChildComponent<T extends (...args: any[]) => React.JSX.Element>(
 | 
				
			||||||
  children: React.ReactNode | React.ReactNode[],
 | 
					  children: React.ReactNode | React.ReactNode[],
 | 
				
			||||||
  type: T,
 | 
					  type: T,
 | 
				
			||||||
  propsOverride?: Partial<Parameters<T>[0]>,
 | 
					  propsOverride?: Partial<Parameters<T>[0]>
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  const childrenArr = React.Children.toArray(children);
 | 
					  const childrenArr = React.Children.toArray(children);
 | 
				
			||||||
  let child = childrenArr.find(
 | 
					  let child = childrenArr.find(
 | 
				
			||||||
    (child) => React.isValidElement(child) && child.type === type,
 | 
					    (child) => React.isValidElement(child) && child.type === type
 | 
				
			||||||
  ) as React.ReactElement<
 | 
					  ) as React.ReactElement<
 | 
				
			||||||
    Parameters<T>[0],
 | 
					    Parameters<T>[0],
 | 
				
			||||||
    string | React.JSXElementConstructor<any>
 | 
					    string | React.JSXElementConstructor<any>
 | 
				
			||||||
@ -466,12 +470,12 @@ function getChildComponent<T extends (...args: any[]) => React.JSX.Element>(
 | 
				
			|||||||
function getChildComponents<T extends (...args: any[]) => React.JSX.Element>(
 | 
					function getChildComponents<T extends (...args: any[]) => React.JSX.Element>(
 | 
				
			||||||
  children: React.ReactNode | React.ReactNode[],
 | 
					  children: React.ReactNode | React.ReactNode[],
 | 
				
			||||||
  type: T,
 | 
					  type: T,
 | 
				
			||||||
  propsOverride?: Partial<Parameters<T>[0]>,
 | 
					  propsOverride?: Partial<Parameters<T>[0]>
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  const childrenArr = React.Children.toArray(children);
 | 
					  const childrenArr = React.Children.toArray(children);
 | 
				
			||||||
  let child = (
 | 
					  const child = (
 | 
				
			||||||
    childrenArr.filter(
 | 
					    childrenArr.filter(
 | 
				
			||||||
      (child) => React.isValidElement(child) && child.type === type,
 | 
					      (child) => React.isValidElement(child) && child.type === type
 | 
				
			||||||
    ) as React.ReactElement<
 | 
					    ) as React.ReactElement<
 | 
				
			||||||
      Parameters<T>[0],
 | 
					      Parameters<T>[0],
 | 
				
			||||||
      string | React.JSXElementConstructor<any>
 | 
					      string | React.JSXElementConstructor<any>
 | 
				
			||||||
@ -492,10 +496,10 @@ function getChildComponents<T extends (...args: any[]) => React.JSX.Element>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function removeFromChildren(
 | 
					function removeFromChildren(
 | 
				
			||||||
  children: React.ReactNode | React.ReactNode[],
 | 
					  children: React.ReactNode | React.ReactNode[],
 | 
				
			||||||
  types: any[],
 | 
					  types: any[]
 | 
				
			||||||
): React.ReactNode[] {
 | 
					): React.ReactNode[] {
 | 
				
			||||||
  return React.Children.toArray(children).filter(
 | 
					  return React.Children.toArray(children).filter(
 | 
				
			||||||
    (child) => React.isValidElement(child) && !types.includes(child.type),
 | 
					    (child) => React.isValidElement(child) && !types.includes(child.type)
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -508,11 +512,11 @@ function FAQItem({
 | 
				
			|||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  children: React.ReactNode | React.ReactNode[];
 | 
					  children: React.ReactNode | React.ReactNode[];
 | 
				
			||||||
  'aria-label': string;
 | 
					  "aria-label": string;
 | 
				
			||||||
  title: string;
 | 
					  title: string;
 | 
				
			||||||
}): JSX.Element {
 | 
					}): JSX.Element {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <AccordionItem value={props['aria-label']}>
 | 
					    <AccordionItem value={props["aria-label"]}>
 | 
				
			||||||
      <AccordionTrigger>{props.title}</AccordionTrigger>
 | 
					      <AccordionTrigger>{props.title}</AccordionTrigger>
 | 
				
			||||||
      <AccordionContent>{children}</AccordionContent>
 | 
					      <AccordionContent>{children}</AccordionContent>
 | 
				
			||||||
    </AccordionItem>
 | 
					    </AccordionItem>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										85
									
								
								web/src/components/SharePageSettings.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								web/src/components/SharePageSettings.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useServerActionData } from "./useServerActionData";
 | 
				
			||||||
 | 
					import { ButtonAction } from "@/components/ButtonActionLoader";
 | 
				
			||||||
 | 
					import { UpdateModal } from "@/components/InsertModal";
 | 
				
			||||||
 | 
					import { LoadingPageWrapper } from "@/components/LoadingWrapper";
 | 
				
			||||||
 | 
					import { Button } from "@/components/ui/button";
 | 
				
			||||||
 | 
					import { publicShareDeployment } from "@/db/schema";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  findUserShareDeployment,
 | 
				
			||||||
 | 
					  removePublicShareDeployment,
 | 
				
			||||||
 | 
					  updateSharePageInfo,
 | 
				
			||||||
 | 
					} from "@/server/curdDeploments";
 | 
				
			||||||
 | 
					import { ExternalLink } from "lucide-react";
 | 
				
			||||||
 | 
					import Link from "next/link";
 | 
				
			||||||
 | 
					import { useRouter } from "next/navigation";
 | 
				
			||||||
 | 
					import { useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function SharePageSettings({
 | 
				
			||||||
 | 
					  deployment_id,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  deployment_id: string;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  const {
 | 
				
			||||||
 | 
					    data: deployment,
 | 
				
			||||||
 | 
					    pending,
 | 
				
			||||||
 | 
					    started,
 | 
				
			||||||
 | 
					  } = useServerActionData(findUserShareDeployment, deployment_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [_open, _setOpen] = useState(false);
 | 
				
			||||||
 | 
					  const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (pending) return <LoadingPageWrapper className="h-full" tag="settings" />;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!deployment && started && !pending)
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div className="h-full w-full flex items-center justify-center">
 | 
				
			||||||
 | 
					        <p>Settings page not found.</p>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!deployment) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <UpdateModal
 | 
				
			||||||
 | 
					        dialogClassName="sm:max-w-[600px]"
 | 
				
			||||||
 | 
					        open={true}
 | 
				
			||||||
 | 
					        setOpen={() => {
 | 
				
			||||||
 | 
					          router.back();
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        extraButtons={
 | 
				
			||||||
 | 
					          <>
 | 
				
			||||||
 | 
					            <Button
 | 
				
			||||||
 | 
					              asChild
 | 
				
			||||||
 | 
					              className="gap-2 truncate"
 | 
				
			||||||
 | 
					              variant="outline"
 | 
				
			||||||
 | 
					              type="button"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <ButtonAction
 | 
				
			||||||
 | 
					                action={removePublicShareDeployment.bind(null, deployment.id)}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                Remove
 | 
				
			||||||
 | 
					              </ButtonAction>
 | 
				
			||||||
 | 
					            </Button>
 | 
				
			||||||
 | 
					            <Button asChild className="gap-2 truncate" type="button">
 | 
				
			||||||
 | 
					              <Link href={`/share/${deployment.id}`} target="_blank">
 | 
				
			||||||
 | 
					                View Share Page <ExternalLink size={14} />
 | 
				
			||||||
 | 
					              </Link>
 | 
				
			||||||
 | 
					            </Button>
 | 
				
			||||||
 | 
					          </>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        data={{
 | 
				
			||||||
 | 
					          id: deployment.id,
 | 
				
			||||||
 | 
					          description: deployment.description,
 | 
				
			||||||
 | 
					          showcase_media: deployment.showcase_media ?? [],
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        title="Share Page"
 | 
				
			||||||
 | 
					        description="Edit share page details."
 | 
				
			||||||
 | 
					        serverAction={updateSharePageInfo}
 | 
				
			||||||
 | 
					        formSchema={publicShareDeployment}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -39,7 +39,7 @@ import {
 | 
				
			|||||||
  TableHeader,
 | 
					  TableHeader,
 | 
				
			||||||
  TableRow,
 | 
					  TableRow,
 | 
				
			||||||
} from "@/components/ui/table";
 | 
					} from "@/components/ui/table";
 | 
				
			||||||
import type { workflowAPINodeType } from "@/db/schema";
 | 
					import type { showcaseMediaNullable, workflowAPINodeType } from "@/db/schema";
 | 
				
			||||||
import { checkStatus, createRun } from "@/server/createRun";
 | 
					import { checkStatus, createRun } from "@/server/createRun";
 | 
				
			||||||
import { createDeployments } from "@/server/curdDeploments";
 | 
					import { createDeployments } from "@/server/curdDeploments";
 | 
				
			||||||
import type { getMachines } from "@/server/curdMachine";
 | 
					import type { getMachines } from "@/server/curdMachine";
 | 
				
			||||||
@ -154,7 +154,9 @@ export const publicRunStore = create<PublicRunStore>((set) => ({
 | 
				
			|||||||
  setStatus: (status) => set({ status }),
 | 
					  setStatus: (status) => set({ status }),
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function PublicRunOutputs() {
 | 
					export function PublicRunOutputs(props: {
 | 
				
			||||||
 | 
					  preview: z.infer<typeof showcaseMediaNullable>;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
  const { image, loading, runId, status, setStatus, setImage, setLoading } =
 | 
					  const { image, loading, runId, status, setStatus, setImage, setLoading } =
 | 
				
			||||||
    publicRunStore();
 | 
					    publicRunStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,6 +178,15 @@ export function PublicRunOutputs() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="border border-gray-200 w-full square h-[400px] rounded-lg relative">
 | 
					    <div className="border border-gray-200 w-full square h-[400px] rounded-lg relative">
 | 
				
			||||||
 | 
					      {!loading && !image && props.preview && props.preview.length > 0 && (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					          <img
 | 
				
			||||||
 | 
					            className="w-full h-full object-contain"
 | 
				
			||||||
 | 
					            src={props.preview[0]?.url}
 | 
				
			||||||
 | 
					            alt="Generated image"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
      {!loading && image && (
 | 
					      {!loading && image && (
 | 
				
			||||||
        <img
 | 
					        <img
 | 
				
			||||||
          className="w-full h-full object-contain"
 | 
					          className="w-full h-full object-contain"
 | 
				
			||||||
 | 
				
			|||||||
@ -10,12 +10,11 @@ export default function ErrorPage({
 | 
				
			|||||||
  error,
 | 
					  error,
 | 
				
			||||||
  reset,
 | 
					  reset,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
  error?: Error & { digest?: string };
 | 
					  error: Error & { digest?: string };
 | 
				
			||||||
  reset?: () => void;
 | 
					  reset: () => void;
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    // Log the error to an error reporting service
 | 
					    console.log(error.message);
 | 
				
			||||||
    console.log(error?.message);
 | 
					 | 
				
			||||||
  }, [error]);
 | 
					  }, [error]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@ -26,9 +25,14 @@ export default function ErrorPage({
 | 
				
			|||||||
            <div className="text-xl">Unexpected error.</div>
 | 
					            <div className="text-xl">Unexpected error.</div>
 | 
				
			||||||
          </CardTitle>
 | 
					          </CardTitle>
 | 
				
			||||||
          <CardDescription className="flex flex-col gap-4">
 | 
					          <CardDescription className="flex flex-col gap-4">
 | 
				
			||||||
            <div className="text-sm">Error: {error?.message}</div>
 | 
					            <div className="text-sm">Error: {error.message}</div>
 | 
				
			||||||
            <div className="flex w-full justify-end">
 | 
					            <div className="flex w-full justify-end">
 | 
				
			||||||
              <Button className="w-fit" onClick={() => reset?.()}>
 | 
					              <Button
 | 
				
			||||||
 | 
					                className="w-fit"
 | 
				
			||||||
 | 
					                onClick={() => {
 | 
				
			||||||
 | 
					                  window.location.reload();
 | 
				
			||||||
 | 
					                }}
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
                Refresh Page
 | 
					                Refresh Page
 | 
				
			||||||
              </Button>
 | 
					              </Button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@ -39,14 +43,20 @@ export default function ErrorPage({
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function ErrorFullPage() {
 | 
					export function ErrorFullPage({
 | 
				
			||||||
 | 
					  error,
 | 
				
			||||||
 | 
					  reset,
 | 
				
			||||||
 | 
					}: {
 | 
				
			||||||
 | 
					  error: Error & { digest?: string };
 | 
				
			||||||
 | 
					  reset: () => void;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      className={cn(
 | 
					      className={cn(
 | 
				
			||||||
        "w-full py-4 flex justify-center items-center gap-2 text-sm h-full"
 | 
					        "w-full py-4 flex justify-center items-center gap-2 text-sm h-full"
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <ErrorPage />
 | 
					      <ErrorPage error={error} reset={reset} />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { DefaultValues } from "react-hook-form";
 | 
					import type { DefaultValues } from "react-hook-form";
 | 
				
			||||||
import { z } from "zod";
 | 
					import type { z } from "zod";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: This should support recursive ZodEffects but TypeScript doesn't allow circular type definitions.
 | 
					// TODO: This should support recursive ZodEffects but TypeScript doesn't allow circular type definitions.
 | 
				
			||||||
export type ZodObjectOrWrapped =
 | 
					export type ZodObjectOrWrapped =
 | 
				
			||||||
@ -21,7 +21,7 @@ export function beautifyObjectName(string: string) {
 | 
				
			|||||||
 * This will unpack optionals, refinements, etc.
 | 
					 * This will unpack optionals, refinements, etc.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function getBaseSchema<
 | 
					export function getBaseSchema<
 | 
				
			||||||
  ChildType extends z.ZodAny | z.AnyZodObject = z.ZodAny,
 | 
					  ChildType extends z.ZodAny | z.AnyZodObject = z.ZodAny
 | 
				
			||||||
>(schema: ChildType | z.ZodEffects<ChildType>): ChildType {
 | 
					>(schema: ChildType | z.ZodEffects<ChildType>): ChildType {
 | 
				
			||||||
  if ("innerType" in schema._def) {
 | 
					  if ("innerType" in schema._def) {
 | 
				
			||||||
    return getBaseSchema(schema._def.innerType as ChildType);
 | 
					    return getBaseSchema(schema._def.innerType as ChildType);
 | 
				
			||||||
@ -54,12 +54,12 @@ export function getDefaultValueInZodStack(schema: z.ZodAny): any {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if ("innerType" in typedSchema._def) {
 | 
					  if ("innerType" in typedSchema._def) {
 | 
				
			||||||
    return getDefaultValueInZodStack(
 | 
					    return getDefaultValueInZodStack(
 | 
				
			||||||
      typedSchema._def.innerType as unknown as z.ZodAny,
 | 
					      typedSchema._def.innerType as unknown as z.ZodAny
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if ("schema" in typedSchema._def) {
 | 
					  if ("schema" in typedSchema._def) {
 | 
				
			||||||
    return getDefaultValueInZodStack(
 | 
					    return getDefaultValueInZodStack(
 | 
				
			||||||
      (typedSchema._def as any).schema as z.ZodAny,
 | 
					      (typedSchema._def as any).schema as z.ZodAny
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return undefined;
 | 
					  return undefined;
 | 
				
			||||||
@ -69,7 +69,7 @@ export function getDefaultValueInZodStack(schema: z.ZodAny): any {
 | 
				
			|||||||
 * Get all default values from a Zod schema.
 | 
					 * Get all default values from a Zod schema.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function getDefaultValues<Schema extends z.ZodObject<any, any>>(
 | 
					export function getDefaultValues<Schema extends z.ZodObject<any, any>>(
 | 
				
			||||||
  schema: Schema,
 | 
					  schema: Schema
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  const { shape } = schema;
 | 
					  const { shape } = schema;
 | 
				
			||||||
  type DefaultValuesType = DefaultValues<Partial<z.infer<Schema>>>;
 | 
					  type DefaultValuesType = DefaultValues<Partial<z.infer<Schema>>>;
 | 
				
			||||||
@ -80,7 +80,7 @@ export function getDefaultValues<Schema extends z.ZodObject<any, any>>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (getBaseType(item) === "ZodObject") {
 | 
					    if (getBaseType(item) === "ZodObject") {
 | 
				
			||||||
      const defaultItems = getDefaultValues(
 | 
					      const defaultItems = getDefaultValues(
 | 
				
			||||||
        getBaseSchema(item) as unknown as z.ZodObject<any, any>,
 | 
					        getBaseSchema(item) as unknown as z.ZodObject<any, any>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
      for (const defaultItemKey of Object.keys(defaultItems)) {
 | 
					      for (const defaultItemKey of Object.keys(defaultItems)) {
 | 
				
			||||||
        const pathKey = `${key}.${defaultItemKey}` as keyof DefaultValuesType;
 | 
					        const pathKey = `${key}.${defaultItemKey}` as keyof DefaultValuesType;
 | 
				
			||||||
@ -98,7 +98,7 @@ export function getDefaultValues<Schema extends z.ZodObject<any, any>>(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getObjectFormSchema(
 | 
					export function getObjectFormSchema(
 | 
				
			||||||
  schema: ZodObjectOrWrapped,
 | 
					  schema: ZodObjectOrWrapped
 | 
				
			||||||
): z.ZodObject<any, any> {
 | 
					): z.ZodObject<any, any> {
 | 
				
			||||||
  if (schema._def.typeName === "ZodEffects") {
 | 
					  if (schema._def.typeName === "ZodEffects") {
 | 
				
			||||||
    const typedSchema = schema as z.ZodEffects<z.ZodObject<any, any>>;
 | 
					    const typedSchema = schema as z.ZodEffects<z.ZodObject<any, any>>;
 | 
				
			||||||
@ -116,7 +116,7 @@ export function zodToHtmlInputProps(
 | 
				
			|||||||
    | z.ZodNumber
 | 
					    | z.ZodNumber
 | 
				
			||||||
    | z.ZodString
 | 
					    | z.ZodString
 | 
				
			||||||
    | z.ZodOptional<z.ZodNumber | z.ZodString>
 | 
					    | z.ZodOptional<z.ZodNumber | z.ZodString>
 | 
				
			||||||
    | any,
 | 
					    | any
 | 
				
			||||||
): React.InputHTMLAttributes<HTMLInputElement> {
 | 
					): React.InputHTMLAttributes<HTMLInputElement> {
 | 
				
			||||||
  if (["ZodOptional", "ZodNullable"].includes(schema._def.typeName)) {
 | 
					  if (["ZodOptional", "ZodNullable"].includes(schema._def.typeName)) {
 | 
				
			||||||
    const typedSchema = schema as z.ZodOptional<z.ZodNumber | z.ZodString>;
 | 
					    const typedSchema = schema as z.ZodOptional<z.ZodNumber | z.ZodString>;
 | 
				
			||||||
@ -128,9 +128,10 @@ export function zodToHtmlInputProps(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const typedSchema = schema as z.ZodNumber | z.ZodString;
 | 
					  const typedSchema = schema as z.ZodNumber | z.ZodString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!("checks" in typedSchema._def)) return {
 | 
					  if (!("checks" in typedSchema._def))
 | 
				
			||||||
    required: true
 | 
					    return {
 | 
				
			||||||
  };
 | 
					      required: true,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { checks } = typedSchema._def;
 | 
					  const { checks } = typedSchema._def;
 | 
				
			||||||
  const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {
 | 
					  const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										262
									
								
								web/src/components/ui/carousel.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								web/src/components/ui/carousel.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,262 @@
 | 
				
			|||||||
 | 
					"use client"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as React from "react"
 | 
				
			||||||
 | 
					import useEmblaCarousel, {
 | 
				
			||||||
 | 
					  type UseEmblaCarouselType,
 | 
				
			||||||
 | 
					} from "embla-carousel-react"
 | 
				
			||||||
 | 
					import { ArrowLeft, ArrowRight } from "lucide-react"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { cn } from "@/lib/utils"
 | 
				
			||||||
 | 
					import { Button } from "@/components/ui/button"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CarouselApi = UseEmblaCarouselType[1]
 | 
				
			||||||
 | 
					type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
 | 
				
			||||||
 | 
					type CarouselOptions = UseCarouselParameters[0]
 | 
				
			||||||
 | 
					type CarouselPlugin = UseCarouselParameters[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CarouselProps = {
 | 
				
			||||||
 | 
					  opts?: CarouselOptions
 | 
				
			||||||
 | 
					  plugins?: CarouselPlugin
 | 
				
			||||||
 | 
					  orientation?: "horizontal" | "vertical"
 | 
				
			||||||
 | 
					  setApi?: (api: CarouselApi) => void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CarouselContextProps = {
 | 
				
			||||||
 | 
					  carouselRef: ReturnType<typeof useEmblaCarousel>[0]
 | 
				
			||||||
 | 
					  api: ReturnType<typeof useEmblaCarousel>[1]
 | 
				
			||||||
 | 
					  scrollPrev: () => void
 | 
				
			||||||
 | 
					  scrollNext: () => void
 | 
				
			||||||
 | 
					  canScrollPrev: boolean
 | 
				
			||||||
 | 
					  canScrollNext: boolean
 | 
				
			||||||
 | 
					} & CarouselProps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CarouselContext = React.createContext<CarouselContextProps | null>(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function useCarousel() {
 | 
				
			||||||
 | 
					  const context = React.useContext(CarouselContext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!context) {
 | 
				
			||||||
 | 
					    throw new Error("useCarousel must be used within a <Carousel />")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Carousel = React.forwardRef<
 | 
				
			||||||
 | 
					  HTMLDivElement,
 | 
				
			||||||
 | 
					  React.HTMLAttributes<HTMLDivElement> & CarouselProps
 | 
				
			||||||
 | 
					>(
 | 
				
			||||||
 | 
					  (
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      orientation = "horizontal",
 | 
				
			||||||
 | 
					      opts,
 | 
				
			||||||
 | 
					      setApi,
 | 
				
			||||||
 | 
					      plugins,
 | 
				
			||||||
 | 
					      className,
 | 
				
			||||||
 | 
					      children,
 | 
				
			||||||
 | 
					      ...props
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    ref
 | 
				
			||||||
 | 
					  ) => {
 | 
				
			||||||
 | 
					    const [carouselRef, api] = useEmblaCarousel(
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        ...opts,
 | 
				
			||||||
 | 
					        axis: orientation === "horizontal" ? "x" : "y",
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      plugins
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    const [canScrollPrev, setCanScrollPrev] = React.useState(false)
 | 
				
			||||||
 | 
					    const [canScrollNext, setCanScrollNext] = React.useState(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const onSelect = React.useCallback((api: CarouselApi) => {
 | 
				
			||||||
 | 
					      if (!api) {
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      setCanScrollPrev(api.canScrollPrev())
 | 
				
			||||||
 | 
					      setCanScrollNext(api.canScrollNext())
 | 
				
			||||||
 | 
					    }, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const scrollPrev = React.useCallback(() => {
 | 
				
			||||||
 | 
					      api?.scrollPrev()
 | 
				
			||||||
 | 
					    }, [api])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const scrollNext = React.useCallback(() => {
 | 
				
			||||||
 | 
					      api?.scrollNext()
 | 
				
			||||||
 | 
					    }, [api])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const handleKeyDown = React.useCallback(
 | 
				
			||||||
 | 
					      (event: React.KeyboardEvent<HTMLDivElement>) => {
 | 
				
			||||||
 | 
					        if (event.key === "ArrowLeft") {
 | 
				
			||||||
 | 
					          event.preventDefault()
 | 
				
			||||||
 | 
					          scrollPrev()
 | 
				
			||||||
 | 
					        } else if (event.key === "ArrowRight") {
 | 
				
			||||||
 | 
					          event.preventDefault()
 | 
				
			||||||
 | 
					          scrollNext()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      [scrollPrev, scrollNext]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    React.useEffect(() => {
 | 
				
			||||||
 | 
					      if (!api || !setApi) {
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      setApi(api)
 | 
				
			||||||
 | 
					    }, [api, setApi])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    React.useEffect(() => {
 | 
				
			||||||
 | 
					      if (!api) {
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      onSelect(api)
 | 
				
			||||||
 | 
					      api.on("reInit", onSelect)
 | 
				
			||||||
 | 
					      api.on("select", onSelect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return () => {
 | 
				
			||||||
 | 
					        api?.off("select", onSelect)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }, [api, onSelect])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <CarouselContext.Provider
 | 
				
			||||||
 | 
					        value={{
 | 
				
			||||||
 | 
					          carouselRef,
 | 
				
			||||||
 | 
					          api: api,
 | 
				
			||||||
 | 
					          opts,
 | 
				
			||||||
 | 
					          orientation:
 | 
				
			||||||
 | 
					            orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
 | 
				
			||||||
 | 
					          scrollPrev,
 | 
				
			||||||
 | 
					          scrollNext,
 | 
				
			||||||
 | 
					          canScrollPrev,
 | 
				
			||||||
 | 
					          canScrollNext,
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          ref={ref}
 | 
				
			||||||
 | 
					          onKeyDownCapture={handleKeyDown}
 | 
				
			||||||
 | 
					          className={cn("relative", className)}
 | 
				
			||||||
 | 
					          role="region"
 | 
				
			||||||
 | 
					          aria-roledescription="carousel"
 | 
				
			||||||
 | 
					          {...props}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {children}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </CarouselContext.Provider>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					Carousel.displayName = "Carousel"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CarouselContent = React.forwardRef<
 | 
				
			||||||
 | 
					  HTMLDivElement,
 | 
				
			||||||
 | 
					  React.HTMLAttributes<HTMLDivElement>
 | 
				
			||||||
 | 
					>(({ className, ...props }, ref) => {
 | 
				
			||||||
 | 
					  const { carouselRef, orientation } = useCarousel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div ref={carouselRef} className="overflow-hidden">
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        ref={ref}
 | 
				
			||||||
 | 
					        className={cn(
 | 
				
			||||||
 | 
					          "flex",
 | 
				
			||||||
 | 
					          orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
 | 
				
			||||||
 | 
					          className
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					        {...props}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					CarouselContent.displayName = "CarouselContent"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CarouselItem = React.forwardRef<
 | 
				
			||||||
 | 
					  HTMLDivElement,
 | 
				
			||||||
 | 
					  React.HTMLAttributes<HTMLDivElement>
 | 
				
			||||||
 | 
					>(({ className, ...props }, ref) => {
 | 
				
			||||||
 | 
					  const { orientation } = useCarousel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div
 | 
				
			||||||
 | 
					      ref={ref}
 | 
				
			||||||
 | 
					      role="group"
 | 
				
			||||||
 | 
					      aria-roledescription="slide"
 | 
				
			||||||
 | 
					      className={cn(
 | 
				
			||||||
 | 
					        "min-w-0 shrink-0 grow-0 basis-full",
 | 
				
			||||||
 | 
					        orientation === "horizontal" ? "pl-4" : "pt-4",
 | 
				
			||||||
 | 
					        className
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					      {...props}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					CarouselItem.displayName = "CarouselItem"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CarouselPrevious = React.forwardRef<
 | 
				
			||||||
 | 
					  HTMLButtonElement,
 | 
				
			||||||
 | 
					  React.ComponentProps<typeof Button>
 | 
				
			||||||
 | 
					>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
 | 
				
			||||||
 | 
					  const { orientation, scrollPrev, canScrollPrev } = useCarousel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Button
 | 
				
			||||||
 | 
					      ref={ref}
 | 
				
			||||||
 | 
					      variant={variant}
 | 
				
			||||||
 | 
					      size={size}
 | 
				
			||||||
 | 
					      className={cn(
 | 
				
			||||||
 | 
					        "absolute  h-8 w-8 rounded-full",
 | 
				
			||||||
 | 
					        orientation === "horizontal"
 | 
				
			||||||
 | 
					          ? "-left-12 top-1/2 -translate-y-1/2"
 | 
				
			||||||
 | 
					          : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
 | 
				
			||||||
 | 
					        className
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					      disabled={!canScrollPrev}
 | 
				
			||||||
 | 
					      onClick={scrollPrev}
 | 
				
			||||||
 | 
					      {...props}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <ArrowLeft className="h-4 w-4" />
 | 
				
			||||||
 | 
					      <span className="sr-only">Previous slide</span>
 | 
				
			||||||
 | 
					    </Button>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					CarouselPrevious.displayName = "CarouselPrevious"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CarouselNext = React.forwardRef<
 | 
				
			||||||
 | 
					  HTMLButtonElement,
 | 
				
			||||||
 | 
					  React.ComponentProps<typeof Button>
 | 
				
			||||||
 | 
					>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
 | 
				
			||||||
 | 
					  const { orientation, scrollNext, canScrollNext } = useCarousel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Button
 | 
				
			||||||
 | 
					      ref={ref}
 | 
				
			||||||
 | 
					      variant={variant}
 | 
				
			||||||
 | 
					      size={size}
 | 
				
			||||||
 | 
					      className={cn(
 | 
				
			||||||
 | 
					        "absolute h-8 w-8 rounded-full",
 | 
				
			||||||
 | 
					        orientation === "horizontal"
 | 
				
			||||||
 | 
					          ? "-right-12 top-1/2 -translate-y-1/2"
 | 
				
			||||||
 | 
					          : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
 | 
				
			||||||
 | 
					        className
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					      disabled={!canScrollNext}
 | 
				
			||||||
 | 
					      onClick={scrollNext}
 | 
				
			||||||
 | 
					      {...props}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <ArrowRight className="h-4 w-4" />
 | 
				
			||||||
 | 
					      <span className="sr-only">Next slide</span>
 | 
				
			||||||
 | 
					    </Button>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					CarouselNext.displayName = "CarouselNext"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  type CarouselApi,
 | 
				
			||||||
 | 
					  Carousel,
 | 
				
			||||||
 | 
					  CarouselContent,
 | 
				
			||||||
 | 
					  CarouselItem,
 | 
				
			||||||
 | 
					  CarouselPrevious,
 | 
				
			||||||
 | 
					  CarouselNext,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								web/src/components/useServerActionData.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								web/src/components/useServerActionData.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { callServerPromise } from "@/components/callServerPromise";
 | 
				
			||||||
 | 
					import { useEffect, useState, useTransition } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function useServerActionData<I, O>(
 | 
				
			||||||
 | 
					  action: (data: I) => Promise<O>,
 | 
				
			||||||
 | 
					  input: I
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  const [data, setData] = useState<O | null>(null);
 | 
				
			||||||
 | 
					  const [pending, startTransition] = useTransition();
 | 
				
			||||||
 | 
					  const [started, setStarted] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    startTransition(() => {
 | 
				
			||||||
 | 
					      setStarted(true);
 | 
				
			||||||
 | 
					      callServerPromise(action(input)).then(setData);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }, [action, input]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    started,
 | 
				
			||||||
 | 
					    data,
 | 
				
			||||||
 | 
					    pending,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -239,6 +239,22 @@ export const insertMachineSchema = createInsertSchema(machinesTable, {
 | 
				
			|||||||
  type: (schema) => schema.type.default("classic"),
 | 
					  type: (schema) => schema.type.default("classic"),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const showcaseMedia = z.array(
 | 
				
			||||||
 | 
					  z.object({
 | 
				
			||||||
 | 
					    url: z.string(),
 | 
				
			||||||
 | 
					    isCover: z.boolean().default(false),
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const showcaseMediaNullable = z
 | 
				
			||||||
 | 
					  .array(
 | 
				
			||||||
 | 
					    z.object({
 | 
				
			||||||
 | 
					      url: z.string(),
 | 
				
			||||||
 | 
					      isCover: z.boolean().default(false),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					  .nullable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const deploymentsTable = dbSchema.table("deployments", {
 | 
					export const deploymentsTable = dbSchema.table("deployments", {
 | 
				
			||||||
  id: uuid("id").primaryKey().defaultRandom().notNull(),
 | 
					  id: uuid("id").primaryKey().defaultRandom().notNull(),
 | 
				
			||||||
  user_id: text("user_id")
 | 
					  user_id: text("user_id")
 | 
				
			||||||
@ -246,6 +262,7 @@ export const deploymentsTable = dbSchema.table("deployments", {
 | 
				
			|||||||
      onDelete: "cascade",
 | 
					      onDelete: "cascade",
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .notNull(),
 | 
					    .notNull(),
 | 
				
			||||||
 | 
					  org_id: text("org_id"),
 | 
				
			||||||
  workflow_version_id: uuid("workflow_version_id")
 | 
					  workflow_version_id: uuid("workflow_version_id")
 | 
				
			||||||
    .notNull()
 | 
					    .notNull()
 | 
				
			||||||
    .references(() => workflowVersionTable.id),
 | 
					    .references(() => workflowVersionTable.id),
 | 
				
			||||||
@ -257,11 +274,27 @@ export const deploymentsTable = dbSchema.table("deployments", {
 | 
				
			|||||||
  machine_id: uuid("machine_id")
 | 
					  machine_id: uuid("machine_id")
 | 
				
			||||||
    .notNull()
 | 
					    .notNull()
 | 
				
			||||||
    .references(() => machinesTable.id),
 | 
					    .references(() => machinesTable.id),
 | 
				
			||||||
 | 
					  description: text("description"),
 | 
				
			||||||
 | 
					  showcase_media:
 | 
				
			||||||
 | 
					    jsonb("showcase_media").$type<z.infer<typeof showcaseMedia>>(),
 | 
				
			||||||
  environment: deploymentEnvironment("environment").notNull(),
 | 
					  environment: deploymentEnvironment("environment").notNull(),
 | 
				
			||||||
  created_at: timestamp("created_at").defaultNow().notNull(),
 | 
					  created_at: timestamp("created_at").defaultNow().notNull(),
 | 
				
			||||||
  updated_at: timestamp("updated_at").defaultNow().notNull(),
 | 
					  updated_at: timestamp("updated_at").defaultNow().notNull(),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const publicShareDeployment = z.object({
 | 
				
			||||||
 | 
					  description: z.string().nullable(),
 | 
				
			||||||
 | 
					  showcase_media: showcaseMedia,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// createInsertSchema(deploymentsTable, {
 | 
				
			||||||
 | 
					//   description: (schema) => schema.description.default(""),
 | 
				
			||||||
 | 
					//   showcase_media: () => showcaseMedia.default([]),
 | 
				
			||||||
 | 
					// }).pick({
 | 
				
			||||||
 | 
					//   description: true,
 | 
				
			||||||
 | 
					//   showcase_media: true,
 | 
				
			||||||
 | 
					// });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const deploymentsRelations = relations(deploymentsTable, ({ one }) => ({
 | 
					export const deploymentsRelations = relations(deploymentsTable, ({ one }) => ({
 | 
				
			||||||
  machine: one(machinesTable, {
 | 
					  machine: one(machinesTable, {
 | 
				
			||||||
    fields: [deploymentsTable.machine_id],
 | 
					    fields: [deploymentsTable.machine_id],
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
"use server";
 | 
					"use server";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { db } from "@/db/db";
 | 
					import { db } from "@/db/db";
 | 
				
			||||||
import type { DeploymentType } from "@/db/schema";
 | 
					import type { DeploymentType, publicShareDeployment } from "@/db/schema";
 | 
				
			||||||
import { deploymentsTable, workflowTable } from "@/db/schema";
 | 
					import { deploymentsTable, workflowTable } from "@/db/schema";
 | 
				
			||||||
import { createNewWorkflow } from "@/server/createNewWorkflow";
 | 
					import { createNewWorkflow } from "@/server/createNewWorkflow";
 | 
				
			||||||
import { addCustomMachine } from "@/server/curdMachine";
 | 
					import { addCustomMachine } from "@/server/curdMachine";
 | 
				
			||||||
@ -11,6 +11,7 @@ import { and, eq, isNull } from "drizzle-orm";
 | 
				
			|||||||
import { revalidatePath } from "next/cache";
 | 
					import { revalidatePath } from "next/cache";
 | 
				
			||||||
import { redirect } from "next/navigation";
 | 
					import { redirect } from "next/navigation";
 | 
				
			||||||
import "server-only";
 | 
					import "server-only";
 | 
				
			||||||
 | 
					import type { z } from "zod";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function createDeployments(
 | 
					export async function createDeployments(
 | 
				
			||||||
  workflow_id: string,
 | 
					  workflow_id: string,
 | 
				
			||||||
@ -18,7 +19,7 @@ export async function createDeployments(
 | 
				
			|||||||
  machine_id: string,
 | 
					  machine_id: string,
 | 
				
			||||||
  environment: DeploymentType["environment"]
 | 
					  environment: DeploymentType["environment"]
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  const { userId } = auth();
 | 
					  const { userId, orgId } = auth();
 | 
				
			||||||
  if (!userId) throw new Error("No user id");
 | 
					  if (!userId) throw new Error("No user id");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!machine_id) {
 | 
					  if (!machine_id) {
 | 
				
			||||||
@ -40,6 +41,7 @@ export async function createDeployments(
 | 
				
			|||||||
        workflow_id,
 | 
					        workflow_id,
 | 
				
			||||||
        workflow_version_id: version_id,
 | 
					        workflow_version_id: version_id,
 | 
				
			||||||
        machine_id,
 | 
					        machine_id,
 | 
				
			||||||
 | 
					        org_id: orgId,
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .where(eq(deploymentsTable.id, existingDeployment.id));
 | 
					      .where(eq(deploymentsTable.id, existingDeployment.id));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
@ -49,6 +51,7 @@ export async function createDeployments(
 | 
				
			|||||||
      workflow_version_id: version_id,
 | 
					      workflow_version_id: version_id,
 | 
				
			||||||
      machine_id,
 | 
					      machine_id,
 | 
				
			||||||
      environment,
 | 
					      environment,
 | 
				
			||||||
 | 
					      org_id: orgId,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  revalidatePath(`/${workflow_id}`);
 | 
					  revalidatePath(`/${workflow_id}`);
 | 
				
			||||||
@ -195,3 +198,56 @@ export const cloneMachine = withServerPromise(async (deployment_id: string) => {
 | 
				
			|||||||
    message: "Successfully cloned workflow",
 | 
					    message: "Successfully cloned workflow",
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function findUserShareDeployment(share_id: string) {
 | 
				
			||||||
 | 
					  const { userId, orgId } = auth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!userId) throw new Error("No user id");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [deployment] = await db
 | 
				
			||||||
 | 
					    .select()
 | 
				
			||||||
 | 
					    .from(deploymentsTable)
 | 
				
			||||||
 | 
					    .where(
 | 
				
			||||||
 | 
					      and(
 | 
				
			||||||
 | 
					        eq(deploymentsTable.id, share_id),
 | 
				
			||||||
 | 
					        eq(deploymentsTable.environment, "public-share"),
 | 
				
			||||||
 | 
					        orgId
 | 
				
			||||||
 | 
					          ? eq(deploymentsTable.org_id, orgId)
 | 
				
			||||||
 | 
					          : and(
 | 
				
			||||||
 | 
					              eq(deploymentsTable.user_id, userId),
 | 
				
			||||||
 | 
					              isNull(deploymentsTable.org_id)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!deployment) throw new Error("No deployment found");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return deployment;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const updateSharePageInfo = withServerPromise(
 | 
				
			||||||
 | 
					  async ({
 | 
				
			||||||
 | 
					    id,
 | 
				
			||||||
 | 
					    ...data
 | 
				
			||||||
 | 
					  }: z.infer<typeof publicShareDeployment> & {
 | 
				
			||||||
 | 
					    id: string;
 | 
				
			||||||
 | 
					  }) => {
 | 
				
			||||||
 | 
					    const { userId } = auth();
 | 
				
			||||||
 | 
					    if (!userId) return { error: "No user id" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const [deployment] = await db
 | 
				
			||||||
 | 
					      .update(deploymentsTable)
 | 
				
			||||||
 | 
					      .set(data)
 | 
				
			||||||
 | 
					      .where(
 | 
				
			||||||
 | 
					        and(
 | 
				
			||||||
 | 
					          eq(deploymentsTable.environment, "public-share"),
 | 
				
			||||||
 | 
					          eq(deploymentsTable.id, id)
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .returning();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return { message: "Info Updated" };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user