Skip to content

Commit 70af2bd

Browse files
l0minousDiler Zaza
andauthored
feat(stepfunctions): Handling newExecution and editStateMachine (#7779)
## Problem Currently the New Execution and Edit State Machine Buttons in Execution Details don't work ## Solution New Execution button now opens a new input webview Edit State Machine launches Workflow Studio Added message handling for new execution and edit state machine Refactoring in utils ## Verification ![test9](https://github.com/user-attachments/assets/6056c3cb-c6cd-4b03-a0fc-d7bbf71210c8) --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Diler Zaza <[email protected]>
1 parent e75caf3 commit 70af2bd

File tree

7 files changed

+353
-88
lines changed

7 files changed

+353
-88
lines changed

packages/core/src/stepFunctions/commands/downloadStateMachineDefinition.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { Result } from '../../shared/telemetry/telemetry'
1717
import { StateMachineNode } from '../explorer/stepFunctionsNodes'
1818
import { telemetry } from '../../shared/telemetry/telemetry'
1919
import { fs } from '../../shared/fs/fs'
20-
import { WorkflowStudioEditorProvider } from '../workflowStudio/workflowStudioEditorProvider'
20+
import { openWorkflowStudioWithDefinition } from '../utils'
2121

2222
export async function downloadStateMachineDefinition(params: {
2323
outputChannel: vscode.OutputChannel
@@ -35,13 +35,7 @@ export async function downloadStateMachineDefinition(params: {
3535
})
3636

3737
if (params.isPreviewAndRender) {
38-
const doc = await vscode.workspace.openTextDocument({
39-
language: 'asl',
40-
content: stateMachineDetails.definition,
41-
})
42-
43-
const textEditor = await vscode.window.showTextDocument(doc)
44-
await WorkflowStudioEditorProvider.openWithWorkflowStudio(textEditor.document.uri, {
38+
await openWorkflowStudioWithDefinition(stateMachineDetails.definition, {
4539
preserveFocus: true,
4640
viewColumn: vscode.ViewColumn.Beside,
4741
})

packages/core/src/stepFunctions/executionDetails/executionDetailProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class ExecutionDetailProvider {
3535
const panel = vscode.window.createWebviewPanel(
3636
ExecutionDetailProvider.viewType,
3737
`Execution: ${executionArn.split(':').pop() || executionArn}`,
38-
vscode.ViewColumn.Beside,
38+
vscode.ViewColumn.One,
3939
{
4040
enableScripts: true,
4141
retainContextWhenHidden: true,
@@ -96,6 +96,7 @@ export class ExecutionDetailProvider {
9696
* Initializes a WebView panel with execution details.
9797
* @param panel The WebView panel to initialize
9898
* @param executionArn The ARN of the execution to display
99+
* @param startTime Optional start time for the execution
99100
*/
100101
public async initializePanel(panel: vscode.WebviewPanel, executionArn: string, startTime?: string): Promise<void> {
101102
try {

packages/core/src/stepFunctions/executionDetails/handleMessage.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
handleUnsupportedMessage,
1818
apiCallMessageHandler,
1919
} from '../messageHandlers/handleMessageHelpers'
20+
import { parseExecutionArnForStateMachine, openWorkflowStudio, showExecuteStateMachineWebview } from '../utils'
21+
import { getLogger } from '../../shared/logger/logger'
2022

2123
/**
2224
* Handles messages received from the ExecutionDetails webview. Depending on the message type and command,
@@ -34,6 +36,12 @@ export async function handleMessage(message: Message, context: ExecutionDetailsC
3436
case Command.API_CALL:
3537
void apiCallMessageHandler(message as ApiCallRequestMessage, context)
3638
break
39+
case Command.START_EXECUTION:
40+
void startExecutionMessageHandler(context)
41+
break
42+
case Command.EDIT_STATE_MACHINE:
43+
void editStateMachineMessageHandler(context)
44+
break
3745
default:
3846
void handleUnsupportedMessage(context, message)
3947
break
@@ -74,3 +82,29 @@ async function initMessageHandler(context: ExecutionDetailsContext) {
7482
} as InitResponseMessage)
7583
}
7684
}
85+
86+
async function startExecutionMessageHandler(context: ExecutionDetailsContext) {
87+
const logger = getLogger('stepfunctions')
88+
try {
89+
// Parsing execution ARN to get state machine info
90+
const parsedArn = parseExecutionArnForStateMachine(context.executionArn)
91+
if (!parsedArn) {
92+
throw new Error(`Invalid execution ARN format: ${context.executionArn}`)
93+
}
94+
95+
const { region, stateMachineName, stateMachineArn } = parsedArn
96+
97+
await showExecuteStateMachineWebview({
98+
arn: stateMachineArn,
99+
name: stateMachineName,
100+
region: region,
101+
})
102+
} catch (error) {
103+
logger.error('Start execution failed: %O', error)
104+
}
105+
}
106+
107+
async function editStateMachineMessageHandler(context: ExecutionDetailsContext) {
108+
const params = parseExecutionArnForStateMachine(context.executionArn)
109+
await openWorkflowStudio(params!.stateMachineArn, params!.region)
110+
}

packages/core/src/stepFunctions/messageHandlers/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export enum Command {
6666
CLOSE_WFS = 'CLOSE_WFS',
6767
API_CALL = 'API_CALL',
6868
UNSUPPORTED_COMMAND = 'UNSUPPORTED_COMMAND',
69+
START_EXECUTION = 'START_EXECUTION',
70+
EDIT_STATE_MACHINE = 'EDIT_STATE_MACHINE',
6971
}
7072

7173
export type FileWatchInfo = {

packages/core/src/stepFunctions/utils.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ import {
1717
} from 'amazon-states-language-service'
1818
import { fromExtensionManifest } from '../shared/settings'
1919
import { IamRole } from '../shared/clients/iam'
20+
import { WorkflowStudioEditorProvider } from './workflowStudio/workflowStudioEditorProvider'
21+
import { VueWebview } from '../webviews/main'
22+
import { ExecuteStateMachineWebview } from './vue/executeStateMachine/executeStateMachine'
23+
import globals from '../shared/extensionGlobals'
2024

2125
const documentSettings: DocumentLanguageSettings = { comments: 'error', trailingCommas: 'error' }
2226
const languageService = getLanguageService({})
2327

2428
const arnResourceTypeSegmentIndex = 5
2529
const expressExecutionArnSegmentCount = 9
30+
const executionArnSegmentCount = 8
31+
const arnRegionSegmentIndex = 3
32+
const arnAccountIdSegmentIndex = 4
33+
const arnStateMachineNameSegmentIndex = 6
2634

2735
export async function* listStateMachines(
2836
client: StepFunctionsClient
@@ -107,6 +115,91 @@ export const isExpressExecution = (arn: string): boolean => {
107115
)
108116
}
109117

118+
/**
119+
* Parses an execution ARN to extract state machine information
120+
* @param executionArn The execution ARN to parse
121+
* @returns Object containing region, state machine name, and state machine ARN
122+
*/
123+
export const parseExecutionArnForStateMachine = (executionArn: string) => {
124+
const arnSegments = executionArn.split(':')
125+
if (arnSegments.length === executionArnSegmentCount || arnSegments.length === expressExecutionArnSegmentCount) {
126+
const region = arnSegments[arnRegionSegmentIndex]
127+
const stateMachineName = arnSegments[arnStateMachineNameSegmentIndex]
128+
const stateMachineArn = `arn:aws:states:${region}:${arnSegments[arnAccountIdSegmentIndex]}:stateMachine:${stateMachineName}`
129+
130+
return {
131+
region,
132+
stateMachineName,
133+
stateMachineArn,
134+
}
135+
}
136+
}
137+
138+
/**
139+
* Opens a state machine definition in Workflow Studio
140+
* @param stateMachineArn The ARN of the state machine
141+
* @param region The AWS region
142+
*/
143+
export const openWorkflowStudio = async (stateMachineArn: string, region: string) => {
144+
const client: StepFunctionsClient = new StepFunctionsClient(region)
145+
const stateMachineDetails: StepFunctions.DescribeStateMachineCommandOutput = await client.getStateMachineDetails({
146+
stateMachineArn,
147+
})
148+
149+
await openWorkflowStudioWithDefinition(stateMachineDetails.definition)
150+
}
151+
152+
/**
153+
* Opens a state machine definition in Workflow Studio using pre-fetched definition content
154+
* @param definition The state machine definition content
155+
* @param options Optional webview configuration options
156+
*/
157+
export const openWorkflowStudioWithDefinition = async (
158+
definition: string | undefined,
159+
options?: {
160+
preserveFocus?: boolean
161+
viewColumn?: vscode.ViewColumn
162+
}
163+
) => {
164+
const doc = await vscode.workspace.openTextDocument({
165+
language: 'asl',
166+
content: definition,
167+
})
168+
169+
const textEditor = await vscode.window.showTextDocument(doc)
170+
await WorkflowStudioEditorProvider.openWithWorkflowStudio(textEditor.document.uri, {
171+
preserveFocus: options?.preserveFocus ?? false,
172+
viewColumn: options?.viewColumn ?? vscode.ViewColumn.One,
173+
})
174+
}
175+
176+
/**
177+
* Shows the Execute State Machine webview with the provided state machine data
178+
* @param extensionContext The extension context
179+
* @param outputChannel The output channel for logging
180+
* @param stateMachineData Object containing arn, name, and region of the state machine
181+
* @returns The webview instance
182+
*/
183+
export const showExecuteStateMachineWebview = async (stateMachineData: {
184+
arn: string
185+
name: string
186+
region: string
187+
}) => {
188+
const Panel = VueWebview.compilePanel(ExecuteStateMachineWebview)
189+
const wv = new Panel(globals.context, globals.outputChannel, {
190+
arn: stateMachineData.arn,
191+
name: stateMachineData.name,
192+
region: stateMachineData.region,
193+
})
194+
195+
await wv.show({
196+
title: localize('AWS.executeStateMachine.title', 'Start Execution'),
197+
cssFiles: ['executeStateMachine.css'],
198+
})
199+
200+
return wv
201+
}
202+
110203
const isInvalidJson = (content: string): boolean => {
111204
try {
112205
JSON.parse(content)

packages/core/src/stepFunctions/vue/executeStateMachine/executeStateMachine.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { VueWebview } from '../../../webviews/main'
1616
import * as vscode from 'vscode'
1717
import { telemetry } from '../../../shared/telemetry/telemetry'
1818
import { ExecutionDetailProvider } from '../../executionDetails/executionDetailProvider'
19+
import { showExecuteStateMachineWebview } from '../../utils'
1920

2021
interface StateMachine {
2122
arn: string
@@ -88,18 +89,11 @@ export class ExecuteStateMachineWebview extends VueWebview {
8889
}
8990
}
9091

91-
const Panel = VueWebview.compilePanel(ExecuteStateMachineWebview)
92-
9392
export async function executeStateMachine(context: ExtContext, node: StateMachineNode): Promise<void> {
94-
const wv = new Panel(context.extensionContext, context.outputChannel, {
93+
await showExecuteStateMachineWebview({
9594
arn: node.details.stateMachineArn || '',
9695
name: node.details.name || '',
9796
region: node.regionCode,
9897
})
99-
100-
await wv.show({
101-
title: localize('AWS.executeStateMachine.title', 'Start Execution'),
102-
cssFiles: ['executeStateMachine.css'],
103-
})
10498
telemetry.stepfunctions_executeStateMachineView.emit()
10599
}

0 commit comments

Comments
 (0)