Skip to content
This repository was archived by the owner on Apr 6, 2024. It is now read-only.

Commit 159142f

Browse files
committed
(GH-49) Add IDE integration option
1 parent 6c343f8 commit 159142f

File tree

5 files changed

+185
-19
lines changed

5 files changed

+185
-19
lines changed

src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
<Compile Include="GenericIssueReportFormatSettingsExtensions.cs" />
7979
<Compile Include="GenericIssueReportGenerator.cs" />
8080
<Compile Include="GenericIssueReportFormatSettings.cs" />
81+
<Compile Include="IdeIntegrationSettings.cs" />
8182
<Compile Include="IIssueExtensions.cs" />
8283
<Compile Include="ReportColumn.cs" />
8384
<Compile Include="UriExtensions.cs" />

src/Cake.Issues.Reporting.Generic/GenericIssueReportFormatAliases.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,21 @@ public static FileLinkSettings GenericIssueReportFileLinkSettingsForTeamFoundati
107107
return FileLinkSettings.TeamFoundationServer(repositoryUrl, branch, rootPath);
108108
}
109109

110+
/// <summary>
111+
/// Gets an instance of the IDE integration settings for opening files in Visual Studio using the TeamCity addin.
112+
/// </summary>
113+
/// <param name="context">The context.</param>
114+
/// <returns>IDE integration settings.</returns>
115+
[CakeMethodAlias]
116+
[CakeAliasCategory(ReportingAliasConstants.ReportingFormatCakeAliasCategory)]
117+
public static IdeIntegrationSettings GenericIssueReportIdeIntegrationSettingsForVisualStudioUsingTeamCityAddin(
118+
this ICakeContext context)
119+
{
120+
context.NotNull(nameof(context));
121+
122+
return IdeIntegrationSettings.ForVisualStudioUsingTeamCityAddin();
123+
}
124+
110125
/// <summary>
111126
/// Gets an instance of a the generic report format using an embedded template.
112127
/// </summary>

src/Cake.Issues.Reporting.Generic/HtmlDxDataGridOption.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,13 @@ public enum HtmlDxDataGridOption
300300
/// If setting this the matching <see cref="JQueryVersion"/> needs to also be set.
301301
/// Default value is <c>18.2.7</c>.
302302
/// </summary>
303-
DevExtremeVersion
303+
DevExtremeVersion,
304+
305+
/// <summary>
306+
/// Settings for having functionality to open files affected by issues in IDEs.
307+
/// Value needs to be an instance of <see cref="IdeIntegrationSettings"/>.
308+
/// Default value is <c>null</c>.
309+
/// </summary>
310+
IdeIntegrationSettings
304311
}
305312
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
namespace Cake.Issues.Reporting.Generic
2+
{
3+
/// <summary>
4+
/// Settings how issues should be integrated to IDEs.
5+
/// </summary>
6+
public class IdeIntegrationSettings
7+
{
8+
/// <summary>
9+
/// Gets or sets additional JavaScript which should be added.
10+
/// </summary>
11+
public string JavaScript { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets JavaScript which should be called to open the file affected by an issue in an IDE.
15+
/// </summary>
16+
public string OpenInIdeCall { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets text which should be shown in the drop down menu for opening the file affected
20+
/// by an issue in an IDE.
21+
/// Default value is <c>Open in IDE</c>.
22+
/// </summary>
23+
public string MenuEntryText { get; set; } = "Open in IDE";
24+
25+
/// <summary>
26+
/// Returns settings for integrating with Visual Studio using the TeamCity addin.
27+
/// </summary>
28+
/// <returns>Settings for integrating with Visual Studio using the TeamCity addin.</returns>
29+
public static IdeIntegrationSettings ForVisualStudioUsingTeamCityAddin()
30+
{
31+
return new IdeIntegrationSettings()
32+
{
33+
MenuEntryText = "Open in Visual Studio",
34+
JavaScript =
35+
@"function sendHttpGetRequest(filePath, lineNumber) {
36+
var url = 'http://127.0.0.1:63330/file?file=' + filePath + '&line=' + lineNumber;
37+
var xmlHttp = new XMLHttpRequest();
38+
xmlHttp.open('GET', url, false);
39+
xmlHttp.send(null);
40+
}",
41+
OpenInIdeCall = "sendHttpGetRequest({FilePath}, {Line});"
42+
};
43+
}
44+
45+
/// <summary>
46+
/// Returns the JavaScript which should be called to open the file affected by an issue in an IDE
47+
/// with all patterns of <see cref="OpenInIdeCall"/> replaced.
48+
/// </summary>
49+
/// <param name="filePathExpression">Expression which should be used to get the path and name
50+
/// of the file at runtime.</param>
51+
/// <param name="lineExpression">Expression which should be used to get the line number at runtime.</param>
52+
/// <returns>JavaScript which should be called to open the file affected by an issue in an IDE
53+
/// with all patterns replaced.</returns>
54+
public string GetOpenInIdeCall(string filePathExpression, string lineExpression)
55+
{
56+
filePathExpression.NotNullOrWhiteSpace(nameof(filePathExpression));
57+
lineExpression.NotNullOrWhiteSpace(nameof(lineExpression));
58+
59+
if (string.IsNullOrWhiteSpace(this.OpenInIdeCall))
60+
{
61+
return null;
62+
}
63+
64+
return
65+
this.OpenInIdeCall
66+
.Replace("{FilePath}", filePathExpression)
67+
.Replace("{Line}", lineExpression);
68+
}
69+
}
70+
}

src/Cake.Issues.Reporting.Generic/Templates/DxDataGrid.cshtml

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
var groupedColumns = ViewBagHelper.ValueOrDefault(ViewBag.GroupedColumns, new List<ReportColumn> { ReportColumn.ProviderName });
4343
var sortedColumns = ViewBagHelper.ValueOrDefault(ViewBag.SortedColumns, new List<ReportColumn> { ReportColumn.PriorityName, ReportColumn.ProjectName, ReportColumn.FileDirectory, ReportColumn.FileName, ReportColumn.Line });
4444
FileLinkSettings fileLinkSettings = ViewBagHelper.ValueOrDefault(ViewBag.FileLinkSettings, new FileLinkSettings());
45+
IdeIntegrationSettings ideIntegrationSettings = ViewBagHelper.ValueOrDefault<IdeIntegrationSettings>(ViewBag.IdeIntegrationSettings, null);
4546
List<HtmlDxDataGridColumnDescription> additionalColumns = ViewBagHelper.ValueOrDefault(ViewBag.AdditionalColumns, new List<HtmlDxDataGridColumnDescription>());
4647
string jQueryLocation = ViewBagHelper.ValueOrDefault(ViewBag.JQueryLocation, "https://ajax.aspnetcdn.com/ajax/jquery/");
4748
string jQueryVersion = ViewBagHelper.ValueOrDefault(ViewBag.JQueryVersion, "3.1.0");
@@ -61,7 +62,7 @@
6162
addPriorityName: priorityNameVisible,
6263
addProjectPath: projectPathVisible,
6364
addProjectName: projectNameVisible,
64-
addFilePath: filePathVisible,
65+
addFilePath: filePathVisible || ideIntegrationSettings != null,
6566
addFileDirectory: fileDirectoryVisible,
6667
addFileName: fileNameVisible,
6768
addLine: lineVisible,
@@ -94,6 +95,30 @@
9495
<link rel="stylesheet" type="text/css" href="@(devExtremeLocation)@(devExtremeVersion)/css/@(theme.GetCssFileName())" />
9596
@* DevExtreme library *@
9697
<script type="text/javascript" src="@(devExtremeLocation)@(devExtremeVersion)/js/dx.all.js"></script>
98+
@* Additional JavaScript for IDE integration *@
99+
@if (ideIntegrationSettings != null && !string.IsNullOrWhiteSpace(ideIntegrationSettings.JavaScript))
100+
{
101+
<script type="text/javascript">
102+
@Raw(ideIntegrationSettings.JavaScript)
103+
</script>
104+
}
105+
106+
<style>
107+
@* Styles for making sure drop down glyph is not shown for menu in file column in any theme *@
108+
td[role=gridcell] .dx-menu-item-popout
109+
{
110+
display: none;
111+
}
112+
td[role=gridcell] .dx-icon
113+
{
114+
margin: 0px !important;
115+
}
116+
@* Style for making sure menu in file column in any theme is not too high *@
117+
.dx-datagrid .dx-menu .dx-menu-item .dx-menu-item-content, .dx-datagrid-container .dx-menu .dx-menu-item .dx-menu-item-content
118+
{
119+
padding: 0px;
120+
}
121+
</style>
97122
</head>
98123
<body class="dx-viewport">
99124
@if (showHeader)
@@ -110,7 +135,37 @@
110135
</script>
111136

112137
<script type="text/javascript">
113-
$(function(){
138+
$(function () {
139+
@if (ideIntegrationSettings != null && !string.IsNullOrWhiteSpace(ideIntegrationSettings.OpenInIdeCall))
140+
{
141+
<text>
142+
@* Creates the menu in the file column *@
143+
function getFileCellMenuElement(filePath, line) {
144+
var element =
145+
$('<div>')
146+
.css("float", "right")
147+
.dxMenu({
148+
items: [{
149+
text: "",
150+
icon: "overflow",
151+
items: [
152+
{
153+
text: "@ideIntegrationSettings.MenuEntryText",
154+
action: "openInIde"
155+
}
156+
]
157+
}],
158+
onItemClick: function (e) {
159+
if (e.itemData.action === "openInIde") {
160+
@Raw(ideIntegrationSettings.GetOpenInIdeCall("filePath", "line"))
161+
}
162+
}
163+
});
164+
return element;
165+
}
166+
</text>
167+
};
168+
114169
$("#gridContainer").dxDataGrid({
115170
dataSource: issues,
116171
loadPanel: {
@@ -259,6 +314,13 @@
259314
}
260315
},
261316
</text>
317+
} else {
318+
<text>
319+
{
320+
dataField: "FilePath",
321+
visible: false
322+
},
323+
</text>
262324
}
263325
@if (fileDirectoryVisible)
264326
{
@@ -295,22 +357,33 @@
295357
@:sortIndex: @sortedColumns.IndexOf(ReportColumn.FileName),
296358
@:sortOrder: "@fileNameSortOrder.ToShortString()",
297359
}
298-
@if (fileLinkSettings != null && !string.IsNullOrWhiteSpace(fileLinkSettings.FileLinkPattern))
299-
{
300-
<text>
301-
cellTemplate: function (container, options) {
302-
if (options.data["FileLink"]) {
303-
$('<a>', {
304-
text: options.value,
305-
href: options.data["FileLink"],
306-
target: "_blank"
307-
}).appendTo(container);
308-
}
309-
else {
310-
container.text(options.value);
311-
}
312-
}
313-
</text>
360+
cellTemplate: function (container, options) {
361+
if (options.data["FileLink"]) {
362+
var $wrapper =
363+
$('<div>')
364+
.css("float", "left");
365+
var $link =
366+
$('<a>', {
367+
text: options.value,
368+
href: options.data["FileLink"],
369+
target: "_blank"
370+
});
371+
$wrapper.append($link);
372+
$wrapper.appendTo(container);
373+
}
374+
else {
375+
$('<div>')
376+
.text(options.value)
377+
.css("float", "left")
378+
.appendTo(container);
379+
}
380+
@if (ideIntegrationSettings != null && !string.IsNullOrWhiteSpace(ideIntegrationSettings.OpenInIdeCall))
381+
{
382+
<text>
383+
getFileCellMenuElement(options.data["FilePath"], options.data["Line"])
384+
.appendTo(container);
385+
</text>
386+
}
314387
}
315388
},
316389
</text>

0 commit comments

Comments
 (0)