From 8ae266b6a9ced16e1b7416cfc8bea5fe7a7af042 Mon Sep 17 00:00:00 2001 From: hugocasa Date: Wed, 19 Nov 2025 00:04:12 +0100 Subject: [PATCH] feat: disabling/enabling email triggers (#7171) Co-authored-by: Ruben Fiszel --- ...010d4476d5c222184f09e5a189975a37b941.json} | 4 +-- ...8a186fc91f94d4fcc40eeb9914084e4ef60c.json} | 7 ++-- ...d6994d75c6b9e5f61daf54d298a2fdcfd9af.json} | 5 +-- ...bdf5b5feac9c6fa9de38bd24104bac8539d2.json} | 5 +-- ...5ae228697602e3769c479582470dc0b9488b.json} | 4 +-- ...a80eeac12c6ca07a0e8950941ba796b0ba79.json} | 5 +-- backend/ee-repo-ref.txt | 2 +- backend/windmill-api/openapi.yaml | 30 ++++++++++++++++- .../src/triggers/email/handler_oss.rs | 1 - .../src/triggers/gcp/handler_oss.rs | 1 - backend/windmill-api/src/triggers/handler.rs | 18 +++------- .../windmill-api/src/triggers/http/handler.rs | 31 ++++++++--------- .../src/triggers/kafka/handler_oss.rs | 1 - .../windmill-api/src/triggers/mqtt/handler.rs | 1 - .../src/triggers/nats/handler_oss.rs | 1 - .../src/triggers/postgres/handler.rs | 2 -- .../src/triggers/sqs/handler_oss.rs | 1 - .../src/triggers/websocket/handler.rs | 1 - .../email/EmailTriggerEditorInner.svelte | 33 ++++++++++++++----- .../lib/components/triggers/email/utils.ts | 27 +++++++-------- .../triggers/http/RouteEditorInner.svelte | 2 +- .../src/lib/components/triggers/http/utils.ts | 2 +- .../(logged)/email_triggers/+page.svelte | 26 ++++++++++++++- 23 files changed, 133 insertions(+), 77 deletions(-) rename backend/.sqlx/{query-668edc2f84eccf5db6b8daa3ed97e25e46a37c50a9d1a6eca5a277fb58a2e7b4.json => query-628d303956d55d22e5ac64496b66010d4476d5c222184f09e5a189975a37b941.json} (90%) rename backend/.sqlx/{query-d328d00e5393b0e8d2c4b3674221fabbae580fc404e0d4481fd8d7fb51272c94.json => query-6c568509908c1833d9e6f58f739b8a186fc91f94d4fcc40eeb9914084e4ef60c.json} (70%) rename backend/.sqlx/{query-acb094aef60bba9083087264d65034fce38417099f15e8312be72a386f10bc1f.json => query-a704283ff62ac1cd6db489ca3f84d6994d75c6b9e5f61daf54d298a2fdcfd9af.json} (73%) rename backend/.sqlx/{query-4c64bd0e364f536597db83161b5a27ff58b5ec7148bc94807423593bcfa27b90.json => query-ada1a14b4f25e41742df153b07e8bdf5b5feac9c6fa9de38bd24104bac8539d2.json} (67%) rename backend/.sqlx/{query-bbd51f4f0a8bb2db5d6b634f2d32f5f7f7f57390a0e4b6e7cad45c9147fd6356.json => query-df6972fb16a2364f10379fe37e125ae228697602e3769c479582470dc0b9488b.json} (91%) rename backend/.sqlx/{query-6fafc23924eded970689040bd4a94d4d23ebee4f2b7d37bb54c47edb7720be00.json => query-fe12006498b9e7aece6b104fc5d9a80eeac12c6ca07a0e8950941ba796b0ba79.json} (73%) diff --git a/backend/.sqlx/query-668edc2f84eccf5db6b8daa3ed97e25e46a37c50a9d1a6eca5a277fb58a2e7b4.json b/backend/.sqlx/query-628d303956d55d22e5ac64496b66010d4476d5c222184f09e5a189975a37b941.json similarity index 90% rename from backend/.sqlx/query-668edc2f84eccf5db6b8daa3ed97e25e46a37c50a9d1a6eca5a277fb58a2e7b4.json rename to backend/.sqlx/query-628d303956d55d22e5ac64496b66010d4476d5c222184f09e5a189975a37b941.json index 7520bc8879..3f5e733cb1 100644 --- a/backend/.sqlx/query-668edc2f84eccf5db6b8daa3ed97e25e46a37c50a9d1a6eca5a277fb58a2e7b4.json +++ b/backend/.sqlx/query-628d303956d55d22e5ac64496b66010d4476d5c222184f09e5a189975a37b941.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT \n script_path, \n is_flow, \n workspace_id, \n edited_by, \n email, \n path, \n error_handler_path as \"error_handler_path: _\", \n error_handler_args as \"error_handler_args: _\", \n retry as \"retry: _\" \n FROM email_trigger \n WHERE local_part = $1 \n AND workspaced_local_part = FALSE\n ", + "query": "\n SELECT \n script_path, \n is_flow, \n workspace_id, \n edited_by, \n email, \n path, \n error_handler_path as \"error_handler_path: _\", \n error_handler_args as \"error_handler_args: _\", \n retry as \"retry: _\" \n FROM email_trigger \n WHERE local_part = $1 \n AND workspaced_local_part = FALSE\n AND enabled IS TRUE\n ", "describe": { "columns": [ { @@ -66,5 +66,5 @@ true ] }, - "hash": "668edc2f84eccf5db6b8daa3ed97e25e46a37c50a9d1a6eca5a277fb58a2e7b4" + "hash": "628d303956d55d22e5ac64496b66010d4476d5c222184f09e5a189975a37b941" } diff --git a/backend/.sqlx/query-d328d00e5393b0e8d2c4b3674221fabbae580fc404e0d4481fd8d7fb51272c94.json b/backend/.sqlx/query-6c568509908c1833d9e6f58f739b8a186fc91f94d4fcc40eeb9914084e4ef60c.json similarity index 70% rename from backend/.sqlx/query-d328d00e5393b0e8d2c4b3674221fabbae580fc404e0d4481fd8d7fb51272c94.json rename to backend/.sqlx/query-6c568509908c1833d9e6f58f739b8a186fc91f94d4fcc40eeb9914084e4ef60c.json index 474ce7b688..b6e4f96c3c 100644 --- a/backend/.sqlx/query-d328d00e5393b0e8d2c4b3674221fabbae580fc404e0d4481fd8d7fb51272c94.json +++ b/backend/.sqlx/query-6c568509908c1833d9e6f58f739b8a186fc91f94d4fcc40eeb9914084e4ef60c.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO email_trigger (\n workspace_id,\n path,\n script_path,\n is_flow,\n local_part,\n workspaced_local_part,\n edited_by,\n email,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, now(), $9, $10, $11\n )\n ", + "query": "\n INSERT INTO email_trigger (\n workspace_id,\n path,\n script_path,\n is_flow,\n local_part,\n workspaced_local_part,\n edited_by,\n email,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry,\n enabled\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, now(), $9, $10, $11, $12\n )\n ", "describe": { "columns": [], "parameters": { @@ -15,10 +15,11 @@ "Varchar", "Varchar", "Jsonb", - "Jsonb" + "Jsonb", + "Bool" ] }, "nullable": [] }, - "hash": "d328d00e5393b0e8d2c4b3674221fabbae580fc404e0d4481fd8d7fb51272c94" + "hash": "6c568509908c1833d9e6f58f739b8a186fc91f94d4fcc40eeb9914084e4ef60c" } diff --git a/backend/.sqlx/query-acb094aef60bba9083087264d65034fce38417099f15e8312be72a386f10bc1f.json b/backend/.sqlx/query-a704283ff62ac1cd6db489ca3f84d6994d75c6b9e5f61daf54d298a2fdcfd9af.json similarity index 73% rename from backend/.sqlx/query-acb094aef60bba9083087264d65034fce38417099f15e8312be72a386f10bc1f.json rename to backend/.sqlx/query-a704283ff62ac1cd6db489ca3f84d6994d75c6b9e5f61daf54d298a2fdcfd9af.json index 805e5f0e79..b59a7f294a 100644 --- a/backend/.sqlx/query-acb094aef60bba9083087264d65034fce38417099f15e8312be72a386f10bc1f.json +++ b/backend/.sqlx/query-a704283ff62ac1cd6db489ca3f84d6994d75c6b9e5f61daf54d298a2fdcfd9af.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n UPDATE email_trigger \n SET \n script_path = $1,\n path = $2,\n is_flow = $3,\n edited_by = $4,\n email = $5,\n edited_at = now(),\n error_handler_path = $6,\n error_handler_args = $7,\n retry = $8\n WHERE \n workspace_id = $9 AND path = $10\n ", + "query": "\n UPDATE email_trigger \n SET \n script_path = $1,\n path = $2,\n is_flow = $3,\n edited_by = $4,\n email = $5,\n edited_at = now(),\n error_handler_path = $6,\n error_handler_args = $7,\n retry = $8,\n enabled = $9\n WHERE \n workspace_id = $10 AND path = $11\n ", "describe": { "columns": [], "parameters": { @@ -13,11 +13,12 @@ "Varchar", "Jsonb", "Jsonb", + "Bool", "Text", "Text" ] }, "nullable": [] }, - "hash": "acb094aef60bba9083087264d65034fce38417099f15e8312be72a386f10bc1f" + "hash": "a704283ff62ac1cd6db489ca3f84d6994d75c6b9e5f61daf54d298a2fdcfd9af" } diff --git a/backend/.sqlx/query-4c64bd0e364f536597db83161b5a27ff58b5ec7148bc94807423593bcfa27b90.json b/backend/.sqlx/query-ada1a14b4f25e41742df153b07e8bdf5b5feac9c6fa9de38bd24104bac8539d2.json similarity index 67% rename from backend/.sqlx/query-4c64bd0e364f536597db83161b5a27ff58b5ec7148bc94807423593bcfa27b90.json rename to backend/.sqlx/query-ada1a14b4f25e41742df153b07e8bdf5b5feac9c6fa9de38bd24104bac8539d2.json index dfe905113e..1a33383b67 100644 --- a/backend/.sqlx/query-4c64bd0e364f536597db83161b5a27ff58b5ec7148bc94807423593bcfa27b90.json +++ b/backend/.sqlx/query-ada1a14b4f25e41742df153b07e8bdf5b5feac9c6fa9de38bd24104bac8539d2.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n UPDATE\n http_trigger\n SET\n wrap_body = $1,\n raw_string = $2,\n authentication_resource_path = $3,\n script_path = $4,\n path = $5,\n is_flow = $6,\n http_method = $7,\n static_asset_config = $8,\n edited_by = $9,\n email = $10,\n request_type = $11,\n authentication_method = $12,\n summary = $13,\n description = $14,\n edited_at = now(),\n is_static_website = $15,\n error_handler_path = $16,\n error_handler_args = $17,\n retry = $18\n WHERE\n workspace_id = $19 AND\n path = $20\n ", + "query": "\n UPDATE\n http_trigger\n SET\n wrap_body = $1,\n raw_string = $2,\n authentication_resource_path = $3,\n script_path = $4,\n path = $5,\n is_flow = $6,\n enabled = $7,\n http_method = $8,\n static_asset_config = $9,\n edited_by = $10,\n email = $11,\n request_type = $12,\n authentication_method = $13,\n summary = $14,\n description = $15,\n edited_at = now(),\n is_static_website = $16,\n error_handler_path = $17,\n error_handler_args = $18,\n retry = $19\n WHERE\n workspace_id = $20 AND\n path = $21\n ", "describe": { "columns": [], "parameters": { @@ -11,6 +11,7 @@ "Varchar", "Varchar", "Bool", + "Bool", { "Custom": { "name": "http_method", @@ -67,5 +68,5 @@ }, "nullable": [] }, - "hash": "4c64bd0e364f536597db83161b5a27ff58b5ec7148bc94807423593bcfa27b90" + "hash": "ada1a14b4f25e41742df153b07e8bdf5b5feac9c6fa9de38bd24104bac8539d2" } diff --git a/backend/.sqlx/query-bbd51f4f0a8bb2db5d6b634f2d32f5f7f7f57390a0e4b6e7cad45c9147fd6356.json b/backend/.sqlx/query-df6972fb16a2364f10379fe37e125ae228697602e3769c479582470dc0b9488b.json similarity index 91% rename from backend/.sqlx/query-bbd51f4f0a8bb2db5d6b634f2d32f5f7f7f57390a0e4b6e7cad45c9147fd6356.json rename to backend/.sqlx/query-df6972fb16a2364f10379fe37e125ae228697602e3769c479582470dc0b9488b.json index ab4e5e5d36..1e5c26b2e7 100644 --- a/backend/.sqlx/query-bbd51f4f0a8bb2db5d6b634f2d32f5f7f7f57390a0e4b6e7cad45c9147fd6356.json +++ b/backend/.sqlx/query-df6972fb16a2364f10379fe37e125ae228697602e3769c479582470dc0b9488b.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT \n script_path, \n is_flow, \n workspace_id, \n edited_by, \n email, \n path, \n error_handler_path as \"error_handler_path: _\", \n error_handler_args as \"error_handler_args: _\", \n retry as \"retry: _\" \n FROM email_trigger \n WHERE workspace_id = $1 \n AND local_part = $2 \n AND (workspaced_local_part = TRUE OR $3 IS TRUE)\n ", + "query": "\n SELECT \n script_path, \n is_flow, \n workspace_id, \n edited_by, \n email, \n path, \n error_handler_path as \"error_handler_path: _\", \n error_handler_args as \"error_handler_args: _\", \n retry as \"retry: _\" \n FROM email_trigger \n WHERE workspace_id = $1 \n AND local_part = $2 \n AND (workspaced_local_part = TRUE OR $3 IS TRUE)\n AND enabled IS TRUE\n ", "describe": { "columns": [ { @@ -68,5 +68,5 @@ true ] }, - "hash": "bbd51f4f0a8bb2db5d6b634f2d32f5f7f7f57390a0e4b6e7cad45c9147fd6356" + "hash": "df6972fb16a2364f10379fe37e125ae228697602e3769c479582470dc0b9488b" } diff --git a/backend/.sqlx/query-6fafc23924eded970689040bd4a94d4d23ebee4f2b7d37bb54c47edb7720be00.json b/backend/.sqlx/query-fe12006498b9e7aece6b104fc5d9a80eeac12c6ca07a0e8950941ba796b0ba79.json similarity index 73% rename from backend/.sqlx/query-6fafc23924eded970689040bd4a94d4d23ebee4f2b7d37bb54c47edb7720be00.json rename to backend/.sqlx/query-fe12006498b9e7aece6b104fc5d9a80eeac12c6ca07a0e8950941ba796b0ba79.json index 706bcacdb2..150d2d9504 100644 --- a/backend/.sqlx/query-6fafc23924eded970689040bd4a94d4d23ebee4f2b7d37bb54c47edb7720be00.json +++ b/backend/.sqlx/query-fe12006498b9e7aece6b104fc5d9a80eeac12c6ca07a0e8950941ba796b0ba79.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n UPDATE email_trigger \n SET \n script_path = $1,\n path = $2,\n is_flow = $3,\n local_part = $4,\n workspaced_local_part = $5,\n edited_by = $6,\n email = $7,\n edited_at = now(),\n error_handler_path = $8,\n error_handler_args = $9,\n retry = $10\n WHERE \n workspace_id = $11 AND path = $12\n ", + "query": "\n UPDATE email_trigger \n SET \n script_path = $1,\n path = $2,\n is_flow = $3,\n local_part = $4,\n workspaced_local_part = $5,\n edited_by = $6,\n email = $7,\n edited_at = now(),\n error_handler_path = $8,\n error_handler_args = $9,\n retry = $10,\n enabled = $11\n WHERE \n workspace_id = $12 AND path = $13\n ", "describe": { "columns": [], "parameters": { @@ -15,11 +15,12 @@ "Varchar", "Jsonb", "Jsonb", + "Bool", "Text", "Text" ] }, "nullable": [] }, - "hash": "6fafc23924eded970689040bd4a94d4d23ebee4f2b7d37bb54c47edb7720be00" + "hash": "fe12006498b9e7aece6b104fc5d9a80eeac12c6ca07a0e8950941ba796b0ba79" } diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 7dd5e2c77a..ada9554f8a 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -6694dfbc62ff69570743f028aa19c543ae846e6e \ No newline at end of file +6009dffc0e9549463e34d748ad54c401cbe46ffd diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 928e5d007a..85740d0d2f 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -11998,6 +11998,33 @@ paths: application/json: schema: type: boolean + /w/{workspace}/email_triggers/setenabled/{path}: + post: + summary: enable/disable email trigger + operationId: setEmailTriggerEnabled + tags: + - email_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + required: + - enabled + responses: + "200": + description: email trigger enable/disable + content: + text/plain: + schema: + type: string /groups/list: get: @@ -18612,7 +18639,8 @@ components: $ref: "#/components/schemas/ScriptArgs" retry: $ref: "../../openflow.openapi.yaml#/components/schemas/Retry" - + enabled: + type: boolean required: - path - script_path diff --git a/backend/windmill-api/src/triggers/email/handler_oss.rs b/backend/windmill-api/src/triggers/email/handler_oss.rs index ca4de1733e..03a377df98 100644 --- a/backend/windmill-api/src/triggers/email/handler_oss.rs +++ b/backend/windmill-api/src/triggers/email/handler_oss.rs @@ -28,7 +28,6 @@ impl TriggerCrud for EmailTrigger { const TABLE_NAME: &'static str = ""; const TRIGGER_TYPE: &'static str = ""; - const SUPPORTS_ENABLED: bool = true; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/email_triggers"; diff --git a/backend/windmill-api/src/triggers/gcp/handler_oss.rs b/backend/windmill-api/src/triggers/gcp/handler_oss.rs index 4b52ff9c68..b75a9721eb 100644 --- a/backend/windmill-api/src/triggers/gcp/handler_oss.rs +++ b/backend/windmill-api/src/triggers/gcp/handler_oss.rs @@ -25,7 +25,6 @@ impl TriggerCrud for GcpTrigger { const TABLE_NAME: &'static str = ""; const TRIGGER_TYPE: &'static str = ""; - const SUPPORTS_ENABLED: bool = false; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/gcp_triggers"; diff --git a/backend/windmill-api/src/triggers/handler.rs b/backend/windmill-api/src/triggers/handler.rs index a6019c5a14..05042bd385 100644 --- a/backend/windmill-api/src/triggers/handler.rs +++ b/backend/windmill-api/src/triggers/handler.rs @@ -50,7 +50,6 @@ pub trait TriggerCrud: Send + Sync + 'static { const TABLE_NAME: &'static str; const TRIGGER_TYPE: &'static str; - const SUPPORTS_ENABLED: bool; const SUPPORTS_SERVER_STATE: bool; const SUPPORTS_TEST_CONNECTION: bool; const ROUTE_PREFIX: &'static str; @@ -144,12 +143,9 @@ pub trait TriggerCrud: Send + Sync + 'static { "email", "edited_at", "extra_perms", + "enabled", ]; - if Self::SUPPORTS_ENABLED { - fields.push("enabled"); - } - if Self::SUPPORTS_SERVER_STATE { fields.extend_from_slice(&["server_id", "last_server_ping", "error"]); } @@ -325,12 +321,9 @@ pub trait TriggerCrud: Send + Sync + 'static { "email", "edited_at", "extra_perms", + "enabled", ]; - if Self::SUPPORTS_ENABLED { - fields.push("enabled"); - } - if Self::SUPPORTS_SERVER_STATE { fields.extend_from_slice(&["server_id", "last_server_ping", "error"]); } @@ -380,11 +373,8 @@ pub fn trigger_routes() -> Router { .route("/get/*path", get(get_trigger::)) .route("/update/*path", post(update_trigger::)) .route("/delete/*path", delete(delete_trigger::)) - .route("/exists/*path", get(exists_trigger::)); - - if T::SUPPORTS_ENABLED { - router = router.route("/setenabled/*path", post(set_enabled_trigger::)); - } + .route("/exists/*path", get(exists_trigger::)) + .route("/setenabled/*path", post(set_enabled_trigger::)); if T::SUPPORTS_TEST_CONNECTION { router = router.route("/test", post(test_connection::)); diff --git a/backend/windmill-api/src/triggers/http/handler.rs b/backend/windmill-api/src/triggers/http/handler.rs index 19fabe40ea..cf1a004c32 100644 --- a/backend/windmill-api/src/triggers/http/handler.rs +++ b/backend/windmill-api/src/triggers/http/handler.rs @@ -358,7 +358,6 @@ impl TriggerCrud for HttpTrigger { const TABLE_NAME: &'static str = "http_trigger"; const TRIGGER_TYPE: &'static str = "http"; - const SUPPORTS_ENABLED: bool = true; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/http_triggers"; @@ -543,22 +542,23 @@ impl TriggerCrud for HttpTrigger { script_path = $4, path = $5, is_flow = $6, - http_method = $7, - static_asset_config = $8, - edited_by = $9, - email = $10, - request_type = $11, - authentication_method = $12, - summary = $13, - description = $14, + enabled = $7, + http_method = $8, + static_asset_config = $9, + edited_by = $10, + email = $11, + request_type = $12, + authentication_method = $13, + summary = $14, + description = $15, edited_at = now(), - is_static_website = $15, - error_handler_path = $16, - error_handler_args = $17, - retry = $18 + is_static_website = $16, + error_handler_path = $17, + error_handler_args = $18, + retry = $19 WHERE - workspace_id = $19 AND - path = $20 + workspace_id = $20 AND + path = $21 "#, trigger.config.wrap_body, trigger.config.raw_string, @@ -566,6 +566,7 @@ impl TriggerCrud for HttpTrigger { trigger.base.script_path, trigger.base.path, trigger.base.is_flow, + trigger.base.enabled.unwrap_or(true), trigger.config.http_method as _, trigger.config.static_asset_config as _, &authed.username, diff --git a/backend/windmill-api/src/triggers/kafka/handler_oss.rs b/backend/windmill-api/src/triggers/kafka/handler_oss.rs index bf5537b941..9fda83916f 100644 --- a/backend/windmill-api/src/triggers/kafka/handler_oss.rs +++ b/backend/windmill-api/src/triggers/kafka/handler_oss.rs @@ -28,7 +28,6 @@ impl TriggerCrud for KafkaTrigger { const TABLE_NAME: &'static str = ""; const TRIGGER_TYPE: &'static str = ""; - const SUPPORTS_ENABLED: bool = false; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/kafka_triggers"; diff --git a/backend/windmill-api/src/triggers/mqtt/handler.rs b/backend/windmill-api/src/triggers/mqtt/handler.rs index d8e314a836..fd6054666c 100644 --- a/backend/windmill-api/src/triggers/mqtt/handler.rs +++ b/backend/windmill-api/src/triggers/mqtt/handler.rs @@ -26,7 +26,6 @@ impl TriggerCrud for MqttTrigger { const TABLE_NAME: &'static str = "mqtt_trigger"; const TRIGGER_TYPE: &'static str = "mqtt"; - const SUPPORTS_ENABLED: bool = true; const SUPPORTS_SERVER_STATE: bool = true; const SUPPORTS_TEST_CONNECTION: bool = true; const ROUTE_PREFIX: &'static str = "/mqtt_triggers"; diff --git a/backend/windmill-api/src/triggers/nats/handler_oss.rs b/backend/windmill-api/src/triggers/nats/handler_oss.rs index 41f060003f..3ab3430e5f 100644 --- a/backend/windmill-api/src/triggers/nats/handler_oss.rs +++ b/backend/windmill-api/src/triggers/nats/handler_oss.rs @@ -25,7 +25,6 @@ impl TriggerCrud for NatsTrigger { const TABLE_NAME: &'static str = ""; const TRIGGER_TYPE: &'static str = ""; - const SUPPORTS_ENABLED: bool = false; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/nats_triggers"; diff --git a/backend/windmill-api/src/triggers/postgres/handler.rs b/backend/windmill-api/src/triggers/postgres/handler.rs index 5dce0345c6..3b0a1b6972 100644 --- a/backend/windmill-api/src/triggers/postgres/handler.rs +++ b/backend/windmill-api/src/triggers/postgres/handler.rs @@ -47,7 +47,6 @@ impl TriggerCrud for PostgresTrigger { const TABLE_NAME: &'static str = "postgres_trigger"; const TRIGGER_TYPE: &'static str = "postgres"; - const SUPPORTS_ENABLED: bool = true; const SUPPORTS_SERVER_STATE: bool = true; const SUPPORTS_TEST_CONNECTION: bool = true; const ROUTE_PREFIX: &'static str = "/postgres_triggers"; @@ -64,7 +63,6 @@ impl TriggerCrud for PostgresTrigger { DeployedObject::PostgresTrigger { path } } - async fn create_trigger( &self, db: &DB, diff --git a/backend/windmill-api/src/triggers/sqs/handler_oss.rs b/backend/windmill-api/src/triggers/sqs/handler_oss.rs index 6b6d18b72e..21200e8e38 100644 --- a/backend/windmill-api/src/triggers/sqs/handler_oss.rs +++ b/backend/windmill-api/src/triggers/sqs/handler_oss.rs @@ -26,7 +26,6 @@ impl TriggerCrud for SqsTrigger { const TABLE_NAME: &'static str = ""; const TRIGGER_TYPE: &'static str = ""; - const SUPPORTS_ENABLED: bool = false; const SUPPORTS_SERVER_STATE: bool = false; const SUPPORTS_TEST_CONNECTION: bool = false; const ROUTE_PREFIX: &'static str = "/sqs_triggers"; diff --git a/backend/windmill-api/src/triggers/websocket/handler.rs b/backend/windmill-api/src/triggers/websocket/handler.rs index 510f6e97ae..2439be8292 100644 --- a/backend/windmill-api/src/triggers/websocket/handler.rs +++ b/backend/windmill-api/src/triggers/websocket/handler.rs @@ -30,7 +30,6 @@ impl TriggerCrud for WebsocketTrigger { const TABLE_NAME: &'static str = "websocket_trigger"; const TRIGGER_TYPE: &'static str = "websocket"; - const SUPPORTS_ENABLED: bool = true; const SUPPORTS_SERVER_STATE: bool = true; const SUPPORTS_TEST_CONNECTION: bool = true; const ROUTE_PREFIX: &'static str = "/websocket_triggers"; diff --git a/frontend/src/lib/components/triggers/email/EmailTriggerEditorInner.svelte b/frontend/src/lib/components/triggers/email/EmailTriggerEditorInner.svelte index 291a3e08ac..4e8a37e9e0 100644 --- a/frontend/src/lib/components/triggers/email/EmailTriggerEditorInner.svelte +++ b/frontend/src/lib/components/triggers/email/EmailTriggerEditorInner.svelte @@ -65,6 +65,7 @@ let error_handler_path: string | undefined = $state() let error_handler_args: Record = $state({}) let retry: Retry | undefined = $state() + let enabled = $state(false) // Component references let drawer = $state(undefined) let initialConfig: NewEmailTrigger | undefined = undefined @@ -72,7 +73,7 @@ let optionTabSelected: 'error_handler' | 'retries' = $state('error_handler') let errorHandlerSelected: ErrorHandler = $state('slack') const isAdmin = $derived($userStore?.is_admin || $userStore?.is_super_admin) - const routeConfig = $derived.by(getEmailTriggerConfig) + const emailConfig = $derived.by(getEmailTriggerConfig) const captureConfig = $derived.by(isEditor ? getCaptureConfig : () => ({})) const saveDisabled = $derived( drawerLoading || !can_write || pathError != '' || !isValid || emptyString(script_path) @@ -141,6 +142,7 @@ error_handler_args = defaultValues?.error_handler_args ?? {} retry = defaultValues?.retry ?? undefined errorHandlerSelected = getHandlerType(error_handler_path ?? '') + enabled = defaultValues?.enabled ?? false } finally { clearTimeout(loader) drawerLoading = false @@ -161,6 +163,7 @@ error_handler_args = cfg?.error_handler_args ?? {} retry = cfg?.retry errorHandlerSelected = getHandlerType(error_handler_path ?? '') + enabled = cfg?.enabled ?? false } async function loadTrigger(defaultConfig?: Partial): Promise { @@ -179,11 +182,11 @@ async function triggerScript(): Promise { if (customSaveBehavior) { - customSaveBehavior(routeConfig) + customSaveBehavior(emailConfig) drawer?.closeDrawer() } else { deploymentLoading = true - const saveCfg = routeConfig + const saveCfg = emailConfig const isSaved = await saveEmailTriggerFromCfg( initialPath, saveCfg, @@ -210,17 +213,30 @@ extra_perms: extraPerms, error_handler_path, error_handler_args, - retry + retry, + enabled } return nCfg } + async function handleToggleEnabled(newEnabled: boolean) { + enabled = newEnabled + if (!trigger?.draftConfig) { + await EmailTriggerService.setEmailTriggerEnabled({ + path: initialPath, + workspace: $workspaceStore ?? '', + requestBody: { enabled: newEnabled } + }) + sendUserToast(`${newEnabled ? 'enabled' : 'disabled'} email trigger ${initialPath}`) + } + } + // Update config for captures function getCaptureConfig() { const newCaptureConfig = { - local_part: routeConfig.local_part, - path: routeConfig.path + local_part: emailConfig.local_part, + path: emailConfig.path } // return newCaptureConfig @@ -233,7 +249,7 @@ $effect(() => { if (!drawerLoading) { - handleConfigChange(routeConfig, initialConfig, saveDisabled, edit, onConfigChange) + handleConfigChange(emailConfig, initialConfig, saveDisabled, edit, onConfigChange) } }) @@ -338,8 +354,9 @@ {trigger} permissions={drawerLoading || !can_write ? 'none' : can_write && isAdmin ? 'create' : 'write'} {saveDisabled} - enabled={undefined} + {enabled} {allowDraft} + onToggleEnabled={handleToggleEnabled} {edit} isLoading={deploymentLoading} onUpdate={triggerScript} diff --git a/frontend/src/lib/components/triggers/email/utils.ts b/frontend/src/lib/components/triggers/email/utils.ts index 82de2a0a0d..49a94093eb 100644 --- a/frontend/src/lib/components/triggers/email/utils.ts +++ b/frontend/src/lib/components/triggers/email/utils.ts @@ -15,21 +15,22 @@ export function getEmailAddress( export async function saveEmailTriggerFromCfg( initialPath: string, - routeCfg: Record, + emailCfg: Record, edit: boolean, workspace: string, isAdmin: boolean, usedTriggerKinds: Writable ): Promise { const requestBody: NewEmailTrigger = { - path: routeCfg.path, - script_path: routeCfg.script_path, - local_part: routeCfg.local_part, - is_flow: routeCfg.is_flow, - workspaced_local_part: routeCfg.workspaced_local_part, - error_handler_path: routeCfg.error_handler_path, - error_handler_args: routeCfg.error_handler_path ? routeCfg.error_handler_args : undefined, - retry: routeCfg.retry + path: emailCfg.path, + script_path: emailCfg.script_path, + local_part: emailCfg.local_part, + is_flow: emailCfg.is_flow, + workspaced_local_part: emailCfg.workspaced_local_part, + error_handler_path: emailCfg.error_handler_path, + error_handler_args: emailCfg.error_handler_path ? emailCfg.error_handler_args : undefined, + retry: emailCfg.retry, + enabled: emailCfg.enabled } try { if (edit) { @@ -38,16 +39,16 @@ export async function saveEmailTriggerFromCfg( path: initialPath, requestBody: { ...requestBody, - local_part: isAdmin || !edit ? routeCfg.local_part : undefined + local_part: isAdmin || !edit ? emailCfg.local_part : undefined } }) - sendUserToast(`Route ${routeCfg.path} updated`) + sendUserToast(`Email trigger ${emailCfg.path} updated`) } else { await EmailTriggerService.createEmailTrigger({ workspace: workspace, - requestBody: requestBody + requestBody: { ...requestBody, enabled: true } }) - sendUserToast(`Route ${routeCfg.path} created`) + sendUserToast(`Email trigger ${emailCfg.path} created`) } if (!get(usedTriggerKinds).includes('email')) { usedTriggerKinds.update((t) => [...t, 'email']) diff --git a/frontend/src/lib/components/triggers/http/RouteEditorInner.svelte b/frontend/src/lib/components/triggers/http/RouteEditorInner.svelte index bb11e620bf..085360df6a 100644 --- a/frontend/src/lib/components/triggers/http/RouteEditorInner.svelte +++ b/frontend/src/lib/components/triggers/http/RouteEditorInner.svelte @@ -236,7 +236,7 @@ s3FileUploadRawMode = defaultValues?.s3FileUploadRawMode ?? false path = defaultValues?.path ?? '' initialPath = '' - enabled = defaultValues?.enabled ?? true + enabled = defaultValues?.enabled ?? false dirtyPath = false is_static_website = defaultValues?.is_static_website ?? false workspaced_route = defaultValues?.workspaced_route ?? false diff --git a/frontend/src/lib/components/triggers/http/utils.ts b/frontend/src/lib/components/triggers/http/utils.ts index 212201f0b6..5cb2cf2b4f 100644 --- a/frontend/src/lib/components/triggers/http/utils.ts +++ b/frontend/src/lib/components/triggers/http/utils.ts @@ -77,7 +77,7 @@ export async function saveHttpRouteFromCfg( } else { await HttpTriggerService.createHttpTrigger({ workspace: workspace, - requestBody: requestBody + requestBody: { ...requestBody, enabled: true } }) sendUserToast(`Route ${routeCfg.path} created`) } diff --git a/frontend/src/routes/(root)/(logged)/email_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/email_triggers/+page.svelte index 8ea6a5069a..386db77449 100644 --- a/frontend/src/routes/(root)/(logged)/email_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/email_triggers/+page.svelte @@ -193,6 +193,23 @@ } } + async function setTriggerEnabled(path: string, enabled: boolean): Promise { + try { + await EmailTriggerService.setEmailTriggerEnabled({ + path, + workspace: $workspaceStore!, + requestBody: { enabled } + }) + } catch (err) { + sendUserToast( + `Cannot ` + (enabled ? 'enable' : 'disable') + ` email trigger: ${err.body}`, + true + ) + } finally { + loadTriggers() + } + } + onMount(() => { loadQueryFilters() }) @@ -274,7 +291,7 @@
No email triggers
{:else if items?.length}
- {#each items.slice(0, nbDisplayed) as { workspace_id, workspaced_local_part, path, edited_by, edited_at, script_path, is_flow, extra_perms, canWrite, marked, local_part } (path)} + {#each items.slice(0, nbDisplayed) as { workspace_id, workspaced_local_part, path, edited_by, edited_at, script_path, is_flow, extra_perms, canWrite, marked, local_part, enabled } (path)} {@const href = `${is_flow ? '/flows/get' : '/scripts/get'}/${script_path}`} {@const emailAddress = getEmailAddress( local_part, @@ -317,6 +334,13 @@ + { + setTriggerEnabled(path, e.detail) + }} + />