diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e233f60..325e626 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,11 +18,15 @@ jobs:
with:
dotnet-version: 8.0.x
+ - name: Install WASM workload
+ run: dotnet workload install wasm-tools
+
- name: Restore dependencies
run: |
dotnet restore src/PlanViewer.Core/PlanViewer.Core.csproj
dotnet restore src/PlanViewer.App/PlanViewer.App.csproj
dotnet restore src/PlanViewer.Cli/PlanViewer.Cli.csproj
+ dotnet restore src/PlanViewer.Web/PlanViewer.Web.csproj
dotnet restore tests/PlanViewer.Core.Tests/PlanViewer.Core.Tests.csproj
- name: Build all projects
@@ -30,6 +34,7 @@ jobs:
dotnet build src/PlanViewer.Core/PlanViewer.Core.csproj -c Release --no-restore
dotnet build src/PlanViewer.App/PlanViewer.App.csproj -c Release --no-restore
dotnet build src/PlanViewer.Cli/PlanViewer.Cli.csproj -c Release --no-restore
+ dotnet build src/PlanViewer.Web/PlanViewer.Web.csproj -c Release --no-restore
dotnet build tests/PlanViewer.Core.Tests/PlanViewer.Core.Tests.csproj -c Release --no-restore
- name: Run tests
diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml
new file mode 100644
index 0000000..412d720
--- /dev/null
+++ b/.github/workflows/deploy-web.yml
@@ -0,0 +1,58 @@
+name: Deploy Web App
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - 'src/PlanViewer.Core/**'
+ - 'src/PlanViewer.Web/**'
+ - '.github/workflows/deploy-web.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: true
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup .NET 8.0
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 8.0.x
+
+ - name: Install WASM workload
+ run: dotnet workload install wasm-tools
+
+ - name: Publish Blazor WASM
+ run: dotnet publish src/PlanViewer.Web/PlanViewer.Web.csproj -c Release -o publish
+
+ - name: Add .nojekyll
+ run: touch publish/wwwroot/.nojekyll
+
+ - name: Add CNAME
+ run: echo 'plans.erikdarling.com' > publish/wwwroot/CNAME
+
+ - name: Add 404 fallback
+ run: cp publish/wwwroot/index.html publish/wwwroot/404.html
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: publish/wwwroot
+
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/PlanViewer.sln b/PlanViewer.sln
index 2f57790..685bc60 100644
--- a/PlanViewer.sln
+++ b/PlanViewer.sln
@@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanViewer.App", "src\PlanV
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanViewer.Cli", "src\PlanViewer.Cli\PlanViewer.Cli.csproj", "{1504CE29-3CBF-4F0B-A46E-54644946B8ED}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanViewer.Web", "src\PlanViewer.Web\PlanViewer.Web.csproj", "{B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A06217BE-DBE2-47D0-BD59-93F2108D447C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanViewer.Core.Tests", "tests\PlanViewer.Core.Tests\PlanViewer.Core.Tests.csproj", "{399A69AD-0CD1-4E9B-9988-E94882B827E6}"
@@ -40,11 +42,16 @@ Global
{399A69AD-0CD1-4E9B-9988-E94882B827E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{399A69AD-0CD1-4E9B-9988-E94882B827E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{399A69AD-0CD1-4E9B-9988-E94882B827E6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8904045D-E083-4010-A320-104B7466C044} = {21F75D2E-F228-49B3-825F-43F621760061}
{F1018F88-B289-40CE-852A-56478DFBA91E} = {21F75D2E-F228-49B3-825F-43F621760061}
{1504CE29-3CBF-4F0B-A46E-54644946B8ED} = {21F75D2E-F228-49B3-825F-43F621760061}
+ {B2D3F7A1-8C4E-4F5A-9D6B-1E2F3A4B5C6D} = {21F75D2E-F228-49B3-825F-43F621760061}
{399A69AD-0CD1-4E9B-9988-E94882B827E6} = {A06217BE-DBE2-47D0-BD59-93F2108D447C}
EndGlobalSection
EndGlobal
diff --git a/src/PlanViewer.Web/App.razor b/src/PlanViewer.Web/App.razor
new file mode 100644
index 0000000..bf076d1
--- /dev/null
+++ b/src/PlanViewer.Web/App.razor
@@ -0,0 +1,10 @@
+ Page not found.
+
+ Performance Studio
+
Paste or upload a .sqlplan file. Your plan XML never leaves your browser.
+ + @if (errorMessage != null) + { + + } + +Accepts .sqlplan and .xml files up to 10 MB
+@mi.CreateStatement+
| Name | +Type | +Compiled | + @if (ActiveStmt!.Parameters.Any(p => p.RuntimeValue != null)) + { +Runtime | + } +
|---|---|---|---|
| @p.Name | +@p.DataType | +@(p.CompiledValue ?? "?") | + @if (ActiveStmt!.Parameters.Any(pp => pp.RuntimeValue != null)) + { +@(p.RuntimeValue ?? "") | + } +
@ActiveStmt!.StatementText+
@textOutput+