diff --git a/src/Cake.Issues.Reporting.Generic.Tests/GenericIssueReportGeneratorTests.cs b/src/Cake.Issues.Reporting.Generic.Tests/GenericIssueReportGeneratorTests.cs index 52181679..59b1ad6e 100644 --- a/src/Cake.Issues.Reporting.Generic.Tests/GenericIssueReportGeneratorTests.cs +++ b/src/Cake.Issues.Reporting.Generic.Tests/GenericIssueReportGeneratorTests.cs @@ -46,6 +46,7 @@ public sealed class TheInternalCreateReportMethod [InlineData(GenericIssueReportTemplate.HtmlDiagnostic)] [InlineData(GenericIssueReportTemplate.HtmlDataTable)] [InlineData(GenericIssueReportTemplate.HtmlDxDataGrid)] + [InlineData(GenericIssueReportTemplate.HtmlDxPivotGrid)] public void Should_Generate_Report_From_Embedded_Template(GenericIssueReportTemplate template) { // Given diff --git a/src/Cake.Issues.Reporting.Generic.Tests/HtmlDxPivotGridAreaExtensionsTests.cs b/src/Cake.Issues.Reporting.Generic.Tests/HtmlDxPivotGridAreaExtensionsTests.cs new file mode 100644 index 00000000..2f30c1f7 --- /dev/null +++ b/src/Cake.Issues.Reporting.Generic.Tests/HtmlDxPivotGridAreaExtensionsTests.cs @@ -0,0 +1,27 @@ +namespace Cake.Issues.Reporting.Generic.Tests +{ + using Shouldly; + using Xunit; + + public sealed class HtmlDxPivotGridAreaExtensionsTests + { + public sealed class TheToJavaScriptIdentifierMethod + { + [Theory] + [InlineData(HtmlDxPivotGridArea.Column)] + [InlineData(HtmlDxPivotGridArea.Row)] + [InlineData(HtmlDxPivotGridArea.Filter)] + [InlineData(HtmlDxPivotGridArea.Data)] + public void Should_Return_Identifier(HtmlDxPivotGridArea area) + { + // Given + + // When + var result = area.ToJavaScriptIdentifier(); + + // Then + result.ShouldNotBeNullOrWhiteSpace(); + } + } + } +} diff --git a/src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj b/src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj index 5eecb083..a58269dc 100644 --- a/src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj +++ b/src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj @@ -21,6 +21,7 @@ <EmbeddedResource Include="Templates\DataTable.cshtml" /> <EmbeddedResource Include="Templates\Diagnostic.cshtml" /> <EmbeddedResource Include="Templates\DxDataGrid.cshtml" /> + <EmbeddedResource Include="Templates\DxPivotGrid.cshtml" /> </ItemGroup> <ItemGroup> diff --git a/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplate.cs b/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplate.cs index fb1a5ec3..c7ef8320 100644 --- a/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplate.cs +++ b/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplate.cs @@ -20,5 +20,11 @@ public enum GenericIssueReportTemplate /// See <see cref="HtmlDxDataGridOption"/> for template specific options. /// </summary> HtmlDxDataGrid, + + /// <summary> + /// Template for a HTML report containing a pivot grid showing number of errors, warnings, suggestions and hints, + /// with a detail drill down view and an overview chart. + /// </summary> + HtmlDxPivotGrid, } } diff --git a/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplateExtensions.cs b/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplateExtensions.cs index 6086da48..70ce92d2 100644 --- a/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplateExtensions.cs +++ b/src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplateExtensions.cs @@ -25,6 +25,9 @@ public static string GetTemplateResourceName(this GenericIssueReportTemplate tem case GenericIssueReportTemplate.HtmlDxDataGrid: return "DxDataGrid.cshtml"; + case GenericIssueReportTemplate.HtmlDxPivotGrid: + return "DxPivotGrid.cshtml"; + default: throw new ArgumentOutOfRangeException(nameof(template)); } diff --git a/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridArea.cs b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridArea.cs new file mode 100644 index 00000000..9ffbe829 --- /dev/null +++ b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridArea.cs @@ -0,0 +1,28 @@ +namespace Cake.Issues.Reporting.Generic +{ + /// <summary> + /// Possible areas for fields. + /// </summary> + public enum HtmlDxPivotGridArea + { + /// <summary> + /// Field will be shown as row. + /// </summary> + Row, + + /// <summary> + /// Field will be shown as column. + /// </summary> + Column, + + /// <summary> + /// Field will be shown as data. + /// </summary> + Data, + + /// <summary> + /// Field will be available to filter. + /// </summary> + Filter + } +} diff --git a/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridAreaExtensions.cs b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridAreaExtensions.cs new file mode 100644 index 00000000..14d25dce --- /dev/null +++ b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridAreaExtensions.cs @@ -0,0 +1,32 @@ +namespace Cake.Issues.Reporting.Generic +{ + using System; + + /// <summary> + /// Extension methods for the <see cref="HtmlDxPivotGridArea"/> enumeration. + /// </summary> + public static class HtmlDxPivotGridAreaExtensions + { + /// <summary> + /// Returns the short identifier of the pivot grid area. + /// </summary> + /// <param name="area">Area for which the identifier should be returned.</param> + /// <returns>Short identifier of the area.</returns> + public static string ToJavaScriptIdentifier(this HtmlDxPivotGridArea area) + { + switch (area) + { + case HtmlDxPivotGridArea.Row: + return "row"; + case HtmlDxPivotGridArea.Column: + return "column"; + case HtmlDxPivotGridArea.Data: + return "data"; + case HtmlDxPivotGridArea.Filter: + return "filter"; + default: + throw new ArgumentException("Unknown enumeration value", nameof(area)); + } + } + } +} diff --git a/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridOption.cs b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridOption.cs new file mode 100644 index 00000000..86bed848 --- /dev/null +++ b/src/Cake.Issues.Reporting.Generic/HtmlDxPivotGridOption.cs @@ -0,0 +1,396 @@ +namespace Cake.Issues.Reporting.Generic +{ + /// <summary> + /// Options for the <see cref="GenericIssueReportTemplate.HtmlDxPivotGrid"/> template. + /// </summary> + public enum HtmlDxPivotGridOption + { + /// <summary> + /// Title of the report. + /// Default value is <c>Issues Report</c>. + /// </summary> + Title, + + /// <summary> + /// DevExtreme theme to use. + /// See <see cref="DevExtremeTheme"/> for possible values. + /// Default value is <see cref="DevExtremeTheme.Light"/>. + /// </summary> + Theme, + + /// <summary> + /// Flag if the title should be shown as header on the top of the page. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + ShowHeader, + + ///// <summary> + ///// Flag if the search panel for full text searching should be visible or not. + ///// Either <c>true</c> or <c>false</c>. + ///// Default value is <c>true</c>. + ///// </summary> + //EnableSearching, + + ///// <summary> + ///// Flag if the group panel which allows end-user grouping should be visible or not. + ///// Either <c>true</c> or <c>false</c>. + ///// If <c>false</c> grouping defined by <see cref="GroupedColumns"/> is still applied. + ///// Default value is <c>true</c>. + ///// </summary> + //EnableGrouping, + + /// <summary> + /// Flag if filtering should be available or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + EnableFiltering, + + /// <summary> + /// Flag if the <see cref="ReportColumn.ProviderType"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>false</c>. + /// </summary> + ProviderTypeVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.ProviderType"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + ProviderTypeArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.ProviderType"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //ProviderTypeSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.ProviderName"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + ProviderNameVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.ProviderName"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Filter"/>. + /// </summary> + ProviderNameArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.ProviderName"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //ProviderNameSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.Priority"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>false</c>. + /// </summary> + PriorityVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.Priority"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + PriorityArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.Priority"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Descending"/>. + ///// </summary> + //PrioritySortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.PriorityName"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + PriorityNameVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.PriorityName"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Column"/>. + /// </summary> + PriorityNameArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.PriorityName"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Descending"/>. + ///// </summary> + //PriorityNameSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.ProjectPath"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>false</c>. + /// </summary> + ProjectPathVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.ProjectPath"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + ProjectPathArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.ProjectPath"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //ProjectPathSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.ProjectName"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + ProjectNameVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.ProjectName"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + ProjectNameArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.ProjectName"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //ProjectNameSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.FilePath"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>false</c>. + /// </summary> + FilePathVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.FilePath"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + FilePathArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.FilePath"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //FilePathSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.FileDirectory"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + FileDirectoryVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.FileDirectory"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + FileDirectoryArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.FileDirectory"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //FileDirectorySortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.FileName"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + FileNameVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.FileName"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + FileNameArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.FileName"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //FileNameSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.Line"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + LineVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.Line"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + LineArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.Line"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //LineSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.Rule"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + RuleVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.Rule"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Data"/>. + /// </summary> + RuleArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.Rule"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //RuleSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.RuleUrl"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>false</c>. + /// </summary> + RuleUrlVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.RuleUrl"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + RuleUrlArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.RuleUrl"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //RuleUrlSortOrder, + + /// <summary> + /// Flag if the <see cref="ReportColumn.Message"/> column should be visible or not. + /// Either <c>true</c> or <c>false</c>. + /// Default value is <c>true</c>. + /// </summary> + MessageVisible, + + /// <summary> + /// Area where the <see cref="ReportColumn.Message"/> column should be shown. + /// See <see cref="HtmlDxPivotGridArea"/> for possible values. + /// Default value is <see cref="HtmlDxPivotGridArea.Row"/>. + /// </summary> + MessageArea, + + ///// <summary> + ///// Sort order of the <see cref="ReportColumn.Message"/> column if it is part of <see cref="SortedColumns"/>. + ///// See <see cref="ColumnSortOrder"/> for possible values. + ///// Default value is <see cref="ColumnSortOrder.Ascending"/>. + ///// </summary> + //MessageSortOrder, + + ///// <summary> + ///// List of <see cref="ReportColumn"/> which should be grouped. + ///// Grouped columns are always visible. + ///// Default value is <see cref="ReportColumn.ProviderName"/>. + ///// </summary> + //GroupedColumns, + + ///// <summary> + ///// List of <see cref="ReportColumn"/> which should be sorted. + ///// Default value is <see cref="ReportColumn.PriorityName"/>, <see cref="ReportColumn.ProjectName"/>, + ///// <see cref="ReportColumn.FileDirectory"/>, <see cref="ReportColumn.FileName"/>, <see cref="ReportColumn.Line"/>. + ///// </summary> + //SortedColumns, + + ///// <summary> + ///// List of <see cref="HtmlDxDataGridColumnDescription"/> for additional columsn which should be added to the grid. + ///// Default value is an empty list. + ///// </summary> + //AdditionalColumns, + + ///// <summary> + ///// Settings for having issues linked to files. + ///// Value needs to be an instance of <see cref="FileLinkSettings"/>. + ///// Default value is <c>null</c>. + ///// </summary> + //FileLinkSettings, + + /// <summary> + /// Location where jQuery can be found. + /// The following files need to be available: + /// <list type="bullet"> + /// <item> + /// <description><c>{JQueryLocation}/jquery-{JQueryVersion}.min.js</c></description> + /// </item> + /// </list> + /// Default value is <c>https://ajax.aspnetcdn.com/ajax/jquery/</c>. + /// </summary> + JQueryLocation, + + /// <summary> + /// Version of jQuery which should be used. + /// This version needs to match the version required by the selected <see cref="DevExtremeVersion"/>. + /// Default value is <c>3.1.0</c>. + /// </summary> + JQueryVersion, + + /// <summary> + /// Location where the DevExtreme libraries can be found. + /// Below the location there needs to be a folder matching <see cref="DevExtremeVersion"/> and + /// inside there subfolders <c>js</c> and <c>css</c>. + /// The following files need to be available: + /// <list type="bullet"> + /// <item> + /// <description><c>{DevExtremeLocation}/{DevExtremeVersion}/js/dx.all.js</c></description> + /// </item> + /// <item> + /// <description><c>{DevExtremeLocation}/{DevExtremeVersion}/css/dx.common.css</c></description> + /// </item> + /// <item> + /// <description><c>{DevExtremeLocation}/{DevExtremeVersion}/css/{Theme}</c></description> + /// </item> + /// </list> + /// Default value is <c>https://cdn3.devexpress.com/jslib/</c>. + /// </summary> + DevExtremeLocation, + + /// <summary> + /// Version of the DevExtreme libraries which should be used. + /// If setting this the matching <see cref="JQueryVersion"/> needs to also be set. + /// Default value is <c>18.2.7</c>. + /// </summary> + DevExtremeVersion + } +} diff --git a/src/Cake.Issues.Reporting.Generic/Templates/DxPivotGrid.cshtml b/src/Cake.Issues.Reporting.Generic/Templates/DxPivotGrid.cshtml new file mode 100644 index 00000000..95c198eb --- /dev/null +++ b/src/Cake.Issues.Reporting.Generic/Templates/DxPivotGrid.cshtml @@ -0,0 +1,331 @@ +@model IEnumerable<Cake.Issues.IIssue> + +@using Newtonsoft.Json +@using Cake.Issues.Reporting.Generic + +<!DOCTYPE html> + +@{ + // Read options and apply default values. + var title = ViewBagHelper.ValueOrDefault(ViewBag.Title, "Issues Report"); + DevExtremeTheme theme = ViewBagHelper.ValueOrDefault(ViewBag.Theme, DevExtremeTheme.Light); + bool showHeader = ViewBagHelper.ValueOrDefault(ViewBag.ShowHeader, true); + //bool enableSearching = ViewBagHelper.ValueOrDefault(ViewBag.EnableSearching, true); + //bool enableGrouping = ViewBagHelper.ValueOrDefault(ViewBag.EnableGrouping, true); + bool enableFiltering = ViewBagHelper.ValueOrDefault(ViewBag.EnableFiltering, true); + bool providerTypeVisible = ViewBagHelper.ValueOrDefault(ViewBag.ProviderTypeVisible, false); + HtmlDxPivotGridArea providerTypeArea = ViewBagHelper.ValueOrDefault(ViewBag.ProviderTypeArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder providerTypeSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.ProviderTypeSortOder, ColumnSortOrder.Ascending); + bool providerNameVisible = ViewBagHelper.ValueOrDefault(ViewBag.ProviderNameVisible, true); + HtmlDxPivotGridArea providerNameArea = ViewBagHelper.ValueOrDefault(ViewBag.ProviderNameArea, HtmlDxPivotGridArea.Filter); + //ColumnSortOrder providerNameSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.ProviderNameSortOder, ColumnSortOrder.Ascending); + bool priorityVisible = ViewBagHelper.ValueOrDefault(ViewBag.PriorityVisible, false); + HtmlDxPivotGridArea priorityArea = ViewBagHelper.ValueOrDefault(ViewBag.PriorityArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder prioritySortOrder = ViewBagHelper.ValueOrDefault(ViewBag.PrioritySortOrder, ColumnSortOrder.Descending); + bool priorityNameVisible = ViewBagHelper.ValueOrDefault(ViewBag.PriorityNameVisible, true); + HtmlDxPivotGridArea priorityNameArea = ViewBagHelper.ValueOrDefault(ViewBag.PriorityNameArea, HtmlDxPivotGridArea.Column); + //ColumnSortOrder priorityNameSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.PriorityNameSortOrder, ColumnSortOrder.Descending); + bool projectPathVisible = ViewBagHelper.ValueOrDefault(ViewBag.ProjectPathVisible, false); + HtmlDxPivotGridArea projectPathArea = ViewBagHelper.ValueOrDefault(ViewBag.ProjectPathArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder projectPathSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.ProjectPathSortOder, ColumnSortOrder.Ascending); + bool projectNameVisible = ViewBagHelper.ValueOrDefault(ViewBag.ProjectNameVisible, true); + HtmlDxPivotGridArea projectNameArea = ViewBagHelper.ValueOrDefault(ViewBag.ProjectNameArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder projectNameSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.ProjectNameSortOder, ColumnSortOrder.Ascending); + bool filePathVisible = ViewBagHelper.ValueOrDefault(ViewBag.FilePathVisible, true); + HtmlDxPivotGridArea filePathArea = ViewBagHelper.ValueOrDefault(ViewBag.FilePathArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder filePathSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.FilePathSortOder, ColumnSortOrder.Ascending); + bool fileDirectoryVisible = ViewBagHelper.ValueOrDefault(ViewBag.FileDirectoryVisible, false); + HtmlDxPivotGridArea fileDirectoryArea = ViewBagHelper.ValueOrDefault(ViewBag.FileDirectoryArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder fileDirectorySortOrder = ViewBagHelper.ValueOrDefault(ViewBag.FileDirectorySortOder, ColumnSortOrder.Ascending); + bool fileNameVisible = ViewBagHelper.ValueOrDefault(ViewBag.FileNameVisible, true); + HtmlDxPivotGridArea fileNameArea = ViewBagHelper.ValueOrDefault(ViewBag.FileNameArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder fileNameSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.FileNameSortOder, ColumnSortOrder.Ascending); + bool lineVisible = ViewBagHelper.ValueOrDefault(ViewBag.LineVisible, false); + HtmlDxPivotGridArea lineArea = ViewBagHelper.ValueOrDefault(ViewBag.LineArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder lineSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.LineSortOder, ColumnSortOrder.Ascending); + bool ruleVisible = ViewBagHelper.ValueOrDefault(ViewBag.RuleVisible, true); + HtmlDxPivotGridArea ruleArea = ViewBagHelper.ValueOrDefault(ViewBag.RuleArea, HtmlDxPivotGridArea.Data); + //ColumnSortOrder ruleSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.RuleSortOder, ColumnSortOrder.Ascending); + bool ruleUrlVisible = ViewBagHelper.ValueOrDefault(ViewBag.RuleUrlVisible, false); + HtmlDxPivotGridArea ruleUrlArea = ViewBagHelper.ValueOrDefault(ViewBag.RuleUrlArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder ruleUrlSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.RuleUrlSortOder, ColumnSortOrder.Ascending); + bool messageVisible = ViewBagHelper.ValueOrDefault(ViewBag.MessageVisible, false); + HtmlDxPivotGridArea messageArea = ViewBagHelper.ValueOrDefault(ViewBag.MessageArea, HtmlDxPivotGridArea.Row); + //ColumnSortOrder messageSortOrder = ViewBagHelper.ValueOrDefault(ViewBag.MessageSortOder, ColumnSortOrder.Ascending); + //var groupedColumns = ViewBagHelper.ValueOrDefault(ViewBag.GroupedColumns, new List<ReportColumn> { ReportColumn.ProviderName }); + //var sortedColumns = ViewBagHelper.ValueOrDefault(ViewBag.SortedColumns, new List<ReportColumn> { ReportColumn.PriorityName, ReportColumn.ProjectName, ReportColumn.FileDirectory, ReportColumn.FileName, ReportColumn.Line }); + //FileLinkSettings fileLinkSettings = ViewBagHelper.ValueOrDefault(ViewBag.FileLinkSettings, new FileLinkSettings()); + //List<HtmlDxDataGridColumnDescription> additionalColumns = ViewBagHelper.ValueOrDefault(ViewBag.AdditionalColumns, new List<HtmlDxDataGridColumnDescription>()); + string jQueryLocation = ViewBagHelper.ValueOrDefault(ViewBag.JQueryLocation, "https://ajax.aspnetcdn.com/ajax/jquery/"); + string jQueryVersion = ViewBagHelper.ValueOrDefault(ViewBag.JQueryVersion, "3.1.0"); + string devExtremeLocation = ViewBagHelper.ValueOrDefault(ViewBag.DevExtremeLocation, "https://cdn3.devexpress.com/jslib/"); + string devExtremeVersion = ViewBagHelper.ValueOrDefault(ViewBag.DevExtremeVersion, "18.2.7"); +} + +@{ + // Prepare issues. + var issues = + from issue in Model + select + issue.GetExpandoObject( + addProviderType: providerTypeVisible, + addProviderName: providerNameVisible, + addPriority: priorityVisible || priorityNameVisible, + addPriorityName: priorityNameVisible, + addProjectPath: projectPathVisible, + addProjectName: projectNameVisible, + addFilePath: filePathVisible, + addFileDirectory: fileDirectoryVisible, + addFileName: fileNameVisible, + addLine: lineVisible, + addRule: ruleVisible, + addRuleUrl: ruleVisible || ruleUrlVisible, + addMessage: messageVisible); + + if (!jQueryLocation.EndsWith("/")) + { + jQueryLocation += "/"; + } + + if (!devExtremeLocation.EndsWith("/")) + { + devExtremeLocation += "/"; + } +} + + +<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta charset="utf-8" /> + <title>@title</title> + + @* DevExtreme dependencies *@ + <script type="text/javascript" src="@(jQueryLocation)jquery-@(jQueryVersion).min.js"></script> + @* DevExtreme themes *@ + <link rel="stylesheet" type="text/css" href="@(devExtremeLocation)@(devExtremeVersion)/css/dx.common.css" /> + <link rel="stylesheet" type="text/css" href="@(devExtremeLocation)@(devExtremeVersion)/css/@(theme.GetCssFileName())" /> + @* DevExtreme library *@ + <script type="text/javascript" src="@(devExtremeLocation)@(devExtremeVersion)/js/dx.all.js"></script> +</head> +<body class="dx-viewport"> + @if (showHeader) + { + <h1>@title</h1> + } + + <div class="container"> + <div id="pivotgrid-chart"></div> + <div id="pivotgrid"></div> + <div id="pivotgrid-popup"></div> + </div> + + <script type="text/javascript"> + var issues = @Raw(JsonConvert.SerializeObject(issues)); + </script> + <script type="text/javascript"> + $(function () { + var pivotGridChart = $("#pivotgrid-chart").dxChart({ + commonSeriesSettings: { + type: "bar" + }, + tooltip: { + enabled: true, + customizeTooltip: function (args) { + return { + html: "Total " + args.seriesName + ": " + args.valueText + }; + } + }, + size: { + height: 200 + }, + adaptiveLayout: { + width: 450 + } + }).dxChart("instance"); + + var pivotGrid = $("#pivotgrid").dxPivotGrid({ + height: "calc(100% - 200px)", + allowFiltering: @enableFiltering.ToString().ToLowerInvariant(), + fieldPanel: { + showColumnFields: false, + showDataFields: false, + showFilterFields: true, + showRowFields: false, + allowFieldDragging: true, + visible: true + }, + onCellClick: function (e) { + if (e.area == "data") { + var pivotGridDataSource = e.component.getDataSource(), + rowPathLength = e.cell.rowPath.length, + rowPathName = e.cell.rowPath[rowPathLength - 1], + popupTitle = (rowPathName ? rowPathName : "Total") + " issues"; + + drillDownDataSource = pivotGridDataSource.createDrillDownDataSource(e.cell); + pivotgridPopup.option("title", popupTitle); + pivotgridPopup.show(); + } + }, + dataSource: { + fields: [ + @if (providerTypeVisible) + { + <text> + { + dataField: "ProviderType", + area: "@providerTypeArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (providerNameVisible) + { + <text> + { + caption: "Provider", + dataField: "ProviderName", + area: "@providerNameArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (priorityVisible) + { + <text> + { + dataField: "Priority", + area: "@priorityArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (priorityNameVisible) + { + <text> + { + caption: "Severity", + dataField: "PriorityName", + area: "@priorityNameArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (projectPathVisible) + { + <text> + { + dataField: "ProjectPath", + area: "@projectPathArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (projectNameVisible) + { + <text> + { + caption: "Project", + dataField: "ProjectName", + area: "@projectNameArea.ToJavaScriptIdentifier()", + }, + </text> + } + @if (filePathVisible) + { + <text> + { + dataField: "FilePath", + area: "row", + }, + </text> + } + @if (fileDirectoryVisible) + { + <text> + { + caption: "Directory", + dataField: "FileDirectory", + area: "row", + }, + </text> + } + @if (fileNameVisible) + { + <text> + { + caption: "File", + dataField: "FileName", + area: "row", + }, + </text> + } + @if (lineVisible) + { + <text> + { + dataField: "Line", + area: "row", + }, + </text> + } + @if (ruleVisible) + { + <text> + { + dataField: "Rule", + area: "data", + }, + </text> + } + @if (ruleUrlVisible) + { + <text> + { + dataField: "RuleUrl", + area: "row", + }, + </text> + } + @if (messageVisible) + { + <text> + { + dataField: "Message", + area: "row", + }, + </text> + } + ], + store: issues + } + }).dxPivotGrid("instance"); + + pivotGrid.bindChart( + pivotGridChart, + { + inverted: true, + dataFieldsDisplayMode: "splitPanes", + alternateDataFields: false + } + ); + + var pivotgridPopup = $("#pivotgrid-popup").dxPopup({ + width: 600, + height: 400, + resizeEnabled: true, + contentTemplate: function (contentElement) { + $("<div />") + .addClass("drill-down") + .dxDataGrid({ + width: "100%", + height: "100%", + columns: ["ProjectName", "FileDirectory", "FileName", "Line", "Rule", "Message"] + }) + .appendTo(contentElement); + }, + onShowing: function () { + $(".drill-down") + .dxDataGrid("instance") + .option("dataSource", drillDownDataSource); + } + }).dxPopup("instance"); + }); + </script> +</body> +</html> \ No newline at end of file