Skip to content

Commit

Permalink
feat: ai fix html
Browse files Browse the repository at this point in the history
  • Loading branch information
teodora-sandu committed May 31, 2024
1 parent b14182a commit 95776f7
Show file tree
Hide file tree
Showing 2 changed files with 333 additions and 0 deletions.
17 changes: 17 additions & 0 deletions infrastructure/code/code_html.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,22 @@ func getCodeDetailsHtml(issue snyk.Issue) string {
"LessonUrl": issue.LessonUrl,
"LessonIcon": getLessonIconSvg(),
"IgnoreLineAction": getLineToIgnoreAction(issue),
"ShowAIFix": additionalData.HasAIFix,
"ArrowLeftDarkIcon": template.HTML(`<svg width="10" height="12" viewBox="0 0 10 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.86723 11.4303L8.86721 11.4302L0.641823 6.22447L0.387031 6.62706L0.641821 6.22447C0.532336 6.15518 0.5 6.06763 0.5 6.00001C0.5 5.93239 0.532336 5.84484 0.641821 5.77555L0.641824 5.77555L8.86721 0.569741L8.86723 0.569731C9.00417 0.483055 9.17298 0.480315 9.31053 0.543871C9.44734 0.607082 9.5 0.705333 9.5 0.79421V11.2058C9.5 11.2947 9.44734 11.3929 9.31054 11.4561C9.173 11.5197 9.00418 11.5169 8.86723 11.4303Z" stroke="#CCCCCC"/>
</svg>`),
"ArrowLeftLightIcon": template.HTML(`<svg width="10" height="12" viewBox="0 0 10 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.86723 11.4303L8.86721 11.4302L0.641823 6.22447L0.387031 6.62706L0.641821 6.22447C0.532336 6.15518 0.5 6.06763 0.5 6.00001C0.5 5.93239 0.532336 5.84484 0.641821 5.77555L0.641824 5.77555L8.86721 0.569741L8.86723 0.569731C9.00417 0.483055 9.17298 0.480315 9.31053 0.543871C9.44734 0.607082 9.5 0.705333 9.5 0.79421V11.2058C9.5 11.2947 9.44734 11.3929 9.31054 11.4561C9.173 11.5197 9.00418 11.5169 8.86723 11.4303Z" stroke="#3B3B3B"/>
</svg>
`),
"ArrowRightDarkIcon": template.HTML(`<svg width="10" height="12" viewBox="0 0 10 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.13277 11.4303L1.13279 11.4302L9.35818 6.22447L9.61297 6.62706L9.35818 6.22447C9.46766 6.15518 9.5 6.06763 9.5 6.00001C9.5 5.93239 9.46766 5.84484 9.35818 5.77555L9.35818 5.77555L1.13279 0.569741L1.13277 0.569731C0.995832 0.483055 0.827023 0.480315 0.689467 0.543871C0.55266 0.607082 0.5 0.705333 0.5 0.79421V11.2058C0.5 11.2947 0.552661 11.3929 0.689456 11.4561C0.827003 11.5197 0.99582 11.5169 1.13277 11.4303Z" stroke="#CCCCCC"/>
</svg>
`),
"ArrowRightLightIcon": template.HTML(`<svg width="10" height="12" viewBox="0 0 10 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.13277 11.4303L1.13279 11.4302L9.35818 6.22447L9.61297 6.62706L9.35818 6.22447C9.46766 6.15518 9.5 6.06763 9.5 6.00001C9.5 5.93239 9.46766 5.84484 9.35818 5.77555L9.35818 5.77555L1.13279 0.569741L1.13277 0.569731C0.995832 0.483055 0.827023 0.480315 0.689467 0.543871C0.55266 0.607082 0.5 0.705333 0.5 0.79421V11.2058C0.5 11.2947 0.552661 11.3929 0.689456 11.4561C0.827003 11.5197 0.99582 11.5169 1.13277 11.4303Z" stroke="#3B3B3B"/>
</svg>
`),
}

if issue.IsIgnored {
Expand Down Expand Up @@ -236,6 +252,7 @@ func generateNonce() (string, error) {
}

func getSeverityIconSvg(issue snyk.Issue) template.HTML {
// TODO: move these to actual icons
switch issue.Severity {
case snyk.Critical:
return template.HTML(`<svg fill="none" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 16 16">
Expand Down
316 changes: 316 additions & 0 deletions infrastructure/code/template/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,252 @@
border-color: var(--vscode-button-hoverBackground);
color: var(--vscode-button-foreground);
}

/* TODO: CSS extract once we have approval of https://github.com/snyk/snyk-intellij-plugin/pull/535 */
.ide-ai-fix-visibility {
display: none;
}

.sn-ai-fix-hidden {
display: none;
}

.ai-fix {
padding-bottom: 0;
}

.ai-fix p {
margin-bottom: 0;
}

.sn-fix-wrapper {
padding: 2rem;
margin-top:1rem;
background-color: var(--vscode-editor-background);
border-radius: .8rem;
overflow: auto;
}

.generate-ai-fix {
width: auto;
padding: 8px 16px;
}

.sn-apply-fix {}


.sn-loading {
display: flex;
}

.sn-loading svg {
inline-size: 6rem;
block-size: auto
}

.sn-loading-wrapper {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
}

.sn-loading-message {
opacity: 0;
position: absolute;
width: 100%;
padding-left: 16px;
margin-bottom: 8px;
font-size: 14px;
}

.sn-loading-title {
font-weight: 600;
line-height: 1.5;
}

.sn-loading-description {
margin-bottom: 0;
opacity: .75
}


.sn-msg-1 {
animation: reduce 4s ease-in;
}

.sn-msg-2 {
animation: reduce 4s ease-in;
animation-delay: 4s;
}

.sn-msg-3 {
animation: reduce 4s ease-in;
animation-delay: 8s;
}

.sn-msg-4 {
animation: inference 4s ease-in infinite;
animation-delay: 12s;
}


#s0 {
animation: s0ani 3000ms linear infinite;
}

#l1 {
animation: l1ani 3000ms linear infinite;
}

#l2 {
animation: l2ani 3000ms linear infinite;
}

#l3 {
animation: l3ani 3000ms linear infinite;
}

#b1 {
animation: b1ani 3000ms linear infinite;
}

#b2 {
animation: b2ani 3000ms linear infinite;
}

#b3 {
animation: b3ani 3000ms linear infinite;
}

@keyframes s0ani {
0% {
transform: translate(50%, -15%);
}

100% {
transform: translate(50%, 115%);
}
}

@keyframes l1ani {

0%,
23% {
fill: rgba(255, 255, 255, 0.2);
}

40%,
100% {
fill: rgba(249, 122, 153, 0.6);
}
}

@keyframes l2ani {

0%,
40% {
fill: rgba(255, 255, 255, 0.2);
}

56%,
100% {
fill: rgba(249, 122, 153, 0.6);
}
}

@keyframes l3ani {

0%,
56% {
fill: rgba(255, 255, 255, 0.2);
}

72%,
100% {
fill: rgba(67, 181, 154, 0.6);
}
}

@keyframes b1ani {

0%,
8% {
opacity: 0;
transform: scale(1, 1);
}

33% {
transform: translate(-10%, -18%) scale(1.6, 1.6);
}

53%,
100% {
opacity: 1;
transform: scale(1, 1);
}
}

@keyframes b2ani {

0%,
36% {
opacity: 0;
transform: scale(1, 1);
}

50% {
transform: translate(-20%, -18%) scale(1.4, 1.4);
}

60%,
100% {
opacity: 1;
transform: scale(1, 1);
}
}

@keyframes b3ani {

0%,
54% {
opacity: 0;
transform: scale(1, 1);
}

66% {
transform: translate(-10%, -27%) scale(1.4, 1.4);
}

76%,
100% {
opacity: 1;
transform: scale(1, 1);
}
}


@keyframes reduce {

15%,
85% {
opacity: 1
}

86%,
100%,
0% {
opacity: 0;
}
}

@keyframes inference {
0%,
25%,
100% {
opacity: 1
}
}
</style>
</head>

Expand Down Expand Up @@ -496,6 +742,7 @@ <h2 class="data-flow-header">
</article>

<!-- External example fixes -->
{{if not .ShowAIFix}}
<article class="example-fixes">
<h2 class="example-fixes-header">External example fixes</h2>
<div class="example-fixes-text">
Expand Down Expand Up @@ -525,6 +772,75 @@ <h2 class="example-fixes-header">External example fixes</h2>
{{end}}
</div>
</article>
{{end}

<!-- AI fixes -->
{{if .ShowAIFix}}
<article id="fix-wrapper" class="ai-fix sn-ai-fix-hidden ide-ai-fix-visibility">
<p>⚡ Fix this issue by generating a solution using Snyk DeepCode AI</p>

<div class="sn-fix-wrapper">
<button id="generate-ai-fix" class="generate-ai-fix">✨ Generate fix <span class="wide">using Snyk DeepCode AI</span></button>

<div id="fix-loading-indicator" class="sn-loading hidden">
<div class="sn-loading-icon">
<svg id="scan-animation" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 248 204" shape-rendering="geometricPrecision"><defs><linearGradient id="mg" x1="16.0903" y1="180" x2="92.743" y2="107.462" spreadMethod="pad" gradientUnits="userSpaceOnUse" gradientTransform="translate(0 0)"><stop id="eQeHIUZsTfX2-fill-0" offset="0%" stop-color="#145deb"/><stop id="eQeHIUZsTfX2-fill-1" offset="100%" stop-color="#441c99"/></linearGradient><linearGradient id="sg" x1="116" y1="0" x2="116" y2="64" spreadMethod="pad" gradientUnits="userSpaceOnUse" gradientTransform="translate(0 0)"><stop id="eQeHIUZsTfX26-fill-0" offset="0%" stop-color="#ff78e1"/><stop id="eQeHIUZsTfX26-fill-1" offset="100%" stop-color="rgba(255,120,225,0)"/></linearGradient></defs><rect width="224" height="180" rx="16" ry="16" transform="translate(12 12)" fill="url(#mg)"/><circle r="4" transform="translate(28 28)" opacity="0.3" fill="#fff"/><circle r="4" transform="translate(40 28)" opacity="0.25" fill="#fff"/><circle r="4" transform="translate(52 28)" opacity="0.2" fill="#fff"/><rect width="48" height="12" rx="6" ry="6" transform="translate(162 56)" opacity="0.2" fill="#fff"/><rect width="80" height="12" rx="6" ry="6" transform="translate(32 92)" opacity="0.2" fill="#fff"/><rect width="72" height="12" rx="6" ry="6" transform="translate(96 164)" opacity="0.2" fill="#fff"/><rect width="56" height="12" rx="6" ry="6" transform="translate(156 128)" opacity="0.2" fill="#fff"/><rect id="l3" width="80" height="12" rx="6" ry="6" transform="translate(64 128)"/><rect id="l2" width="64" height="12" rx="6" ry="6" transform="translate(150 92)"/><rect id="l1" width="117" height="12" rx="6" ry="6" transform="translate(32 56)"/><g id="b3"><rect width="32" height="32" rx="6" ry="6" transform="translate(48 118)" fill="#43b59a"/><path d="M54.5991,134c.7987-.816,2.0938-.816,2.8926,0l2.8926,2.955l10.124-10.343c.7988-.816,2.0939-.816,2.8926,0c.7988.816.7988,2.139,0,2.955L61.8306,141.388c-.7988.816-2.0939.816-2.8926,0l-4.3389-4.433c-.7988-.816-.7988-2.139,0-2.955Z" fill="#fff"/></g><g id="b2"><rect width="32" height="32" rx="6" ry="6" transform="translate(124 81)" fill="#f97a99"/><path d="M142,91c0,.7685-.433,5.3087-1.069,8h-1.862c-.636-2.6913-1.069-7.2315-1.069-8c0-1.1046.895-2,2-2s2,.8954,2,2Z" fill="#fff"/><path d="M140,104c1.105,0,2-.895,2-2s-.895-2-2-2-2,.895-2,2s.895,2,2,2Z" fill="#fff"/></g><g id="b1"><rect width="24" height="24" rx="6" ry="6" transform="translate(28 50)" fill="#f97a99"/><path d="M42,56c0,.7685-.4335,5.3087-1.0693,8h-1.8614C38.4335,61.3087,38,56.7685,38,56c0-1.1046.8954-2,2-2s2,.8954,2,2Z" fill="#fff"/><path d="M40,69c1.1046,0,2-.8954,2-2s-.8954-2-2-2-2,.8954-2,2s.8954,2,2,2Z" fill="#fff"/></g><g id="s0" transform="translate(124,-40)"><g transform="translate(-124,-40)"><rect width="232" height="64" rx="0" ry="0" transform="matrix(1 0 0-1 8 64)" opacity="0.5" fill="url(#sg)"/><rect width="248" height="16" rx="8" ry="8" transform="translate(0 64)" fill="#e555ac"/></g></g></svg>
</div>
<div class="sn-loading-wrapper">
<div class="sn-loading-message sn-msg-1">
<span class="sn-loading-title">1<span class="font-light">/4</span> Code Reduction...</span>
<p class="sn-loading-description">Reduces the given files to a smaller and relevant code snippet.</p>
</div>
<div class="sn-loading-message sn-msg-2">
<span class="sn-loading-title">2<span class="font-light">/4</span> Parsing...</span>
<p class="sn-loading-description">Analyzing symbols and generating the graph representation.</p>
</div>
<div class="sn-loading-message sn-msg-3">
<span class="sn-loading-title">3<span class="font-light">/4</span> Static Analysis...</span>
<p class="sn-loading-description">Examining the vulnerability code without having to execute the program.</p>
</div>
<div class="sn-loading-message sn-msg-4">
<span class="sn-loading-title">4<span class="font-light">/4</span> Inferencing...</span>
<p class="sn-loading-description">Feeding the reduced code to our neural network to obtain the prediction.</p>
</div>
</div>
</div>
</div>
</article>

<article id="fixes-section" class="sn-ai-fixes sn-ai-fix-hidden ide-ai-fix-visibility">
<div id="info-no-diffs" class="font-light">
There are no fix diffs for this issue.
</div>
<div id="diff-top" class="row between">
<div id="info-top" class="font-light">Here are <span id="diff-number"></span> AI-generated solutions:</div>
<div class="diffs-nav">
<span id="previous-diff" class="arrow" title="Previous diff">
<img src={{.ArrowLeftDarkIcon}} class="arrow-icon dark-only"></img>
<img src={{.ArrowLeftLightIcon}} class="arrow-icon light-only"></img>
</span>
<span id="diff-text">
AI solution <strong id="diff-counter">1</strong>/<span id="diff-number2"></span>
</span>
<span id="next-diff" class="arrow" title="Next diff">
<img src={{.ArrowRightDarkIcon}} class="arrow-icon dark-only"></img>
<img src={{.ArrowRightLightIcon}} class="arrow-icon light-only"></img>
</span>
</div>
</div>
<div id="diff"></div>
<button id="apply-fix" class="button sn-apply-fix">Apply fix</button>
</article>

<article id="fixes-error-section" class="sn-ai-fix-error sn-ai-fix-hidden ide-ai-fix-visibility">
<div id="info-no-diffs" class="font-light">
⚠️ There was an issue generating the fix
</div>
<div class="sn-fix-wrapper">
<button id="retry-generate-fix" class="button generate-ai-fix">✨ Retry generating AI fixes</button>
</div>
</article>
{{end}}
</main>

<!-- Ignore In Line Actions -->
Expand Down

0 comments on commit 95776f7

Please sign in to comment.