|
3 | 3 | * Licensed under the MIT License. See License.md in the project root for license information. |
4 | 4 | *--------------------------------------------------------------------------------------------*/ |
5 | 5 |
|
| 6 | +import * as vscode from "vscode"; |
6 | 7 | import { type DeploymentPlanData } from "../../webviews/DeploymentPlanView"; |
7 | 8 | import { DeploymentPlanViewController } from "../../webviews/DeploymentPlanViewController"; |
8 | | -import * as vscode from "vscode"; |
| 9 | +import { parseDeploymentPlanMarkdown } from "../../utils/parseDeploymentPlanMarkdown"; |
9 | 10 |
|
10 | 11 | let currentDeploymentPlanViewController: DeploymentPlanViewController | undefined; |
11 | 12 |
|
12 | | -const sampleDeploymentPlanData: DeploymentPlanData = { |
13 | | - status: "Awaiting Approval", |
14 | | - mode: "MODERNIZE — deploy existing full-stack app to Azure", |
15 | | - subscription: "meganmott dev", |
16 | | - location: "East US", |
17 | | - locationCode: "eastus", |
18 | | - mermaidDiagram: `graph TD |
19 | | - Browser -->|HTTPS| SWA[Azure Static Web Apps<br/>React / Vite frontend] |
20 | | - SWA -->|/api/* proxy| FN[Azure Functions App<br/>Node.js 20 · TypeScript] |
21 | | - FN -->|Managed Identity| KV[Azure Key Vault<br/>Cosmos connection string] |
22 | | - FN -->|Cosmos SDK| DB[(Azure Cosmos DB<br/>NoSQL · Serverless)] |
| 13 | +export function openDeploymentPlanView(uri: vscode.Uri): void { |
| 14 | + void openDeploymentPlanViewAsync(uri); |
| 15 | +} |
| 16 | + |
| 17 | +export function openDeploymentPlanViewWithContent(content: string): void { |
| 18 | + const planData = parseDeploymentPlanMarkdown(content); |
| 19 | + showOrUpdateView(planData); |
| 20 | +} |
| 21 | + |
| 22 | +export function refreshDeploymentPlanView(uri: vscode.Uri): void { |
| 23 | + if (currentDeploymentPlanViewController) { |
| 24 | + void refreshDeploymentPlanViewAsync(uri); |
| 25 | + } |
| 26 | +} |
23 | 27 |
|
24 | | - style SWA fill:#0078d4,color:#fff |
25 | | - style FN fill:#0078d4,color:#fff |
26 | | - style KV fill:#0078d4,color:#fff |
27 | | - style DB fill:#0078d4,color:#fff`, |
28 | | - workspaceScan: { |
29 | | - headers: ["Component", "Technology", "Azure Target"], |
30 | | - rows: [ |
31 | | - ["src/web", "React 18, Vite, TypeScript", "Azure Static Web Apps"], |
32 | | - ["src/functions", "Azure Functions v4, Node.js, TypeScript", "Azure Functions (linked to SWA)"], |
33 | | - ["src/shared", "TypeScript library", "Built + bundled (no separate service)"], |
34 | | - ["Cosmos DB", "@azure/cosmos SDK, connection string env var", "Azure Cosmos DB for NoSQL (serverless)"], |
35 | | - ["Web → API routing", "Vite /api proxy in dev", "SWA native /api proxy at runtime"], |
36 | | - ], |
37 | | - }, |
38 | | - decisions: { |
39 | | - headers: ["Decision", "Choice", "Rationale"], |
40 | | - rows: [ |
41 | | - ["Recipe", "AZD + Bicep", "Both tools installed; AZD is the recommended default for end-to-end deploy"], |
42 | | - ["Functions plan", "Consumption", "Cost-efficient for low-to-medium workloads"], |
43 | | - ["Cosmos DB capacity", "Serverless", "No sustained throughput; ideal for dev/compliance calendar usage"], |
44 | | - ["Frontend hosting", "Azure Static Web Apps (SWA)", "Native Vite/React support; built-in /api proxy to linked Functions app"], |
45 | | - ["Secrets", "Key Vault + SWA/Functions app settings", "Cosmos connection string stored in Key Vault; referenced via @Microsoft.KeyVault(...)"], |
46 | | - ["Identity", "System-assigned Managed Identity on Functions app", "Grants Functions access to Key Vault without storing credentials in config"], |
47 | | - ], |
48 | | - }, |
49 | | - resources: { |
50 | | - headers: ["Resource", "Name pattern", "SKU / Tier"], |
51 | | - rows: [ |
52 | | - ["Resource Group", "rg-compliance-<env>", "—"], |
53 | | - ["Static Web Apps", "swa-compliance-<env>", "Free"], |
54 | | - ["Functions App", "func-compliance-<env>", "Consumption (Y1)"], |
55 | | - ["App Service Plan", "asp-compliance-<env>", "[Consumption — auto-created by Functions]"], |
56 | | - ["Storage Account", "stcompliance<env>", "Standard LRS (required by Functions)"], |
57 | | - ["Cosmos DB account", "cosmos-compliance-<env>", "Serverless, NoSQL"], |
58 | | - ["Key Vault", "kv-compliance-<env>", "Standard"], |
59 | | - ["Log Analytics Workspace", "log-compliance-<env>", "PerGB2018"], |
60 | | - ["Application Insights", "appi-compliance-<env>", "—"], |
61 | | - ], |
62 | | - }, |
63 | | -}; |
| 28 | +export async function openDeploymentPlanViewFromWorkspace(): Promise<void> { |
| 29 | + const files = await vscode.workspace.findFiles('**/.azure/plan.md', '**/node_modules/**', 10); |
| 30 | + if (files.length === 0) { |
| 31 | + void vscode.window.showInformationMessage('No deployment plan markdown files found in the workspace.'); |
| 32 | + return; |
| 33 | + } |
| 34 | + |
| 35 | + let selected: vscode.Uri; |
| 36 | + if (files.length === 1) { |
| 37 | + selected = files[0]; |
| 38 | + } else { |
| 39 | + const picked = await vscode.window.showQuickPick( |
| 40 | + files.map((f) => ({ label: vscode.workspace.asRelativePath(f), uri: f })), |
| 41 | + { placeHolder: 'Select a deployment plan file to open' }, |
| 42 | + ); |
| 43 | + if (!picked) { |
| 44 | + return; |
| 45 | + } |
| 46 | + selected = picked.uri; |
| 47 | + } |
| 48 | + |
| 49 | + await openDeploymentPlanViewAsync(selected); |
| 50 | +} |
| 51 | + |
| 52 | +async function openDeploymentPlanViewAsync(uri: vscode.Uri): Promise<void> { |
| 53 | + const content = Buffer.from(await vscode.workspace.fs.readFile(uri)).toString('utf-8'); |
| 54 | + const planData = parseDeploymentPlanMarkdown(content); |
| 55 | + showOrUpdateView(planData); |
| 56 | +} |
| 57 | + |
| 58 | +async function refreshDeploymentPlanViewAsync(uri: vscode.Uri): Promise<void> { |
| 59 | + const content = Buffer.from(await vscode.workspace.fs.readFile(uri)).toString('utf-8'); |
| 60 | + const planData = parseDeploymentPlanMarkdown(content); |
| 61 | + currentDeploymentPlanViewController?.updateDeploymentPlanData(planData); |
| 62 | +} |
64 | 63 |
|
65 | | -export function openDeploymentPlanView(): void { |
| 64 | +function showOrUpdateView(planData: DeploymentPlanData): void { |
66 | 65 | if (currentDeploymentPlanViewController) { |
67 | | - currentDeploymentPlanViewController.updateDeploymentPlanData(sampleDeploymentPlanData); |
| 66 | + currentDeploymentPlanViewController.updateDeploymentPlanData(planData); |
68 | 67 | currentDeploymentPlanViewController.revealToForeground(vscode.ViewColumn.Active); |
69 | 68 | return; |
70 | 69 | } |
71 | 70 |
|
72 | | - currentDeploymentPlanViewController = new DeploymentPlanViewController(sampleDeploymentPlanData); |
| 71 | + currentDeploymentPlanViewController = new DeploymentPlanViewController(planData); |
73 | 72 | currentDeploymentPlanViewController.revealToForeground(vscode.ViewColumn.Active); |
74 | 73 |
|
75 | 74 | currentDeploymentPlanViewController.panel.onDidDispose(() => { |
|
0 commit comments