diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json index 57c5e47f50..ab8340f5c8 100644 --- a/backend/.vscode/settings.json +++ b/backend/.vscode/settings.json @@ -12,5 +12,4 @@ "conventionalCommits.scopes": [ "restructring triggers, decoding trigger message on work" ], - "rust-analyzer.cargo.features": ["mqtt_trigger"] } diff --git a/backend/package-lock.json b/backend/package-lock.json deleted file mode 100644 index dfb18f1156..0000000000 --- a/backend/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "backend", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index e2da676ce4..62784c7b70 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -15275,6 +15275,7 @@ components: - resource - variable - secret + - trigger WorkspaceDefaultScripts: type: object diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index 7f62c373f0..c83370bfb5 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -459,7 +459,6 @@ async fn get_settings( .fetch_one(&mut *tx) .await .map_err(|e| Error::internal_err(format!("getting settings: {e:#}")))?; - tx.commit().await?; Ok(Json(settings)) } @@ -926,7 +925,7 @@ async fn edit_git_sync_config( Ok(format!("Edit git sync config for workspace {}", &w_id)) } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] struct EditDeployUIConfig { #[cfg(feature = "enterprise")] deploy_ui_settings: Option, @@ -954,7 +953,6 @@ async fn edit_deploy_ui_config( require_admin(is_admin, &username)?; let mut tx = db.begin().await?; - let args_for_audit = format!("{:?}", new_config.deploy_ui_settings); audit_log( &mut *tx, diff --git a/backend/windmill-common/src/workspaces.rs b/backend/windmill-common/src/workspaces.rs index d674285479..8fd5471a00 100644 --- a/backend/windmill-common/src/workspaces.rs +++ b/backend/windmill-common/src/workspaces.rs @@ -27,6 +27,7 @@ pub enum ObjectType { ResourceType, User, Group, + Trigger } #[derive(Serialize, Deserialize, Debug)] diff --git a/frontend/src/lib/components/DeployToSetting.svelte b/frontend/src/lib/components/DeployToSetting.svelte index 462ed6a67c..94e7027d91 100644 --- a/frontend/src/lib/components/DeployToSetting.svelte +++ b/frontend/src/lib/components/DeployToSetting.svelte @@ -9,7 +9,6 @@ import Toggle from './Toggle.svelte' import { emptyString } from '$lib/utils' - $: deployableWorkspaces = $usersWorkspaceStore?.workspaces .map((w) => w.id) .filter((w) => w != $workspaceStore) @@ -21,8 +20,9 @@ resources: boolean variables: boolean secrets: boolean + triggers: boolean } - type DeployUIType = 'script' | 'flow' | 'app' | 'resource' | 'variable' | 'secret' + type DeployUIType = 'script' | 'flow' | 'app' | 'resource' | 'variable' | 'secret' | 'trigger' const all_ok: DeployUITypeMap = { scripts: true, @@ -30,7 +30,8 @@ apps: true, resources: true, variables: true, - secrets: true + secrets: true, + triggers: true } export let workspaceToDeployTo: string | undefined @@ -41,8 +42,6 @@ include_path: [], include_type: all_ok } - - function deployUITypeMapToArray( typesMap: DeployUITypeMap, expectedValue: boolean @@ -66,6 +65,9 @@ if (typesMap.secrets == expectedValue) { result.push('secret') } + if (typesMap.triggers == expectedValue) { + result.push('trigger') + } return result } @@ -165,18 +167,9 @@
- - - + + +
+ diff --git a/frontend/src/lib/components/DeployWorkspace.svelte b/frontend/src/lib/components/DeployWorkspace.svelte index 319e67fb1d..7f48195746 100644 --- a/frontend/src/lib/components/DeployWorkspace.svelte +++ b/frontend/src/lib/components/DeployWorkspace.svelte @@ -22,22 +22,21 @@ import { Loader2 } from 'lucide-svelte' import Badge from './common/badge/Badge.svelte' import DiffDrawer from './DiffDrawer.svelte' + import { + existsTrigger, + getTriggerDependency, + getTriggersDeployData, + getTriggerValue, + type AdditionalInformation, + type Kind + } from '$lib/utils_deployable' + import { sendUserToast } from '$lib/toast' const dispatch = createEventDispatcher() - type Kind = - | 'script' - | 'resource' - | 'schedule' - | 'variable' - | 'flow' - | 'app' - | 'raw_app' - | 'resource_type' - | 'folder' - export let kind: Kind export let initialPath: string = '' + export let additionalInformation: AdditionalInformation | undefined = undefined export let workspaceToDeployTo: string | undefined = undefined export let hideButton: boolean = false @@ -148,6 +147,11 @@ } return [...recObj(res.value), { kind: 'resource_type', path: res.resource_type }] + } else if (kind == 'trigger') { + if (additionalInformation?.triggers) { + return getTriggerDependency(additionalInformation.triggers.kind, path, $workspaceStore!) + } + throw new Error('Missing trigger information') } return [] } @@ -171,60 +175,70 @@ } async function checkAlreadyExists(kind: Kind, path: string): Promise { - if (kind == 'flow') { - return await FlowService.existsFlowByPath({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'script') { - return await ScriptService.existsScriptByPath({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'app') { - return await AppService.existsApp({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'raw_app') { - return await RawAppService.existsRawApp({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'variable') { - return await VariableService.existsVariable({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'resource') { - return await ResourceService.existsResource({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'schedule') { - return await ScheduleService.existsSchedule({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'resource_type') { - return await ResourceService.existsResourceType({ - workspace: workspaceToDeployTo!, - path: path - }) - } else if (kind == 'folder') { - let exists = true - try { + let exists = true + try { + if (kind == 'flow') { + exists = await FlowService.existsFlowByPath({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'script') { + exists = await ScriptService.existsScriptByPath({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'app') { + exists = await AppService.existsApp({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'raw_app') { + exists = await RawAppService.existsRawApp({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'variable') { + exists = await VariableService.existsVariable({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'resource') { + exists = await ResourceService.existsResource({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'schedule') { + exists = await ScheduleService.existsSchedule({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'resource_type') { + exists = await ResourceService.existsResourceType({ + workspace: workspaceToDeployTo!, + path: path + }) + } else if (kind == 'folder') { await FolderService.getFolder({ workspace: workspaceToDeployTo!, name: path }) - } catch (e) { - exists = false + } else if (kind === 'trigger') { + if (additionalInformation?.triggers) { + exists = await existsTrigger( + { workspace: workspaceToDeployTo!, path }, + additionalInformation.triggers.kind + ) + } else { + throw new Error('Missing triggers kind') + } + } else { + throw new Error(`Unknown kind ${kind}`) } - return exists - } else { - throw new Error(`Unknown kind ${kind}`) + } catch (error) { + sendUserToast(error.body ? error.body : error instanceof Error ? error.message : error, true) + exists = false } + return exists } const deploymentStatus: Record< @@ -405,6 +419,28 @@ name: path } }) + } else if (kind === 'trigger') { + if (additionalInformation?.triggers) { + const { data, createFn, updateFn } = await getTriggersDeployData( + additionalInformation.triggers.kind, + path, + $workspaceStore! + ) + if (alreadyExists) { + await updateFn({ + path, + workspace: workspaceToDeployTo!, + requestBody: data + } as any) + } else { + await createFn({ + workspace: workspaceToDeployTo!, + requestBody: data + } as any) + } + } else { + throw new Error('Missing triggers kind') + } } else { throw new Error(`Unknown kind ${kind}`) } @@ -502,6 +538,12 @@ return { name: folder.name } + } else if (kind == 'trigger') { + if (additionalInformation?.triggers) { + return await getTriggerValue(additionalInformation.triggers.kind, path, workspace) + } else { + throw new Error(`Missing trigger information`) + } } else { throw new Error(`Unknown kind ${kind}`) } diff --git a/frontend/src/lib/components/DeployWorkspaceDrawer.svelte b/frontend/src/lib/components/DeployWorkspaceDrawer.svelte index e2e7529d7f..280a8900a4 100644 --- a/frontend/src/lib/components/DeployWorkspaceDrawer.svelte +++ b/frontend/src/lib/components/DeployWorkspaceDrawer.svelte @@ -2,16 +2,21 @@ import { Button, Drawer } from './common' import DrawerContent from './common/drawer/DrawerContent.svelte' import DeployWorkspace from './DeployWorkspace.svelte' - - type Kind = 'script' | 'resource' | 'schedule' | 'variable' | 'flow' | 'app' | 'raw_app' + import { type AdditionalInformation, type Kind } from '$lib/utils_deployable' let initialPath: string | undefined = undefined let kind: Kind | undefined = undefined - let drawer: Drawer | undefined = undefined let workspaceToDeployTo: string | undefined = undefined let deployWorkspace: DeployWorkspace | undefined = undefined - export async function openDrawer(initialPath_l: string, kind_l: Kind) { + let additionalInformation: AdditionalInformation | undefined = undefined + + export async function openDrawer( + initialPath_l: string, + kind_l: Kind, + additionalInformation_l?: AdditionalInformation + ) { + additionalInformation = additionalInformation_l initialPath = initialPath_l kind = kind_l drawer?.openDrawer() @@ -20,11 +25,12 @@ - {#if kind != undefined && initialPath != undefined} + {#if (kind != 'trigger' && kind != undefined && initialPath != undefined) || (kind === 'trigger' && initialPath != undefined && additionalInformation?.triggers != undefined)} diff --git a/frontend/src/lib/utils_deployable.ts b/frontend/src/lib/utils_deployable.ts index 9a8efc6ef8..7f3d55a56f 100644 --- a/frontend/src/lib/utils_deployable.ts +++ b/frontend/src/lib/utils_deployable.ts @@ -1,7 +1,41 @@ import { minimatch } from 'minimatch' -import type { WorkspaceDeployUISettings } from './gen' +import { + HttpTriggerService, + KafkaTriggerService, + MqttTriggerService, + NatsTriggerService, + PostgresTriggerService, + ScheduleService, + SqsTriggerService, + WebsocketTriggerService, + type WorkspaceDeployUISettings +} from './gen' +import type { TriggerKind } from './components/triggers' -type DeployUIType = 'script' | 'flow' | 'app' | 'resource' | 'variable' | 'secret' +type DeployUIType = 'script' | 'flow' | 'app' | 'resource' | 'variable' | 'secret' | 'trigger' + +export type Kind = + | 'script' + | 'resource' + | 'schedule' + | 'variable' + | 'flow' + | 'app' + | 'raw_app' + | 'resource_type' + | 'folder' + | 'trigger' + +export const ALL_DEPLOYABLE: WorkspaceDeployUISettings = { + include_path: [], + include_type: ['script', 'flow', 'app', 'resource', 'variable', 'secret', 'trigger'] +} + +export type AdditionalInformation = { + triggers?: { + kind: TriggerKind + } +} export function isDeployable( type: DeployUIType, @@ -27,7 +61,439 @@ export function isDeployable( return true } -export const ALL_DEPLOYABLE: WorkspaceDeployUISettings = { - include_path: [], - include_type: ['script', 'flow', 'app', 'resource', 'variable', 'secret'] +export async function existsTrigger( + data: { workspace: string; path: string }, + triggerKind: TriggerKind +) { + if (triggerKind === 'routes') { + return await HttpTriggerService.existsHttpTrigger(data) + } else if (triggerKind === 'kafka') { + return await KafkaTriggerService.existsKafkaTrigger(data) + } else if (triggerKind === 'mqtt') { + return await MqttTriggerService.existsMqttTrigger(data) + } else if (triggerKind === 'postgres') { + return await PostgresTriggerService.existsPostgresTrigger(data) + } else if (triggerKind === 'sqs') { + return await SqsTriggerService.existsSqsTrigger(data) + } else if (triggerKind === 'websockets') { + return await WebsocketTriggerService.existsWebsocketTrigger(data) + } else if (triggerKind === 'nats') { + return await NatsTriggerService.existsNatsTrigger(data) + } else if (triggerKind === 'schedules') { + return await ScheduleService.existsSchedule(data) + } + + throw new Error( + `Unexpected trigger kind ${triggerKind}. Allowed kinds are: routes, kafka, mqtt, postgres, sqs, websockets, nats, schedules.` + ) +} + +export async function getTriggersDeployData(kind: TriggerKind, path: string, workspace: string) { + if (kind === 'sqs') { + const sqsTrigger = await SqsTriggerService.getSqsTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: sqsTrigger, + createFn: SqsTriggerService.createSqsTrigger, + updateFn: SqsTriggerService.updateSqsTrigger + } + } else if (kind === 'kafka') { + const kafkaTrigger = await KafkaTriggerService.getKafkaTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: kafkaTrigger, + createFn: KafkaTriggerService.createKafkaTrigger, + updateFn: KafkaTriggerService.updateKafkaTrigger + } + } else if (kind === 'mqtt') { + const mqttTrigger = await MqttTriggerService.getMqttTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: mqttTrigger, + createFn: MqttTriggerService.createMqttTrigger, + updateFn: MqttTriggerService.updateMqttTrigger + } + } else if (kind === 'nats') { + const natsTrigger = await NatsTriggerService.getNatsTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: natsTrigger, + createFn: NatsTriggerService.createNatsTrigger, + updateFn: NatsTriggerService.updateNatsTrigger + } + } else if (kind === 'postgres') { + const postgresTrigger = await PostgresTriggerService.getPostgresTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: postgresTrigger, + createFn: PostgresTriggerService.createPostgresTrigger, + updateFn: PostgresTriggerService.updatePostgresTrigger + } + } else if (kind === 'websockets') { + const websocketTrigger = await WebsocketTriggerService.getWebsocketTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: websocketTrigger, + createFn: WebsocketTriggerService.createWebsocketTrigger, + updateFn: WebsocketTriggerService.updateWebsocketTrigger + } + } else if (kind === 'routes') { + const httpTrigger = await HttpTriggerService.getHttpTrigger({ + workspace: workspace!, + path: path + }) + + return { + data: httpTrigger, + createFn: HttpTriggerService.createHttpTrigger, + updateFn: HttpTriggerService.updateHttpTrigger + } + } else if (kind === 'schedules') { + const schedulesTrigger = await ScheduleService.getSchedule({ + workspace: workspace!, + path: path + }) + return { + data: schedulesTrigger, + createFn: ScheduleService.createSchedule, + updateFn: ScheduleService.updateSchedule + } + } + + throw new Error(`Unexpected trigger kind got: ${kind}`) +} + +export async function getTriggerValue(kind: TriggerKind, path: string, workspace: string) { + if (kind === 'sqs') { + const { enabled, script_path, is_flow, queue_url, aws_resource_path, message_attributes } = + await SqsTriggerService.getSqsTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + queue_url, + aws_resource_path, + message_attributes + } + } else if (kind === 'kafka') { + const { enabled, script_path, is_flow, kafka_resource_path, topics, group_id } = + await KafkaTriggerService.getKafkaTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + kafka_resource_path, + topics, + group_id + } + } else if (kind === 'mqtt') { + const { + enabled, + script_path, + is_flow, + mqtt_resource_path, + v3_config, + v5_config, + client_id, + subscribe_topics, + client_version + } = await MqttTriggerService.getMqttTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + mqtt_resource_path, + v3_config, + v5_config, + client_id, + subscribe_topics, + client_version + } + } else if (kind === 'nats') { + const { + enabled, + script_path, + is_flow, + nats_resource_path, + use_jetstream, + stream_name, + consumer_name, + subjects + } = await NatsTriggerService.getNatsTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + nats_resource_path, + use_jetstream, + stream_name, + consumer_name, + subjects + } + } else if (kind === 'postgres') { + const { + enabled, + script_path, + is_flow, + postgres_resource_path, + replication_slot_name, + publication_name + } = await PostgresTriggerService.getPostgresTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + postgres_resource_path, + replication_slot_name, + publication_name + } + } else if (kind === 'websockets') { + const { + enabled, + script_path, + is_flow, + url, + url_runnable_args, + can_return_message, + filters, + initial_messages + } = await WebsocketTriggerService.getWebsocketTrigger({ + workspace: workspace!, + path: path + }) + + return { + enabled, + script_path, + is_flow, + url, + url_runnable_args, + can_return_message, + filters, + initial_messages + } + } else if (kind === 'routes') { + const { + script_path, + is_flow, + http_method, + route_path, + static_asset_config, + is_async, + requires_auth, + is_static_website + } = await HttpTriggerService.getHttpTrigger({ + workspace: workspace!, + path: path + }) + + return { + script_path, + is_flow, + http_method, + route_path, + static_asset_config, + is_async, + requires_auth, + is_static_website + } + } else if (kind === 'schedules') { + const { + script_path, + is_flow, + on_failure, + schedule, + timezone, + on_failure_times, + on_failure_exact, + on_failure_extra_args, + on_recovery, + on_recovery_times, + on_recovery_extra_args, + on_success, + on_success_extra_args, + ws_error_handler_muted, + retry, + summary, + no_flow_overlap, + tag, + paused_until, + cron_version + } = await ScheduleService.getSchedule({ + workspace: workspace!, + path: path + }) + + return { + script_path, + is_flow, + on_failure, + schedule, + timezone, + on_failure_times, + on_failure_exact, + on_failure_extra_args, + on_recovery, + on_recovery_times, + on_recovery_extra_args, + on_success, + on_success_extra_args, + ws_error_handler_muted, + retry, + summary, + no_flow_overlap, + tag, + paused_until, + cron_version + } + } + + throw new Error(`Unexpected trigger kind got: ${kind}`) +} + +function retrieveScriptOrFlowKind(path: string, is_flow: boolean): { kind: Kind; path: string } { + return { + kind: is_flow ? 'flow' : 'script', + path + } +} + +function retrieveKindsValues({ + resource_path, + script_path, + is_flow +}: { + resource_path?: string + script_path: string + is_flow: boolean +}) { + const result: { kind: Kind; path: string }[] = [] + + if (resource_path) { + result.push({ kind: 'resource', path: resource_path }) + } + result.push(retrieveScriptOrFlowKind(script_path, is_flow)) + return result +} + +export async function getTriggerDependency(kind: TriggerKind, path: string, workspace: string) { + let result: { kind: Kind; path: string }[] + if (kind === 'sqs') { + const { aws_resource_path, script_path, is_flow } = await SqsTriggerService.getSqsTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ resource_path: aws_resource_path, script_path, is_flow }) + } else if (kind === 'kafka') { + const { kafka_resource_path, script_path, is_flow } = await KafkaTriggerService.getKafkaTrigger( + { + workspace: workspace!, + path: path + } + ) + + result = retrieveKindsValues({ resource_path: kafka_resource_path, script_path, is_flow }) + } else if (kind === 'mqtt') { + const { mqtt_resource_path, script_path, is_flow } = await MqttTriggerService.getMqttTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ resource_path: mqtt_resource_path, script_path, is_flow }) + } else if (kind === 'nats') { + const { nats_resource_path, script_path, is_flow } = await NatsTriggerService.getNatsTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ resource_path: nats_resource_path, script_path, is_flow }) + } else if (kind === 'postgres') { + const { postgres_resource_path, script_path, is_flow } = + await PostgresTriggerService.getPostgresTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ resource_path: postgres_resource_path, script_path, is_flow }) + } else if (kind === 'websockets') { + const { script_path, is_flow, url, initial_messages } = + await WebsocketTriggerService.getWebsocketTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ script_path, is_flow }) + + const SCRIPT_PREFIX = '$script:' + const FLOW_PREFIX = '$flow:' + + if (url.startsWith(SCRIPT_PREFIX)) + result.push(retrieveScriptOrFlowKind(url.substring(SCRIPT_PREFIX.length), false)) + else if (url.startsWith(FLOW_PREFIX)) + result.push(retrieveScriptOrFlowKind(url.substring(FLOW_PREFIX.length), true)) + + initial_messages?.map((message) => { + if ('runnable_result' in message) { + result.push( + retrieveScriptOrFlowKind(message.runnable_result.path, message.runnable_result.is_flow) + ) + } + }) + } else if (kind === 'routes') { + const { script_path, is_flow } = await HttpTriggerService.getHttpTrigger({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ script_path, is_flow }) + } else if (kind === 'schedules') { + const { script_path, is_flow } = await ScheduleService.getSchedule({ + workspace: workspace!, + path: path + }) + + result = retrieveKindsValues({ script_path, is_flow }) + } else { + throw new Error(`Unexpected trigger kind got: ${kind}`) + } + return result } diff --git a/frontend/src/routes/(root)/(logged)/kafka_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/kafka_triggers/+page.svelte index b0d339a812..9c76da1349 100644 --- a/frontend/src/routes/(root)/(logged)/kafka_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/kafka_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'kafka' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/mqtt_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/mqtt_triggers/+page.svelte index 7c94e23ec4..bdb8d26721 100644 --- a/frontend/src/routes/(root)/(logged)/mqtt_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/mqtt_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'mqtt' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/nats_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/nats_triggers/+page.svelte index a51b011613..4da330866b 100644 --- a/frontend/src/routes/(root)/(logged)/nats_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/nats_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'nats' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/postgres_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/postgres_triggers/+page.svelte index 32bb203dbb..7658a10676 100644 --- a/frontend/src/routes/(root)/(logged)/postgres_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/postgres_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'postgres' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/routes/+page.svelte b/frontend/src/routes/(root)/(logged)/routes/+page.svelte index 3efd9a3a3b..03a87d7b86 100644 --- a/frontend/src/routes/(root)/(logged)/routes/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/routes/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'routes' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte index f3e351cefe..6591b3e210 100644 --- a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte @@ -1,5 +1,11 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'schedules' + } + }) + } + } + ] + : []), { displayName: 'View runs', icon: List, diff --git a/frontend/src/routes/(root)/(logged)/sqs_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/sqs_triggers/+page.svelte index c1f1acc6cf..93c32b3bf0 100644 --- a/frontend/src/routes/(root)/(logged)/sqs_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/sqs_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'sqs' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/websocket_triggers/+page.svelte b/frontend/src/routes/(root)/(logged)/websocket_triggers/+page.svelte index 8941aeb54b..89e9632729 100644 --- a/frontend/src/routes/(root)/(logged)/websocket_triggers/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/websocket_triggers/+page.svelte @@ -1,5 +1,10 @@ + { + deploymentDrawer.openDrawer(path, 'trigger', { + triggers: { + kind: 'websockets' + } + }) + } + } + ] + : []), { displayName: 'Audit logs', icon: Eye, diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index 4a08eaa08c..b40d7f3885 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -539,7 +539,8 @@ apps: (settings.deploy_ui.include_type?.indexOf('app') ?? -1) >= 0, resources: (settings.deploy_ui.include_type?.indexOf('resource') ?? -1) >= 0, variables: (settings.deploy_ui.include_type?.indexOf('variable') ?? -1) >= 0, - secrets: (settings.deploy_ui.include_type?.indexOf('secret') ?? -1) >= 0 + secrets: (settings.deploy_ui.include_type?.indexOf('secret') ?? -1) >= 0, + triggers: (settings.deploy_ui.include_type?.indexOf('trigger') ?? -1) >= 0 } } } @@ -562,6 +563,7 @@ resources: boolean variables: boolean secrets: boolean + triggers: boolean } }