diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index cdf1edf711..91b007d17d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,3 +1,3 @@
# At least one of the code owners below will be required on each PR:
-* @markAtMicrosoft @sibille @mvegaca @dgomezc @smmatte @trevorNgo @jcoc611-microsoft @piotrmark @MehaKaushik @Tanya0609 @javieraparisivaldes
+* @sibille @mvegaca @dgomezc @trevorNgo @jcoc611-microsoft @piotrmark @MehaKaushik @Tanya0609 @javieraparisivaldes
diff --git a/README.md b/README.md
index 2d3995e122..b15de1234d 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ are merged together by [Core Template Studio](https://github.com/Microsoft/CoreT
# Documentation
- [Installing the extension](/docs/install.md)
-- [Getting started with the codebase](/docs/getting-started-developers.md)
+- [Getting started with the codebase](/docs/contributing/getting-started-developers.md)
- [Terminology for developers](/docs/terminology.md)
## SHA256
diff --git a/_build/CoreTemplateStudio.local.debug.config.json b/_build/CoreTemplateStudio.local.debug.config.json
new file mode 100644
index 0000000000..d97e5b7457
--- /dev/null
+++ b/_build/CoreTemplateStudio.local.debug.config.json
@@ -0,0 +1,26 @@
+{
+ "Environment": "WebTSDebug",
+ "CdnUrl": "",
+ "RemoteTelemetryKey": "",
+ "LogFileFolderPath": "WebTS\\Logs",
+ "CustomTelemetryEndpoint": "",
+ "RepositoryFolderName": "WebTS",
+ "BackupFolderPath": "",
+ "TempGenerationFolderPath": "WTSTempGeneration",
+ "DiagnosticsTraceLevel": "Verbose",
+ "GitHubDocsUrl": "",
+ "DaysToKeepTempGenerations": 5,
+ "DaysToKeepDiagnosticsLogs": 5,
+ "AllowedPublicKeysPins": [
+ "14CAC54E3A89855AF3F33C6C2F88E389094305F15EC3E7CC18844E8ABD4651A8992710E005DE189A313039064B082D62D41077B44BEFA4D837C1FC320083D422",
+ "51E93470FD838DFCE5F4ADF0D7750D2B66635677499A73160B9CB3BA84884A9EBA5F4E80C346323C0F61D2A8EDDC8EE5E02E7F186D13C953270F68AEB44CFE3D",
+ "8A79BF09C49440C614229A2338384348443353A4B3DBA4AD46EDC0FE1054ED220A0D3445783493869186DEADBF0D9D8627E0EAC2D37475C9EC991A0324038EA4",
+ "2A0A69F1AB9BB46A8AE3563B72702FD6CCB16ECBF669D62A7DC92D217A084E318EC8BB2AE87A4A2C6855BDB9C0F4FD93D77E802AAACDDEB795C2EF718D7D4890",
+ "3887006BEB41CEE5386343BE28289FB8D08ED52D4DCB0907FBC4624D0EA886E9295303467AD3323D98D20703CBFBDA331680B2D8D90B3A561A98C94E05E9A021",
+ "C70A54064923A7CFB68FFA0E2C4308D496CA4B56FFE5ECCC4338F4A4E87083EB881CFFC73B19FC60DC362F45D381CFEB1C719B08AB47A8BE6190D7DEB7A83834",
+ "82B4B76E0A82BCBA2DE619851CF3EB205C233BFB1A4135EC4E05329D8258DC8B30408B21B827EFF3D6008BBFBAFB115E4AD72DE66988888A44BE02CD74A4BE5F",
+ "26859EB6CDE0744E0B5DA300681265837D0B9F8CFCBB8071C914367EF5C6E14EA806BA770281F64077536C97F477BF55AE7083EEC93F0EC376DA6D357F1F6699"
+ ],
+ "AllowedPackages": [ "" ],
+ "BreakingChangesVersions": []
+}
\ No newline at end of file
diff --git a/_build/CoreTemplateStudio.local.release.config.json b/_build/CoreTemplateStudio.local.release.config.json
new file mode 100644
index 0000000000..8847198f0b
--- /dev/null
+++ b/_build/CoreTemplateStudio.local.release.config.json
@@ -0,0 +1,26 @@
+{
+ "Environment": "Local",
+ "CdnUrl": "",
+ "RemoteTelemetryKey": "",
+ "LogFileFolderPath": "WebTS\\Logs",
+ "CustomTelemetryEndpoint": "",
+ "RepositoryFolderName": "WebTS",
+ "BackupFolderPath": "",
+ "TempGenerationFolderPath": "WTSTempGeneration",
+ "DiagnosticsTraceLevel": "Verbose",
+ "GitHubDocsUrl": "",
+ "DaysToKeepTempGenerations": 5,
+ "DaysToKeepDiagnosticsLogs": 5,
+ "AllowedPublicKeysPins": [
+ "14CAC54E3A89855AF3F33C6C2F88E389094305F15EC3E7CC18844E8ABD4651A8992710E005DE189A313039064B082D62D41077B44BEFA4D837C1FC320083D422",
+ "51E93470FD838DFCE5F4ADF0D7750D2B66635677499A73160B9CB3BA84884A9EBA5F4E80C346323C0F61D2A8EDDC8EE5E02E7F186D13C953270F68AEB44CFE3D",
+ "8A79BF09C49440C614229A2338384348443353A4B3DBA4AD46EDC0FE1054ED220A0D3445783493869186DEADBF0D9D8627E0EAC2D37475C9EC991A0324038EA4",
+ "2A0A69F1AB9BB46A8AE3563B72702FD6CCB16ECBF669D62A7DC92D217A084E318EC8BB2AE87A4A2C6855BDB9C0F4FD93D77E802AAACDDEB795C2EF718D7D4890",
+ "3887006BEB41CEE5386343BE28289FB8D08ED52D4DCB0907FBC4624D0EA886E9295303467AD3323D98D20703CBFBDA331680B2D8D90B3A561A98C94E05E9A021",
+ "C70A54064923A7CFB68FFA0E2C4308D496CA4B56FFE5ECCC4338F4A4E87083EB881CFFC73B19FC60DC362F45D381CFEB1C719B08AB47A8BE6190D7DEB7A83834",
+ "82B4B76E0A82BCBA2DE619851CF3EB205C233BFB1A4135EC4E05329D8258DC8B30408B21B827EFF3D6008BBFBAFB115E4AD72DE66988888A44BE02CD74A4BE5F",
+ "26859EB6CDE0744E0B5DA300681265837D0B9F8CFCBB8071C914367EF5C6E14EA806BA770281F64077536C97F477BF55AE7083EEC93F0EC376DA6D357F1F6699"
+ ],
+ "AllowedPackages": [ "38B3095D8E46591DB6BDF8A6C9816AA50AF486124649F23B86306482B8C62EA5" ],
+ "BreakingChangesVersions": []
+}
\ No newline at end of file
diff --git a/_build/Extension-ReplaceNames.ps1 b/_build/Extension-ReplaceNames.ps1
new file mode 100644
index 0000000000..795e56e8e6
--- /dev/null
+++ b/_build/Extension-ReplaceNames.ps1
@@ -0,0 +1,56 @@
+[CmdletBinding()]
+Param(
+ [Parameter(Mandatory=$True,Position=1)]
+ [string]$vsixPackageJson,
+
+ [Parameter(Mandatory=$True,Position=2)]
+ [string]$vsixName,
+
+ [Parameter(Mandatory=$True,Position=3)]
+ [string]$vsixDisplayName,
+
+ [Parameter(Mandatory=$True,Position=4)]
+ [string]$versionNumber,
+
+ [Parameter(Mandatory=$True,Position=5)]
+ [string]$aikey
+)
+function Clear-WhiteSpace ($Text) {
+ "$($Text -replace "(`t|`n|`r)"," " -replace "\s+"," ")".Trim()
+}
+
+## SET NAME AND VERSION IN VSIX Package json
+if($vsixName){
+ Write-Host
+ Write-Host "Setting name and version in VSIX package json"
+
+ if(Test-Path($vsixPackageJson)){
+ $packagejsonContent = Get-Content $vsixPackageJson | ConvertFrom-Json
+ $LocalIdentity = $packagejsonContent.name
+ $localDisplayName = $packagejsonContent.displayName
+ $localVersionNumber = $packagejsonContent.version
+ $localAiKey = $packagejsonContent.aiKey
+
+ Write-Host "Replacing $LocalIdentity by $vsixName"
+ Write-Host "Replacing $localDisplayName by $vsixDisplayName"
+ Write-Host "Replacing $localVersionNumber by $versionNumber"
+
+ $content = (Get-Content -path $vsixPackageJson -Raw)
+
+ $content = $content -replace "$LocalIdentity" , "$vsixName"
+ $content = $content -replace [regex]::Escape("$localDisplayName") , "$vsixDisplayName"
+ $content = $content -replace "$localVersionNumber" , "$versionNumber"
+ $content = $content -replace "$localAiKey" , "$aikey"
+
+ [System.IO.File]::WriteAllLines($vsixPackageJson, $content, [System.Text.UTF8Encoding]($False))
+
+ Write-Host "$resolvedPath - Version, Name & DisplayName applied ($versionNumber, $vsixName, $vsixDisplayName)"
+ }
+ else{
+ throw "No VSIX package json file found."
+ }
+}
+else{
+ throw "Identity is mandatory."
+}
+
diff --git a/_build/build-all.sh b/_build/build-all.sh
new file mode 100644
index 0000000000..431015acab
--- /dev/null
+++ b/_build/build-all.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# This script installs and builds the client and cli and copies the output to the extensions folder
+
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+# Build the client
+sh ./build-client.sh
+
+# Build the cli in debug
+sh ./build-coretscli.sh "debug"
+
+# Build the extension
+sh ./build-extension.sh
\ No newline at end of file
diff --git a/_build/build-client.sh b/_build/build-client.sh
new file mode 100644
index 0000000000..d39329528c
--- /dev/null
+++ b/_build/build-client.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# This script installs client dependencies and builds the client and copies the output to the extensions react folder
+
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+echo -e "${magenta}Installing client dependencies ${nc}"
+echo
+yarn --cwd ../src/client install
+echo
+
+echo -e "${magenta}Building client ${nc}"
+echo
+yarn --cwd ../src/client build
+
+
diff --git a/_build/build-coretscli-and-client.sh b/_build/build-coretscli-and-client.sh
new file mode 100644
index 0000000000..d4aea077bb
--- /dev/null
+++ b/_build/build-coretscli-and-client.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This script installs and builds the client and cli and copies the output to the extensions folder
+
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+# Build the client
+sh ./build-client.sh
+
+# Build the cli in debug
+sh ./build-coretscli.sh "debug"
diff --git a/_build/build-coretscli.sh b/_build/build-coretscli.sh
new file mode 100644
index 0000000000..4c6a38951c
--- /dev/null
+++ b/_build/build-coretscli.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+# This script builds the cli as a selfconatined executable and copies the output to the extensions corets-cli folders for mac, linux and windows
+
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+if [ ! -z "$1" ] && ([ "$1" == "release" ] || [ "$1" == "debug" ]); then # Check if release was passed as parameter, else ignore it
+
+ rm -rf ../src/extension/src/corets-cli/win32/
+ rm -rf ../src/extension/src/corets-cli/linux/
+ rm -rf ../src/extension/src/corets-cli/darwin/
+
+ configuration=$1
+
+ echo -e "${magenta}Building and publishing cli in configuration $configuration ${nc}"
+ echo
+
+ dotnet publish ../src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c $configuration -r win-x64 --self-contained true -o ../src/extension/src/corets-cli/win32/
+ dotnet publish ../src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c $configuration -r linux-x64 --self-contained true -o ../src/extension/src/corets-cli/linux/
+ dotnet publish ../src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c $configuration -r osx-x64 --self-contained true -o ../src/extension/src/corets-cli/darwin/
+
+
+ echo -e "${magenta}Copy config file $configuration ${nc}"
+ cp -v CoreTemplateStudio.local.$configuration.config.json ../src/extension/src/corets-cli/win32/CoreTemplateStudio.config.json
+ cp -v CoreTemplateStudio.local.$configuration.config.json ../src/extension/src/corets-cli/linux/CoreTemplateStudio.config.json
+ cp -v CoreTemplateStudio.local.$configuration.config.json ../src/extension/src/corets-cli/darwin/CoreTemplateStudio.config.json
+else
+ echo -e "${red}Invalid parmeter $1, expected values: 'debug' or ' release' for build configuration.${nc}"
+fi
+
+
+
+
+
diff --git a/_build/build-extension.sh b/_build/build-extension.sh
new file mode 100644
index 0000000000..19c08908c3
--- /dev/null
+++ b/_build/build-extension.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# This script installs extension dependencies and builds the extension
+
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+echo -e "${magenta}Installing extension dependencies ${nc}"
+echo
+yarn --cwd ../src/extension install
+echo
+
+echo -e "${magenta}Building extension ${nc}"
+echo
+yarn --cwd ../src/extension build
+
+
diff --git a/_build/createLocalVsix.sh b/_build/createLocalVsix.sh
new file mode 100644
index 0000000000..339cf42e13
--- /dev/null
+++ b/_build/createLocalVsix.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+# This script builds the client, the cli (in release) and the extension and generates a vsix
+magenta='\033[0;35m'
+red='\033[0;31m'
+nc='\033[0m'
+
+# Build the client
+sh ./build-client.sh
+
+# Build the cli in release
+sh ./build-coretscli.sh "release"
+
+# Create vsix package
+echo -e "${magenta}Creating vsix package ${nc}"
+echo
+yarn --cwd ../src/extension createVsixPackage && echo -e "${magenta}vsix file is now available in root/dist/ ${nc}"
diff --git a/build b/build
deleted file mode 100755
index d7fdebd5c1..0000000000
--- a/build
+++ /dev/null
@@ -1,8 +0,0 @@
-yarn --cwd ./src/client install
-yarn --cwd ./src/client build
-yarn --cwd ./src/extension install
-yarn --cwd ./src/extension build
-
-dotnet publish src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c debug -r win-x64 --self-contained true -o src/extension/src/corets-cli/win32/
-dotnet publish src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c debug -r linux-x64 --self-contained true -o src/extension/src/corets-cli/linux/
-dotnet publish src/CoreTemplateStudio/code/src/CoreTemplateStudio/CoreTemplateStudio.Cli/CoreTemplateStudio.Cli.csproj -c debug -r osx-x64 --self-contained true -o src/extension/src/corets-cli/darwin/
\ No newline at end of file
diff --git a/createVsix b/createVsix
deleted file mode 100755
index dc56961577..0000000000
--- a/createVsix
+++ /dev/null
@@ -1,7 +0,0 @@
-./build || bash build
-yarn --cwd ./src/extension createVsixPackage
-RED='\033[0;31m'
-CYAN='\033[0;36m'
-GREEN='\033[0;32m'
-NC='\033[0m'
-echo -e "\n${GREEN}wts.vsix${NC} is now built in ${RED}root/dist/${NC} and is ready for distribution.\n"
diff --git a/docs/contributing/getting-started-developers.md b/docs/contributing/getting-started-developers.md
new file mode 100644
index 0000000000..8c1989b23e
--- /dev/null
+++ b/docs/contributing/getting-started-developers.md
@@ -0,0 +1,146 @@
+# Getting started developers (to contribute to Web Template Studio)
+
+If you are authoring templates for Web Template Studio, or interested in contributing to this repo, then you are likely interested in how to use the latest version of this code.
+
+This document covers:
+- Prerequisites
+- Project folder structure
+- Core Template Studio Submodule
+- How to run the extension locally
+- How to develop the client
+- How to built a local vsix
+
+Before starting make sure you read the [Web Template Studio arquitecture](application-architecture.md) document.
+
+If you just want to take advantage from Web Template Studio extension, check the [Web Template Studio Installation Instructions page](../install.md).
+
+## Prerequisites
+
+1. Install [Node.js](https://nodejs.org/en/download/)
+2. Install [Gulp](https://gulpjs.com/)
+3. Install [Git](https://git-scm.com/downloads)
+4. Install [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1)
+5. Install [Visual Studio Code](https://code.visualstudio.com/)
+6. Install [Yarn](https://yarnpkg.com/en/docs/install). You will need to finish installing Node.js before you install Yarn.
+7. Run the command `npm config set scripts-prepend-node-path true`. This tells VSCode which Node version to run during the extension compilation (otherwise you'll get an error during the build process).
+
+_Note: If using Windows, use Git Bash_.
+
+## Project folder structure
+
+### src folder
+This folder contains the source code for the different components of Web Template Studio.
+
+- client: This folder contains the client or wizard code.
+ - src:
+ - Assets: Assets directory contains all the SVGs used for the front-end.
+ - Components: Components contains all React components that are not connected to the Redux store.
+ - Containers: Containers are React components that are connected to the Redux store. This is the only difference between components and containers.
+ - CSS: CSS contains styling that is global.
+ - Store: Store contains the folder structure of the final store, each folder contains the next files
+ - Reducer: Reducers for the Redux store are defined here.
+ - Selector: Selectors contain helper methods which takes the Redux store as an argument and returns a specific field.
+ - Action: Actions for the Redux store
+ - Model: Interfaces for actions, reducers and selectors.
+
+
+- extension: This folder contains the Visual Studio extensions code.
+ - src:
+ - Azure: contains all functionality related to azure services
+ - client-modules: contains the client-modules that allow client-extension communication
+ - telemetry: contains all functionality related to telemetry
+ - utils: contains helper functions as logger and validators
+
+- CoreTemplateStudio: This solution contains the Core Template Studio code.
+
+For more information on internal structure, see [Core Template Studio docs](https://github.com/microsoft/CoreTemplateStudio/blob/dev/docs/getting-started-developers.md).
+
+### _build folder
+This folder contains scripts for local development and usage from the build pipeline.
+
+### templates folder
+This folder contains the templates that are used to generate the code. For more info on templates see [Understanding the Templates](templates.md).
+
+## Core Template Studio Submodule
+Web Template Studio relies on Core Template Studio for template synchronization and template composition, generation and postaction. Core Template Studio has its [own Github repository](github.com/Microsoft/CoreTemplateStudio) as it is shared with the sister project [Windows Template Studio](github.com/Microsoft/WindowsTemplateStudio).
+
+Core Template Studio is integrated into Web Template Studio using a git submodule under the folder [CoreTemplateStudio](../src/CoreTemplateStudio). The submodule points to a specific commit in Core Template Studio, that you can see in github:
+
+![Core Template Studio Submodule](../resources/corets-submodule.png)
+
+### Init /update
+When you clone Web Template Studio you have to run two commands: `git submodule init` and `git submodule update` to fetch all the data from Core Template Studio. When fetching changes, also execute `git submodule update` after doing git fetch to be sure you're submodule is up to date.
+
+### Update with remote changes
+Changes on Core Template Studio should be done on the Core Template Studio repos. In WebTS, to update the submodule to the most recent commit, you have to run the command: `git submodule update --remote`.
+
+## Run the extension locally
+1. Run `./build-all.sh` from the _build folder. This script installs dependencies and compiles the client and core template studio and copies it to the extension. It also builds and installs the extension. There are also separate scripts for building the client (build-client.sh), the Core Template Studio Cli (build-coretscli.sh), or the extension (build-extension.sh) available.
+2. Open the `src/extension` folder using `VSCode`.
+3. Start the debugger by pressing `F5`. This should open the Extension Development Host in a new Visual Studio Code window.
+4. In the Extension Development Host, press `Ctrl + Shift + P` on Windows/Linux or `Command ⌘ + Shift + P` to open the Command Palette.
+5. In the Command Palette, type `Web Template Studio: Launch` and press `Enter` to launch the extension. Make sure that you don't have the Web Template Studio from the marketplace installed, concurrent installation is nor yet supported.
+
+## Developing the client
+As the client is injected as a static web app in the webview of the extension, debugging inside the extension can be challenging. Running the client in a browser is useful for quickly testing HTML or CSS changes and for debugging since you can use Chrome extensions such as React and Redux developer tools.
+
+When running in the browser communication with the extension is done agains the mock mockVsCodeApi.ts in the mockData folder. Note that the behavior of on the browser may differ from the behavior in the extension so make sure to test out both.
+
+1. Run `./build-client.sh` from the _build folder.
+2. Open the `src/client` folder using `VSCode`.
+3. Start the client using `yarn start` to begin development in the browser. We recommend using a chromium based browser such as Chrome.
+
+More info:
+- React Developer Tools: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
+- Redux DevTools: https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd
+
+### To debug from Visual Studio Code:
+Install [Debugger for Chrome extension](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) in Visual Studio Code debug Wizard Client.
+After starting the client using `yarn start` in VSCode Debug View (Ctrl+Shift+D) select "Debug WebTS Client" and start debugging (F5)
+
+More info:
+- https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome
+- https://code.visualstudio.com/docs/editor/debugging
+
+## Create VSIX Package
+Run `./createLocalVsix.sh` from the _build folder.
+
+The script will compile the client, CoreTS (in release mode) and the extension and package the extension into the root directory `/dist` folder. The vsix package can be distributed and installed by anyone who has VSCode using the command in the extension directory:
+
+```
+code --install-extension [extensionName].vsix
+```
+
+`webts-0.0.0-UNTRACKEDVERSION.vsix` is the default extensionName.
+
+Alternatively, the extension can be installed from the context menu of the extension section in Visual Studio code using the "install from VSIX..." command. The installed vsix package can be found in the extensions folder. For _Windows_, it is `%USERPROFILE%\.vscode\extensions`. For _Mac/Linux_, it is `~/.vscode/extensions` (By Default).
+
+After installation, use `ctrl+shift+p (Windows)` or `cmd+shift+p (Mac)` to open the Extension Launcher and select `Web Template Studio: Launch` to run the extension.
+
+## Tests
+
+### Client Tests
+Currently, we use Jest and React Testing Library for our unit tests which was set up by create-react-app.
+
+To run the client tests, go to src/client and run `yarn test` to run all the tests. Running this execute tests in files that end with *.{spec,test}.{js,jsx,ts,tsx}.
+
+More info:
+- Jest: https://jestjs.io/
+- React Testing Library: https://testing-library.com/docs/react-testing-library/intro
+
+### Template Tests
+Currently we use scripts to test the generated code. The scripts are located in the folder ..\src\extension\src\scripts.
+Ther genrate-tests script generates all the different permutations of a fullstack project (without azure services).
+Afterwards the run-tests script installes the dependencies for the generated project, runs yarn start, yarn lint and yarn test on all the generated projects.
+
+To run the template tests go to src/extension and run `yarn template-test` to run the tests.
+
+
+## Under the Hood
+
+The following notes are inspired by the [vscode-webview-react](https://github.com/rebornix/vscode-webview-react)
+repository by [rebornix](https://github.com/rebornix):
+
+- We inline `index.html` content in `src/extension/src/extension.ts` when creating the webview
+- For all resources going to the webview, their scheme is `vscode-resource`
+- We add a baseUrl `` and then all relative paths work.
diff --git a/docs/contributing/templates.md b/docs/contributing/templates.md
new file mode 100644
index 0000000000..9d3f2d1add
--- /dev/null
+++ b/docs/contributing/templates.md
@@ -0,0 +1,35 @@
+# Understanding the Templates
+
+Templates are used to generate the code. In Web Template Studio we have the following kinds of templates: Frameworks, Projects Types, Pages and Features.
+
+For example, consider the following scenarios:
+
+- **Scenario #1**: you want to generate a project to create a target web app which uses the React on the frontend and Node on the backend, with some pages (Home, Products -a master detail page-, Todo -a list page-, etc. ) and including some extra features like Azure App Service and Cosmos DB...
+- **Scenario #2**: you want to create as in *Scenario #1* but with Angular as frontend framework and without CosmosDB support.
+
+The Web Template Studio allow you to combine different templates to generate the project you want, using your preferred framework, and using the features you most like. Moreover, the templates available in Web Template Studio are extensible.
+
+## Interested in contributing
+
+Do you want to contribute? Here are our [contribution guidelines](../CONTRIBUTING.md).
+
+## Anatomy of Templates and Template Authoring
+
+For more info about how templates work see [Core Template Studio](https://github.com/microsoft/CoreTemplateStudio/tree/dev/docs/templates.md)
+
+## Templates repository structure
+
+The [Templates Repository](../../templates) has the following structure:
+
+- [Web](../../templates/Web): this folder contains all templates used for Web projects
+ - [_catalog](../../templates/Web/_catalog): this folder contains the catalog of available Frameworks and Project Types, including the required information and metadata (descriptions, icons, images, etc.) to be displayed in the Wizard.
+ - [_composition](../../templates/Web/_composition): this folder contains the partial code templates that will be generated when certain constraints are met, including framework specific templates.
+ - [Projects](../../templates/Web/Projects): Project templates which define the actual folder structure, source files and auxiliary files to create a base project.
+ - [Pages](../../templates/Web/Pages): Page templates define the source files needed to create a page of a certain type.
+ - [Features](../../templates/Web/Features): Feature templates with the sources required to add different features and / or capabilities to the target web app.
+
+
+## Learn more
+
+- [Templates doc in Core Template Studio](https://github.com/microsoft/CoreTemplateStudio/tree/dev/docs/tenmplates.md)
+- [All docs](./readme.md)
diff --git a/docs/deployment.md b/docs/deployment.md
deleted file mode 100644
index ae411b3da6..0000000000
--- a/docs/deployment.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Deployment
-
-After implementing your business logic, we recommend deploying your website to the cloud.
-Deploying your website to the cloud allows people to view your website by visiting a URL.
-
-## Azure App Service
-
-One way to deploy is using Azure App Service. This service will allow you to deploy and scale web, mobile and API apps.
-
-## VS Code Extension Method (Recommended)
-
-The Azure App Service Extension provides an easy way to manage and deploy your web application.
-
-1. Download the [Azure App Service Extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice).
-2. Open the project in Visual Studio Code, and run `yarn build` or `npm build`.
-3. Move the build folder into the server folder.
-4. Click the deploy button in the Azure App Service Extension.
-
-![Azure App Service Extension Deploy Button](./resources/azure-appservice-deploy-button.png)
-
-5. When prompted on which folder to deploy, select the server folder.
-6. Click yes when prompted to update your configuration to run `npm install` on the target server.
-
-![Azure App Service Extension Update Build Notification](./resources/azure-appservice-update-build-notification.png)
-
-7. If you are using a Cosmos Database add the Cosmos Keys in the .env file to the Application Settings of your Azure App Service. To run the app in production mode set the variable NODE_ENV to production in your Application Settings. You can add an Application Setting by right clicking the Application Settings tab in the Azure App Service Extension.
-
-![Azure App Service Extension Application Settings](./resources/azure-appservice-application-settings.png)
-
-8. Consider adding authentication and securing back-end APIs by following [Azure App Service Security](https://docs.microsoft.com/en-us/azure/app-service/overview-security).
-
-## Local Git Deployment Method
-
-This method will require you to have [git](https://git-scm.com/downloads) installed on your computer.
-
-#### Creating the App Service through the Azure Portal
-
-- Go to the [Azure Portal](https://portal.azure.com) and click on the _App Services_ button.
-
- ![Portal image the button is on the left](./resources/azure-appservice-portal.png)
-
-- Click on the _Add_ button in the new window that appears.
-
- ![Portal image the add button is on the top left](./resources/azure-appservice-add.png)
-
-- Click the _web app_ button.
-
- ![Portal image click webapp](./resources/azure-appservice-click-webapp.png)
-
-- You will be presented with another screen on which you should click _create_.
-
- ![Portal image click create](./resources/azure-appservice-click-create.png)
-
-- Another screen will appear in which you are required to do the following actions:
-
-1. Enter the name of the website in the _app name_ field.
-2. Select a subscription.
-3. Create a resource group or use an existing one.
-4. Select the publish _code_ option.
-5. If no _app service_ exists create an _app service_ on this screen (costs money but required if one doesn't already exist).
- 1. Click on the _App service_ button and you will be to create a new app service.
- 2. If creating an _app service_ name it and select a location, and finally select the tier you want.
-
-![Portal image create resource](./resources/azure-appservice-createresource.png)
-
-6. Click create resource.
-
-![Portal image create resource create button](./resources/azure-appservice-createadd.png)
-
-- After clicking create you will get a notification. Click the bell icon on the top right to view notifications, then click the _go to resource_ button.
-
-![Portal image go to resource](./resources/azure-appservice-notification.png)
-
-You now have an app service resource in the cloud, where you can upload your web application.
-
-#### Deploying the website to the App Service
-
-To be able to deploy your web application, you will need to do the following set of commands in either _terminal_ or _git bash_. **Note: you must be in the root of your generated project's directory**.
-
-![Root directory of generated project](./resources/azure-appservice-rootdirectory.png)
-
-`npm install && npm build` or `yarn install && yarn build`
-
-You should then have a build folder in the root directory. Run the following command to move the production build of your client side into the server folder. Doing so will remove any prior builds.
-
-`rm -rf server/build && mv build/ server/`
-
-You will then want to `git init` to make the root directory a local git repository.
-
-Finally, run the following command to create a .deployment file with the proper parameters.
-
-```
-echo "[config]
-project=server" > .deployment
-```
-
-Follow the documentation created by the Azure team for [deploying with a local git repository](https://docs.microsoft.com/en-us/azure/app-service/deploy-local-git#open-azure-cloud-shell)
-
-Your newly deployed web app can be found at `.azurewebsites.net`
diff --git a/docs/generated-apps/deployment.md b/docs/generated-apps/deployment.md
new file mode 100644
index 0000000000..dd6f6803eb
--- /dev/null
+++ b/docs/generated-apps/deployment.md
@@ -0,0 +1,61 @@
+# Deployment
+
+After implementing your business logic, we recommend deploying your website to the cloud.
+Deploying your website to the cloud allows people to view your website by visiting a URL.
+
+## Azure App Service
+
+One way to deploy is using Azure App Service. This service will allow you to deploy and scale web, mobile and API apps.
+
+## Web Template Studio: Deploy App command
+
+NOTE: Make sure that the [Web Template Studio](https://marketplace.visualstudio.com/items?itemName=WASTeamAccount.WebTemplateStudio-dev-nightly) and [Azure App Service](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice) extensions are installed in visual studio code.
+
+The easiest way to deploy an application generated with Web Template Studio is to use the `Web Template Studio: Deploy Application` command. To execute this command, follow these steps:
+
+1. Open the application generated with Web Template Studio in Visual Studio Code.
+
+2. Press `Ctrl + Shift + P` on Windows/Linux or `Command ⌘ + Shift + P` to open the Command Palette.
+
+3. In the Command Palette, type `Web Template Studio: Deploy App` and press `Enter` to launch the deploy.
+
+![Web Template Studio Deploy App Command](../resources/select-webts-deploy-command.png)
+
+Web Template Studio will begin preparing the application for deployment. You can see the progress in the Visual Studio Code output. In addition, a notification will be launched for each step executed.
+
+ - It will run the `npm install` command to install all the necessary dependencies for the frontend and the backend apps.
+
+![Install Dependencies](../resources/preparing-deploy-install-dependencies.png)
+
+ - Create a Production Build: This step will creates a build directory with a production build of your frontend app.
+
+![Build project](../resources/preparing-deploy-build-project.png)
+
+ - Copy the build directory to `server/build`, so the `server` folder will contain all the necessary frontend and backend files for the deployment.
+
+![Build directory](../resources/deploy-build-directory.png)
+
+ - Web Template Studio will then automatically launch the command `Azure App Service: Deploy to Web App...`, which will be in charge of deploying the application to an Azure App Service.
+
+ - If you have added an Azure App Service when creating your application with Web Template Studio, the application already has a deployment configuration, so it will use the created Azure App Service.
+
+ - Otherwise, Visual Studio Code will ask you for the deployment directory and if you want to create a new Azure App Service or use a previously created.
+
+ **IMPORTANT**:exclamation: - Remember to select the `server` folder for deployment to be successful.
+
+![Select deploy directory](../resources/select-folder-to-deploy.png)
+
+ - Start the application deployment to Azure App Service. We can see the progress of the deployment in the output of the Azure App Service extension.
+
+![Deploying app service](../resources/deploying-azure-app-service.png)
+
+ - At the end of the deployment, Visual Studio Code shows us a notification that the deployment has been successful.
+
+![Deploying app service finished](../resources/deploying-azure-app-service-finished.png)
+
+
+More info on Azure App Service and deployment:
+
+- [Deploy the app to Azure](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-get-started-nodejs#deploy-the-app-to-azure)
+- [Azure App Service for Visual Studio Code](https://github.com/Microsoft/vscode-azureappservice)
+- [Azure App Service documentation](https://docs.microsoft.com/en-us/azure/app-service/)
diff --git a/docs/generated-apps/services/azure-appservice.md b/docs/generated-apps/services/azure-appservice.md
index 8166a20e34..3607b63b2e 100644
--- a/docs/generated-apps/services/azure-appservice.md
+++ b/docs/generated-apps/services/azure-appservice.md
@@ -17,10 +17,21 @@ To create an Azure App Service using Web Template Studio:
- Enter a _Name_ for your azure web app. Enter a unique app name that includes only the valid characters, those are a-z, A-Z, 0-9, and -. Alternatively, you can accept the automatically generated unique name. The URL of the web app is `http://.azurewebsites.net`, where `` is your app name.
-_**Note:**_ by default, Web Template Studio creates a Resource Group with the same name as the web app. It will also create the free BASIC App Service Plan that hosts the web app. [More info for App Service Plans](https://azure.microsoft.com/en-us/pricing/details/app-service/plans/).
-
![azure-appservice-card](../../resources/azure-appservice-createappservice.png)
+### Advanced mode
+
+By default, Web Template Studio deploys the App Service in the location Central US and creates a Resource Group with the same name as the web app. It will also create the free BASIC App Service Plan that hosts the web app. [More info for App Service Plans](https://azure.microsoft.com/en-us/pricing/details/app-service/plans/).
+
+We can change these settings using the advanced mode. To display the advanced mode, click on the "advanced mode" button and the App Service modal will show two new configuration options.
+
+![azure-appservice-card](../../resources/azure-appservice-createappservice-advanced-mode.png)
+
+- Location: Azure region where the App Service will be deployed. Central US is selected by default. [More info about Azure Locations](https://azure.microsoft.com/en-us/global-infrastructure/regions/).
+
+- Resource Group: A resource group is a container that holds related resources for an Azure solution. If we want to deploy the App Service in any resource group that you have created in the Azure Subscription previously, we can select it in the dropdown. If you don't select any resource group, it will be created in a new Resource Group with the same name as the web app.
+
+## Creating App Service
Once you hit generate on the summary page, Web Template Studio will create an Azure App Service that will be accessible from `http://.azurewebsites.net`.
Web Template Studio uses an arm-template for Azure App Services (generated under the arm-templates directory). This template contains the definitions and parameters for all resources that need to deploy. Once Azure receives your template, it takes about 2-3 minutes to create the App Service and the App Service Plan. The app service initially contains an empty web app.
diff --git a/docs/generated-apps/services/azure-cosmos.md b/docs/generated-apps/services/azure-cosmos.md
index f9171413de..53de025176 100644
--- a/docs/generated-apps/services/azure-cosmos.md
+++ b/docs/generated-apps/services/azure-cosmos.md
@@ -25,6 +25,20 @@ To deploy Cosmos DB using Web Template Studio:
![azure-cosmos-modal](../../resources/azure-cosmos-modal.png)
+### Advanced mode
+
+By default, Web Template Studio deploys the Cosmos DB in the location Central US and creates a Resource Group with the same name as the web app.
+
+We can change these settings using advanced mode. To display the advanced mode, click on the "advanced mode" button and the Cosmos DB modal will show two new configuration options.
+
+![azure-cosmos-modal](../../resources/azure-cosmos-modal-advanced-mode.png)
+
+- Location: Azure region where the Cosmos DB will be deployed. Central US is selected by default. [More info about Azure Locations](https://azure.microsoft.com/en-us/global-infrastructure/regions/).
+
+- Resource Group: A resource group is a container that holds related resources for an Azure solution. If you want to deploy the Cosmos DB in any resource group that you have created in the Azure Subscription previously, you can select it in the dropdown. If you don't select any resource group, it will be created a new Resource Group with the same name as the web app.
+
+## Creating Cosmos DB
+
Once you hit generate on the summary page, Web Template Studio will deploy your database and display a popup with your
database connection string once it's available (usually within 5-6 minutes). This will prompt you to replace the
connection string in your _.env_ file with the new connection string. _**Note:**_ For advanced users, the _arm templates_
diff --git a/docs/getting-started-developers.md b/docs/getting-started-developers.md
deleted file mode 100644
index 822e0db172..0000000000
--- a/docs/getting-started-developers.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Getting started with the Codebase
-
-## Prerequisites
-
-1. Install [Node.js](https://nodejs.org/en/download/)
-2. Install [Gulp](https://gulpjs.com/)
-3. Install [Git](https://git-scm.com/downloads)
-4. Install [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/2.2)
-5. Install [Visual Studio Code](https://code.visualstudio.com/)
-6. Install [Yarn](https://yarnpkg.com/en/docs/install). You will need to finish installing Node.js before you install Yarn.
-7. Run the command `npm config set scripts-prepend-node-path true`. This tells VSCode which Node version to run during the extension compilation (otherwise you'll get an error during the build process).
-
-_Note: If using Windows, use Git Bash_.
-
-## Running the Extension
-
-1. Clone the repository with `git clone https://github.com/microsoft/WebTemplateStudio.git` or `git clone git@github.com:microsoft/WebTemplateStudio.git`.
-2. The repository depends on another submodule called [CoreTemplateStudio](https://github.com/microsoft/CoreTemplateStudio). To copy dependent code from submodule, run:
-
-```
- git submodule init
- git submodule update
-```
-
-3. Run `./build`. This script compiles the client and builds the extension.
-4. Open the `src/extension` folder using `VSCode`.
-5. Start the debugger by pressing `F5`. This should open the Extension Development Host in a new Visual Studio Code window.
-6. In the Extension Development Host, press `Ctrl + Shift + P` on Windows/Linux or `Command ⌘ + Shift + P` to open the Command Palette.
-7. In the Command Palette, type `Web Template Studio: Launch` and press `Enter` to launch the extension. Make sure that you don't have the Web Template Studio from the marketplace installed, otherwise it will throw an error.
-
-## Developing the Client
-
-The client was bootstrapped using [Create-React-App with TypeScript](https://facebook.github.io/create-react-app/docs/adding-typescript).
-
-The client lives in the `src/client` directory. To run the client for development, navigate to `src/client` and use the command
-
-```
-yarn start
-```
-
-to begin development in the browser. We recommend using a chromium based browser such as Chrome.
-
-### To debug from Visual Studio Code:
-
-Install [Debugger for Chrome extension](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) in Visual Studio Code debug Wizard Client.
-
-Steps:
-
-- Use the command:
-```
-yarn start
-```
-- In VSCode Debug View (Ctrl+Shift+D) select "Debug WebTS Client" and start debugging (F5)
-
-
-More info:
-- https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome
-- https://code.visualstudio.com/docs/editor/debugging
-
-
-## Creating VSIX Package
-
-_**Note: You cannot sideload the VSIX and build/run the extension through Extension Development Host (using `F5` on VSCode) at the same time or there will be naming conflicts. The VSIX should be uninstalled first.**_
-
-The installation script `createVsix` will build the extension package (_.vsix_) for you.
-
-```
-./createVsix
-```
-
-The script will package the extension into the root directory `/dist` folder. The vsix package can be distributed and
-installed by anyone who has VSCode using the command in the extension directory:
-
-```
-code --install-extension [extensionName].vsix
-```
-
-`webts-0.0.0-UNTRACKEDVERSION.vsix` is the default extensionName.
-
-Alternatively, copy the extension into your extensions directory. For _Windows_, it is
-`%USERPROFILE%\.vscode\extensions`. For _Mac/Linux_, it is `~/.vscode/extensions` (By Default).
-
-After installation, use `ctrl+shift+p (Windows)` or `cmd+shift+p (Mac)` to open the Extension Launcher and select `Web Template Studio: Launch` to run the extension.
-
-## Running the client in the VSCode Extension
-
-To see any changes made on the client within VSCode, run the instructions shown in the `Running the extension` section to rebuild the client and the extension. The resulting changes should appear in VSCode when the extension runs.
-
-Rebuilding the client is required because the client is injected into a [VSCode Webview](https://code.visualstudio.com/api/extension-guides/webview) using the production build of the client.
-
-### Under the Hood
-
-The following notes are inspired by the [vscode-webview-react](https://github.com/rebornix/vscode-webview-react)
-repository by [rebornix](https://github.com/rebornix):
-
-- We inline `index.html` content in `src/extension/src/extension.ts` when creating the webview
-- For all resources going to the webview, their scheme is `vscode-resource`
-- We add a baseUrl `` and then all relative paths work.
diff --git a/docs/resources/azure-appservice-createappservice-advanced-mode.png b/docs/resources/azure-appservice-createappservice-advanced-mode.png
new file mode 100644
index 0000000000..7f6af74e44
Binary files /dev/null and b/docs/resources/azure-appservice-createappservice-advanced-mode.png differ
diff --git a/docs/resources/azure-appservice-createappservice.png b/docs/resources/azure-appservice-createappservice.png
index 489022ab6c..da2cfa2e1f 100644
Binary files a/docs/resources/azure-appservice-createappservice.png and b/docs/resources/azure-appservice-createappservice.png differ
diff --git a/docs/resources/azure-cosmos-modal-advanced-mode.png b/docs/resources/azure-cosmos-modal-advanced-mode.png
new file mode 100644
index 0000000000..7ad2655465
Binary files /dev/null and b/docs/resources/azure-cosmos-modal-advanced-mode.png differ
diff --git a/docs/resources/azure-cosmos-modal.png b/docs/resources/azure-cosmos-modal.png
index 00b1a59a68..96b794a770 100644
Binary files a/docs/resources/azure-cosmos-modal.png and b/docs/resources/azure-cosmos-modal.png differ
diff --git a/docs/resources/corets-submodule.png b/docs/resources/corets-submodule.png
new file mode 100644
index 0000000000..31e45433a0
Binary files /dev/null and b/docs/resources/corets-submodule.png differ
diff --git a/docs/resources/deploy-build-directory.png b/docs/resources/deploy-build-directory.png
new file mode 100644
index 0000000000..6de5f71906
Binary files /dev/null and b/docs/resources/deploy-build-directory.png differ
diff --git a/docs/resources/deploying-azure-app-service-finished.png b/docs/resources/deploying-azure-app-service-finished.png
new file mode 100644
index 0000000000..2147e52f50
Binary files /dev/null and b/docs/resources/deploying-azure-app-service-finished.png differ
diff --git a/docs/resources/deploying-azure-app-service.png b/docs/resources/deploying-azure-app-service.png
new file mode 100644
index 0000000000..39da1498dc
Binary files /dev/null and b/docs/resources/deploying-azure-app-service.png differ
diff --git a/docs/resources/preparing-deploy-build-project.png b/docs/resources/preparing-deploy-build-project.png
new file mode 100644
index 0000000000..be2e689cd1
Binary files /dev/null and b/docs/resources/preparing-deploy-build-project.png differ
diff --git a/docs/resources/preparing-deploy-install-dependencies.png b/docs/resources/preparing-deploy-install-dependencies.png
new file mode 100644
index 0000000000..81bb8bdc31
Binary files /dev/null and b/docs/resources/preparing-deploy-install-dependencies.png differ
diff --git a/docs/resources/select-folder-to-deploy.png b/docs/resources/select-folder-to-deploy.png
new file mode 100644
index 0000000000..22bb242b2b
Binary files /dev/null and b/docs/resources/select-folder-to-deploy.png differ
diff --git a/docs/resources/select-webts-deploy-command.png b/docs/resources/select-webts-deploy-command.png
new file mode 100644
index 0000000000..e249357d74
Binary files /dev/null and b/docs/resources/select-webts-deploy-command.png differ
diff --git a/sha256-staging-weekly.md b/sha256-staging-weekly.md
index 4ebd834f71..c15ecd7ada 100644
--- a/sha256-staging-weekly.md
+++ b/sha256-staging-weekly.md
@@ -1,3 +1,3 @@
-Version: 0.1.1934601
+Version: 0.2.2007701
-sha256: DF6AE6F0BAB4A47A681F57D135C1127CCD320028527CB2DA8E20FCFE5E1A52AB
+sha256: BFB858315A674075AF7E653A04BAE5DF5E5879DE450462D6529EF933A9E7DFB3
diff --git a/src/CoreTemplateStudio b/src/CoreTemplateStudio
index 8e0d4f60eb..c9ce876b69 160000
--- a/src/CoreTemplateStudio
+++ b/src/CoreTemplateStudio
@@ -1 +1 @@
-Subproject commit 8e0d4f60ebc19054c859e4f6f38566681266a998
+Subproject commit c9ce876b69dfeb5b26ed478cc8e7775ce91bd8d8
diff --git a/src/client/.prettierrc.js b/src/client/.prettierrc.js
new file mode 100644
index 0000000000..bdd2fa4a39
--- /dev/null
+++ b/src/client/.prettierrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+ printWidth: 120,
+ tabWidth: 2,
+ trailingComma: "es5",
+ };
\ No newline at end of file
diff --git a/src/client/package.json b/src/client/package.json
index c11a4a414e..8b3d18e483 100644
--- a/src/client/package.json
+++ b/src/client/package.json
@@ -3,45 +3,42 @@
"version": "0.1.0",
"private": true,
"dependencies": {
- "@testing-library/react": "^9.4.0",
+ "@testing-library/react": "^10.0.3",
"@testing-library/react-hooks": "^3.2.1",
- "@types/classnames": "^2.2.7",
- "@types/jest": "23.3.13",
- "@types/lodash": "^4.14.121",
+ "@types/classnames": "^2.2.10",
+ "@types/jest": "^25.2.1",
+ "@types/lodash": "^4.14.150",
"@types/node": "10.12.19",
"@types/node-fetch": "^2.1.6",
- "@types/react": "16.7.22",
- "@types/react-dom": "16.0.11",
+ "@types/react": "^16.9.34",
+ "@types/react-dom": "^16.9.6",
"@types/react-intl": "^2.3.17",
+ "@types/react-loadable": "^5.5.3",
"@types/react-modal": "^3.8.1",
- "@types/react-redux": "^7.0.1",
- "@types/react-router": "^4.4.3",
- "@types/react-router-dom": "^4.3.1",
- "@types/react-select": "^2.0.11",
- "@types/react-sortable-hoc": "^0.6.5",
- "@types/redux-thunk": "^2.1.0",
+ "@types/react-redux": "^7.1.7",
+ "@types/react-select": "^3.0.11",
+ "@types/react-sortable-hoc": "^0.7.1",
"@types/reselect": "^2.2.0",
"classnames": "^2.2.6",
- "focus-visible": "^5.0.2",
- "global": "^4.3.2",
+ "focus-visible": "^5.1.0",
+ "global": "^4.4.0",
"latest-version": "^5.1.0",
- "lodash": "^4.17.14",
+ "lodash": "^4.17.15",
"node-fetch": "^2.3.0",
- "npm": "^6.13.6",
- "react": "^16.7.0",
- "react-dom": "^16.7.0",
+ "npm": "^6.14.4",
+ "react": "^16.13.1",
+ "react-dom": "^16.13.1",
"react-intl": "^2.8.0",
- "react-markdown": "^4.0.6",
+ "react-loadable": "^5.5.0",
+ "react-markdown": "^4.3.1",
"react-modal": "^3.8.1",
- "react-redux": "^6.0.0",
- "react-router": "^4.3.1",
- "react-router-dom": "^4.3.1",
- "react-scripts": "^3.3.0",
- "react-select": "^2.3.0",
- "react-sortable-hoc": "^1.7.1",
- "redux": "^4.0.1",
+ "react-redux": "^7.2.0",
+ "react-scripts": "^3.4.1",
+ "react-select": "^3.1.0",
+ "react-sortable-hoc": "^1.11.0",
+ "redux": "^4.0.5",
"redux-mock-store": "^1.5.4",
- "redux-thunk": "^2.3.0",
+ "redux-saga": "^1.1.3",
"reselect": "^4.0.0",
"rewire": "^4.0.1",
"typescript": "3.2.4",
@@ -53,7 +50,7 @@
"build": "yarn manage:translations && node ./scripts/build-non-split.js",
"postbuild": "rm -rf ../extension/react && mv build ../extension/react",
"manage:translations": "node scripts/manageTranslations.js",
- "test": "react-scripts test --coverage",
+ "test": "react-scripts test --env=jest-environment-jsdom-sixteen",
"eject": "react-scripts eject",
"format": "prettier --write src/**/*.{ts,tsx}",
"lint": "eslint ./src/**/*.{ts,tsx}"
@@ -68,15 +65,18 @@
"not op_mini all"
],
"devDependencies": {
- "@types/enzyme": "^3.9.3",
- "@types/enzyme-adapter-react-16": "^1.0.5",
- "@typescript-eslint/eslint-plugin": "^2.20.0",
- "@typescript-eslint/parser": "^2.20.0",
- "enzyme": "^3.9.0",
- "enzyme-adapter-react-16": "^1.13.2",
+ "@testing-library/jest-dom": "^5.5.0",
+ "@types/enzyme": "^3.10.5",
+ "@types/enzyme-adapter-react-16": "^1.0.6",
+ "@types/redux-mock-store": "^1.0.2",
+ "@typescript-eslint/eslint-plugin": "^2.29.0",
+ "@typescript-eslint/parser": "^2.29.0",
+ "enzyme": "^3.11.0",
+ "enzyme-adapter-react-16": "^1.15.2",
"eslint": "^6.8.0",
- "eslint-plugin-react": "^7.18.3",
- "eslint-plugin-react-hooks": "^2.4.0",
+ "eslint-plugin-react": "^7.19.0",
+ "eslint-plugin-react-hooks": "^3.0.0",
+ "jest-environment-jsdom-sixteen": "^1.0.3",
"react-intl-translations-manager": "^5.0.3",
"redux-mock-store": "^1.5.4"
},
diff --git a/src/client/scripts/build-non-split.js b/src/client/scripts/build-non-split.js
index d8921c54bd..546002fed8 100644
--- a/src/client/scripts/build-non-split.js
+++ b/src/client/scripts/build-non-split.js
@@ -5,7 +5,10 @@ let config = defaults.__get__('config');
config.optimization.splitChunks = {
cacheGroups: {
default: false,
- },
+ }
};
-config.optimization.runtimeChunk = false;
\ No newline at end of file
+config.optimization.runtimeChunk = false;
+
+config.output = config.output || {};
+config.output.publicPath= "";
\ No newline at end of file
diff --git a/src/client/src/App.test.tsx b/src/client/src/App.test.tsx
index 28947a35d7..3c9176477c 100644
--- a/src/client/src/App.test.tsx
+++ b/src/client/src/App.test.tsx
@@ -1,9 +1,8 @@
import * as React from "react";
import { shallow } from "enzyme";
-
import App from "./App";
-describe("App", () => {
+xdescribe("App", () => {
let props: any;
let wrapper: any;
diff --git a/src/client/src/App.tsx b/src/client/src/App.tsx
index 0abc8e6d7a..f3ebd4681e 100644
--- a/src/client/src/App.tsx
+++ b/src/client/src/App.tsx
@@ -1,325 +1,147 @@
import classnames from "classnames";
import * as React from "react";
-import { connect } from "react-redux";
-import { withRouter } from "react-router";
-import { Route, RouteComponentProps } from "react-router-dom";
-
-import PageDetails from "./containers/PageDetails";
-import PageAddPages from "./containers/PageAddPages";
-import PageNewProject from "./containers/PageNewProject";
-import CosmosResourceModal from "./containers/CosmosResourceModal";
-import Footer from "./containers/Footer";
-import Header from "./containers/Header";
-import PageReviewAndGenerate from "./containers/PageReviewAndGenerate";
-import RightSidebar from "./containers/RightSidebar";
-import RedirectModal from "./containers/RedirectModal";
-import ViewLicensesModal from "./containers/ViewLicensesModal";
-
+import { connect, useDispatch } from "react-redux";
import { ReactComponent as HomeSplashSVG } from "./assets/homeSplash.svg";
import { ReactComponent as SummarySplashSVG } from "./assets/summarySplash.svg";
import {
EXTENSION_COMMANDS,
- EXTENSION_MODULES,
ROUTES,
- DEVELOPMENT,
- BOOTSTRAP_LICENSE,
- FRAMEWORK_TYPE
+ DEVELOPMENT
} from "./utils/constants";
-import { getVSCodeApi } from "./actions/vscodeApiActions/getVSCodeApi";
-import { logIntoAzureAction } from "./actions/azureActions/logIntoAzure";
-import {
- updateOutputPathAction
-} from "./actions/wizardSelectionActions/updateProjectNameAndPath";
-import {
- setAccountAvailability,
- setAppNameAvailabilityAction,
- setSiteNameAvailabilityAction,
- IAvailabilityFromExtension
-} from "./actions/azureActions/setAccountAvailability";
-import PageAzureLogin from "./containers/PageAzureLogin";
-import { getSubscriptionData } from "./actions/azureActions/subscriptionData";
-import { setValidations } from "./actions/wizardSelectionActions/setValidations";
-import {
- updateTemplateGenerationStatusMessageAction,
- updateTemplateGenerationStatusAction
-} from "./actions/wizardInfoActions/updateGenStatusActions";
-import {
- selectPagesAction
-} from "./actions/wizardSelectionActions/selectPages";
-import { getVersionsDataAction } from "./actions/wizardInfoActions/getVersionData";
-import {
- updateDependencyInfoAction,
- IDependencyInfo
-} from "./actions/wizardInfoActions/updateDependencyInfo";
-
import appStyles from "./appStyles.module.css";
-import { startLogOutAzure } from "./actions/azureActions/logOutAzure";
-import { IVersions } from "./types/version";
-import { getVSCodeApiSelector } from "./selectors/vscodeApiSelector";
-import { IVSCodeObject } from "./reducers/vscodeApiReducer";
-import { setAzureValidationStatusAction } from "./actions/azureActions/setAzureValidationStatusAction";
-import { IServiceStatus } from "./reducers/generationStatus/genStatus";
-import { resetPagesAction } from "./actions/wizardSelectionActions/selectPages";
-import { ISelected } from "./types/selected";
-import { AppState } from "./reducers";
+import { AppState } from "./store/combineReducers";
import { IOption } from "./types/option";
-import { setPreviewStatusAction } from "./actions/wizardContentActions/setPreviewStatus";
-import { setPortAction } from "./actions/wizardContentActions/setPort";
-import { ThunkDispatch } from "redux-thunk";
-import RootAction from "./actions/ActionType";
+import Loadable from "react-loadable";
+import PageDetails from "./containers/PageDetails";
+import { NAVIGATION_MODAL_TYPES } from "./store/navigation/typeKeys";
+import RightSidebar from "./containers/RightSidebar";
import TopNavBar from "./components/TopNavBar";
-import { getPagesOptionsAction } from "./actions/wizardContentActions/getPagesOptions";
-import PageSelectFrameworks from './containers/PageSelectFrameworks';
-import { getPages, getFrameworks } from "./utils/extensionService/extensionService";
-import AppServiceModal from "./containers/AppServiceModal";
-import PostGenerationModal from "./containers/PostGenerationModal";
-import { setBackendFrameworksAction } from "./actions/wizardContentActions/setBackendFrameworks";
-import { setFrontendFrameworksAction } from "./actions/wizardContentActions/setFrontendFrameworks";
-import { parseFrameworksPayload } from "./utils/parseFrameworksPayload";
+import { setOutputPathAction } from "./store/userSelection/app/action";
+import { loadAction } from "./store/config/config/action";
+
+const PageSelectFrameworks = Loadable({
+ loader: () => import(/* webpackChunkName: "PageSelectFrameworks" */ "./containers/PageSelectFrameworks"),
+ loading:() =>
+});
+const PageAddPages = Loadable({
+ loader: () => import(/* webpackChunkName: "PageAddPages" */ "./containers/PageAddPages"),
+ loading:() =>
+});
+const PageReviewAndGenerate = Loadable({
+ loader: () => import(/* webpackChunkName: "PageReviewAndGenerate" */ "./containers/PageReviewAndGenerate"),
+ loading:() =>
+});
+const PageAzureLogin = Loadable({
+ loader: () => import(/* webpackChunkName: "PageAzureLogin" */ "./containers/PageAzureLogin"),
+ loading:() =>
+});
+const GenerationModal = Loadable({
+ loader: () => import(/* webpackChunkName: "GenerationModal" */ "./containers/GenerationModal"),
+ loading:() =>
+});
+const CosmosDbModal = Loadable({
+ loader: () => import(/* webpackChunkName: "CosmosDbModal" */ "./containers/CosmosDbModal"),
+ loading:() =>
+});
+const AppServiceModal = Loadable({
+ loader: () => import(/* webpackChunkName: "AppServiceModal" */ "./containers/AppServiceModal"),
+ loading:() =>
+});
+const ViewLicensesModal = Loadable({
+ loader: () => import(/* webpackChunkName: "ViewLicensesModal" */ "./containers/ViewLicensesModal"),
+ loading:() =>
+});
if (process.env.NODE_ENV === DEVELOPMENT) {
require("./css/themes.css");
}
-interface IDispatchProps {
- updateOutputPath: (outputPath: string) => any;
- getVSCodeApi: () => void;
- logIntoAzure: (email: string, subscriptions: []) => void;
- startLogOutToAzure: () => any;
- saveSubscriptionData: (subscriptionData: any) => void;
- setCosmosResourceAccountNameAvailability: (
- isAvailableObject: IAvailabilityFromExtension
- ) => any;
- setAppNameAvailability: (
- isAvailableObject: IAvailabilityFromExtension
- ) => any;
- setSiteNameAvailability: (
- isAvailableObject: IAvailabilityFromExtension
- ) => any;
- setValidations: (validations: any) => void;
- setAzureValidationStatus: (status: boolean) => void;
- updateTemplateGenStatusMessage: (status: string) => any;
- updateTemplateGenStatus: (isGenerated: IServiceStatus) => any;
- getVersionsData: (versions: IVersions) => any;
- updateDependencyInfo: (dependencyInfo: IDependencyInfo) => any;
- getPages: (pages: IOption[]) => any;
- selectPages: (pages: ISelected[]) => void;
- resetPageSelection: () => any;
- setPreviewStatus: (isPreview: boolean) => void;
- setPort: (port: number) => void;
- setPages: (pages: ISelected[]) => void;
- setBackendFrameworks: (frameworks: IOption[]) => any;
- setFrontendFrameworks: (frameworks: IOption[]) => any;
-}
-
interface IStateProps {
- vscode: IVSCodeObject;
frontendOptions: IOption[];
- selectedFrontend: ISelected;
- selectedBackend: ISelected;
- selectedPages: ISelected[];
- isPreview: boolean;
+ modalState: any;
+ selectedRoute: string;
}
-type Props = IDispatchProps & IStateProps & RouteComponentProps;
+type Props = IStateProps;
const App = (props: Props) => {
- const { selectedFrontend, selectedBackend, vscode, selectedPages, setPages, frontendOptions,isPreview, setFrontendFrameworks, setBackendFrameworks } = props;
+ const { frontendOptions,
+ modalState, selectedRoute } = props;
+ const [isLoaded, setIsLoaded] = React.useState(false);
+ const promisesLoading: Array = new Array();
+ const dispatch = useDispatch();
+
+ const addToPromisesList = (promise: Promise)=>{
+ promisesLoading.push(promise);
+ return promise;
+ }
+ const Header = Loadable({
+ loader: () => addToPromisesList(import(/* webpackChunkName: "Header" */ "./containers/Header")),
+ loading:() =>
+ });
+
+ const Footer = Loadable({
+ loader: () => addToPromisesList(import(/* webpackChunkName: "Footer" */ "./containers/Footer")),
+ loading:() =>
+ });
+ const PageNewProject = Loadable({
+ loader: () => addToPromisesList(import(/* webpackChunkName: "PageNewProject" */ "./containers/PageNewProject")),
+ loading:() =>
+ });
+
if (frontendOptions.length === 0){
messageEventsFromExtension();
- getFrameworksListAndSetToStore();
}
- React.useEffect(()=>{
- props.getVSCodeApi();
- },[]);
-
- React.useEffect(()=>{
- const { vscode } = props;
- vscode.postMessage({
- module: EXTENSION_MODULES.AZURE,
- command: EXTENSION_COMMANDS.GET_USER_STATUS,
- track: true
- });
- },[props.vscode]);
+ Promise.all(promisesLoading).then(()=>{
+ setIsLoaded(true);
+ })
React.useEffect(()=>{
- loadPages();
- },[selectedFrontend, selectedBackend]);
-
- function getFrameworksListAndSetToStore(){
- getFrameworks(vscode, isPreview).then((event: any)=>{
- const message = event.data;
- setFrontendFrameworks(
- parseFrameworksPayload(
- message.payload.frameworks,
- FRAMEWORK_TYPE.FRONTEND,
- message.payload.isPreview
- )
- );
- setBackendFrameworks(
- parseFrameworksPayload(
- message.payload.frameworks,
- FRAMEWORK_TYPE.BACKEND,
- message.payload.isPreview
- )
- );
- });
- }
-
- const loadPages = () => {
- getPages(vscode, selectedFrontend.internalName, selectedBackend.internalName).then((event)=>{
- props.getPages(event.data.payload.pages);
- selectedPages.map((selectedPage)=>{
- selectedPage.internalName = `wts.Page.${selectedFrontend.internalName}.${selectedPage.defaultName ? selectedPage.defaultName.replace(" ",""):""}`;
- });
- setPages(selectedPages);
- });
- }
+ dispatch(loadAction());
+ },[]);
function messageEventsFromExtension(){
window.addEventListener("message", event => {
const message = event.data;
switch (message.command) {
- case EXTENSION_COMMANDS.GET_DEPENDENCY_INFO:
- props.updateDependencyInfo(message.payload);
- break;
case EXTENSION_COMMANDS.GET_OUTPUT_PATH:
if (message.payload !== null && message.payload.outputPath !== undefined) {
- props.updateOutputPath(message.payload.outputPath);
- }
- break;
- case EXTENSION_COMMANDS.GET_USER_STATUS:
- case EXTENSION_COMMANDS.AZURE_LOGIN:
- // email will be null or undefined if login didn't work correctly
- if (message.payload !== null) {
- props.logIntoAzure(
- message.payload.email,
- message.payload.subscriptions
- );
- }
- break;
- case EXTENSION_COMMANDS.AZURE_LOGOUT:
- // Update UI only if user sign out is confirmed by the extension
- if (message.payload) {
- props.startLogOutToAzure();
- }
- break;
- case EXTENSION_COMMANDS.SUBSCRIPTION_DATA_FUNCTIONS:
- case EXTENSION_COMMANDS.SUBSCRIPTION_DATA_COSMOS:
- case EXTENSION_COMMANDS.SUBSCRIPTION_DATA_APP_SERVICE:
- // Expect resource groups and locations on this request
- // Receive resource groups and locations
- // and update redux (resourceGroups, locations)
- if (message.payload !== null) {
- props.saveSubscriptionData({
- locations: message.payload.locations,
- resourceGroups: message.payload.resourceGroups,
- validName: message.payload.validName
- });
+ dispatch(setOutputPathAction(message.payload.outputPath));
}
break;
- case EXTENSION_COMMANDS.NAME_COSMOS:
- // Receive input validation
- // and update redux (boolean, string)
- props.setCosmosResourceAccountNameAvailability({
- isAvailable: message.payload.isAvailable,
- message: message.payload.reason
- });
- props.setAzureValidationStatus(false);
- break;
- case EXTENSION_COMMANDS.NAME_FUNCTIONS:
- props.setAppNameAvailability({
- isAvailable: message.payload.isAvailable,
- message: message.payload.reason
- });
- props.setAzureValidationStatus(false);
- break;
- case EXTENSION_COMMANDS.NAME_APP_SERVICE:
- props.setSiteNameAvailability({
- isAvailable: message.payload.isAvailable,
- message: message.payload.reason
- });
- props.setAzureValidationStatus(false);
- break;
- case EXTENSION_COMMANDS.GEN_STATUS_MESSAGE:
- props.updateTemplateGenStatusMessage(message.payload.status);
- break;
- case EXTENSION_COMMANDS.GEN_STATUS:
- props.updateTemplateGenStatus(message.payload);
- break;
- case EXTENSION_COMMANDS.GET_TEMPLATE_INFO:
- const versionData: IVersions = {
- templatesVersion:message.payload.templatesVersion,
- wizardVersion: message.payload.wizardVersion
- };
- props.getVersionsData(versionData);
- props.setValidations({
- itemNameValidationConfig:message.payload.itemNameValidationConfig,
- projectNameValidationConfig:message.payload.projectNameValidationConfig
- });
- break;
- case EXTENSION_COMMANDS.RESET_PAGES:
- if (message.payload.resetPages) {
- props.resetPageSelection();
-
- // select default blank page
- const PAGES_SELECTION: ISelected[] = [
- {
- title: "Blank",
- internalName: `wts.Page.${message.payload.internalName}.Blank`,
- id: "Blank",
- defaultName: "Blank",
- isValidTitle: true,
- licenses: [
- {
- text: "Bootstrap",
- url: BOOTSTRAP_LICENSE
- }
- ],
- author: "Microsoft"
- }
- ];
- props.selectPages(PAGES_SELECTION);
- }
- break;
- case EXTENSION_COMMANDS.GET_PREVIEW_STATUS:
- props.setPreviewStatus(message.payload.preview);
- break;
}
});
}
- const { pathname } = props.location;
return (
-
-
+ {isLoaded && ()}
+ {isLoaded && ()}
-