From 6bf7499e786e774508aa38088804433075b7601e Mon Sep 17 00:00:00 2001 From: Anthony Martin <38542602+anthony-c-martin@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:02:47 -0400 Subject: [PATCH] Replace @vscode/webview-ui-toolkit (#15440) Closes #15264 Addresses #15143 Closes #13771 ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/15440) --- src/vscode-bicep/package-lock.json | 307 ++++++------------ src/vscode-bicep/package.json | 3 +- .../src/panes/deploy/app/components/App.tsx | 39 ++- .../deploy/app/components/ParamInputBox.tsx | 94 +++--- .../deploy/app/components/hooks/useAzure.ts | 80 ++--- .../src/panes/deploy/app/components/index.css | 9 + .../deploy/app/components/localDeploy.tsx | 109 ++++--- .../sections/DeploymentOperationsView.tsx | 97 +++--- .../sections/DeploymentOutputsView.tsx | 43 ++- .../sections/DeploymentScopeInputView.tsx | 53 +-- .../app/components/sections/FormSection.tsx | 7 +- .../sections/ParametersInputView.tsx | 12 +- .../app/components/sections/PortalButton.tsx | 31 ++ .../app/components/sections/ResultsView.tsx | 112 ++++--- .../components/sections/WhatIfChangesView.tsx | 69 ++-- src/vscode-bicep/src/panes/deploy/models.ts | 5 +- src/vscode-bicep/src/panes/deploy/view.ts | 4 + src/vscode-bicep/webpack.config.ts | 6 + 18 files changed, 532 insertions(+), 548 deletions(-) create mode 100644 src/vscode-bicep/src/panes/deploy/app/components/sections/PortalButton.tsx diff --git a/src/vscode-bicep/package-lock.json b/src/vscode-bicep/package-lock.json index 4efaa64e306..60f0a94a74b 100644 --- a/src/vscode-bicep/package-lock.json +++ b/src/vscode-bicep/package-lock.json @@ -16,7 +16,8 @@ "@microsoft/vscode-azext-azureutils": "^3.1.1", "@microsoft/vscode-azext-utils": "^2.5.10", "@vscode-bicep-ui/components": "file:../vscode-bicep-ui/packages/components", - "@vscode/webview-ui-toolkit": "^1.4.0", + "@vscode-elements/react-elements": "^0.5.0", + "@vscode/codicons": "^0.0.36", "cytoscape": "^3.30.2", "cytoscape-elk": "^2.2.0", "fs-extra": "^11.2.0", @@ -121,11 +122,6 @@ "node": ">=8.0.0" } }, - "node_modules/@azure/abort-controller/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/arm-authorization": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@azure/arm-authorization/-/arm-authorization-9.0.0.tgz", @@ -158,18 +154,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/arm-authorization-profile-2020-09-01-hybrid/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, - "node_modules/@azure/arm-authorization/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, "node_modules/@azure/arm-managementgroups": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@azure/arm-managementgroups/-/arm-managementgroups-2.0.2.tgz", @@ -187,11 +171,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/arm-managementgroups/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/arm-msi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@azure/arm-msi/-/arm-msi-2.1.0.tgz", @@ -208,12 +187,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/arm-msi/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, "node_modules/@azure/arm-resources": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-5.2.0.tgz", @@ -248,11 +221,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/arm-resources-profile-2020-09-01-hybrid/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "node_modules/@azure/arm-resources-subscriptions": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@azure/arm-resources-subscriptions/-/arm-resources-subscriptions-2.0.1.tgz", @@ -268,16 +236,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/arm-resources-subscriptions/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, - "node_modules/@azure/arm-resources/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/arm-storage": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/@azure/arm-storage/-/arm-storage-18.3.0.tgz", @@ -312,16 +270,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/arm-storage-profile-2020-09-01-hybrid/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, - "node_modules/@azure/arm-storage/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/arm-subscriptions": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@azure/arm-subscriptions/-/arm-subscriptions-5.1.0.tgz", @@ -339,11 +287,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/arm-subscriptions/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/core-asynciterator-polyfill": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz", @@ -376,11 +319,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-auth/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/core-client": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz", @@ -420,11 +358,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/core-client/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/core-lro": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz", @@ -450,11 +383,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-lro/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/core-paging": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.1.tgz", @@ -467,11 +395,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/core-paging/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/core-rest-pipeline": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.17.0.tgz", @@ -535,11 +458,6 @@ "node": ">= 14" } }, - "node_modules/@azure/core-rest-pipeline/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/core-util": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz", @@ -563,11 +481,6 @@ "node": ">=18.0.0" } }, - "node_modules/@azure/core-util/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@azure/identity": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.5.0.tgz", @@ -614,11 +527,6 @@ "node": ">=12.0.0" } }, - "node_modules/@azure/identity/node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" - }, "node_modules/@azure/logger": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", @@ -630,11 +538,6 @@ "node": ">=14.0.0" } }, - "node_modules/@azure/logger/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/@azure/ms-rest-azure-env": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz", @@ -2072,6 +1975,30 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/react": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.6.tgz", + "integrity": "sha512-QIss8MPh6qUoFJmuaF4dSHts3qCsA36S3HcOLiNPShxhgYPr4XJRnCBKPipk85sR9xr6TQrOcDMfexwbNdJHYA==", + "license": "BSD-3-Clause", + "peerDependencies": { + "@types/react": "17 || 18" + } + }, + "node_modules/@lit/reactive-element": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", + "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, "node_modules/@microsoft/1ds-core-js": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.3.2.tgz", @@ -2181,42 +2108,6 @@ "@nevware21/ts-utils": ">= 0.10.4 < 2.x" } }, - "node_modules/@microsoft/fast-element": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.12.0.tgz", - "integrity": "sha512-gQutuDHPKNxUEcQ4pypZT4Wmrbapus+P9s3bR/SEOLsMbNqNoXigGImITygI5zhb+aA5rzflM6O8YWkmRbGkPA==" - }, - "node_modules/@microsoft/fast-foundation": { - "version": "2.49.4", - "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.49.4.tgz", - "integrity": "sha512-5I2tSPo6bnOfVAIX7XzX+LhilahwvD7h+yzl3jW0t5IYmMX9Lci9VUVyx5f8hHdb1O9a8Y9Atb7Asw7yFO/u+w==", - "dependencies": { - "@microsoft/fast-element": "^1.12.0", - "@microsoft/fast-web-utilities": "^5.4.1", - "tabbable": "^5.2.0", - "tslib": "^1.13.0" - } - }, - "node_modules/@microsoft/fast-react-wrapper": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.22.tgz", - "integrity": "sha512-XhlX4m6znh7XW92oPvlKoG9USUn9JtF9rP1qtUoIbkaDaFtUS+H8o1Jn6/oK/rS44LbBLJXrvRkInmSWlDiGFw==", - "dependencies": { - "@microsoft/fast-element": "^1.12.0", - "@microsoft/fast-foundation": "^2.49.4" - }, - "peerDependencies": { - "react": ">=16.9.0" - } - }, - "node_modules/@microsoft/fast-web-utilities": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@microsoft/fast-web-utilities/-/fast-web-utilities-5.4.1.tgz", - "integrity": "sha512-ReWYncndjV3c8D8iq9tp7NcFNc1vbVHvcBFPME2nNFKNbS1XCesYZGlIlf3ot5EmuOXPlrzUHOWzQ2vFpIkqDg==", - "dependencies": { - "exenv-es6": "^1.1.1" - } - }, "node_modules/@microsoft/vscode-azext-azureutils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-azureutils/-/vscode-azext-azureutils-3.1.1.tgz", @@ -2601,14 +2492,12 @@ "node_modules/@types/prop-types": { "version": "15.7.4", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", - "dev": true + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" }, "node_modules/@types/react": { "version": "18.3.5", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", - "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -2661,6 +2550,12 @@ "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, "node_modules/@types/vscode": { "version": "1.93.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.93.0.tgz", @@ -3018,6 +2913,32 @@ "styled-components": "^6.1.11" } }, + "node_modules/@vscode-elements/elements": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@vscode-elements/elements/-/elements-1.7.0.tgz", + "integrity": "sha512-EFuI+kyMVLNuLtv8eohFN8+KTQyvXGOe9NxxkDasaDMNrI7BFJ+xSonfI/2NcSDtbcZ4Pt0xtapINBADChXnEw==", + "license": "MIT", + "dependencies": { + "lit": "^3.2.0" + } + }, + "node_modules/@vscode-elements/react-elements": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@vscode-elements/react-elements/-/react-elements-0.5.0.tgz", + "integrity": "sha512-+H1aKuD7uID8Dc/YiQCQUFtGcWxCX+rWH9EIcQTUB1Gj8SfQrwN4Cd46BqQbwJAwtYJkOMl9i+Urfc5mkw8HWw==", + "license": "ISC", + "dependencies": { + "@lit/react": "^1.0.6", + "@vscode-elements/elements": "~1.7.0", + "react": "~18.3.1" + } + }, + "node_modules/@vscode/codicons": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.36.tgz", + "integrity": "sha512-wsNOvNMMJ2BY8rC2N2MNBG7yOowV3ov8KlvUE/AiVUlHKTfWsw3OgAOQduX7h0Un6GssKD3aoTVH+TF3DSQwKQ==", + "license": "CC-BY-4.0" + }, "node_modules/@vscode/extension-telemetry": { "version": "0.9.7", "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.7.tgz", @@ -3251,25 +3172,6 @@ "node": ">=4" } }, - "node_modules/@vscode/webview-ui-toolkit": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.4.0.tgz", - "integrity": "sha512-modXVHQkZLsxgmd5yoP3ptRC/G8NBDD+ob+ngPiWNQdlrH6H1xR/qgOBD85bfU3BhOB5sZzFWBwwhp9/SfoHww==", - "dependencies": { - "@microsoft/fast-element": "^1.12.0", - "@microsoft/fast-foundation": "^2.49.4", - "@microsoft/fast-react-wrapper": "^0.3.22", - "tslib": "^2.6.2" - }, - "peerDependencies": { - "react": ">=16.9.0" - } - }, - "node_modules/@vscode/webview-ui-toolkit/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -4211,12 +4113,6 @@ "tslib": "^2.0.3" } }, - "node_modules/camel-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -4317,12 +4213,6 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cheerio/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -6047,11 +5937,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exenv-es6": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exenv-es6/-/exenv-es6-1.1.1.tgz", - "integrity": "sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==" - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -6362,9 +6247,9 @@ } }, "node_modules/framer-motion": { - "version": "11.11.9", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.9.tgz", - "integrity": "sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==", + "version": "11.11.10", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.10.tgz", + "integrity": "sha512-061Bt1jL/vIm+diYIiA4dP/Yld7vD47ROextS7ESBW5hr4wQFhxB5D5T5zAc3c/5me3cOa+iO5LqhA38WDln/A==", "license": "MIT", "peer": true, "dependencies": { @@ -6387,13 +6272,6 @@ } } }, - "node_modules/framer-motion/node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", - "license": "0BSD", - "peer": true - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -8747,6 +8625,37 @@ "uc.micro": "^2.0.0" } }, + "node_modules/lit": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", + "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-element": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", + "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.0.4", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-html": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", + "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, "node_modules/loader-runner": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", @@ -8899,12 +8808,6 @@ "tslib": "^2.0.3" } }, - "node_modules/lower-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -9249,12 +9152,6 @@ "tslib": "^2.0.3" } }, - "node_modules/no-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - }, "node_modules/node-abi": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz", @@ -9733,12 +9630,6 @@ "tslib": "^2.0.3" } }, - "node_modules/pascal-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11387,11 +11278,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/tabbable": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz", - "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==" - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -11705,9 +11591,10 @@ } }, "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD" }, "node_modules/tunnel": { "version": "0.0.6", diff --git a/src/vscode-bicep/package.json b/src/vscode-bicep/package.json index a149c0573f0..8c5110c3857 100644 --- a/src/vscode-bicep/package.json +++ b/src/vscode-bicep/package.json @@ -811,7 +811,8 @@ "@microsoft/vscode-azext-azureutils": "^3.1.1", "@microsoft/vscode-azext-utils": "^2.5.10", "@vscode-bicep-ui/components": "file:../vscode-bicep-ui/packages/components", - "@vscode/webview-ui-toolkit": "^1.4.0", + "@vscode-elements/react-elements": "^0.5.0", + "@vscode/codicons": "^0.0.36", "cytoscape": "^3.30.2", "cytoscape-elk": "^2.2.0", "fs-extra": "^11.2.0", diff --git a/src/vscode-bicep/src/panes/deploy/app/components/App.tsx b/src/vscode-bicep/src/panes/deploy/app/components/App.tsx index 0f036a40cad..e2ddf895fae 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/App.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/App.tsx @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { VSCodeButton, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react"; +import { VscodeProgressRing, VscodeButton, VscodeIcon } from "@vscode-elements/react-elements"; import { FC, useState } from "react"; import "./index.css"; @@ -16,7 +16,6 @@ import { FormSection } from "./sections/FormSection"; import { ParametersInputView } from "./sections/ParametersInputView"; import { ResultsView } from "./sections/ResultsView"; import { WhatIfChangesView } from "./sections/WhatIfChangesView"; -import { Codicon } from "@vscode-bicep-ui/components"; export const App: FC = () => { const [errorMessage, setErrorMessage] = useState(); @@ -29,6 +28,7 @@ export const App: FC = () => { parametersMetadata: messages.paramsMetadata, setErrorMessage, }); + const isRunning = azure.deployState.status === "running" || localDeployRunning; function setParamValue(key: string, data: ParamData) { const parameters = Object.assign({}, messages.paramsMetadata.parameters, { [key]: data }); @@ -39,7 +39,7 @@ export const App: FC = () => { messages.setParamsMetadata({ ...messages.paramsMetadata, sourceFilePath: undefined }); } - const azureDisabled = !messages.scope || !messages.templateMetadata || azure.running; + const azureDisabled = !messages.scope || !messages.templateMetadata || isRunning; async function handleDeployClick() { messages.publishTelemetry("deployPane/deploy", {}); @@ -62,7 +62,7 @@ export const App: FC = () => { } if (!messages.messageState.initialized) { - return ; + return ; } const showLocalDeployControls = @@ -76,7 +76,7 @@ export const App: FC = () => { <>
- + The Bicep Deployment Pane is an experimental feature.
Documentation is available{" "} @@ -89,7 +89,7 @@ export const App: FC = () => { { {errorMessage && (
- + {errorMessage}
)}
- + Deploy - - + + Validate - - + + What-If - +
- {azure.running && }
{messages.scope && ( <> - + @@ -131,7 +130,7 @@ export const App: FC = () => { <>
- + Local Deployment is an experimental feature.
@@ -149,16 +148,16 @@ export const App: FC = () => { {errorMessage && (
- + {errorMessage}
)}
- + Deploy - +
- {localDeployRunning && } + {localDeployRunning && }
{!localDeployRunning && messages.localDeployResult && ( diff --git a/src/vscode-bicep/src/panes/deploy/app/components/ParamInputBox.tsx b/src/vscode-bicep/src/panes/deploy/app/components/ParamInputBox.tsx index ef5551cae68..9f3e3b39b96 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/ParamInputBox.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/ParamInputBox.tsx @@ -1,13 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { - VSCodeButton, - VSCodeCheckbox, - VSCodeDropdown, - VSCodeOption, - VSCodeTextArea, - VSCodeTextField, -} from "@vscode/webview-ui-toolkit/react"; + VscodeButton, + VscodeCheckbox, + VscodeLabel, + VscodeOption, + VscodeSingleSelect, + VscodeTextarea, + VscodeTextfield +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { ParamData, ParamDefinition } from "../../models"; @@ -32,64 +33,71 @@ export const ParamInputBox: FC = (props) => { } function getInputBox() { + const inputHtmlId = `param-input-${name.toLowerCase()}`; switch (type) { case "bool": return ( - handleValueChange(!value)} disabled={disabled}> + handleValueChange(!value)} + disabled={disabled}> {name} - + ); case "int": return ( - handleValueChange(parseInt((e.currentTarget as HTMLInputElement).value, 10))} - disabled={disabled} - > - {name} - + <> + {name} + handleValueChange(parseInt((e.currentTarget as HTMLInputElement).value, 10))} + disabled={disabled} /> + ); case "string": if (definition.allowedValues) { - const dropdownHtmlId = `param-input-${name.toLowerCase()}`; return ( -
- - + {name} + handleValueChange((e.currentTarget as HTMLSelectElement).value)} disabled={disabled} > {definition.allowedValues.map((option) => ( - + {option} - + ))} - -
+ + ); } else { return ( - handleValueChange((e.currentTarget as HTMLInputElement).value)} - disabled={disabled} - > - {name} - + <> + {name} + handleValueChange((e.currentTarget as HTMLInputElement).value)} + disabled={disabled} /> + ); } default: return ( - handleValueChange(JSON.parse((e.currentTarget as HTMLInputElement).value))} - disabled={disabled} - > - {name} - + <> + {name} + handleValueChange(JSON.parse((e.currentTarget as HTMLInputElement).value))} + disabled={disabled} /> + ); } } @@ -98,9 +106,9 @@ export const ParamInputBox: FC = (props) => { {getInputBox()} {defaultValue !== undefined && value !== defaultValue && ( - + Reset to default - + )} ); diff --git a/src/vscode-bicep/src/panes/deploy/app/components/hooks/useAzure.ts b/src/vscode-bicep/src/panes/deploy/app/components/hooks/useAzure.ts index 6b0263b8e30..aa6eb9469bb 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/hooks/useAzure.ts +++ b/src/vscode-bicep/src/panes/deploy/app/components/hooks/useAzure.ts @@ -4,6 +4,7 @@ import { CloudError, Deployment, DeploymentOperation, + ErrorResponse, ResourceManagementClient, WhatIfChange, } from "@azure/arm-resources"; @@ -12,7 +13,7 @@ import { AccessToken, TokenCredential } from "@azure/identity"; import { useState } from "react"; import { DeploymentScope, - DeployResult, + DeployState, ParamData, ParametersMetadata, TemplateMetadata, @@ -29,12 +30,10 @@ export interface UseAzureProps { export function useAzure(props: UseAzureProps) { const { scope, templateMetadata, parametersMetadata, acquireAccessToken, setErrorMessage } = props; - const deploymentName = "bicep-deploy"; const [operations, setOperations] = useState(); const [whatIfChanges, setWhatIfChanges] = useState(); const [outputs, setOutputs] = useState>(); - const [result, setResult] = useState(); - const [running, setRunning] = useState(false); + const [deployState, setDeployState] = useState({}); function getArmClient(scope: DeploymentScope, accessToken: AccessToken) { const tokenProvider: TokenCredential = { @@ -55,7 +54,8 @@ export function useAzure(props: UseAzureProps) { async function doDeploymentOperation( scope: DeploymentScope, - operation: (armClient: ResourceManagementClient, deployment: Deployment) => Promise, + deploymentName: string | undefined, + operation: (armClient: ResourceManagementClient, deployment: Deployment) => Promise<{ success: boolean, error?: ErrorResponse}>, ) { if (!templateMetadata) { return; @@ -63,17 +63,18 @@ export function useAzure(props: UseAzureProps) { try { setErrorMessage(undefined); - clearState(); - setRunning(true); + setOperations(undefined); + setWhatIfChanges(undefined); + setDeployState({ status: "running", name: deploymentName }); const deployment = getDeploymentProperties(scope, templateMetadata, parametersMetadata.parameters); const accessToken = await acquireAccessToken(); const armClient = getArmClient(scope, accessToken); - await operation(armClient, deployment); + const { success, error } = await operation(armClient, deployment); + setDeployState({ status: success ? "succeeded" : "failed", name: deploymentName, error }); } catch (error) { + setDeployState({ status: "failed", name: deploymentName }); setErrorMessage(`Azure operation failed: ${error}`); - } finally { - setRunning(false); } } @@ -82,7 +83,8 @@ export function useAzure(props: UseAzureProps) { return; } - await doDeploymentOperation(scope, async (client, deployment) => { + const deploymentName = `bicep-deploy-${Date.now()}`; + await doDeploymentOperation(scope, deploymentName, async (client, deployment) => { const updateOperations = async () => { const operations = []; const result = client.deploymentOperations.listAtScope(getScopeId(scope), deploymentName); @@ -102,20 +104,14 @@ export function useAzure(props: UseAzureProps) { await poller.poll(); } } catch (e) { - setResult({ - success: false, - error: parseError(e), - }); - return; + return { success: false, error: parseError(e) }; } finally { await updateOperations(); } const finalResult = poller.getResult(); setOutputs(finalResult?.properties?.outputs); - setResult({ - success: true, - }); + return { success: true }; }); } @@ -124,23 +120,17 @@ export function useAzure(props: UseAzureProps) { return; } - await doDeploymentOperation(scope, async (client, deployment) => { + await doDeploymentOperation(scope, undefined, async (client, deployment) => { try { const response = await client.deployments.beginValidateAtScopeAndWait( getScopeId(scope), - deploymentName, + "bicep-deploy", deployment, ); - setResult({ - success: !response.error, - error: response.error, - }); + return { success: !response.error, error: response.error }; } catch (e) { - setResult({ - success: false, - error: parseError(e), - }); + return { success: false, error: parseError(e) }; } }); } @@ -150,37 +140,23 @@ export function useAzure(props: UseAzureProps) { return; } - await doDeploymentOperation(scope, async (client, deployment) => { + await doDeploymentOperation(scope, undefined, async (client, deployment) => { try { - const response = await beginWhatIfAndWait(client, scope, deploymentName, deployment); + const response = await beginWhatIfAndWait(client, scope, "bicep-deploy", deployment); - setResult({ - success: !response.error, - error: response.error, - }); setWhatIfChanges(response.changes); + return { success: !response.error, error: response.error }; } catch (e) { - setResult({ - success: false, - error: parseError(e), - }); + return { success: false, error: parseError(e) }; } }); } - function clearState() { - setOutputs(undefined); - setResult(undefined); - setOperations(undefined); - setWhatIfChanges(undefined); - } - return { - running, + deployState, operations, whatIfChanges, outputs, - result, deploy, validate, whatIf, @@ -235,6 +211,14 @@ function getScopeId(scope: DeploymentScope) { } } +export function getDeploymentResourceId(scope: DeploymentScope, deploymentName: string) { + let scopeId = getScopeId(scope); + if (scopeId.endsWith("/")) { + scopeId = scopeId.slice(0, -1); + } + return `${scopeId}/providers/Microsoft.Resources/deployments/${deploymentName}`; +} + async function beginWhatIfAndWait( client: ResourceManagementClient, scope: DeploymentScope, diff --git a/src/vscode-bicep/src/panes/deploy/app/components/index.css b/src/vscode-bicep/src/panes/deploy/app/components/index.css index e352b8183b7..0c01f1f7236 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/index.css +++ b/src/vscode-bicep/src/panes/deploy/app/components/index.css @@ -72,13 +72,22 @@ vscode-button { margin-bottom: 2px; } +.code-textarea-container { + width: auto; +} + .code-textarea-container textarea { white-space: pre; font-family: monospace; + width: auto; } .code-wrapped { white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; +} + +vscode-table-cell { + text-wrap: wrap; } \ No newline at end of file diff --git a/src/vscode-bicep/src/panes/deploy/app/components/localDeploy.tsx b/src/vscode-bicep/src/panes/deploy/app/components/localDeploy.tsx index 38b8103abfc..47e02b7e7de 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/localDeploy.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/localDeploy.tsx @@ -1,6 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { VSCodeDataGrid, VSCodeDataGridCell, VSCodeDataGridRow } from "@vscode/webview-ui-toolkit/react"; +import { + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableHeader, + VscodeTableHeaderCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { LocalDeploymentOperationContent, LocalDeployResponse } from "../../../../language"; import { FormSection } from "./sections/FormSection"; @@ -12,20 +19,20 @@ export const LocalDeployResult: FC<{ result: LocalDeployResponse }> = ({ result

{result.deployment.provisioningState}

{error && ( - + {error && ( - - Code - {error.code} - + + Code + {error.code} + )} {error.message && ( - - Message - {error.message} - + + Message + {error.message} + )} - + )}
); @@ -38,31 +45,33 @@ export const LocalDeployOperations: FC<{ result: LocalDeployResponse }> = ({ res return ( - - - + + + Resource Name - - + + State - - + + Error - - - {result.operations.map((operation) => ( - - {operation.resourceName} - {operation.provisioningState} - - {operation.error ? getPreformattedJson(operation.error) : ""} - - - ))} - + + + + {result.operations.map((operation) => ( + + {operation.resourceName} + {operation.provisioningState} + + {operation.error ? getPreformattedJson(operation.error) : ""} + + + ))} + + ); }; @@ -74,24 +83,26 @@ export const LocalDeployOutputs: FC<{ result: LocalDeployResponse }> = ({ result return ( - - - + + + Name - - + + Value - - - {Object.keys(result.deployment.outputs).map((name) => ( - - {name} - - {getPreformattedJson(result.deployment.outputs[name])} - - - ))} - + + + + {Object.keys(result.deployment.outputs).map((name) => ( + + {name} + + {getPreformattedJson(result.deployment.outputs[name])} + + + ))} + + ); }; diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOperationsView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOperationsView.tsx index 59ad78f736d..2966627568a 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOperationsView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOperationsView.tsx @@ -2,17 +2,19 @@ // Licensed under the MIT License. import { DeploymentOperation } from "@azure/arm-resources"; import { - VSCodeDataGrid, - VSCodeDataGridCell, - VSCodeDataGridRow, - VSCodeLink, - VSCodeProgressRing, -} from "@vscode/webview-ui-toolkit/react"; + VscodeProgressRing, + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableHeader, + VscodeTableHeaderCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { DeploymentScope } from "../../../models"; import { getPreformattedJson, isFailed, isInProgress } from "../utils"; import { FormSection } from "./FormSection"; -import { Codicon } from "@vscode-bicep-ui/components"; +import { PortalButton } from "./PortalButton"; interface DeploymentOperationsViewProps { scope: DeploymentScope; @@ -34,41 +36,43 @@ export const DeploymentOperationsView: FC = ({ sc return ( - - - + + + Resource Name - - + + Resource Type - - + + Operation - - + + State - - + + Status - - - {filteredOperations.map((operation) => ( - - {getResourceNameContents(scope, operation)} - {operation.properties?.targetResource?.resourceType} - {operation.properties?.provisioningOperation} - - {isInProgress(operation) ? : operation.properties?.provisioningState} - - - {getPreformattedJson(operation.properties?.statusMessage)} - - - ))} - + + + + {filteredOperations.map((operation) => ( + + {getResourceNameContents(scope, operation)} + {operation.properties?.targetResource?.resourceType} + {operation.properties?.provisioningOperation} + + {isInProgress(operation) ? : operation.properties?.provisioningState} + + + {getPreformattedJson(operation.properties?.statusMessage)} + + + ))} + + ); }; @@ -84,7 +88,7 @@ function getResourceNameContents(scope: DeploymentScope, operation: DeploymentOp ); } -function getPortalLinkButton(scope: DeploymentScope, operation: DeploymentOperation) { +export function getPortalLinkButton(scope: DeploymentScope, operation: DeploymentOperation) { const { targetResource, provisioningOperation } = operation.properties ?? {}; if (!targetResource || !targetResource.id || !targetResource.resourceType) { return; @@ -95,20 +99,5 @@ function getPortalLinkButton(scope: DeploymentScope, operation: DeploymentOperat return; } - let portalResourceUrl; - switch (targetResource.resourceType.toLowerCase()) { - case 'microsoft.resources/deployments': - // Deployments have a dedicated Portal blade to track progress - portalResourceUrl = `${scope.portalUrl}/#@${scope.tenantId}/blade/HubsExtension/DeploymentDetailsBlade/overview/id/${encodeURIComponent(targetResource.id)}`; - break; - default: - portalResourceUrl = `${scope.portalUrl}/#@${scope.tenantId}/resource${targetResource.id}`; - break; - } - - return ( - - - - ); + return ; } \ No newline at end of file diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOutputsView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOutputsView.tsx index ae02876a6c6..70e8195e9a1 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOutputsView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentOutputsView.tsx @@ -1,6 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { VSCodeDataGrid, VSCodeDataGridCell, VSCodeDataGridRow } from "@vscode/webview-ui-toolkit/react"; +import { + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableHeader, + VscodeTableHeaderCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { getPreformattedJson } from "../utils"; import { FormSection } from "./FormSection"; @@ -16,24 +23,26 @@ export const DeploymentOutputsView: FC = ({ outputs return ( - - - + + + Name - - + + Value - - - {Object.keys(outputs).map((name) => ( - - {name} - - {getPreformattedJson((outputs[name] as { value: unknown }).value)} - - - ))} - + + + + {Object.keys(outputs).map((name) => ( + + {name} + + {getPreformattedJson((outputs[name] as { value: unknown }).value)} + + + ))} + + ); }; diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentScopeInputView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentScopeInputView.tsx index d4204157712..ff000a6f920 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentScopeInputView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/DeploymentScopeInputView.tsx @@ -1,12 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { - VSCodeBadge, - VSCodeButton, - VSCodeDataGrid, - VSCodeDataGridCell, - VSCodeDataGridRow, -} from "@vscode/webview-ui-toolkit/react"; + VscodeBadge, + VscodeButton, + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { DeploymentScope } from "../../../models"; import { FormSection } from "./FormSection"; @@ -20,23 +21,25 @@ export const DeploymentScopeInputView: FC = ({ sc return ( {scope && ( - - {(scope.scopeType === "resourceGroup" || scope.scopeType === "subscription") && - getGridRow("Subscription Id", scope.subscriptionId)} - {scope.scopeType === "resourceGroup" && getGridRow("Resource Group", scope.resourceGroup)} - {(scope.scopeType === "managementGroup" || scope.scopeType === "tenant") && - getGridRow("Tenant Id", scope.tenantId)} - {scope.scopeType === "managementGroup" && getGridRow("Management Group", scope.managementGroup)} - {(scope.scopeType === "managementGroup" || scope.scopeType === "tenant") && - getGridRow("Authenticated Subscription Id", scope.associatedSubscriptionId)} - {scope.scopeType !== "resourceGroup" && getGridRow("Location", scope.location)} - + + + {(scope.scopeType === "resourceGroup" || scope.scopeType === "subscription") && + getGridRow("Subscription Id", scope.subscriptionId)} + {scope.scopeType === "resourceGroup" && getGridRow("Resource Group", scope.resourceGroup)} + {(scope.scopeType === "managementGroup" || scope.scopeType === "tenant") && + getGridRow("Tenant Id", scope.tenantId)} + {scope.scopeType === "managementGroup" && getGridRow("Management Group", scope.managementGroup)} + {(scope.scopeType === "managementGroup" || scope.scopeType === "tenant") && + getGridRow("Authenticated Subscription Id", scope.associatedSubscriptionId)} + {scope.scopeType !== "resourceGroup" && getGridRow("Location", scope.location)} + + )}
- + {!scope ? "Pick Scope" : "Change Scope"} - +
); @@ -44,11 +47,11 @@ export const DeploymentScopeInputView: FC = ({ sc function getGridRow(label: string, value: string) { return ( - - {label} - - {value} - - + + {label} + + {value} + + ); } diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/FormSection.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/FormSection.tsx index c1191a627f2..d2ccf57f073 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/FormSection.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/FormSection.tsx @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { Codicon } from "@vscode-bicep-ui/components"; -import { VSCodeDivider } from "@vscode/webview-ui-toolkit/react"; +import { VscodeDivider, VscodeIcon } from "@vscode-elements/react-elements"; import { FC, PropsWithChildren, useState } from "react"; type FormSectionProps = PropsWithChildren<{ @@ -13,9 +12,9 @@ export const FormSection: FC = ({ title, children }) => { return (
- +
setOpen(!open)}> - +

{title}

{open &&
{children}
} diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/ParametersInputView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/ParametersInputView.tsx index 541def284d5..0719d906162 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/ParametersInputView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/ParametersInputView.tsx @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { VSCodeButton, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"; +import { VscodeButton, VscodeTextfield } from "@vscode-elements/react-elements"; import { FC } from "react"; import { ParamData, ParamDefinition, ParametersMetadata, TemplateMetadata } from "../../../models"; import { ParamInputBox } from "../ParamInputBox"; @@ -27,20 +27,22 @@ export const ParametersInputView: FC = ({ return null; } + console.log(parameters); + const { parameterDefinitions } = template; const { sourceFilePath } = parameters; return ( {sourceFilePath && ( - + File Path - + )} {sourceFilePath && !sourceFilePath.endsWith(".bicepparam") && ( - Edit Parameters + Edit Parameters )} - {!sourceFilePath && Pick JSON Parameters File} + {!sourceFilePath && Pick JSON Parameters File} {!sourceFilePath && parameterDefinitions.map((definition) => ( + + + ); +} \ No newline at end of file diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/ResultsView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/ResultsView.tsx index 41b99a0ff35..bbcf8180325 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/ResultsView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/ResultsView.tsx @@ -2,22 +2,28 @@ // Licensed under the MIT License. import { ErrorResponse } from "@azure/arm-resources"; import { - VSCodeCheckbox, - VSCodeDataGrid, - VSCodeDataGridCell, - VSCodeDataGridRow, -} from "@vscode/webview-ui-toolkit/react"; + VscodeBadge, + VscodeCheckbox, + VscodeProgressRing, + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC, useState } from "react"; -import { DeployResult } from "../../../models"; +import { DeploymentScope, DeployState } from "../../../models"; import { getPreformattedJson } from "../utils"; import { FormSection } from "./FormSection"; +import { PortalButton } from "./PortalButton"; +import { getDeploymentResourceId } from "../hooks/useAzure"; interface ResultsViewProps { - result?: DeployResult; + deployState: DeployState; + scope: DeploymentScope; } -export const ResultsView: FC = ({ result }) => { - if (!result) { +export const ResultsView: FC = ({ deployState, scope }) => { + if (!deployState.status) { return null; } @@ -25,13 +31,37 @@ export const ResultsView: FC = ({ result }) => { return ( -

{result.success ? "Succeeded" : "Failed"}

- {result.error && ( - setShowJson(!showJson)} checked={showJson}> + + + {deployState.name && ( + Deployment Name + + + {deployState.name} + + + + )} + + Status + + {deployState.status === 'running' && ()} + {deployState.status !== 'running' && ( + + {deployState.status === "succeeded" ? "Succeeded" : "Failed"} + + )} + + + + + + {deployState.error && ( + setShowJson(!showJson)} checked={showJson}> Show JSON? - + )} - {result.error && getError(result.error, showJson)} + {deployState.error && getError(deployState.error, showJson)}
); }; @@ -42,31 +72,33 @@ function getError(error: ErrorResponse, showJson: boolean) { } return ( - - {error.code && ( - - Code - {error.code} - - )} - {error.message && ( - - Message - {error.message} - - )} - {error.target && ( - - Target - {error.target} - - )} - {error.details && ( - - Details - {error.details.map((x) => getError(x, showJson))} - - )} - + + + {error.code && ( + + Code + {error.code} + + )} + {error.message && ( + + Message + {error.message} + + )} + {error.target && ( + + Target + {error.target} + + )} + {error.details && ( + + Details + {error.details.map((x) => getError(x, showJson))} + + )} + + ); } diff --git a/src/vscode-bicep/src/panes/deploy/app/components/sections/WhatIfChangesView.tsx b/src/vscode-bicep/src/panes/deploy/app/components/sections/WhatIfChangesView.tsx index c44e14c79e5..a524da75c4b 100644 --- a/src/vscode-bicep/src/panes/deploy/app/components/sections/WhatIfChangesView.tsx +++ b/src/vscode-bicep/src/panes/deploy/app/components/sections/WhatIfChangesView.tsx @@ -1,7 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { WhatIfChange, WhatIfPropertyChange } from "@azure/arm-resources"; -import { VSCodeDataGrid, VSCodeDataGridCell, VSCodeDataGridRow } from "@vscode/webview-ui-toolkit/react"; +import { + VscodeTable, + VscodeTableBody, + VscodeTableCell, + VscodeTableHeader, + VscodeTableHeaderCell, + VscodeTableRow +} from "@vscode-elements/react-elements"; import { FC } from "react"; import { FormSection } from "./FormSection"; @@ -17,26 +24,28 @@ export const WhatIfChangesView: FC = ({ changes }) => { const filteredChanges = changes.filter((x) => x.changeType !== "Ignore"); return ( - - - + + + Resource Id - - + + Change Type - - + + Changes - - - {filteredChanges.map((change) => ( - - {change.resourceId} - {change.changeType} - {getWhatIfPropertyChanges(change.delta)} - - ))} - + + + + {filteredChanges.map((change) => ( + + {change.resourceId} + {change.changeType} + {getWhatIfPropertyChanges(change.delta)} + + ))} + + ); }; @@ -48,21 +57,21 @@ function getWhatIfPropertyChanges(changes?: WhatIfPropertyChange[]) { const filteredChanges = changes.filter((x) => x.propertyChangeType !== "NoEffect"); return ( - - - + + + Path - - + + Change Type - - + + {filteredChanges.map((change) => ( - - {change.path} - {change.propertyChangeType} - + + {change.path} + {change.propertyChangeType} + ))} - + ); } diff --git a/src/vscode-bicep/src/panes/deploy/models.ts b/src/vscode-bicep/src/panes/deploy/models.ts index 02bb046e1ef..2e19a5a1bd5 100644 --- a/src/vscode-bicep/src/panes/deploy/models.ts +++ b/src/vscode-bicep/src/panes/deploy/models.ts @@ -27,8 +27,9 @@ export interface ParamData { value: ParameterValue; } -export interface DeployResult { - success: boolean; +export interface DeployState { + name?: string; + status?: "running" | "succeeded" | "failed"; error?: ErrorResponse; } diff --git a/src/vscode-bicep/src/panes/deploy/view.ts b/src/vscode-bicep/src/panes/deploy/view.ts index 4a091a7bebe..0914296ba6c 100644 --- a/src/vscode-bicep/src/panes/deploy/view.ts +++ b/src/vscode-bicep/src/panes/deploy/view.ts @@ -247,6 +247,9 @@ export class DeployPaneView extends Disposable { const scriptUri = this.webviewPanel.webview.asWebviewUri( vscode.Uri.joinPath(this.extensionUri, "out", "deployPane.js"), ); + const codiconCssUri = this.webviewPanel.webview.asWebviewUri( + vscode.Uri.joinPath(this.extensionUri, "out", "codicon.css"), + ); return ` @@ -259,6 +262,7 @@ export class DeployPaneView extends Disposable { --> +
diff --git a/src/vscode-bicep/webpack.config.ts b/src/vscode-bicep/webpack.config.ts index 44d7bc7659a..2bf9e5e6e8f 100644 --- a/src/vscode-bicep/webpack.config.ts +++ b/src/vscode-bicep/webpack.config.ts @@ -159,6 +159,12 @@ const deployPaneConfig: webpack.Configuration = { new webpack.ProvidePlugin({ React: "react", }), + new CopyPlugin({ + patterns: [ + { from: "node_modules/@vscode/codicons/dist/codicon.css", to: outputPath }, + { from: "node_modules/@vscode/codicons/dist/codicon.ttf", to: outputPath }, + ], + }), ], };