Skip to content

Commit

Permalink
Merge pull request #342 from snyk/feat/scan-summary-panel
Browse files Browse the repository at this point in the history
feat: handle summary panel notification and render it in toolwindow [IDE-893]
  • Loading branch information
DariusZdroba authored Feb 4, 2025
2 parents d783971 + 7b987f6 commit 93003ff
Show file tree
Hide file tree
Showing 18 changed files with 358 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Snyk Security Changelog
## [2.1.0]
### Changed
- New Summary Panel for scan information and Net New Issues filtering.

## [2.0.1]
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public class FolderConfigsParam
{
public List<FolderConfig> FolderConfigs { get; set; }
}
public class ScanSummaryParam
{
public string ScanSummary { get; set; }
}

public class FilterSeverityOptions
{
Expand Down
1 change: 1 addition & 0 deletions Snyk.VisualStudio.Extension.2022/Language/LsConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static class LsConstants
// This notification is needed because we are sending Issue data in the Diagnostic.Data field and Visual Studio filters it out.
// We had to send the same notification but with a different to avoid Visual Studio's filtering behavior.
public const string OnPublishDiagnostics316 = "$/snyk.publishDiagnostics316";
public const string SnykScanSummary = "$/snyk.scanSummary";

// Requests
public const string WorkspaceChangeConfiguration = "workspace/didChangeConfiguration";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ public async Task OnFolderConfig(JToken arg)
serviceProvider.SnykOptionsManager.Save(serviceProvider.Options);
}

[JsonRpcMethod(LsConstants.SnykScanSummary)]
public async Task OnScanSummary(JToken arg)
{
var html = arg;
var scanSummaryParam = arg.TryParse<ScanSummaryParam>();
if (scanSummaryParam?.ScanSummary == null || serviceProvider?.ToolWindow?.SummaryPanel == null) return;
ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
serviceProvider.ToolWindow.SummaryPanel.SetContent(scanSummaryParam.ScanSummary, "summary");
}).FireAndForget();
}

[JsonRpcMethod(LsConstants.SnykHasAuthenticated)]
public async Task OnHasAuthenticated(JToken arg)
{
Expand Down
102 changes: 102 additions & 0 deletions Snyk.VisualStudio.Extension.2022/Resources/LoadingSummary.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=unicode' />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Security-Policy"
content="style-src 'self' 'nonce-${nonce}' 'nonce-ideNonce' https://fonts.googleapis.com;
script-src 'nonce-${nonce}' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;" />
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');

:root {
font-size: var(--main-font-size);
--default-font: "SF Pro Text", "Segoe UI", "Ubuntu", Geneva, Verdana, Tahoma, sans-serif;
--ide-background-color: var(--vscode-sideBar-background);
--text-color: var(--vscode-foreground);
--input-border: var(--vscode-input-border);
}

p {
font-size: 1.3rem;
margin: .8rem 0;
}

hr {
margin: 2rem 0;
}

body {
background-color: var(--ide-background-color);
color: var(--text-color);
font-family: var(--default-font);
}

.snx-loader {
display: inline-block;
width: 12px;
height: 12px;
border: 2px solid rgba(125,125,125,.65);
border-bottom-color: transparent;
border-radius: 50%;
margin-right: .8rem;
animation: spin 1s linear infinite;
}

.size-s {
width: 12px;
height: 12px;
border-width: 2px
}

@keyframes spin {
from {
transform: rotate(0deg);
}

to {
transform: rotate(360deg);
}
}

.snx-h1 {
font-size: 2rem;
font-weight: 600;
margin: .8rem 0;
}

.snx-status {
display: flex;
align-items: center;
padding: .4rem 1.2rem;
background-color: rgba(255,255,255,.1);
border-radius: 1rem;
}

.snx-header {
display: flex;
gap: 1.6rem;
}

.snx-message {
display: flex;
align-items: center
}
</style>
</head>
<body>

<div class="snx-header">
<h1 class="snx-title snx-h1">Snyk Security is loading...</h1>
</div>
<div class="snx-summary">
<div class="snx-status">
<span class="snx-loader size-s"></span>
<p class="snx-message">Waiting for the Snyk CLI to be downloaded and the Language Server to be initialized. </p>
</div>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@
<Resource Include="Resources\branch-dark.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Content Include="Resources\LoadingSummary.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
<Content Include="Resources\SnykLsInit.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX>
Expand Down Expand Up @@ -242,6 +246,8 @@
<Compile Include="UI\Html\ColorExtension.cs" />
<Compile Include="UI\Html\IacHtmlProvider.cs" />
<Compile Include="UI\Html\IHtmlProvider.cs" />
<Compile Include="UI\Html\StaticHtmlProvider.cs" />
<Compile Include="UI\Html\SummaryHtmlProvider.cs" />
<Compile Include="UI\Html\OssHtmlProvider.cs" />
<Compile Include="UI\Html\CodeHtmlProvider.cs" />
<Compile Include="UI\Html\HtmlProviderFactory.cs" />
Expand All @@ -253,6 +259,9 @@
<Compile Include="UI\ResourceLoader.cs" />
<Compile Include="UI\SeverityFilter.cs" />
<Compile Include="UI\SnykIconProvider.cs" />
<Compile Include="UI\Toolwindow\SummaryHtmlPanel.xaml.cs">
<DependentUpon>SummaryHtmlPanel.xaml</DependentUpon>
</Compile>
<Compile Include="UI\Toolwindow\HtmlDescriptionPanel.xaml.cs">
<DependentUpon>HtmlDescriptionPanel.xaml</DependentUpon>
</Compile>
Expand Down Expand Up @@ -389,6 +398,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Toolwindow\SummaryHtmlPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="UI\Toolwindow\HtmlDescriptionPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down
8 changes: 5 additions & 3 deletions Snyk.VisualStudio.Extension.2022/Theme/ColorExtension.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
namespace Snyk.VisualStudio.Extension.Theme
using System.Windows.Media;

namespace Snyk.VisualStudio.Extension.Theme
{
public static class ColorExtension
{
public static System.Windows.Media.SolidColorBrush ToBrush(this System.Drawing.Color color)
public static SolidColorBrush ToBrush(this System.Drawing.Color color)
{
return new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B));
return new SolidColorBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
}
}
}
12 changes: 5 additions & 7 deletions Snyk.VisualStudio.Extension.2022/UI/Html/BaseHtmlProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using System;
using Microsoft.VisualStudio.PlatformUI;
using Snyk.VisualStudio.Extension.Theme;

namespace Snyk.VisualStudio.Extension.UI.Html
{
Expand Down Expand Up @@ -40,6 +41,7 @@ public string GetNonce()

public virtual string ReplaceCssVariables(string html)
{
var isDarkTheme = ThemeInfo.IsDarkTheme();
var css = "<style nonce=\"${nonce}\">";
css += GetCss();

Expand All @@ -56,13 +58,9 @@ public virtual string ReplaceCssVariables(string html)
html = html.Replace("var(--horizontal-border-color)", VSColorTheme.GetThemedColor(EnvironmentColors.ClassDesignerDefaultShapeTextBrushKey).ToHex());
html = html.Replace("var(--code-background-color)", VSColorTheme.GetThemedColor(EnvironmentColors.EditorExpansionFillBrushKey).ToHex());
html = html.Replace("var(--circle-color)", borderColor);

var ideHeaders = """
<head>
<meta http-equiv='Content-Type' content='text/html; charset=unicode' />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
""";
html = html.Replace("<head>", ideHeaders);
html = html.Replace("var(--input-border)", borderColor);
html = html.Replace("var(--main-font-size)", "15px");
html = html.Replace("var(--ide-background-color)", isDarkTheme ? "#242424" : "#FBFBFB");
html = html.Replace("${headerEnd}", "");
var nonce = GetNonce();
html = html.Replace("${nonce}", nonce);
Expand Down
3 changes: 3 additions & 0 deletions Snyk.VisualStudio.Extension.2022/UI/Html/ColorExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ public static class ColorExtension
public static string ToHex(this System.Drawing.Color c)
=> $"#{c.R:X2}{c.G:X2}{c.B:X2}";

public static string ToHex(this System.Windows.Media.Color c)
=> $"#{c.R:X2}{c.G:X2}{c.B:X2}";

private static string ToRGB(this System.Drawing.Color c)
=> $"rgb({c.R},{c.G},{c.B}, {c.A})";
}
Expand Down
12 changes: 8 additions & 4 deletions Snyk.VisualStudio.Extension.2022/UI/Html/HtmlProviderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
{
public static class HtmlProviderFactory
{
public static IHtmlProvider GetHtmlProvider(string product)
public static IHtmlProvider GetHtmlProvider(string provider)
{
switch (product)
switch (provider)
{
case Product.Code:
return CodeHtmlProvider.Instance;
case Product.Oss:
return OssHtmlProvider.Instance;
case Product.Iac:
return IacHtmlProvider.Instance;
case "summary":
return SummaryHtmlProvider.Instance;
case "static":
return StaticHtmlProvider.Instance;
default:
return null;
}

return null;
}
}
}
44 changes: 44 additions & 0 deletions Snyk.VisualStudio.Extension.2022/UI/Html/StaticHtmlProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Microsoft.VisualStudio.Shell;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;

namespace Snyk.VisualStudio.Extension.UI.Html
{
public class StaticHtmlProvider : BaseHtmlProvider
{
private static StaticHtmlProvider _instance;

public static StaticHtmlProvider Instance
{
get
{
if (_instance == null)
{
_instance = new StaticHtmlProvider();
}
return _instance;
}
}
public override string GetInitScript()
{
return @"";
}

public async Task<string> GetInitHtmlAsync()
{
return await ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
var assemblyLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (assemblyLocation == null) return string.Empty;
var path = Path.Combine(assemblyLocation, "Resources", "LoadingSummary.html");
using (var stream = new StreamReader(path))
{
var html = await stream.ReadToEndAsync();
return html;
}
});
}
}
}
37 changes: 37 additions & 0 deletions Snyk.VisualStudio.Extension.2022/UI/Html/SummaryHtmlProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Microsoft.VisualStudio.PlatformUI;
using System;

namespace Snyk.VisualStudio.Extension.UI.Html
{
public class SummaryHtmlProvider : BaseHtmlProvider
{
private static SummaryHtmlProvider _instance;

public static SummaryHtmlProvider Instance
{
get
{
if (_instance == null)
{
_instance = new SummaryHtmlProvider();
}
return _instance;
}
}
public override string ReplaceCssVariables(string html)
{
html = html.Replace("${ideFunc}", "window.external.EnableDelta(isEnabled);");
html = base.ReplaceCssVariables(html);

return html;
}

public override string GetCss()
{
return @"
body { overflow: hidden; }
.body-padding { padding: 0px 4px 8px 4px; }
";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public HtmlDescriptionPanel()
ScriptErrorsSuppressed = true,
};

HtmlViewer.ObjectForScripting = new SnykScriptManager();
HtmlViewer.ObjectForScripting = new SnykScriptManager(SnykVSPackage.ServiceProvider);
_wbHandler.LoadCompleted += HtmlViewerOnLoadCompleted;
}

Expand Down
Loading

0 comments on commit 93003ff

Please sign in to comment.