diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index aa1ac167917..203b3762dc4 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -32,6 +32,7 @@ "AWS.stepFunctions.executeStateMachine.info.executing": "Starting execution of '{0}' in {1}...", "AWS.stepFunctions.executeStateMachine.info.started": "Execution started", "AWS.stepFunctions.executeStateMachine.error.failedToStart": "There was an error starting execution for '{0}', check AWS Toolkit logs for more information.", + "AWS.stepfunctions.viewExecutionDetailsByExecutionARN": "View Execution Details by Execution ARN", "AWS.stepFunctions.asl.format.enable.desc": "Enables the default formatter used with Amazon States Language files", "AWS.stepFunctions.asl.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).", "AWS.stepFunctions.workflowStudio.actions.progressMessage": "Opening asl file in Workflow Studio", diff --git a/packages/core/src/stepFunctions/activation.ts b/packages/core/src/stepFunctions/activation.ts index 4898fc36b54..d062974458d 100644 --- a/packages/core/src/stepFunctions/activation.ts +++ b/packages/core/src/stepFunctions/activation.ts @@ -23,6 +23,7 @@ import { ASLLanguageClient } from './asl/client' import { WorkflowStudioEditorProvider } from './workflowStudio/workflowStudioEditorProvider' import { StateMachineNode } from './explorer/stepFunctionsNodes' import { downloadStateMachineDefinition } from './commands/downloadStateMachineDefinition' +import { ExecutionDetailProvider } from './executionDetails/executionDetailProvider' /** * Activate Step Functions related functionality for the extension. @@ -97,6 +98,9 @@ async function registerStepFunctionCommands( Commands.register('aws.stepfunctions.publishStateMachine', async (node?: any) => { const region: string | undefined = node?.regionCode await publishStateMachine(awsContext, outputChannel, region) + }), + Commands.register('aws.stepfunctions.viewExecutionDetailsByExecutionARN', async () => { + await ExecutionDetailProvider.openExecutionDetails('') }) ) } diff --git a/packages/core/src/stepFunctions/constants/webviewResources.ts b/packages/core/src/stepFunctions/constants/webviewResources.ts new file mode 100644 index 00000000000..627599e5b9d --- /dev/null +++ b/packages/core/src/stepFunctions/constants/webviewResources.ts @@ -0,0 +1,8 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +export const isLocalDev = true +export const localhost = 'http://127.0.0.1:3002' +export const cdn = 'https://d5t62uwepi9lu.cloudfront.net' diff --git a/packages/core/src/stepFunctions/executionDetails/executionDetailProvider.ts b/packages/core/src/stepFunctions/executionDetails/executionDetailProvider.ts new file mode 100644 index 00000000000..7ad945aba55 --- /dev/null +++ b/packages/core/src/stepFunctions/executionDetails/executionDetailProvider.ts @@ -0,0 +1,112 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode' +import { getLogger } from '../../shared/logger/logger' +import request from '../../shared/request' +import { ToolkitError } from '../../shared/errors' +import { i18n } from '../../shared/i18n-helper' +import { ComponentType } from '../workflowStudio/types' +import { isLocalDev, localhost, cdn } from '../constants/webviewResources' + +/** + * Provider for Execution Details panels. + * + * Execution Details displays information about state machine executions in a WebView panel. + */ +export class ExecutionDetailProvider { + public static readonly viewType = 'stepfunctions.executionDetails' + + /** + * Opens execution details in a WebView panel. + * @param executionArn The ARN of the execution to display details for + * @param params Optional parameters to customize the WebView panel + */ + public static async openExecutionDetails( + executionArn: string, + params?: vscode.WebviewPanelOptions & vscode.WebviewOptions + ): Promise { + // Create and show the webview panel + const panel = vscode.window.createWebviewPanel( + ExecutionDetailProvider.viewType, + `Execution: ${executionArn.split(':').pop() || executionArn}`, + vscode.ViewColumn.Beside, + { + enableScripts: true, + retainContextWhenHidden: true, + ...params, + } + ) + // Create the provider and initialize the panel + const provider = new ExecutionDetailProvider() + await provider.initializePanel(panel, executionArn) + } + + protected webviewHtml: string + protected readonly logger = getLogger() + + constructor() { + this.webviewHtml = '' + } + + /** + * Fetches the webview HTML from the CDN or local server. + * @private + */ + private async fetchWebviewHtml(): Promise { + const source = isLocalDev ? localhost : cdn + const response = await request.fetch('GET', `${source}/index.html`).response + this.webviewHtml = await response.text() + } + + /** + * Gets the webview content for Execution Details. + * @private + */ + private getWebviewContent = async (): Promise => { + const htmlFileSplit = this.webviewHtml.split('') + + // Set asset source to CDN + const source = isLocalDev ? localhost : cdn + const baseTag = `` + + // Set locale, dark mode + const locale = vscode.env.language + const localeTag = `` + const theme = vscode.window.activeColorTheme.kind + const isDarkMode = theme === vscode.ColorThemeKind.Dark || theme === vscode.ColorThemeKind.HighContrast + const darkModeTag = `` + + // Set component type to ExecutionDetails + const componentTypeTag = `` + + return `${htmlFileSplit[0]} ${baseTag} ${localeTag} ${darkModeTag} ${componentTypeTag} ${htmlFileSplit[1]}` + } + + /** + * Initializes a WebView panel with execution details. + * @param panel The WebView panel to initialize + * @param executionArn The ARN of the execution to display + */ + public async initializePanel(panel: vscode.WebviewPanel, executionArn: string): Promise { + try { + if (!this.webviewHtml) { + await this.fetchWebviewHtml() + } + + // Set up the content + panel.webview.html = await this.getWebviewContent() + + // Handle messages from the webview + panel.webview.onDidReceiveMessage(async (message) => { + this.logger.debug('Received message from execution details webview: %O', message) + // Add message handlers as needed + }) + } catch (err) { + void vscode.window.showErrorMessage(i18n('AWS.stepFunctions.executionDetails.failed')) + throw ToolkitError.chain(err, 'Could not open Execution Details', { code: 'OpenExecutionDetailsFailed' }) + } + } +} diff --git a/packages/core/src/stepFunctions/workflowStudio/types.ts b/packages/core/src/stepFunctions/workflowStudio/types.ts index 989ef4517d6..725e87ebc1b 100644 --- a/packages/core/src/stepFunctions/workflowStudio/types.ts +++ b/packages/core/src/stepFunctions/workflowStudio/types.ts @@ -5,6 +5,11 @@ import { IAM, StepFunctions } from 'aws-sdk' import * as vscode from 'vscode' +export enum ComponentType { + WorkflowStudio = 'WorkflowStudio', + ExecutionDetails = 'ExecutionDetails', +} + export enum WorkflowMode { Editable = 'toolkit', Readonly = 'readonly', diff --git a/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts b/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts index 797ac80fbe7..4cf47e700a5 100644 --- a/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts +++ b/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts @@ -15,11 +15,9 @@ import { getTabSizeSetting } from '../../shared/utilities/editorUtilities' import { WorkflowStudioEditor } from './workflowStudioEditor' import { i18n } from '../../shared/i18n-helper' import { isInvalidJsonFile, isInvalidYamlFile } from '../utils' -import { WorkflowMode } from './types' +import { ComponentType, WorkflowMode } from './types' +import { isLocalDev, localhost, cdn } from '../constants/webviewResources' -const isLocalDev = false -const localhost = 'http://127.0.0.1:3002' -const cdn = 'https://d5t62uwepi9lu.cloudfront.net' let clientId = '' /** @@ -133,7 +131,11 @@ export class WorkflowStudioEditorProvider implements vscode.CustomTextEditorProv const darkModeTag = `` const modeTag = `` - return `${htmlFileSplit[0]} ${baseTag} ${localeTag} ${darkModeTag} ${tabSizeTag} ${modeTag} ${htmlFileSplit[1]}` + + // Set component type to WorkflowStudio + const componentTypeTag = `` + + return `${htmlFileSplit[0]} ${baseTag} ${localeTag} ${darkModeTag} ${tabSizeTag} ${modeTag} ${componentTypeTag} ${htmlFileSplit[1]}` } /** diff --git a/packages/toolkit/.changes/next-release/Feature-ce02287b-d043-4d71-8589-685903fb5ee7.json b/packages/toolkit/.changes/next-release/Feature-ce02287b-d043-4d71-8589-685903fb5ee7.json new file mode 100644 index 00000000000..170c17b0944 --- /dev/null +++ b/packages/toolkit/.changes/next-release/Feature-ce02287b-d043-4d71-8589-685903fb5ee7.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Added view by execution ARN command to visualize an execution" +} diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index f509647ab10..73e35d4e7ed 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -3380,6 +3380,17 @@ } } }, + { + "command": "aws.stepfunctions.viewExecutionDetailsByExecutionARN", + "title": "%AWS.command.stepFunctions.viewExecutionDetailsByExecutionARN%", + "category": "%AWS.title%", + "enablement": "isCloud9 || !aws.isWebExtHost", + "cloud9": { + "cn": { + "category": "%AWS.title.cn%" + } + } + }, { "command": "aws.cdk.renderStateMachineGraph", "title": "%AWS.command.cdk.previewStateMachine%",