diff --git a/backend/.sqlx/query-08f288d2781d823e109a9e5b8848234ca7d1efeee9661f3901f298da375e73f7.json b/backend/.sqlx/query-08f288d2781d823e109a9e5b8848234ca7d1efeee9661f3901f298da375e73f7.json new file mode 100644 index 0000000000..4bcf3c6ce3 --- /dev/null +++ b/backend/.sqlx/query-08f288d2781d823e109a9e5b8848234ca7d1efeee9661f3901f298da375e73f7.json @@ -0,0 +1,196 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT * FROM workspace_settings WHERE teams_team_id = $1 AND teams_command_script IS NOT NULL", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "slack_team_id", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "slack_name", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "slack_command_script", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "slack_email", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "auto_invite_domain", + "type_info": "Varchar" + }, + { + "ordinal": 6, + "name": "auto_invite_operator", + "type_info": "Bool" + }, + { + "ordinal": 7, + "name": "customer_id", + "type_info": "Varchar" + }, + { + "ordinal": 8, + "name": "plan", + "type_info": "Varchar" + }, + { + "ordinal": 9, + "name": "webhook", + "type_info": "Text" + }, + { + "ordinal": 10, + "name": "deploy_to", + "type_info": "Varchar" + }, + { + "ordinal": 11, + "name": "error_handler", + "type_info": "Varchar" + }, + { + "ordinal": 12, + "name": "ai_resource", + "type_info": "Jsonb" + }, + { + "ordinal": 13, + "name": "error_handler_extra_args", + "type_info": "Json" + }, + { + "ordinal": 14, + "name": "error_handler_muted_on_cancel", + "type_info": "Bool" + }, + { + "ordinal": 15, + "name": "large_file_storage", + "type_info": "Jsonb" + }, + { + "ordinal": 16, + "name": "git_sync", + "type_info": "Jsonb" + }, + { + "ordinal": 17, + "name": "default_app", + "type_info": "Varchar" + }, + { + "ordinal": 18, + "name": "auto_add", + "type_info": "Bool" + }, + { + "ordinal": 19, + "name": "automatic_billing", + "type_info": "Bool" + }, + { + "ordinal": 20, + "name": "default_scripts", + "type_info": "Jsonb" + }, + { + "ordinal": 21, + "name": "deploy_ui", + "type_info": "Jsonb" + }, + { + "ordinal": 22, + "name": "mute_critical_alerts", + "type_info": "Bool" + }, + { + "ordinal": 23, + "name": "color", + "type_info": "Varchar" + }, + { + "ordinal": 24, + "name": "operator_settings", + "type_info": "Jsonb" + }, + { + "ordinal": 25, + "name": "ai_models", + "type_info": "VarcharArray" + }, + { + "ordinal": 26, + "name": "code_completion_model", + "type_info": "Varchar" + }, + { + "ordinal": 27, + "name": "teams_command_script", + "type_info": "Text" + }, + { + "ordinal": 28, + "name": "teams_team_id", + "type_info": "Text" + }, + { + "ordinal": 29, + "name": "teams_team_name", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + true, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true, + false, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true + ] + }, + "hash": "08f288d2781d823e109a9e5b8848234ca7d1efeee9661f3901f298da375e73f7" +} diff --git a/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json b/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json index 03da2cee85..6df517592a 100644 --- a/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json +++ b/backend/.sqlx/query-1730f39fd1793d45fbb41b21389c61296a3ff7489ae12f52a19f9543173ac597.json @@ -137,6 +137,21 @@ "ordinal": 26, "name": "code_completion_model", "type_info": "Varchar" + }, + { + "ordinal": 27, + "name": "teams_command_script", + "type_info": "Text" + }, + { + "ordinal": 28, + "name": "teams_team_id", + "type_info": "Text" + }, + { + "ordinal": 29, + "name": "teams_team_name", + "type_info": "Text" } ], "parameters": { @@ -171,6 +186,9 @@ true, true, false, + true, + true, + true, true ] }, diff --git a/backend/.sqlx/query-1ace9bdcde90fd2261fd64344a2d9474b17887711128dbb2ef15d247d50686b0.json b/backend/.sqlx/query-1ace9bdcde90fd2261fd64344a2d9474b17887711128dbb2ef15d247d50686b0.json new file mode 100644 index 0000000000..9a8ef973a4 --- /dev/null +++ b/backend/.sqlx/query-1ace9bdcde90fd2261fd64344a2d9474b17887711128dbb2ef15d247d50686b0.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT teams_team_id FROM workspace_settings WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "teams_team_id", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + true + ] + }, + "hash": "1ace9bdcde90fd2261fd64344a2d9474b17887711128dbb2ef15d247d50686b0" +} diff --git a/backend/.sqlx/query-23c37d36e16251763fabf194e41de63612a7506cc0671b0eb83e528c1c839db4.json b/backend/.sqlx/query-23c37d36e16251763fabf194e41de63612a7506cc0671b0eb83e528c1c839db4.json new file mode 100644 index 0000000000..917540aec4 --- /dev/null +++ b/backend/.sqlx/query-23c37d36e16251763fabf194e41de63612a7506cc0671b0eb83e528c1c839db4.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings\n SET teams_team_id = null, teams_team_name = null WHERE workspace_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "23c37d36e16251763fabf194e41de63612a7506cc0671b0eb83e528c1c839db4" +} diff --git a/backend/.sqlx/query-2fa27b0a71740e4e168879cf9a58ed593004c22bb5d11170b3196e290dd1d966.json b/backend/.sqlx/query-2fa27b0a71740e4e168879cf9a58ed593004c22bb5d11170b3196e290dd1d966.json new file mode 100644 index 0000000000..704778d04a --- /dev/null +++ b/backend/.sqlx/query-2fa27b0a71740e4e168879cf9a58ed593004c22bb5d11170b3196e290dd1d966.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH assigned_teams AS (\n SELECT teams_team_id\n FROM workspace_settings\n ),\n all_teams AS (\n SELECT jsonb_array_elements(value::jsonb) AS team\n FROM global_settings\n WHERE name = 'teams'\n )\n SELECT team->>'team_name' AS team_name, team->>'team_internal_id' AS team_id\n FROM all_teams\n WHERE NOT EXISTS (\n SELECT 1\n FROM assigned_teams\n WHERE assigned_teams.teams_team_id = team->>'team_internal_id'\n )\n AND team->>'team_name' IS NOT NULL\n AND team->>'team_id' IS NOT NULL\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "team_name", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "team_id", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null + ] + }, + "hash": "2fa27b0a71740e4e168879cf9a58ed593004c22bb5d11170b3196e290dd1d966" +} diff --git a/backend/.sqlx/query-3b02f3ec6b92706c26065b2fa703cd1a1d6eca4083286c6f29c9acba522d2fe3.json b/backend/.sqlx/query-3b02f3ec6b92706c26065b2fa703cd1a1d6eca4083286c6f29c9acba522d2fe3.json new file mode 100644 index 0000000000..7c35515d12 --- /dev/null +++ b/backend/.sqlx/query-3b02f3ec6b92706c26065b2fa703cd1a1d6eca4083286c6f29c9acba522d2fe3.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT EXISTS (SELECT 1\n FROM workspace_settings\n WHERE workspace_id <> $1\n AND teams_command_script IS NOT NULL\n AND teams_team_id IS NOT NULL\n AND teams_team_id = (SELECT teams_team_id FROM workspace_settings WHERE workspace_id = $1))\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "3b02f3ec6b92706c26065b2fa703cd1a1d6eca4083286c6f29c9acba522d2fe3" +} diff --git a/backend/.sqlx/query-551c78392919e18019bb0a4344fb1bd45853bf5b72e0ab991e0e61fedcfb42fc.json b/backend/.sqlx/query-551c78392919e18019bb0a4344fb1bd45853bf5b72e0ab991e0e61fedcfb42fc.json new file mode 100644 index 0000000000..4a9bcd8cf3 --- /dev/null +++ b/backend/.sqlx/query-551c78392919e18019bb0a4344fb1bd45853bf5b72e0ab991e0e61fedcfb42fc.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE workspace_settings\n SET teams_team_id = $1, teams_team_name = $2\n WHERE workspace_id = $3\n AND NOT EXISTS (\n SELECT 1 FROM workspace_settings\n WHERE teams_team_id = $1 AND workspace_id <> $2\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "551c78392919e18019bb0a4344fb1bd45853bf5b72e0ab991e0e61fedcfb42fc" +} diff --git a/backend/.sqlx/query-55cb03040bc2a8c53dd7fbb42bbdcc40f463cbc52d94ed9315cf9a547d4c89f2.json b/backend/.sqlx/query-55cb03040bc2a8c53dd7fbb42bbdcc40f463cbc52d94ed9315cf9a547d4c89f2.json index 920176991b..14685a8bfa 100644 --- a/backend/.sqlx/query-55cb03040bc2a8c53dd7fbb42bbdcc40f463cbc52d94ed9315cf9a547d4c89f2.json +++ b/backend/.sqlx/query-55cb03040bc2a8c53dd7fbb42bbdcc40f463cbc52d94ed9315cf9a547d4c89f2.json @@ -137,6 +137,21 @@ "ordinal": 26, "name": "code_completion_model", "type_info": "Varchar" + }, + { + "ordinal": 27, + "name": "teams_command_script", + "type_info": "Text" + }, + { + "ordinal": 28, + "name": "teams_team_id", + "type_info": "Text" + }, + { + "ordinal": 29, + "name": "teams_team_name", + "type_info": "Text" } ], "parameters": { @@ -171,6 +186,9 @@ true, true, false, + true, + true, + true, true ] }, diff --git a/backend/.sqlx/query-72f98539ff9874479f6fc0e9f45f55354ad0397356c67a6162249a3cc553f125.json b/backend/.sqlx/query-72f98539ff9874479f6fc0e9f45f55354ad0397356c67a6162249a3cc553f125.json new file mode 100644 index 0000000000..1f10da84cf --- /dev/null +++ b/backend/.sqlx/query-72f98539ff9874479f6fc0e9f45f55354ad0397356c67a6162249a3cc553f125.json @@ -0,0 +1,53 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n workspace.id AS \"id!\",\n workspace.name AS \"name!\",\n workspace.owner AS \"owner!\",\n workspace.deleted AS \"deleted!\",\n workspace.premium AS \"premium!\",\n workspace_settings.color AS \"color!\"\n FROM workspace\n LEFT JOIN workspace_settings ON workspace.id = workspace_settings.workspace_id\n LIMIT $1 OFFSET $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "name!", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "owner!", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "deleted!", + "type_info": "Bool" + }, + { + "ordinal": 4, + "name": "premium!", + "type_info": "Bool" + }, + { + "ordinal": 5, + "name": "color!", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [ + true, + true, + true, + true, + true, + true + ] + }, + "hash": "72f98539ff9874479f6fc0e9f45f55354ad0397356c67a6162249a3cc553f125" +} diff --git a/backend/.sqlx/query-ebbe03cad470d0c6ae98964f630315ff25dad08e4cb714718505b77a75d44b95.json b/backend/.sqlx/query-ebbe03cad470d0c6ae98964f630315ff25dad08e4cb714718505b77a75d44b95.json new file mode 100644 index 0000000000..e087310961 --- /dev/null +++ b/backend/.sqlx/query-ebbe03cad470d0c6ae98964f630315ff25dad08e4cb714718505b77a75d44b95.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings SET teams_command_script = $1 WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "ebbe03cad470d0c6ae98964f630315ff25dad08e4cb714718505b77a75d44b95" +} diff --git a/backend/.sqlx/query-eed16e356f3f36183c3db13fcc1950295e0d0fbdabb38434534fb3430eeddc25.json b/backend/.sqlx/query-eed16e356f3f36183c3db13fcc1950295e0d0fbdabb38434534fb3430eeddc25.json deleted file mode 100644 index 5e0817ae84..0000000000 --- a/backend/.sqlx/query-eed16e356f3f36183c3db13fcc1950295e0d0fbdabb38434534fb3430eeddc25.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT workspace.id, workspace.name, workspace.owner, workspace.deleted, workspace.premium, workspace_settings.color\n FROM workspace\n LEFT JOIN workspace_settings ON workspace.id = workspace_settings.workspace_id\n LIMIT $1 OFFSET $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "owner", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "deleted", - "type_info": "Bool" - }, - { - "ordinal": 4, - "name": "premium", - "type_info": "Bool" - }, - { - "ordinal": 5, - "name": "color", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - true - ] - }, - "hash": "eed16e356f3f36183c3db13fcc1950295e0d0fbdabb38434534fb3430eeddc25" -} diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index b3154d15ef..fa0585b17f 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -8dab3198496461e40610145e4c818fce2345e20a \ No newline at end of file +841642097f07cc1f765ef74059d66aae2eba2c1d \ No newline at end of file diff --git a/backend/migrations/20250128201251_teams_workspace_command_script.down.sql b/backend/migrations/20250128201251_teams_workspace_command_script.down.sql new file mode 100644 index 0000000000..5b8b721e87 --- /dev/null +++ b/backend/migrations/20250128201251_teams_workspace_command_script.down.sql @@ -0,0 +1,3 @@ +ALTER TABLE workspace_settings DROP COLUMN teams_command_script; +ALTER TABLE workspace_settings DROP COLUMN teams_team_id; +ALTER TABLE workspace_settings DROP COLUMN teams_team_name; \ No newline at end of file diff --git a/backend/migrations/20250128201251_teams_workspace_command_script.up.sql b/backend/migrations/20250128201251_teams_workspace_command_script.up.sql new file mode 100644 index 0000000000..5373b6c57b --- /dev/null +++ b/backend/migrations/20250128201251_teams_workspace_command_script.up.sql @@ -0,0 +1,3 @@ +ALTER TABLE workspace_settings ADD COLUMN teams_command_script TEXT DEFAULT NULL; +ALTER TABLE workspace_settings ADD COLUMN teams_team_id TEXT DEFAULT NULL; +ALTER TABLE workspace_settings ADD COLUMN teams_team_name TEXT DEFAULT NULL; diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 1bcc37256e..d873da73fc 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -1728,6 +1728,12 @@ paths: type: string slack_command_script: type: string + teams_team_id: + type: string + teams_command_script: + type: string + teams_team_name: + type: string auto_invite_domain: type: string auto_invite_operator: @@ -1954,6 +1960,110 @@ paths: schema: type: string + /w/{workspace}/workspaces/edit_teams_command: + post: + summary: edit teams command + operationId: editTeamsCommand + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: WorkspaceInvite + required: true + content: + application/json: + schema: + type: object + properties: + slack_command_script: + type: string + responses: + "200": + description: status + content: + text/plain: + schema: + type: string + + /w/{workspace}/workspaces/available_teams_ids: + get: + summary: list available teams ids + operationId: listAvailableTeamsIds + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + responses: + "200": + description: status + content: + application/json: + schema: + type: array + items: + type: object + properties: + team_name: + type: string + team_id: + type: string + + /w/{workspace}/workspaces/available_teams_channels: + get: + summary: list available teams channels + operationId: listAvailableTeamsChannels + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + responses: + "200": + description: status + content: + application/json: + schema: + type: array + items: + type: object + properties: + channel_name: + type: string + channel_id: + type: string + service_url: + type: string + tenant_id: + type: string + + /w/{workspace}/workspaces/connect_teams: + post: + summary: connect teams + operationId: connectTeams + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: connect teams + required: true + content: + application/json: + schema: + type: object + properties: + team_id: + type: string + team_name: + type: string + responses: + "200": + description: status + content: + text/plain: + schema: + type: string + /w/{workspace}/workspaces/run_slack_message_test_job: post: summary: run a job that sends a message to Slack @@ -1987,6 +2097,40 @@ paths: properties: job_uuid: type: string + + /w/{workspace}/workspaces/run_teams_message_test_job: + post: + summary: run a job that sends a message to Teams + operationId: runTeamsMessageTestJob + tags: + - workspace + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: path to hub script to run and its corresponding args + required: true + content: + application/json: + schema: + type: object + properties: + hub_script_path: + type: string + channel: + type: string + test_msg: + type: string + + responses: + "200": + description: status + content: + text/json: + schema: + type: object + properties: + job_uuid: + type: string /w/{workspace}/workspaces/edit_deploy_to: post: @@ -3199,6 +3343,22 @@ paths: schema: type: string + /w/{workspace}/oauth/disconnect_teams: + post: + summary: disconnect teams + operationId: disconnectTeams + tags: + - oauth + parameters: + - $ref: "#/components/parameters/WorkspaceId" + responses: + "200": + description: disconnected teams + content: + text/plain: + schema: + type: string + /oauth/list_logins: get: summary: list oauth logins @@ -3289,6 +3449,41 @@ paths: items: $ref: '#/components/schemas/TeamInfo' + /teams/activities: + post: + summary: send update to Microsoft Teams activity + description: Respond to a Microsoft Teams activity after a workspace command is run + operationId: sendMessageToConversation + tags: + - teams + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - conversation_id + - text + properties: + conversation_id: + type: string + description: The ID of the Teams conversation/activity + success: + type: boolean + description: Used for styling the card conditionally + default: true + text: + type: string + description: The message text to be sent in the Teams card + card_block: + type: object + description: The card block to be sent in the Teams card + + responses: + '200': + description: Activity processed successfully + /w/{workspace}/resources/create: post: summary: create resource diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index 7ab057292f..b4c262b9eb 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -106,7 +106,6 @@ mod slack_approvals; mod smtp_server_ee; mod static_assets; mod stripe_ee; -#[cfg(feature = "enterprise")] mod teams_ee; mod tracing_init; mod triggers; diff --git a/backend/windmill-api/src/teams_ee.rs b/backend/windmill-api/src/teams_ee.rs index 2933d4214c..46cbe72059 100644 --- a/backend/windmill-api/src/teams_ee.rs +++ b/backend/windmill-api/src/teams_ee.rs @@ -1,5 +1,39 @@ +use http::status::StatusCode; +#[cfg(feature = "enterprise")] use axum::Router; +use windmill_common::error::Error; +pub async fn edit_teams_command() -> Result { + return Err(Error::BadRequest( + "Teams only available on enterprise".to_string(), + )); +} + +pub async fn workspaces_list_available_teams_ids() -> Result { + return Err(Error::BadRequest( + "Teams only available on enterprise".to_string(), + )); +} + +pub async fn connect_teams() -> Result { + return Err(Error::BadRequest( + "Teams only available on enterprise".to_string(), + )); +} + +pub async fn run_teams_message_test_job() -> Result { + return Err(Error::BadRequest( + "Teams only available on enterprise".to_string(), + )); +} + +pub async fn workspaces_list_available_teams_channels() -> Result { + return Err(Error::BadRequest( + "Teams only available on enterprise".to_string(), + )); +} + +#[cfg(feature = "enterprise")] pub fn teams_service() -> Router { Router::new() } \ No newline at end of file diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index f832b85f14..b2dbb9d2f7 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -58,6 +58,11 @@ use sqlx::{FromRow, Postgres, Transaction}; use windmill_common::oauth2::InstanceEvent; use windmill_common::utils::not_found_if_none; +use crate::teams_ee::{ + connect_teams, edit_teams_command, run_teams_message_test_job, + workspaces_list_available_teams_channels, workspaces_list_available_teams_ids, +}; + lazy_static::lazy_static! { static ref WORKSPACE_KEY_REGEXP: Regex = Regex::new("^[a-zA-Z0-9]{64}$").unwrap(); } @@ -73,10 +78,24 @@ pub fn workspaced_service() -> Router { .route("/get_settings", get(get_settings)) .route("/get_deploy_to", get(get_deploy_to)) .route("/edit_slack_command", post(edit_slack_command)) + .route("/edit_teams_command", post(edit_teams_command)) + .route( + "/available_teams_ids", + get(workspaces_list_available_teams_ids), + ) + .route( + "/available_teams_channels", + get(workspaces_list_available_teams_channels), + ) + .route("/connect_teams", post(connect_teams)) .route( "/run_slack_message_test_job", post(run_slack_message_test_job), ) + .route( + "/run_teams_message_test_job", + post(run_teams_message_test_job), + ) .route("/edit_webhook", post(edit_webhook)) .route("/edit_auto_invite", post(edit_auto_invite)) .route("/edit_deploy_to", post(edit_deploy_to)) @@ -168,9 +187,14 @@ pub struct WorkspaceSettings { #[serde(skip_serializing_if = "Option::is_none")] pub slack_team_id: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub teams_team_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub teams_team_name: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub slack_name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub slack_command_script: Option, + pub teams_command_script: Option, pub slack_email: String, #[serde(skip_serializing_if = "Option::is_none")] pub auto_invite_domain: Option, @@ -1380,9 +1404,15 @@ async fn list_workspaces_as_super_admin( let mut tx = user_db.begin(&authed).await?; let workspaces = sqlx::query_as!( Workspace, - "SELECT workspace.id, workspace.name, workspace.owner, workspace.deleted, workspace.premium, workspace_settings.color - FROM workspace - LEFT JOIN workspace_settings ON workspace.id = workspace_settings.workspace_id + "SELECT + workspace.id AS \"id!\", + workspace.name AS \"name!\", + workspace.owner AS \"owner!\", + workspace.deleted AS \"deleted!\", + workspace.premium AS \"premium!\", + workspace_settings.color AS \"color!\" + FROM workspace + LEFT JOIN workspace_settings ON workspace.id = workspace_settings.workspace_id LIMIT $1 OFFSET $2", per_page as i32, offset as i32 diff --git a/frontend/src/lib/components/AuthSettings.svelte b/frontend/src/lib/components/AuthSettings.svelte index f6db65526a..b9ea98aeb9 100644 --- a/frontend/src/lib/components/AuthSettings.svelte +++ b/frontend/src/lib/components/AuthSettings.svelte @@ -172,7 +172,7 @@
- +
{#each Object.keys(oauths) as k} diff --git a/frontend/src/lib/components/ConnectionSection.svelte b/frontend/src/lib/components/ConnectionSection.svelte new file mode 100644 index 0000000000..104d6527b5 --- /dev/null +++ b/frontend/src/lib/components/ConnectionSection.svelte @@ -0,0 +1,184 @@ + + +
+
Connect Workspace to {platform.charAt(0).toUpperCase() + platform.slice(1)}
+ + Connect your Windmill workspace to your {platform} workspace to trigger a script or a flow with a + '/windmill' command. + +
+ +{#if teamName} +
+
+ + {#if display_name} + Connected to Team '{display_name}' + {/if} +
+ {#if $enterpriseLicense || platform === 'slack'} + + + {/if} +
+{:else} +
+ {#if platform === 'teams'} + + {#if $enterpriseLicense} +
+ +
+
+ +
+ {/if} + {:else} + + {/if} + Not connected +
+{/if} + +
+
Script or flow to run on /windmill command
+
+ {#if !teamName || (!$enterpriseLicense && platform === 'teams')} +
+ {/if} + +
+ +
+ Pick a script or flow meant to be triggered when the `/windmill` command is invoked. Upon + connection, templates for a script + and flow are available. + +

+ + The script or flow chosen is passed the parameters `response_url: string` and `text: string` + respectively the url to reply directly to the trigger and the text of the command. + +

+ + It can take additionally the following args: channel_id, user_name, user_id, command, + trigger_id, api_app_id + +

+ + + The script or flow is permissioned as group "{platform}" that will be automatically created + after connection to {platform.charAt(0).toUpperCase() + platform.slice(1)}. + + +

+ + See more on + documentation. +
+
diff --git a/frontend/src/lib/components/ErrorOrRecoveryHandler.svelte b/frontend/src/lib/components/ErrorOrRecoveryHandler.svelte index 57674aedef..6c3b4790ba 100644 --- a/frontend/src/lib/components/ErrorOrRecoveryHandler.svelte +++ b/frontend/src/lib/components/ErrorOrRecoveryHandler.svelte @@ -1,10 +1,13 @@