PSWriteHTML.psm1
function Add-CustomFormatForDatetimeSorting { <# .SYNOPSIS .DESCRIPTION This function adds code to make the datatable columns sortable with different datetime formats. Formatting: Day (of Month) D - 1 2 ... 30 31 Do - 1st 2nd ... 30th 31st DD - 01 02 ... 30 31 Month M - 1 2 ... 11 12 Mo - 1st 2nd ... 11th 12th MM - 01 02 ... 11 12 MMM - Jan Feb ... Nov Dec MMMM - January February ... November December Year YY - 70 71 ... 29 30 YYYY - 1970 1971 ... 2029 2030 Hour H - 0 1 ... 22 23 HH - 00 01 ... 22 23 h - 1 2 ... 11 12 hh - 01 02 ... 11 12 Minute m - 0 1 ... 58 59 mm - 00 01 ... 58 59 Second s - 0 1 ... 58 59 ss - 00 01 ... 58 59 More formats http://momentjs.com/docs/#/displaying/ .PARAMETER CustomDateTimeFormat Array with strings of custom datetime format. The string is build from two parts. Format and locale. Locale is optional. format explanation: http://momentjs.com/docs/#/displaying/ locale explanation: http://momentjs.com/docs/#/i18n/ .LINK format explanation: http://momentjs.com/docs/#/displaying/ locale explanation: http://momentjs.com/docs/#/i18n/ .Example Add-CustomFormatForDatetimeSorting -CustomDateFormat 'dddd, MMMM Do, YYYY','HH:mm MMM D, YY' .Example Add-CustomFormatForDatetimeSorting -CustomDateFormat 'DD.MM.YYYY HH:mm:ss' #> [CmdletBinding()] param([array]$DateTimeSortingFormat) if ($Script:Output) { Remove-Variable Output -Scope Script } if ($DateTimeSortingFormat) { [array]$Script:Output = foreach ($format in $DateTimeSortingFormat) { "$.fn.dataTable.moment( '$format' );" } } else { $Script:Output = "$.fn.dataTable.moment( 'L' );" } return $Script:Output } function Add-TableFiltering { [CmdletBinding()] param([bool] $Filtering, [ValidateSet('Top', 'Bottom', 'Both')][string]$FilteringLocation = 'Bottom') $Output = @{ } if ($Filtering) { if ($FilteringLocation -eq 'Bottom') { $Output.FilteringTopCode = @" // Setup - add a text input to each footer cell `$('#$DataTableName tfoot th').each(function () { var title = `$(this).text(); `$(this).html('<input type="text" placeholder="' + title + '" />'); }); "@ $Output.FilteringBottomCode = @" // Apply the search for footer cells table.columns().every(function () { var that = this; `$('input', this.footer()).on('keyup change', function () { if (that.search() !== this.value) { that.search(this.value).draw(); } }); }); "@ } elseif ($FilteringLocation -eq 'Both') { $Output.FilteringTopCode = @" // Setup - add a text input to each header cell `$('#$DataTableName thead th').each(function () { var title = `$(this).text(); `$(this).html('<input type="text" placeholder="' + title + '" />'); }); // Setup - add a text input to each footer cell `$('#$DataTableName tfoot th').each(function () { var title = `$(this).text(); `$(this).html('<input type="text" placeholder="' + title + '" />'); }); "@ $Output.FilteringBottomCode = @" // Apply the search for header cells table.columns().eq(0).each(function (colIdx) { `$('input', table.column(colIdx).header()).on('keyup change', function () { table .column(colIdx) .search(this.value) .draw(); }); `$('input', table.column(colIdx).header()).on('click', function (e) { e.stopPropagation(); }); }); // Apply the search for footer cells table.columns().every(function () { var that = this; `$('input', this.footer()).on('keyup change', function () { if (that.search() !== this.value) { that.search(this.value).draw(); } }); }); "@ } else { $Output.FilteringTopCode = @" // Setup - add a text input to each header cell `$('#$DataTableName thead th').each(function () { var title = `$(this).text(); `$(this).html('<input type="text" placeholder="' + title + '" />'); }); "@ $Output.FilteringBottomCode = @" // Apply the search for header cells table.columns().eq(0).each(function (colIdx) { `$('input', table.column(colIdx).header()).on('keyup change', function () { table .column(colIdx) .search(this.value) .draw(); }); `$('input', table.column(colIdx).header()).on('click', function (e) { e.stopPropagation(); }); }); "@ } } else { $Output.FilteringTopCode = $Output.FilteringBottomCode = '' } return $Output } function Add-TableState { [CmdletBinding()] param([bool] $Filtering, [bool] $SavedState, [string] $DataTableName, [ValidateSet('Top', 'Bottom', 'Both')][string]$FilteringLocation = 'Bottom') if ($Filtering -and $SavedState) { if ($FilteringLocation -eq 'Top') { $Output = @" // Setup - Looading text input from SavedState `$('#$DataTableName').on('stateLoaded.dt', function(e, settings, data) { settings.aoPreSearchCols.forEach(function(col, index) { if (col.sSearch) setTimeout(function() { `$('#$DataTableName thead th:eq('+index+') input').val(col.sSearch) }, 50) }) }); "@ } elseif ($FilteringLocation -eq 'Both') { $Output = @" // Setup - Looading text input from SavedState `$('#$DataTableName').on('stateLoaded.dt', function(e, settings, data) { settings.aoPreSearchCols.forEach(function(col, index) { if (col.sSearch) setTimeout(function() { `$('#$DataTableName thead th:eq('+index+') input').val(col.sSearch) }, 50) }) }); // Setup - Looading text input from SavedState `$('#$DataTableName').on('stateLoaded.dt', function(e, settings, data) { settings.aoPreSearchCols.forEach(function(col, index) { if (col.sSearch) setTimeout(function() { `$('#$DataTableName tfoot th:eq('+index+') input').val(col.sSearch) }, 50) }) }); "@ } else { $Output = @" // Setup - Looading text input from SavedState `$('#$DataTableName').on('stateLoaded.dt', function(e, settings, data) { settings.aoPreSearchCols.forEach(function(col, index) { if (col.sSearch) setTimeout(function() { `$('#$DataTableName tfoot th:eq('+index+') input').val(col.sSearch) }, 50) }) }) "@ } } else { $Output = '' } return $Output } function Convert-ImagesToBinary { [CmdLetBinding()] param([string[]] $Content, [string] $Search, [string] $ReplacePath) if ($Content -like "*$Search*") { $Replace = "data:image/$FileType;base64," + [Convert]::ToBase64String((Get-Content -LiteralPath $ReplacePath -Encoding Byte)) $Content = $Content.Replace($Search, $Replace) } $Content } function Convert-StyleContent { [CmdLetBinding()] param([string[]] $CSS, [string] $ImagesPath, [string] $SearchPath) $ImageFiles = Get-ChildItem -Path (Join-Path $ImagesPath '\*') -Include *.jpg, *.png, *.bmp foreach ($Image in $ImageFiles) { $CSS = Convert-ImagesToBinary -Content $CSS -Search "$SearchPath$($Image.Name)" -ReplacePath $Image.FullName } return $CSS } function Convert-StyleContent1 { param([PSCustomObject] $Options) if ($null -ne $Options.StyleContent) { Write-Verbose "Logos: $($Options.Logos.Keys -join ',')" foreach ($Logo in $Options.Logos.Keys) { $Search = "../images/$Logo.png", "DataTables-1.10.18/images/$Logo.png" $Replace = $Options.Logos[$Logo] foreach ($S in $Search) { Write-Verbose "Logos - replacing $S with binary representation" $Options.StyleContent = ($Options.StyleContent).Replace($S, $Replace) } } } } function Get-FeaturesInUse { [CmdletBinding()] param() foreach ($Key in $Script:HTMLSchema.Features.Keys) { if ($Script:HTMLSchema.Features[$Key]) { $Key } } } Function Get-HTMLColorSchemes { [CmdletBinding()] param ([Parameter(Mandatory = $false)][String]$SchemePath) if ([String]::IsNullOrEmpty($SchemePath)) { $SchemePath = "$PSScriptRoot\Resources\ColorSchemas" } $Schemes = @{ } Write-Verbose "Retrieving *.rcs from $SchemePath" $SchemeFiles = @(Get-ChildItem $SchemePath -Filter '*.rcs' -Recurse) foreach ($SchemeFile in $SchemeFiles) { $SchemeContent = Import-Csv -Delimiter ';' -Path $SchemeFile.FullName $Schemes.Add($SchemeFile.BaseName, $SchemeContent) } $Schemes.add('Generated1', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated2', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated3', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated4', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated5', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated6', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated7', (Get-RandomColorScheme -NumberOfSchemes 80)) $Schemes.add('Generated8', (Get-RandomColorScheme -NumberOfSchemes 80)) Write-Output $Schemes } Function Get-HTMLLogos { <# .SYNOPSIS Get Base64 HTML #> [CmdletBinding()] param ([Parameter(Mandatory = $false)] [string]$LeftLogoName = "Sample", [string]$RightLogoName = "Alternate", [string]$LeftLogoString, [string]$RightLogoString) $LogoSources = @{ } $LogoPath = @() if ([String]::IsNullOrEmpty($RightLogoString) -eq $false -or [String]::IsNullOrEmpty($LeftLogoString) -eq $false) { if ([String]::IsNullOrEmpty($RightLogoString) -eq $false) { $LogoSources.Add($RightLogoName, $RightLogoString) } if ([String]::IsNullOrEmpty($LeftLogoString) -eq $false) { $LogoSources.Add($LeftLogoName, $LeftLogoString) } } else { $LogoPath += "$PSScriptRoot\Resources\Images\Other" } $LogoPath += "$PSScriptRoot\Resources\Images\DataTables" $ImageFiles = Get-ChildItem -Path (Join-Path $LogoPath '\*') -Include *.jpg, *.png, *.bmp -Recurse foreach ($ImageFile in $ImageFiles) { if ($ImageFile.Extension -eq '.jpg') { $FileType = 'jpeg' } else { $FileType = $ImageFile.Extension.Replace('.', '') } Write-Verbose "Converting $($ImageFile.FullName) to base64 ($FileType)" $LogoSources.Add($ImageFile.BaseName, "data:image/$FileType;base64," + [Convert]::ToBase64String((Get-Content $ImageFile.FullName -Encoding Byte))) } Write-Output $LogoSources } function Get-HTMLPartContent { param([Array] $Content, [string] $Start, [string] $End, [ValidateSet('Before', 'Between', 'After')] $Type = 'Between') $NrStart = $Content.IndexOf($Start) $NrEnd = $Content.IndexOf($End) if ($Type -eq 'Between') { if ($NrStart -eq -1) { return } $Content[$NrStart..$NrEnd] } if ($Type -eq 'After') { if ($NrStart -eq -1) { return $Content } $Content[($NrEnd + 1)..($Content.Count - 1)] } if ($Type -eq 'Before') { if ($NrStart -eq -1) { return } $Content[0..$NrStart] } } Function Get-RandomColor { <# .SYNOPSIS Random colour Function #> param([int]$RMin = 0, [int]$RMax = 255, [int]$GMin = 0, [int]$GMax = 255, [int]$BMin = 0, [int]$BMax = 255) $R = (Get-Random -Maximum $RMax -Minimum $RMin) $G = (Get-Random -Maximum $GMax -Minimum $GMin) $B = (Get-Random -Maximum $BMax -Minimum $BMin) @($R, $G, $B) } Function Get-RandomColorScheme { <# .SYNOPSIS Generate a colour scheme .DESCRIPTION Generate a colour scheme .PARAMETER NumberOfSchemes Parameter description .EXAMPLE An example .NOTES General notes #> param ([Parameter(Mandatory = $false)][int]$NumberOfSchemes = 1, [int] $ColorSwing = 8, [string] $Hover = 0.3, [string] $color = 0.6, [string] $border = 1, [string] $background = 0.7) $ColorReference = Get-Random -Minimum 1 -Maximum 3 $BaseColor = (Get-Random -Maximum (200 - $ColorSwing) -Minimum (50 + $ColorSwing)) $BCMax = $BaseColor + $ColorSwing $BCMin = $BaseColor - $ColorSwing $i = 0 while ($i -ne $NumberOfSchemes) { switch ($ColorReference) { 1 { [int[]] $base = Get-RandomColor -rmin $BCMin -rmax $BCMax } 2 { [int[]] $base = Get-RandomColor -gmin $BCMin -gmax $BCMax } 3 { [int[]] $base = Get-RandomColor -bmin $BCMin -bcmax $BCMax } } [PSCustomObject] @{Background = "rgba($($base + $background -join ','))" Border = "rgba($($base + $border -join ','))" Colour = "rgba($($base + $color -join ','))" Hover = "rgba($($base + $Hover -join ','))" } $i++ } } function Get-Resources { [CmdLetBinding()] param([switch] $UseCssLinks, [switch] $UseJavaScriptLinks, [switch] $NoScript, [ValidateSet('Header', 'Footer', 'HeaderAlways', 'FooterAlways')][string] $Location) DynamicParam { $Names = $Script:Configuration.Features.Keys $ParamAttrib = New-Object System.Management.Automation.ParameterAttribute $ParamAttrib.Mandatory = $true $ParamAttrib.ParameterSetName = '__AllParameterSets' $ReportAttrib = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $ReportAttrib.Add($ParamAttrib) $ReportAttrib.Add((New-Object System.Management.Automation.ValidateSetAttribute($Names))) $ReportRuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Features', [string[]], $ReportAttrib) $RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $RuntimeParamDic.Add('Features', $ReportRuntimeParam) return $RuntimeParamDic } Process { [string[]] $Features = $PSBoundParameters.Features foreach ($Feature in $Features) { Write-Verbose "Get-Resources - Location: $Location - Feature: $Feature UseCssLinks: $UseCssLinks UseJavaScriptLinks: $UseJavaScriptLinks" if ($UseCssLinks) { New-HTMLResourceCSS -Link $Script:Configuration.Features.$Feature.$Location.'CssLink' -ResourceComment $Script:Configuration.Features.$Feature.Comment } else { $CSSOutput = New-HTMLResourceCSS -FilePath $Script:Configuration.Features.$Feature.$Location.'Css' -ResourceComment $Script:Configuration.Features.$Feature.Comment Convert-StyleContent -CSS $CSSOutput -ImagesPath "$PSScriptRoot\Resources\Images\DataTables" -SearchPath "DataTables-1.10.18/images/" } if ($UseJavaScriptLinks) { New-HTMLResourceJS -Link $Script:Configuration.Features.$Feature.$Location.'JsLink' -ResourceComment $Script:Configuration.Features.$Feature.Comment } else { New-HTMLResourceJS -FilePath $Script:Configuration.Features.$Feature.$Location.'Js' -ResourceComment $Script:Configuration.Features.$Feature.Comment } if ($NoScript) { [Array] $Output = @(if ($UseCssLinks) { New-HTMLResourceCSS -Link $Script:Configuration.Features.$Feature.$Location.'CssLinkNoScript' -ResourceComment $Script:Configuration.Features.$Feature.Comment } else { $CSSOutput = New-HTMLResourceCSS -FilePath $Script:Configuration.Features.$Feature.$Location.'CssNoScript' -ResourceComment $Script:Configuration.Features.$Feature.Comment Convert-StyleContent -CSS $CSSOutput -ImagesPath "$PSScriptRoot\Resources\Images\DataTables" -SearchPath "DataTables-1.10.18/images/" }) if (($Output.Count -gt 0) -and ($null -ne $Output[0])) { New-HTMLTag -Tag 'noscript' { $Output } } } } } } function New-ApexChart { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [ValidateSet('', 'central')][string] $Positioning) $Script:HTMLSchema.Features.ChartsApex = $true [string] $ID = "ChartID-" + (Get-RandomStringName -Size 8) $Div = New-HTMLTag -Tag 'div' -Attributes @{id = $ID; class = $Positioning } $Script = New-HTMLTag -Tag 'script' -Value { $JSON = $Options | ConvertTo-Json -Depth 5 | ForEach-Object { [System.Text.RegularExpressions.Regex]::Unescape($_) } "var options = $JSON" "" "var chart = new ApexCharts(document.querySelector('#$ID'), options );" "chart.render();" } $Div $Script:HTMLSchema.Charts.Add($Script) } function New-ChartArea { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [Array] $Data, [Array] $DataNames, [Array] $DataLegend, [ValidateSet('datetime', 'category', 'numeric')][string] $DataCategoriesType = 'category') $Options.chart = @{type = 'area' } $Options.series = @(New-HTMLChartDataSet -Data $Data -DataNames $DataNames) $Options.xaxis = [ordered] @{ } if ($DataCategoriesType -ne '') { $Options.xaxis.type = $DataCategoriesType } if ($DataCategories.Count -gt 0) { $Options.xaxis.categories = $DataCategories } } function New-ChartAxisX { param([System.Collections.IDictionary] $Options, [string] $Title, [int] $MinValue, [int] $MaxValue, [ValidateSet('datetime', 'category', 'numeric')][string] $DataCategoriesType = 'category', $DataCategories) if (-not $Options.Contains('xaxis')) { $Options.xaxis = @{ } } if ($Title -ne '') { $Options.xaxis.title = @{ } $Options.xaxis.title.text = $Title } if ($MinValue -gt 0) { $Options.xaxis.min = $MinValue } if ($MinValue -gt 0) { $Options.xaxis.max = $MaxValue } if ($DataCategoriesType -ne '') { $Options.xaxis.type = $DataCategoriesType } if ($DataCategories.Count -gt 0) { $Options.xaxis.categories = $DataCategories } } function New-ChartAxisY { param([System.Collections.IDictionary] $Options, [string] $Title, [int] $MinValue, [int] $MaxValue) if (-not $Options.Contains('yaxis')) { $Options.yaxis = @{ } } if ($Title -ne '') { $Options.yaxis.title = @{ } $Options.yaxis.title.text = $Title } if ($MinValue -gt 0) { $Options.yaxis.min = $MinValue } if ($MinValue -gt 0) { $Options.yaxis.max = $MaxValue } } Function New-ChartBar { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [bool] $Horizontal = $true, [bool] $DataLabelsEnabled = $true, [int] $DataLabelsOffsetX = -6, [string] $DataLabelsFontSize = '12px', [RGBColors[]] $DataLabelsColor, [string] $Title, [ValidateSet('center', 'left', 'right', '')][string] $TitleAlignment = '', [string] $Formatter, [ValidateSet('bar', 'barStacked', 'barStacked100Percent')] $Type = 'bar', [RGBColors[]] $Colors, [switch] $PatternedColors, [switch] $Distributed, [Array] $Data, [Array] $DataNames, [Array] $DataLegend) if ($Type -eq 'bar') { $Options.chart = [ordered] @{type = 'bar' } } elseif ($Type -eq 'barStacked') { $Options.chart = [ordered] @{type = 'bar' stacked = $true } } else { $Options.chart = [ordered] @{type = 'bar' stacked = $true stackType = '100%' } } if ($Colors.Count -gt 0) { $RGBColor = ConvertFrom-Color -Color $Colors $Options.colors = @($RGBColor) } $Options.plotOptions = @{bar = @{horizontal = $Horizontal } } if ($Distributed) { $Options.plotOptions.bar.distributed = $Distributed.IsPresent } $Options.dataLabels = [ordered] @{enabled = $DataLabelsEnabled offsetX = $DataLabelsOffsetX style = @{fontSize = $DataLabelsFontSize } } if ($null -ne $DataLabelsColor) { $RGBColorLabel = ConvertFrom-Color -Color $DataLabelsColor $Options.dataLabels.style.colors = @($RGBColorLabel) } $Options.series = @(New-HTMLChartDataSet -Data $Data -DataNames $DataLegend) $Options.xaxis = [ordered] @{ } if ($DataNames.Count -gt 0) { $Options.xaxis.categories = $DataNames } New-ChartTitle -Options $Options -Title $Title -TitleAlignment $TitleAlignment if ($PatternedColors) { $Options.fill = @{type = 'pattern' opacity = 1 pattern = @{style = @('circles', 'slantedLines', 'verticalLines', 'horizontalLines') } } } } function New-ChartDataLabels { param([System.Collections.IDictionary] $Options, [bool] $DataLabelsEnabled = $true, [int] $DataLabelsOffsetX = -6, [string] $DataLabelsFontSize = '12px', [RGBColors[]] $DataLabelsColor) $Options.dataLabels = [ordered] @{enabled = $DataLabelsEnabled offsetX = $DataLabelsOffsetX style = @{fontSize = $DataLabelsFontSize } } if ($DataLabelsColor.Count -gt 0) { $Options.dataLabels.style.colors = @(ConvertFrom-Color -Color $DataLabelsColor) } } function New-ChartGridColors { param([System.Collections.IDictionary] $Options, [RGBColors[]] $GridColors, [double] $GridOpacity) $Options.grid = @{ } $Options.grid.row = @{ } if ($GridColors.Count -gt 0) { $Options.grid.row.colors = @(ConvertFrom-Color -Color $GridColors) } if ($GridOpacity -ne 0) { $Options.grid.row.opacity = $GridOpacity } } function New-ChartLegend { param([System.Collections.IDictionary] $Options, [ValidateSet('top', 'topRight', 'left', 'right', 'bottom', '')][string] $LegendPosition = '') if ($LegendPosition -eq '' -or $LegendPosition -eq 'bottom') { } elseif ($LegendPosition -eq 'right') { $Options.legend = [ordered]@{position = 'right' offsetY = 100 height = 230 } } elseif ($LegendPosition -eq 'top') { $Options.legend = [ordered]@{position = 'top' horizontalAlign = 'left' offsetX = 40 } } elseif ($LegendPosition -eq 'topRight') { $Options.legend = [ordered]@{position = 'top' horizontalAlign = 'right' floating = true.exe offsetY = -25 offsetX = -5 } } } function New-ChartLine { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [Array] $Data, [Array] $DataNames, [ValidateSet('datetime', 'category', 'numeric')][string] $DataCategoriesType = 'category') $Options.chart = @{type = 'line' } $Options.series = @(New-HTMLChartDataSet -Data $Data -DataNames $DataNames) $Options.xaxis = [ordered] @{ } if ($DataCategoriesType -ne '') { $Options.xaxis.type = $DataCategoriesType } if ($DataCategories.Count -gt 0) { $Options.xaxis.categories = $DataCategories } } function New-ChartMarker { param([System.Collections.IDictionary] $Options, [int] $MarkerSize) if ($MarkerSize -gt 0) { $Options.markers = @{size = $MarkerSize } } } function New-ChartRadial { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [Array] $Values, [Array] $Names, $Type) $Options.chart = @{type = 'radialBar' } if ($Type -eq '1') { New-ChartRadialType1 -Options $Options } elseif ($Type -eq '2') { New-ChartRadialType2 -Options $Options } $Options.series = @($Values) $Options.labels = @($Names) } function New-ChartRadialCircleType { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [ValidateSet('FullCircleTop', 'FullCircleBottom', 'FullCircleBottomLeft', 'FullCircleLeft', 'Speedometer', 'SemiCircleGauge')] $CircleType) if ($CircleType -eq 'SemiCircleGauge') { $Options.plotOptions.radialBar = [ordered] @{startAngle = -90 endAngle = 90 } } elseif ($CircleType -eq 'FullCircleBottom') { $Options.plotOptions.radialBar = [ordered] @{startAngle = -180 endAngle = 180 } } elseif ($CircleType -eq 'FullCircleLeft') { $Options.plotOptions.radialBar = [ordered] @{startAngle = -90 endAngle = 270 } } elseif ($CircleType -eq 'FullCircleBottomLeft') { $Options.plotOptions.radialBar = [ordered] @{startAngle = -135 endAngle = 225 } } elseif ($CircleType -eq 'Speedometer') { $Options.plotOptions.radialBar = [ordered] @{startAngle = -135 endAngle = 135 } } else { } } function New-ChartRadialDataLabels { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [string] $LabelAverage = 'Average') if ($LabelAverage -ne '') { $Options.plotOptions.radialBar.dataLabels = @{showOn = 'always' name = @{ } value = @{ } total = @{show = $true label = $LabelAverage } } } } function New-ChartRadialType1 { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [Array] $Values, [Array] $Names) $Options.plotOptions = @{radialBar = [ordered] @{hollow = [ordered] @{margin = 0 size = '70%' background = '#fff' image = 'undefined' imageOffsetX = 0 imageOffsetY = 0 position = 'front' dropShadow = @{enabled = $true top = 3 left = 0 blur = 4 opacity = 0.24 } } track = [ordered] @{background = '#fff' strokeWidth = '70%' margin = 0 dropShadow = [ordered] @{enabled = $true top = -3 left = 0 blur = 4 opacity = 0.35 } } } } $Options.fill = [ordered] @{type = 'gradient' gradient = [ordered] @{shade = 'dark' type = 'horizontal' shadeIntensity = 0.5 gradientToColors = @('#ABE5A1') inverseColors = true.exe opacityFrom = 1 opacityTo = 1 stops = @(0, 100) } } $Options.stroke = [ordered] @{dashArray = 4 } } function New-ChartRadialType2 { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [Array] $Values, [Array] $Names) $Options.plotOptions = @{radialBar = [ordered] @{hollow = [ordered] @{margin = 0 size = '70%' background = '#fff' image = 'undefined' imageOffsetX = 0 imageOffsetY = 0 position = 'front' dropShadow = @{enabled = $true top = 3 left = 0 blur = 4 opacity = 0.24 } } } } } function New-ChartSize { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [nullable[int]] $Height = 350, [nullable[int]] $Width) if ($null -ne $Height) { $Options.chart.height = $Height } if ($null -ne $Width) { $Options.chart.width = $Width } } function New-ChartSpark { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [nullable[RGBColors]] $Color, [string] $Title, [string] $SubTitle, [int] $FontSizeTitle = 24, [int] $FontSizeSubtitle = 14, [Array] $Values) if ($Values.Count -eq 0) { Write-Warning 'Get-ChartSpark - Values Empty' } if ($null -ne $Color) { $ColorRGB = ConvertFrom-Color -Color $Color $Options.colors = @($ColorRGB) } $Options.chart = [ordered] @{type = 'area' sparkline = @{enabled = $true } } $Options.stroke = @{curve = 'straight' } $Options.title = [ordered] @{text = $Title offsetX = 0 style = @{fontSize = "$($FontSizeTitle)px" cssClass = 'apexcharts-yaxis-title' } } $Options.subtitle = [ordered] @{text = $SubTitle offsetX = 0 style = @{fontSize = "$($FontSizeSubtitle)px" cssClass = 'apexcharts-yaxis-title' } } $Options.yaxis = @{min = 0 } $Options.fill = @{opacity = 0.3 } $Options.series = @(if ($Values[0] -is [Array]) { foreach ($Value in $Values) { @{data = @($Value) } } } else { @{data = @($Values) } }) } function New-ChartStrokeDefinition { param([System.Collections.IDictionary] $Options, [bool] $LineShow = $true, [ValidateSet('straight', 'smooth', 'stepline')] $LineCurve = 'straight', [int] $LineWidth, [RGBColors[]] $LineColor) $Options.stroke = [ordered] @{show = $LineShow curve = $LineCurve } if ($LineWidth -ne 0) { $Options.stroke.width = $LineWidth } if ($LineColor.Count -gt 0) { $Options.stroke.colors = @(ConvertFrom-Color -Color $LineColor) } } function New-ChartTitle { param([System.Collections.IDictionary] $Options, [string] $Title, [ValidateSet('center', 'left', 'right', '')][string] $TitleAlignment = '') $Options.title = [ordered] @{ } if ($TitleText -ne '') { $Options.title.text = $Title } if ($TitleAlignment -ne '') { $Options.title.align = $TitleAlignment } } function New-ChartToolbar { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [bool] $Show = $true, [bool] $Download = $true, [bool] $Selection = $true, [bool] $Zoom = $true, [bool] $ZoomIn = $true, [bool] $ZoomOut = $true, [bool] $Pan = $true, [bool] $Reset = $true) $Options.chart.toolbar = [ordered] @{show = $show tools = [ordered] @{download = $Download selection = $Selection zoom = $Zoom zoomin = $ZoomIn zoomout = $ZoomOut pan = $Pan reset = $Reset } autoSelected = 'zoom' } } function New-ChartZoom { [CmdletBinding()] param([System.Collections.IDictionary] $Options, [switch] $Enabled) if ($Enabled) { $Options.chart.zoom = @{type = 'x' enabled = $Enabled.IsPresent } } } Function New-HTML { [CmdletBinding()] param([Parameter(Position = 0)][ValidateNotNull()][ScriptBlock] $HtmlData = $(Throw "Have you put the open curly brace on the next line?"), [switch] $UseCssLinks, [switch] $UseJavaScriptLinks, [String] $TitleText, [string] $Author, [string] $DateFormat = 'yyyy-MM-dd HH:mm:ss', [int] $AutoRefresh, [Parameter(Mandatory = $false)][string]$FilePath, [Parameter(Mandatory = $false)][switch]$ShowHTML, [ValidateSet('Unknown', 'String', 'Unicode', 'Byte', 'BigEndianUnicode', 'UTF8', 'UTF7', 'UTF32', 'Ascii', 'Default', 'Oem', 'BigEndianUTF32')] $Encoding = 'UTF8') [string] $CurrentDate = (Get-Date).ToString($DateFormat) $Script:HTMLSchema = @{TabsHeaders = [System.Collections.Generic.List[HashTable]]::new() Features = @{ } Charts = [System.Collections.Generic.List[string]]::new() } $OutputHTML = Invoke-Command -ScriptBlock $HtmlData if ($null -ne $OutputHTML -and $OutputHTML.Count -gt 0) { $Logo = Get-HTMLPartContent -Content $OutputHTML -Start '<!-- START LOGO -->' -End '<!-- END LOGO -->' -Type Between $OutputHTML = Get-HTMLPartContent -Content $OutputHTML -Start '<!-- START LOGO -->' -End '<!-- END LOGO -->' -Type After } $Features = Get-FeaturesInUse $HTML = @('<!DOCTYPE html>' New-HTMLTag -Tag 'html' { '<!-- HEADER -->' New-HTMLTag -Tag 'head' { New-HTMLTag -Tag 'meta' -Attributes @{charset = "utf-8" } -SelfClosing New-HTMLTag -Tag 'meta' -Attributes @{name = 'viewport'; content = 'width=device-width, initial-scale=1' } -SelfClosing New-HTMLTag -Tag 'meta' -Attributes @{name = 'author'; content = $Author } -SelfClosing New-HTMLTag -Tag 'meta' -Attributes @{name = 'revised'; content = $CurrentDate } -SelfClosing New-HTMLTag -Tag 'title' { $TitleText } if ($Autorefresh -gt 0) { New-HTMLTag -Tag 'meta' -Attributes @{'http-equiv' = 'refresh'; content = $Autorefresh } -SelfClosing } Get-Resources -UseCssLinks:$true -UseJavaScriptLinks:$true -Location 'HeaderAlways' -Features Default, DefaultHeadings, Fonts, FontsAwesome Get-Resources -UseCssLinks:$false -UseJavaScriptLinks:$false -Location 'HeaderAlways' -Features Default, DefaultHeadings if ($null -ne $Features) { Get-Resources -UseCssLinks:$true -UseJavaScriptLinks:$true -Location 'HeaderAlways' -Features $Features Get-Resources -UseCssLinks:$false -UseJavaScriptLinks:$false -Location 'HeaderAlways' -Features $Features Get-Resources -UseCssLinks:$true -UseJavaScriptLinks:$true -Location 'HeaderAlways' -Features $Features -NoScript Get-Resources -UseCssLinks:$false -UseJavaScriptLinks:$false -Location 'HeaderAlways' -Features $Features -NoScript Get-Resources -UseCssLinks:$UseCssLinks -UseJavaScriptLinks:$UseJavaScriptLinks -Location 'Header' -Features $Features } } '<!-- END HEADER -->' '<!-- BODY -->' New-HTMLTag -Tag 'body' { $Logo if ($Script:HTMLSchema.TabsHeaders) { New-HTMLTabHead } $OutputHTML foreach ($Chart in $Script:HTMLSchema.Charts) { $Chart } } '<!-- END BODY -->' '<!-- FOOTER -->' New-HTMLTag -Tag 'footer' { if ($null -ne $Features) { Get-Resources -UseCssLinks:$true -UseJavaScriptLinks:$true -Location 'FooterAlways' -Features $Features Get-Resources -UseCssLinks:$false -UseJavaScriptLinks:$false -Location 'FooterAlways' -Features $Features Get-Resources -UseCssLinks:$UseCssLinks -UseJavaScriptLinks:$UseJavaScriptLinks -Location 'Footer' -Features $Features } } '<!-- END FOOTER -->' }) if ($FilePath -ne '') { Save-HTML -HTML $HTML -FilePath $FilePath -ShowHTML:$ShowHTML -Encoding $Encoding } else { $HTML } } function New-HTMLAnchor { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Name Parameter description .PARAMETER Id Parameter description .PARAMETER Target Parameter description .PARAMETER Class Parameter description .PARAMETER HrefLink Parameter description .PARAMETER OnClick Parameter description .PARAMETER Style Parameter description .PARAMETER Text Parameter description .EXAMPLE New-HTMLAnchor -Target _parent New-HTMLAnchor -Id "show_$RandomNumber" -Href '#' -OnClick "show('$RandomNumber');" -Style "color: #ffffff; display:none;" -Text 'Show' Output: <a target = "_parent" /> .NOTES General notes #> param([alias('AnchorName')][string] $Name, [string] $Id, [string] $Target, [string] $Class, [alias('Url', 'Link', 'UrlLink', 'Href')][string] $HrefLink, [string] $OnClick, [string] $Style, [alias('AnchorText', 'Value')][string] $Text) $Attributes = [ordered]@{'id' = $Id 'name' = $Name 'class' = $Class 'target' = $Target 'href' = $HrefLink 'onclick' = $OnClick 'style' = $Style } New-HTMLTag -Tag 'a' -Attributes $Attributes { $Text } } Function New-HTMLAnchorLink { <# .SYNOPSIS Creates Hyperlink for an Anchor .DESCRIPTION Long description .PARAMETER AnchorName The Actual name of the Anchor (Hidden) .PARAMETER AnchorText The HyperLink text. Will default to $AnchorNname if not specified .EXAMPLE Get-HTMLAnchorLink -AnchorName 'test' .NOTES General notes #> [CmdletBinding()] Param ([Parameter(Mandatory = $true)][String] $AnchorName, [Parameter(Mandatory = $false)][String] $AnchorText) if ($AnchorText -eq $null -or $AnchorText -eq '') { $AnchorText = $AnchorName } New-HTMLAnchor -Name $AnchorName -HrefLink '#' -Class 'alink' -Text $AnchorText } Function New-HTMLAnchorName { <# .SYNOPSIS Creates an anchor .DESCRIPTION Long description .PARAMETER AnchorName Parameter description .EXAMPLE An example .NOTES General notes #> [CmdletBinding()] Param ([Parameter(Mandatory = $true)][String] $AnchorName) New-HTMLAnchor -Name $AnchorName } function New-HTMLCanvas { [CmdletBinding()] param([alias('Value')][Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $Content = $(Throw "Open curly brace with Content"), [string] $ID, [string] $Width, [string] $Height, [string] $Style) $Canvas = [Ordered] @{Tag = 'canvas' Attributes = [ordered]@{'id' = $Id 'width' = $Width 'height' = $Height 'style' = $Style } SelfClosing = $false Value = Invoke-Command -ScriptBlock $Content } $HTML = Set-Tag -HtmlObject $Canvas return $HTML } function New-HTMLChartArea { [CmdletBinding()] param([nullable[int]] $Height = 350, [nullable[int]] $Width, [ValidateSet('', 'central')][string] $Positioning, [bool] $DataLabelsEnabled = $true, [int] $DataLabelsOffsetX = -6, [string] $DataLabelsFontSize = '12px', [RGBColors[]] $DataLabelsColor, [ValidateSet('datetime', 'category', 'numeric')][string] $DataCategoriesType = 'category', [ValidateSet('straight', 'smooth', 'stepline')] $LineCurve = 'straight', [int] $LineWidth, [RGBColors[]] $LineColor, [RGBColors[]] $GridColors, [double] $GridOpacity, [string] $Title, [ValidateSet('center', 'left', 'right', '')][string] $TitleAlignment = '', [ValidateSet('top', 'topRight', 'left', 'right', 'bottom', '')][string] $LegendPosition = '', [string] $TitleX, [string] $TitleY, [int] $MarkerSize, [Array] $Data, [Array] $DataNames, [Array] $DataLegend, [switch] $Zoom) $Options = [ordered] @{ } New-ChartArea -Options $Options -Data $Data -DataNames $DataNames New-ChartStrokeDefinition -Options $Options -LineShow $true -LineCurve $LineCurve -LineWidth $LineWidth -LineColor $LineColor New-ChartDataLabels -Options $Options -DataLabelsEnabled $DataLabelsEnabled -DataLabelsOffsetX $DataLabelsOffsetX -DataLabelsFontSize $DataLabelsFontSize -DataLabelsColor $DataLabelsColor New-ChartAxisX -Options $Options -Title $TitleX -DataCategoriesType $DataCategoriesType -DataCategories $DataLegend New-ChartAxisY -Options $Options -Title $TitleY New-ChartMarker -Options $Options -MarkerSize $MarkerSize New-ChartTitle -Options $Options -Title $Title -TitleAlignment $TitleAlignment New-ChartGridColors -Options $Options -GridColors $GridColors -GridOpacity $GridOpacity New-ChartLegend -Options $Options -LegendPosition $LegendPosition New-ChartSize -Options $Options -Height $Height -Width $Width New-ChartZoom -Options $Options -Enabled:$Zoom New-ChartToolbar -Options $Options New-ApexChart -Positioning $Positioning -Options $Options } function New-HTMLChartBar { [CmdletBinding()] param([nullable[int]] $Height = 350, [nullable[int]] $Width, [ValidateSet('', 'central')][string] $Positioning, [ValidateSet('bar', 'barStacked', 'barStacked100Percent')] $Type = 'bar', [RGBColors[]] $Colors, [switch] $PatternedColors, [string] $Title, [ValidateSet('center', 'left', 'right', '')][string] $TitleAlignment = '', [bool] $Horizontal = $true, [bool] $DataLabelsEnabled = $true, [int] $DataLabelsOffsetX = -6, [string] $DataLabelsFontSize = '12px', [nullable[RGBColors]] $DataLabelsColor, [switch] $Distributed, [ValidateSet('top', 'topRight', 'left', 'right', 'bottom', '')][string] $LegendPosition = '', [Array] $Data, [Array] $DataNames, [Array] $DataLegend) $Options = [ordered] @{ } New-ChartBar -Options $Options -Horizontal $Horizontal -DataLabelsEnabled $DataLabelsEnabled -DataLabelsOffsetX $DataLabelsOffsetX -DataLabelsFontSize $DataLabelsFontSize -DataLabelsColor $DataLabelsColor -Data $Data -DataNames $DataNames -DataLegend $DataLegend -Title $Title -TitleAlignment $TitleAlignment -Type $Type -Colors $Colors -PatternedColors:$PatternedColors -Distributed:$Distributed New-ChartLegend -Options $Options -LegendPosition $LegendPosition New-ChartSize -Options $Options -Height $Height -Width $Width New-ChartToolbar -Options $Options New-ApexChart -Positioning $Positioning -Options $Options } function New-HTMLChartDataSet { [CmdletBinding()] param([Array] $Data, [Array] $DataNames) if ($null -ne $Data -and $null -ne $DataNames) { if ($Data[0] -is [Array]) { if ($Data[0].Count -eq $DataNames.Count) { for ($a = 0; $a -lt $Data.Count; $a++) { @{name = $DataNames[$a] data = $Data[$a] } } } elseif ($Data.Count -eq $DataNames.Count) { for ($a = 0; $a -lt $Data.Count; $a++) { @{name = $DataNames[$a] data = $Data[$a] } } } else { New-HTMLChartDataSet -Data $Data } } else { if ($null -ne $DataNames) { @{name = $DataNames data = $Data } } else { @{data = $Data } } } } elseif ($null -ne $Data) { if ($Data[0] -is [Array]) { foreach ($D in $Data) { @{data = $D } } } else { @{data = $Data } } } else { Write-Warning -Message "New-HTMLChartDataSet - No Data provided. Unabled to create dataset." return @{ } } } function New-HTMLChartLine { [CmdletBinding()] param([nullable[int]] $Height = 350, [nullable[int]] $Width, [ValidateSet('', 'central')][string] $Positioning, [bool] $DataLabelsEnabled = $true, [int] $DataLabelsOffsetX = -6, [string] $DataLabelsFontSize = '12px', [RGBColors[]] $DataLabelsColor, [ValidateSet('datetime', 'category', 'numeric')][string] $DataCategoriesType = 'category', [ValidateSet('straight', 'smooth', 'stepline')] $LineCurve = 'straight', [int] $LineWidth, [RGBColors[]] $LineColor, [RGBColors[]] $GridColors, [double] $GridOpacity, [string] $Title, [ValidateSet('center', 'left', 'right', '')][string] $TitleAlignment = '', [ValidateSet('top', 'topRight', 'left', 'right', 'bottom', '')][string] $LegendPosition = '', [string] $TitleX, [string] $TitleY, [int] $MarkerSize, [Array] $Data, [Array] $DataNames, [Array] $DataLegend) $Options = [ordered] @{ } New-ChartLine -Options $Options -Data $Data -DataNames $DataNames New-ChartStrokeDefinition -Options $Options -LineShow $true -LineCurve $LineCurve -LineWidth $LineWidth -LineColor $LineColor New-ChartDataLabels -Options $Options -DataLabelsEnabled $DataLabelsEnabled -DataLabelsOffsetX $DataLabelsOffsetX -DataLabelsFontSize $DataLabelsFontSize -DataLabelsColor $DataLabelsColor New-ChartAxisX -Options $Options -Title $TitleX -DataCategoriesType $DataCategoriesType -DataCategories $DataLegend New-ChartAxisY -Options $Options -Title $TitleY New-ChartMarker -Options $Options -MarkerSize $MarkerSize New-ChartTitle -Options $Options -Title $Title -TitleAlignment $TitleAlignment New-ChartGridColors -Options $Options -GridColors $GridColors -GridOpacity $GridOpacity New-ChartLegend -Options $Options -LegendPosition $LegendPosition New-ChartSize -Options $Options -Height $Height -Width $Width New-ChartToolbar -Options $Options New-ApexChart -Positioning $Positioning -Options $Options } function New-HTMLChartRadial { [CmdletBinding()] param([nullable[int]] $Height = 350, [nullable[int]] $Width, [ValidateSet('', 'central')][string] $Positioning, [Array] $Names, [Array] $Values, $Type, [ValidateSet('FullCircleTop', 'FullCircleBottom', 'FullCircleBottomLeft', 'FullCircleLeft', 'Speedometer', 'SemiCircleGauge')] $CircleType = 'FullCircleTop', [string] $LabelAverage) $Options = [ordered] @{ } New-ChartRadial -Options $Options -Names $Names -Values $Values -Type $Type New-ChartRadialCircleType -Options $Options -CircleType $CircleType New-ChartRadialDataLabels -Options $Options -Label $LabelAverage New-ChartSize -Options $Options -Height $Height -Width $Width New-ChartToolbar -Options $Options New-ApexChart -Positioning $Positioning -Options $Options } function New-HTMLChartSpark { [CmdletBinding()] param([nullable[int]] $Height = 350, [nullable[int]] $Width, [ValidateSet('', 'central')][string] $Positioning, [Array] $Data, [string] $TitleText, [string] $SubTitleText, [int] $FontSizeTitle = 24, [int] $FontSizeSubtitle = 14, [nullable[RGBColors]] $Color) $Options = [ordered] @{ } New-ChartSpark -Options $Options -Color $Color -Title $TitleText -SubTitle $SubTitleText -FontSizeTitle $FontSizeTitle -FontSizeSubtitle $FontSizeSubtitle -Values $Data New-ChartSize -Options $Options -Height $Height -Width $Width New-ChartToolbar -Options $Options New-ApexChart -Positioning $Positioning -Options $Options } Function New-HTMLCodeBlock { [CmdletBinding()] Param ([Parameter(Mandatory = $true)][String] $Code, [Parameter(Mandatory = $false)] [ValidateSet('assembly', 'asm', 'avrassembly', 'avrasm', 'c', 'cpp', 'c++', 'csharp', 'css', 'cython', 'cordpro', 'diff', 'docker', 'dockerfile', 'generic', 'standard', 'groovy', 'go', 'golang', 'html', 'ini', 'conf', 'java', 'js', 'javascript', 'jquery', 'mootools', 'ext.js', 'json', 'kotlin', 'less', 'lua', 'gfm', 'md', 'markdown', 'octave', 'matlab', 'nsis', 'php', 'powershell', 'prolog', 'py', 'python', 'raw', 'ruby', 'rust', 'scss', 'sass', 'shell', 'bash', 'sql', 'squirrel', 'swift', 'typescript', 'vhdl', 'visualbasic', 'vb', 'xml', 'yaml')] [String] $Style = 'powershell', [Parameter(Mandatory = $false)] [ValidateSet('enlighter', 'standard', 'classic', 'bootstrap4', 'beyond', 'godzilla', 'eclipse', 'mootwo', 'droide', 'minimal', 'atomic', 'dracula', 'rowhammer')][String] $Theme, [Parameter(Mandatory = $false)][String] $Group, [Parameter(Mandatory = $false)][String] $Title, [Parameter(Mandatory = $false)][String] $Highlight, [Parameter(Mandatory = $false)][nullable[bool]] $ShowLineNumbers, [Parameter(Mandatory = $false)][String] $LineOffset) $Script:HTMLSchema.Features.CodeBlocks = $true $Attributes = [ordered]@{'data-enlighter-language' = "$Style".ToLower() 'data-enlighter-theme' = "$Theme".ToLower() 'data-enlighter-group' = "$Group".ToLower() 'data-enlighter-title' = "$Title" 'data-enlighter-linenumbers' = "$ShowLineNumbers" 'data-enlighter-highlight' = "$Highlight" 'data-enlighter-lineoffset' = "$LineOffset".ToLower() } New-HTMLTag -Tag 'pre' -Attributes $Attributes { $Code } } function New-HTMLContainer { param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $HTML) New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultPanelOther' } { if ($HTML) { Invoke-Command -ScriptBlock $HTML } } } Function New-HTMLHeading { [CmdletBinding()] Param ([validateset('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7')][string]$Heading, [string]$HeadingText, [validateset('', 'central')][string] $Type, [switch] $Underline, [nullable[RGBColors]] $Color) if ($null -ne $Color) { $RGBcolor = ConvertFrom-Color -Color $Color $Attributes = @{style = "color: $RGBcolor;" } } else { $Attributes = @{ } } if ($Type -eq 'central') { $Attributes.Class = 'central' } if ($Underline) { $Attributes.Class = "$($Attributes.Class) underline" } New-HTMLTag -Tag $Heading -Attributes $Attributes { $HeadingText } } function New-HTMLHorizontalLine { [CmdletBinding()] param() New-HTMLTag -Tag 'hr' -SelfClosing } function New-HTMLImage { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Source Parameter description .PARAMETER UrlLink Parameter description .PARAMETER AlternativeText Parameter description .PARAMETER Class Parameter description .PARAMETER Target Parameter description .PARAMETER Width Parameter description .PARAMETER Height Parameter description .EXAMPLE New-HTMLImage -Source 'https://evotec.pl/image.png' -UrlLink 'https://evotc.pl/' -AlternativeText 'My other text' -Class 'otehr' -Width '100%' .NOTES General notes #> [CmdletBinding()] param([string] $Source, [Uri] $UrlLink = '', [string] $AlternativeText = '', [string] $Class = 'Logo', [string] $Target = '_blank', [string] $Width, [string] $Height) New-HTMLTag -Tag 'div' -Attributes @{class = $Class.ToLower() } { $AAttributes = [ordered]@{'target' = $Target 'href' = $UrlLink } New-HTMLTag -Tag 'a' -Attributes $AAttributes { $ImgAttributes = [ordered]@{'src' = "$Source" 'alt' = "$AlternativeText" 'width' = "$Height" 'height' = "$Width" } New-HTMLTag -Tag 'img' -Attributes $ImgAttributes } } } function New-HTMLList { [CmdletBinding()] param([ScriptBlock]$ListItems, [ValidateSet('Unordered', 'Ordered')] [string] $Type = 'Unordered', [RGBColors] $Color, [RGBColors] $BackGroundColor, [int] $FontSize, [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string] $FontWeight, [ValidateSet('normal', 'italic', 'oblique')][string] $FontStyle, [ValidateSet('normal', 'small-caps')][string] $FontVariant, [string] $FontFamily, [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment, [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, [ValidateSet('rtl')][string] $Direction, [switch] $LineBreak) $newHTMLSplat = @{ } if ($Alignment) { $newHTMLSplat.Alignment = $Alignment } if ($FontSize) { $newHTMLSplat.FontSize = $FontSize } if ($TextTransform) { $newHTMLSplat.TextTransform = $TextTransform } if ($Color) { $newHTMLSplat.Color = $Color } if ($FontFamily) { $newHTMLSplat.FontFamily = $FontFamily } if ($Direction) { $newHTMLSplat.Direction = $Direction } if ($FontStyle) { $newHTMLSplat.FontStyle = $FontStyle } if ($TextDecoration) { $newHTMLSplat.TextDecoration = $TextDecoration } if ($BackGroundColor) { $newHTMLSplat.BackGroundColor = $BackGroundColor } if ($FontVariant) { $newHTMLSplat.FontVariant = $FontVariant } if ($FontWeight) { $newHTMLSplat.FontWeight = $FontWeight } if ($LineBreak) { $newHTMLSplat.LineBreak = $LineBreak } [bool] $SpanRequired = $false foreach ($Entry in $newHTMLSplat.GetEnumerator()) { if ((Get-ObjectCount -Object $Entry.Value) -gt 0) { $SpanRequired = $true break } } if ($SpanRequired) { New-HTMLSpanStyle @newHTMLSplat { if ($Type -eq 'Unordered') { New-HTMLTag -Tag 'ul' { Invoke-Command -ScriptBlock $ListItems } } else { New-HTMLTag -Tag 'ol' { Invoke-Command -ScriptBlock $ListItems } } } } else { if ($Type -eq 'Unordered') { New-HTMLTag -Tag 'ul' { Invoke-Command -ScriptBlock $ListItems } } else { New-HTMLTag -Tag 'ol' { Invoke-Command -ScriptBlock $ListItems } } } } function New-HTMLListItem { [CmdletBinding()] param([string] $Text, [RGBColors[]] $Color = @(), [RGBColors[]] $BackGroundColor = @(), [int[]] $FontSize = @(), [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string[]] $FontWeight = @(), [ValidateSet('normal', 'italic', 'oblique')][string[]] $FontStyle = @(), [ValidateSet('normal', 'small-caps')][string[]] $FontVariant = @(), [string[]] $FontFamily = @(), [ValidateSet('left', 'center', 'right', 'justify')][string[]] $Alignment = @(), [ValidateSet('none', 'line-through', 'overline', 'underline')][string[]] $TextDecoration = @(), [ValidateSet('uppercase', 'lowercase', 'capitalize')][string[]] $TextTransform = @(), [ValidateSet('rtl')][string[]] $Direction = @(), [switch] $LineBreak) $newHTMLTextSplat = @{Alignment = $Alignment FontSize = $FontSize TextTransform = $TextTransform Text = $Text Color = $Color FontFamily = $FontFamily Direction = $Direction FontStyle = $FontStyle TextDecoration = $TextDecoration BackGroundColor = $BackGroundColor FontVariant = $FontVariant FontWeight = $FontWeight LineBreak = $LineBreak } if (($FontSize.Count -eq 0) -or ($FontSize -eq 0)) { $Size = '' } else { $size = "$($FontSize)px" } $Style = @{style = @{'color' = ConvertFrom-Color -Color $Color 'background-color' = ConvertFrom-Color -Color $BackGroundColor 'font-size' = $Size 'font-weight' = $FontWeight 'font-variant' = $FontVariant 'font-family' = $FontFamily 'font-style' = $FontStyle 'text-align' = $Alignment 'text-decoration' = $TextDecoration 'text-transform' = $TextTransform 'direction' = $Direction } } New-HTMLTag -Tag 'li' -Attributes $Style -Value { New-HTMLText @newHTMLTextSplat -SkipParagraph } } function New-HTMLLogo { param([String] $LogoPath, [string] $LeftLogoName = "Sample", [string] $RightLogoName = "Alternate", [string] $LeftLogoString, [string] $RightLogoString, [switch] $HideLogos) $LogoSources = Get-HTMLLogos -RightLogoName $RightLogoName -LeftLogoName $LeftLogoName -LeftLogoString $LeftLogoString -RightLogoString $RightLogoString Convert-StyleContent1 -Options $Options $Options = [PSCustomObject] @{Logos = $LogoSources ColorSchemes = $ColorSchemes } if ($HideLogos -eq $false) { $Leftlogo = $Options.Logos[$LeftLogoName] $Rightlogo = $Options.Logos[$RightLogoName] '<!-- START LOGO -->' $LogoContent = @" <table><tbody> <tr> <td class="clientlogo"><img src="$Leftlogo" /></td> <td class="MainLogo"><img src="$Rightlogo" /></td> </tr> </tbody></table> "@ $LogoContent '<!-- END LOGO -->' } } function New-HTMLMessage { param([Parameter(Mandatory = $false, Position = 0)][alias('')][ScriptBlock] $Content, $Text) $Script:HTMLSchema.Features.Message = $true New-HTMLTag -Tag 'div' -Attributes @{class = 'message green' } { New-HTMLTag -Tag 'div' -Attributes @{class = 'message-icon' } { New-HTMLTag -Tag 'i' -Attributes @{class = 'fa fa-bell-o' } } New-HTMLTag -Tag 'div' -Attributes @{class = 'message-body' } { New-HTMLTag -Tag 'p' -Attributes @{class = '' } { $Text } } } } Function New-HTMLPanel { [alias('New-HTMLColumn')] [CmdletBinding()] param ([Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $Content = $(Throw "Open curly brace with Content"), [alias('BackgroundShade')][RGBColors]$BackgroundColor, [switch] $Invisible) if ($null -ne $BackgroundColor) { $BackGroundColorFromRGB = ConvertFrom-Color -Color $BackgroundColor $DivColumnStyle = "background-color:$BackGroundColorFromRGB;" } else { $DivColumnStyle = "" } if ($Invisible) { $DivColumnStyle = "$DivColumnStyle box-shadow: unset !important;" } New-HTMLTag -Tag 'div' -Attributes @{class = "defaultPanel defaultCard"; style = $DivColumnStyle } { Invoke-Command -ScriptBlock $Content } } function New-HTMLResourceCSS { [alias('New-ResourceCSS', 'New-CSS')] [CmdletBinding()] param([alias('ScriptContent')][Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $Content, [string] $Link, [string] $ResourceComment, [string[]] $FilePath) $Output = @("<!-- CSS $ResourceComment START -->" foreach ($File in $FilePath) { if ($File -ne '') { if (Test-Path -LiteralPath $File) { New-HTMLTag -Tag 'style' -Attributes @{type = 'text/css' } { Write-Verbose "New-HTMLResourceCSS - Reading file from $File" Get-Content -LiteralPath $File } } } } foreach ($L in $Link) { if ($L -ne '') { Write-Verbose "New-HTMLResourceCSS - Adding link $L" New-HTMLTag -Tag 'link' -Attributes @{rel = "stylesheet"; type = "text/css"; href = $L } -SelfClosing } } "<!-- CSS $ResourceComment END -->") if ($Output.Count -gt 2) { $Output } } function New-HTMLResourceJS { [alias('New-ResourceJS', 'New-JavaScript')] [CmdletBinding()] param([alias('ScriptContent')][Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $Content, [string[]] $Link, [string] $ResourceComment, [string[]] $FilePath) $Output = @("<!-- JS $ResourceComment START -->" foreach ($File in $FilePath) { if ($File -ne '') { if (Test-Path -LiteralPath $File) { New-HTMLTag -Tag 'script' -Attributes @{type = 'text/javascript' } { Get-Content -LiteralPath $File } } else { return } } } foreach ($L in $Link) { if ($L -ne '') { New-HTMLTag -Tag 'script' -Attributes @{type = "text/javascript"; src = $L } } else { return } } "<!-- JS $ResourceComment END -->") if ($Output.Count -gt 2) { $Output } } Function New-HTMLSection { [alias('New-HTMLContent')] [CmdletBinding()] Param ([Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $Content = $(Throw "Open curly brace"), [Parameter(Mandatory = $false)][string]$HeaderText, [RGBColors]$HeaderTextColor = [RGBColors]::White, [string][ValidateSet('center', 'left', 'right', 'justify')] $HeaderTextAlignment = 'center', [RGBColors]$HeaderBackGroundColor = [RGBColors]::DeepSkyBlue, [alias('BackgroundShade')][RGBColors]$BackgroundColor = [RGBColors]::None, [Parameter(Mandatory = $false)][switch] $CanCollapse, [Parameter(Mandatory = $false)][switch] $IsHidden, [switch] $Collapsed, [int] $Height, [switch] $Invisible) $RandomNumber = Get-Random $TextHeaderColorFromRGB = ConvertFrom-Color -Color $HeaderTextColor if ($CanCollapse) { $Script:HTMLSchema.Features.HideSection = $true if ($IsHidden) { $ShowStyle = "color: $TextHeaderColorFromRGB;" $HideStyle = "color: $TextHeaderColorFromRGB; display:none;" } else { if ($Collapsed) { $HideStyle = "color: $TextHeaderColorFromRGB; display:none;" $ShowStyle = "color: $TextHeaderColorFromRGB;" $HiddenDivStyle = 'display:none;' } else { $ShowStyle = "color: $TextHeaderColorFromRGB; display:none;" $HideStyle = "color: $TextHeaderColorFromRGB;" } } } else { if ($IsHidden) { $ShowStyle = "color: $TextHeaderColorFromRGB;" $HideStyle = "color: $TextHeaderColorFromRGB; display:none;" } else { $ShowStyle = "color: $TextHeaderColorFromRGB; display:none;" $HideStyle = "color: $TextHeaderColorFromRGB; display:none;" } } if ($IsHidden) { $DivContentStyle = @{"display" = 'none' "height" = if ($Height -ne 0) { "height: $($Height)px" } else { '' } "background-color" = ConvertFrom-Color -Color $BackgroundColor } } else { $DivContentStyle = @{"height" = if ($Height -ne 0) { "height: $($Height)px" } else { '' } "background-color" = ConvertFrom-Color -Color $BackgroundColor } } $DivHeaderStyle = @{"text-align" = $HeaderTextAlignment "background-color" = ConvertFrom-Color -Color $HeaderBackGroundColor } $HeaderStyle = "color: $TextHeaderColorFromRGB;" if ($Invisible) { New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultContainerOther' } -Value { New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultContainerOther defaultPanelOther' } -Value { $Object = Invoke-Command -ScriptBlock $Content if ($null -ne $Object) { $Object } } } } else { New-HTMLTag -Tag 'div' -Attributes @{'class' = "defaultSection defaultCard"; 'style' = $DivContentStyle } -Value { New-HTMLTag -Tag 'div' -Attributes @{'class' = "defaultHeader"; 'style' = $DivHeaderStyle } -Value { New-HTMLAnchor -Name $HeaderText -Text $HeaderText -Style $HeaderStyle New-HTMLAnchor -Id "show_$RandomNumber" -Href 'javascript:void(0)' -OnClick "show('$RandomNumber');" -Style $ShowStyle -Text '(Show)' New-HTMLAnchor -Id "hide_$RandomNumber" -Href 'javascript:void(0)' -OnClick "hide('$RandomNumber');" -Style $HideStyle -Text '(Hide)' } New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultContainerOther'; id = $RandomNumber; Style = $HiddenDivStyle } -Value { New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultContainer defaultPanelOther collapsable'; id = $RandomNumber } -Value { $Object = Invoke-Command -ScriptBlock $Content if ($null -ne $Object) { $Object } } } } } } function New-HTMLSection1 { param([ScriptBlock] $Content, [string] $TextHeader) $ID = "AS-$(Get-RandomStringName -Size 8 -LettersOnly)" New-HTMLTag -Tag 'div' -Attributes @{id = 'aspect-content' } { New-HTMLTag -Tag 'div' -Attributes @{class = 'aspect-tab' } { New-HTMLTag -Tag 'input' -Attributes @{id = $ID; type = "checkbox"; class = "aspect-input"; name = "aspect" } -SelfClosing New-HTMLTag -Tag 'label' -Attributes @{for = $ID; class = "aspect-label" } New-HTMLTag -Tag 'div' -Attributes @{class = "aspect-content" } { New-HTMLTag -Tag 'div' -Attributes @{class = "aspect-info" } { New-HTMLTag -Tag 'div' -Attributes @{class = 'aspect-name' } { $TextHeader } } New-HTMLTag -Tag 'div' -Attributes @{class = "aspect-stat" } { New-HTMLSectionHeader -Text '14' -Type positive-count New-HTMLSectionHeader -Text '12' -Type neutral-count } } New-HTMLTag -Tag 'div' -Attributes @{class = "aspect-tab-content" } { New-HTMLTag -Tag 'div' -Attributes @{class = "sentiment-wrapper" } { if ($null -ne $Content) { & $Content } } } } } } function New-HTMLSubSection { param([ScriptBlock] $Content, [string] $Text, [string[]] $TextHeader, [ValidateSet('positive', 'negative', 'neutral')][string] $Type = 'positive') New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultPanel defaultCar' } { New-HTMLTag -Tag 'div' { New-HTMLTag -Tag 'div' -Attributes @{class = "$Type-count opinion-header" } { New-HTMLText -Text $TextHeader } New-HTMLTag -Tag 'div' { if ($null -ne $Content) { & $Content } } } } } function New-HTMLSectionHeader { param([ValidateSet('all-opinions', 'positive-count', 'neutral-count', 'negative-count')][string] $Type, [string] $Text) New-HTMLTag -Tag 'span' -Attributes @{class = $Type } { $Text } } function New-HTMLSpanStyle { [CmdletBinding()] param([ScriptBlock] $Content, [nullable[RGBColors]] $Color, [nullable[RGBColors]] $BackGroundColor, [int] $FontSize, [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string] $FontWeight, [ValidateSet('normal', 'italic', 'oblique')][string] $FontStyle, [ValidateSet('normal', 'small-caps')][string] $FontVariant, [string] $FontFamily, [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment, [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, [ValidateSet('rtl')][string] $Direction, [switch] $LineBreak) Write-Verbose 'New-SpanStyle - BEGIN' if ($FontSize -eq 0) { $Size = '' } else { $size = "$($FontSize)px" } $Style = @{style = @{'color' = ConvertFrom-Color -Color $Color 'background-color' = ConvertFrom-Color -Color $BackGroundColor 'font-size' = $Size 'font-weight' = $FontWeight 'font-variant' = $FontVariant 'font-family' = $FontFamily 'font-style' = $FontStyle 'text-align' = $Alignment 'text-decoration' = $TextDecoration 'text-transform' = $TextTransform 'direction' = $Direction } } if ($Alignment) { $StyleDiv = @{ } $StyleDiv.Align = $Alignment New-HTMLTag -Tag 'div' -Attributes $StyleDiv { New-HTMLTag -Tag 'span' -Attributes $Style { Invoke-Command -ScriptBlock $Content } } } else { New-HTMLTag -Tag 'span' -Attributes $Style { Invoke-Command -ScriptBlock $Content } } } function New-HTMLStatus { param([Parameter(Mandatory = $false, Position = 0)][alias('')][ScriptBlock] $Content) $Script:HTMLSchema.Features.StatusButtonical = $true New-HTMLTag -Tag 'div' -Attributes @{class = 'buttonicalService' } { Invoke-Command -ScriptBlock $Content } } function New-HTMLStatusItem { param($ServiceName, $ServiceStatus, [ValidateSet('Dead', 'Bad', 'Good')]$Icon = 'Good', [ValidateSet('0%', '10%', '30%', '70%', '100%')][string] $Percentage = '100%') if ($Icon -eq 'Dead') { $IconType = 'performanceDead' } elseif ($Icon -eq 'Bad') { $IconType = 'performanceProblem' } elseif ($Icon -eq 'Good') { } if ($Percentage -eq '100%') { $Colors = 'background-color: #0ef49b;' } elseif ($Percentage -eq '70%') { $Colors = 'background-color: #d2dc69;' } elseif ($Percentage -eq '30%') { $Colors = 'background-color: #faa04b;' } elseif ($Percentage -eq '10%') { $Colors = 'background-color: #ff9035;' } elseif ($Percentage -eq '0%') { $Colors = 'background-color: #ff5a64;' } New-HTMLTag -Tag 'div' -Attributes @{class = 'buttonical'; style = $Colors } -Value { New-HTMLTag -Tag 'div' -Attributes @{class = 'label' } { New-HTMLTag -Tag 'span' -Attributes @{class = 'performance' } { $ServiceName } } New-HTMLTag -Tag 'div' -Attributes @{class = 'middle' } New-HTMLTag -Tag 'div' -Attributes @{class = 'status' } { New-HTMLTag -Tag 'input' -Attributes @{name = Get-Random; type = 'radio'; value = 'other-item'; checked = 'true' } -SelfClosing New-HTMLTag -Tag 'span' -Attributes @{class = "performance $IconType" } { $ServiceStatus } } } } function New-HTMLTab { [CmdletBinding()] param([Parameter(Mandatory = $false, Position = 0)][ValidateNotNull()][ScriptBlock] $HtmlData = $(Throw "No curly brace?)"), [Parameter(Mandatory = $false, Position = 1)][String]$TabHeading, [string] $TabIcon = 'fas fa-bomb', [alias('Name')][string] $TabName) $Script:HTMLSchema.Features.Tabs = $true $Script:HTMLSchema.Features.JQuery = $true foreach ($Tab in $Script:HTMLSchema.TabsHeaders) { $Tab.Current = $false } $Tab = @{ } $Tab.ID = "Tab-$(Get-RandomStringName -Size 8)" $Tab.Name = $TabName $Tab.Current = $true if ($Script:HTMLSchema.TabsHeaders | Where-Object { $_.Active -eq $true }) { $Tab.Active = $false } else { $Tab.Active = $true } $Tab.TabIcon = $TabIcon $Script:HTMLSchema.TabsHeaders.Add($Tab) if ($Tab.Active) { $Class = 'tabs-content active' } else { $Class = 'tabs-content' } New-HTMLTag -Tag 'div' -Attributes @{id = $Tab.ID; class = $Class } { if (-not [string]::IsNullOrWhiteSpace($TabHeading)) { New-HTMLTag -Tag 'h7' { $TabHeading } } Invoke-Command -ScriptBlock $HtmlData } } function New-HTMLTabHead { [CmdletBinding()] Param () New-HTMLTag -Tag 'div' -Attributes @{class = 'tabsWrapper' } { New-HTMLTag -Tag 'div' -Attributes @{class = 'tabs' } { New-HTMLTag -Tag 'div' -Attributes @{class = 'selector' } foreach ($Tab in $Script:HTMLSchema.TabsHeaders) { $AttributesA = @{'href' = 'javascript:void(0)' 'data-id' = "$($Tab.Id)" } if ($Tab.Active) { $AttributesA.class = 'active' } else { $AttributesA.class = '' } New-HTMLTag -Tag 'a' -Attributes $AttributesA { New-HTMLTag -Tag 'div' -Attributes @{class = $Tab.TabIcon } -Value { $Tab.Name } } } } } } function New-HTMLTable { [CmdletBinding()] param([Parameter(Mandatory = $false, Position = 0)][ScriptBlock] $HTML, [Parameter(Mandatory = $false, Position = 1)][ScriptBlock] $PreContent, [Parameter(Mandatory = $false, Position = 2)][ScriptBlock] $PostContent, [alias('ArrayOfObjects', 'Object', 'Table')][Array] $DataTable, [string[]][ValidateSet('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5')] $Buttons = @('copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5'), [string[]][ValidateSet('numbers', 'simple', 'simple_numbers', 'full', 'full_numbers', 'first_last_numbers')] $PagingStyle = 'full_numbers', [int[]]$PagingOptions = @(15, 25, 50, 100), [switch]$DisablePaging, [switch]$DisableOrdering, [switch]$DisableInfo, [switch]$HideFooter, [switch]$DisableColumnReorder, [switch]$DisableProcessing, [switch]$DisableResponsiveTable, [switch]$DisableSelect, [switch]$DisableStateSave, [switch]$DisableSearch, [switch]$ScrollCollapse, [switch]$OrderMulti, [switch]$Filtering, [ValidateSet('Top', 'Bottom', 'Both')][string]$FilteringLocation = 'Bottom', [string[]][ValidateSet('display', 'cell-border', 'compact', 'hover', 'nowrap', 'order-column', 'row-border', 'stripe')] $Style = @('display', 'compact'), [switch]$Simplify, [string]$TextWhenNoData = 'No data available.', [int] $ScreenSizePercent = 0, [string[]] $DefaultSortColumn, [int[]] $DefaultSortIndex, [ValidateSet('Ascending', 'Descending')][string] $DefaultSortOrder = 'Ascending', [string[]] $DateTimeSortingFormat, [alias('Search')][string]$Find, [switch] $InvokeHTMLTags, [switch] $DisableNewLine) if (-not $Script:HTMLSchema.Features) { Write-Warning 'New-HTMLTable - Creation of HTML aborted. Most likely New-HTML is missing.' Exit } [Array] $Output = $HTML.Ast.EndBlock.Statements.Extent [Array] $OutputText = foreach ($Line in $Output) { [string] $Line + [System.Environment]::NewLine } $ConditionalFormattingText = foreach ($Line in $OutputText) { if ($Line.StartsWith('New-HTMLTableCondition') -or $Line.StartsWith('TableConditionalFormatting')) { $Line } } $OtherHTMLText = foreach ($Line in $OutputText) { if ((-not $Line.StartsWith('New-HTMLTableCondition')) -and (-not $Line.StartsWith('TableConditionalFormatting'))) { $Line } } if ($ConditionalFormattingText.Count -gt 0) { $ConditionalFormatting = [scriptblock]::Create($ConditionalFormattingText) } if ($OtherHTMLText.Count -gt 0) { $OtherHTML = [scriptblock]::Create($OtherHTMLText) } [string] $DataTableName = "DT-$(Get-RandomStringName -Size 8 -LettersOnly)" if ($null -eq $DataTable -or $DataTable.Count -eq 0) { $DataTable = $TextWhenNoData } if ($DataTable[0] -is [System.Collections.IDictionary]) { Write-Verbose 'New-HTMLTable - Working with IDictionary' [Array ] $Table = $($DataTable).GetEnumerator() | Select-Object Name, Value | ConvertTo-Html -Fragment | Select-Object -SkipLast 1 | Select-Object -Skip 2 } elseif ($DataTable[0] -is [string]) { [Array] $Table = $DataTable | ForEach-Object { [PSCustomObject]@{'Name' = $_ } } | ConvertTo-Html -Fragment | Select-Object -SkipLast 1 | Select-Object -Skip 2 } else { Write-Verbose 'New-HTMLTable - Working with Objects' [Array] $Table = $DataTable | ConvertTo-Html -Fragment | Select-Object -SkipLast 1 | Select-Object -Skip 2 } [string] $Header = $Table | Select-Object -First 1 [string[]] $HeaderNames = $Header -replace '</th></tr>' -replace '<tr><th>' -split '</th><th>' $Table = $Table | Select-Object -Skip 1 $Options = [ordered] @{dom = 'Bfrtip' buttons = @($Buttons) "colReorder" = -not $DisableColumnReorder.IsPresent "paging" = -not $DisablePaging "scrollCollapse" = $ScrollCollapse.IsPresent "pagingType" = $PagingStyle "lengthMenu" = @(@($PagingOptions, -1) @($PagingOptions, "All")) "ordering" = -not $DisableOrdering.IsPresent "order" = @() "info" = -not $DisableInfo.IsPresent "procesing" = -not $DisableProcessing.IsPresent "responsive" = @{details = -not $DisableResponsiveTable.IsPresent } "select" = -not $DisableSelect.IsPresent "searching" = -not $DisableSearch.IsPresent "stateSave" = -not $DisableStateSave.IsPresent } if ($OrderMulti) { $Options.orderMulti = $OrderMulti.IsPresent } if ($Find -ne '') { $Options.search = @{search = $Find } } if ($DefaultSortOrder -eq 'Ascending') { $Sort = 'asc' } else { $Sort = 'dsc' } if ($DefaultSortColumn.Count -gt 0) { $ColumnsOrder = foreach ($Column in $DefaultSortColumn) { $DefaultSortingNumber = ($HeaderNames).ToLower().IndexOf($Column.ToLower()) if ($DefaultSortingNumber -ne -1) { , @($DefaultSortingNumber, $Sort) } } } if ($DefaultSortIndex.Count -gt 0 -and $DefaultSortColumn.Count -eq 0) { $ColumnsOrder = foreach ($Column in $DefaultSortIndex) { if ($Column -ne -1) { , @($Column, $Sort) } } $Options."order" = @($ColumnsOrder) $Options.colReorder = $false } if ($ScreenSizePercent -gt 0) { $Options."scrollY" = "$($ScreenSizePercent)vh" } if ($null -ne $ConditionalFormatting) { $Options.columnDefs = '' } $Options = $Options | ConvertTo-Json -Depth 6 if ($null -ne $ConditionalFormatting) { $Conditional = Invoke-Command -ScriptBlock $ConditionalFormatting } $Options = New-TableConditionalFormatting -Options $Options -ConditionalFormatting $Conditional -Header $HeaderNames [Array] $Tabs = ($Script:HTMLSchema.TabsHeaders | Where-Object { $_.Current -eq $true }) if ($Tabs.Count -eq 0) { $Tab = @{Active = $true } } else { $Tab = $Tabs[0] } if (-not $Simplify) { $Script:HTMLSchema.Features.DataTables = $true $Script:HTMLSchema.Features.DataTablesPDF = $true $Script:HTMLSchema.Features.DataTablesExcel = $true $TableAttributes = @{id = $DataTableName; class = "$($Style -join ' ')" } $SortingFormatDateTime = Add-CustomFormatForDatetimeSorting -DateTimeSortingFormat $DateTimeSortingFormat $FilteringOutput = Add-TableFiltering -Filtering $Filtering -FilteringLocation $FilteringLocation $FilteringTopCode = $FilteringOutput.FilteringTopCode $FilteringBottomCode = $FilteringOutput.FilteringBottomCode $LoadSavedState = Add-TableState -DataTableName $DataTableName -Filtering $Filtering -FilteringLocation $FilteringLocation -SavedState (-not $DisableStateSave) if ($Tab.Active -eq $true) { New-HTMLTag -Tag 'script' { @" `$(document).ready(function() { $SortingFormatDateTime $LoadSavedState $FilteringTopCode // Table code var table = `$('#$DataTableName').DataTable( $($Options) ); $FilteringBottomCode }); "@ } } else { [string] $TabName = $Tab.Id New-HTMLTag -Tag 'script' { @" `$(document).ready(function() { $SortingFormatDateTime `$('.tabs').on('click', 'a', function (event) { if (`$(event.currentTarget).attr("data-id") == "$TabName" && !$.fn.dataTable.isDataTable("#$DataTableName")) { $LoadSavedState $FilteringTopCode // Table code var table = `$('#$DataTableName').DataTable( $($Options) ); $FilteringBottomCode }; }); }); "@ } } } else { $TableAttributes = @{class = 'sortable' } } if ($InvokeHTMLTags) { $Table = $Table -replace '<', '<' -replace '>', '>' -replace '&nbsp;', ' ' -replace '"', '"' -replace ''', "'" } if (-not $DisableNewLine) { $Table = $Table -replace '(?m)\s+$', "<BR>" } if ($OtherHTML) { $BeforeTableCode = Invoke-Command -ScriptBlock $OtherHTML } else { $BeforeTableCode = '' } if ($PreContent) { $BeforeTable = Invoke-Command -ScriptBlock $PreContent } else { $BeforeTable = '' } if ($PostContent) { $AfterTable = Invoke-Command -ScriptBlock $PostContent } else { $AfterTable = '' } New-HTMLTag -Tag 'div' -Attributes @{class = 'defaultPanelOther' } -Value { $BeforeTableCode $BeforeTable New-HTMLTag -Tag 'table' -Attributes $TableAttributes { New-HTMLTag -Tag 'thead' { $Header } New-HTMLTag -Tag 'tbody' { $Table } if (-not $HideFooter) { New-HTMLTag -Tag 'tfoot' { $Header } } } $AfterTable } } function New-HTMLTableCondition { [CmdletBinding()] param([alias('ColumnName')][string] $Name, [ValidateSet('number', 'string')][string] $Type, [ValidateSet('lt', 'le', 'eq', 'ge', 'gt')][string] $Operator, [Object] $Value, [switch] $Row, [nullable[RGBColors]] $Color, [nullable[RGBColors]] $BackgroundColor) return [PSCustomObject] @{Row = $Row; Type = $Type; Name = $Name; Operator = $Operator; Value = $Value; Color = $Color; BackgroundColor = $BackgroundColor } } function New-HTMLTag { [CmdletBinding()] param([Parameter(Mandatory = $false, Position = 0)][alias('Content')][ScriptBlock] $Value, [Parameter(Mandatory = $true, Position = 1)][string] $Tag, [System.Collections.IDictionary] $Attributes, [switch] $SelfClosing) $HTMLTag = [Ordered] @{Tag = $Tag Attributes = $Attributes Value = if ($null -eq $Value) { '' } else { Invoke-Command -ScriptBlock $Value } SelfClosing = $SelfClosing } $HTML = Set-Tag -HtmlObject $HTMLTag return $HTML } function New-HTMLText { [CmdletBinding()] param([string[]] $Text, [RGBColors[]] $Color = @(), [RGBColors[]] $BackGroundColor = @(), [int[]] $FontSize = @(), [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string[]] $FontWeight = @(), [ValidateSet('normal', 'italic', 'oblique')][string[]] $FontStyle = @(), [ValidateSet('normal', 'small-caps')][string[]] $FontVariant = @(), [string[]] $FontFamily = @(), [ValidateSet('left', 'center', 'right', 'justify')][string[]] $Alignment = @(), [ValidateSet('none', 'line-through', 'overline', 'underline')][string[]] $TextDecoration = @(), [ValidateSet('uppercase', 'lowercase', 'capitalize')][string[]] $TextTransform = @(), [ValidateSet('rtl')][string[]] $Direction = @(), [switch] $LineBreak, [switch] $SkipParagraph) $DefaultColor = $Color[0] $DefaultFontSize = $FontSize[0] $DefaultFontWeight = if ($null -eq $FontWeight[0]) { '' } else { $FontWeight[0] } $DefaultBackGroundColor = $BackGroundColor[0] $DefaultFontFamily = if ($null -eq $FontFamily[0]) { '' } else { $FontFamily[0] } $DefaultFontStyle = if ($null -eq $FontStyle[0]) { '' } else { $FontStyle[0] } $DefaultTextDecoration = if ($null -eq $TextDecoration[0]) { '' } else { $TextDecoration[0] } $DefaultTextTransform = if ($null -eq $TextTransform[0]) { '' } else { $TextTransform[0] } $DefaultFontVariant = if ($null -eq $FontVariant[0]) { '' } else { $FontVariant } $DefaultDirection = if ($null -eq $Direction[0]) { '' } else { $Direction[0] } $DefaultAlignment = if ($null -eq $Alignment[0]) { '' } else { $Alignment[0] } $Output = for ($i = 0; $i -lt $Text.Count; $i++) { if ($null -eq $FontWeight[$i]) { $ParamFontWeight = $DefaultFontWeight } else { $ParamFontWeight = $FontWeight[$i] } if ($null -eq $FontSize[$i]) { $ParamFontSize = $DefaultFontSize } else { $ParamFontSize = $FontSize[$i] } if ($null -eq $Color[$i]) { $ParamColor = $DefaultColor } else { $ParamColor = $Color[$i] } if ($null -eq $BackGroundColor[$i]) { $ParamBackGroundColor = $DefaultBackGroundColor } else { $ParamBackGroundColor = $BackGroundColor[$i] } if ($null -eq $FontFamily[$i]) { $ParamFontFamily = $DefaultFontFamily } else { $ParamFontFamily = $FontFamily[$i] } if ($null -eq $FontStyle[$i]) { $ParamFontStyle = $DefaultFontStyle } else { $ParamFontStyle = $FontStyle[$i] } if ($null -eq $TextDecoration[$i]) { $ParamTextDecoration = $DefaultTextDecoration } else { $ParamTextDecoration = $TextDecoration[$i] } if ($null -eq $TextTransform[$i]) { $ParamTextTransform = $DefaultTextTransform } else { $ParamTextTransform = $TextTransform[$i] } if ($null -eq $FontVariant[$i]) { $ParamFontVariant = $DefaultFontVariant } else { $ParamFontVariant = $FontVariant[$i] } if ($null -eq $Direction[$i]) { $ParamDirection = $DefaultDirection } else { $ParamDirection = $Direction[$i] } if ($null -eq $Alignment[$i]) { $ParamAlignment = $DefaultAlignment } else { $ParamAlignment = $Alignment[$i] } $newSpanTextSplat = @{ } $newSpanTextSplat.Color = $ParamColor $newSpanTextSplat.BackGroundColor = $ParamBackGroundColor $newSpanTextSplat.FontSize = $ParamFontSize if ($ParamFontWeight -ne '') { $newSpanTextSplat.FontWeight = $ParamFontWeight } $newSpanTextSplat.FontFamily = $ParamFontFamily if ($ParamFontStyle -ne '') { $newSpanTextSplat.FontStyle = $ParamFontStyle } if ($ParamFontVariant -ne '') { $newSpanTextSplat.FontVariant = $ParamFontVariant } if ($ParamTextDecoration -ne '') { $newSpanTextSplat.TextDecoration = $ParamTextDecoration } if ($ParamTextTransform -ne '') { $newSpanTextSplat.TextTransform = $ParamTextTransform } if ($ParamDirection -ne '') { $newSpanTextSplat.Direction = $ParamDirection } if ($ParamAlignment -ne '') { $newSpanTextSplat.Alignment = $ParamAlignment } $newSpanTextSplat.LineBreak = $LineBreak New-HTMLSpanStyle @newSpanTextSplat { if ($Text[$i] -match "\[([^\[]*)\)") { $RegexBrackets1 = [regex] "\[([^\[]*)\]" $RegexBrackets2 = [regex] "\(([^\[]*)\)" $RegexBrackets3 = [regex] "\[([^\[]*)\)" $Text1 = $RegexBrackets1.match($Text[$i]).Groups[1].value $Text2 = $RegexBrackets2.match($Text[$i]).Groups[1].value $Text3 = $RegexBrackets3.match($Text[$i]).Groups[0].value if ($Text1 -ne '' -and $Text2 -ne '') { $Link = New-HTMLAnchor -HrefLink $Text2 -Text $Text1 $Text[$i].Replace($Text3, $Link) } } else { $Text[$i] } } } if ($SkipParagraph) { $Output -join '' } else { New-HTMLTag -Tag 'div' { $Output } } if ($LineBreak) { New-HTMLTag -Tag 'br' -SelfClosing } } function New-HTMLTimeline { param([Parameter(Mandatory = $false, Position = 0)][alias('TimeLineItems')][ScriptBlock] $Content) $Script:HTMLSchema.Features.TimeLine = $true New-HTMLTag -Tag 'div' -Attributes @{class = 'timelineSimpleContainer' } { if ($null -eq $Value) { '' } else { Invoke-Command -ScriptBlock $Content } } } function New-HTMLTimelineItem { [CmdletBinding()] param([DateTime] $Date = (Get-Date), [string] $HeadingText, [string] $Text, [nullable[RGBColors]] $Color) $Attributes = @{class = 'timelineSimple-item' "date-is" = $Date } if ($null -ne $Color) { $RGBcolor = ConvertFrom-Color -Color $Color $Style = "color: $RGBcolor;" } else { $Style = '' } New-HTMLTag -Tag 'div' -Attributes $Attributes -Value { New-HTMLTag -Tag 'h1' -Attributes @{class = 'timelineSimple'; style = $style } { $HeadingText } New-HTMLTag -Tag 'p' -Attributes @{class = 'timelineSimple' } { $Text -Replace [Environment]::NewLine, '<br>' -replace '\n', '<br>' } } } function New-HTMLToast { [CmdletBinding()] param([string] $TextHeader, [string] $Text, [ValidateSet('Green', 'Blue', 'Orange')] $Color = "Green", [ValidateSet('Success', 'Information', 'Exclamation')][string] $Icon = 'Success', [string] $Type = 'central') $Script:HTMLSchema.Features.Toast = $true if ($Type -eq 'central') { $DivClass = "toast $($Color.ToLower()) central" } else { $DivClass = "toast $($Color.ToLower())" } New-HTMLTag -Tag 'div' -Attributes @{class = $DivClass } { New-HTMLTag -Tag 'div' -Attributes @{class = 'toast__icon' } { if ($Icon -eq 'Success') { New-IconSuccess } elseif ($Icon -eq 'Information') { New-IconInfo } elseif ($Icon -eq 'Exclamation') { New-IconExclamation } } New-HTMLTag -Tag 'div' -Attributes @{class = 'toast__content' } { New-HTMLTag -Tag 'p' -Attributes @{class = 'toast__type' } { $TextHeader } New-HTMLTag -Tag 'p' -Attributes @{class = 'toast__message' } { $Text } } } } function New-IconExclamation { <# .SYNOPSIS This function is used for New-HTMLToast .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> [CmdletBinding()] param() $SvgAttributes = [ordered] @{version = "1.1" class = "toast__svg" xmlns = "http://www.w3.org/2000/svg" 'xmlns:xlink' = "http://www.w3.org/1999/xlink" x = "0px" y = "0px" viewBox = "0 0 301.691 301.691" style = "enable-background:new 0 0 301.691 301.691;" 'xml:space' = "preserve" } New-HTMLTag -Tag 'svg' -Attributes $SvgAttributes { $Points = @{points = "119.151,0 129.6,218.406 172.06,218.406 182.54,0 " } New-HTMLTag -Tag 'polygon' -Attributes $Points $React = @{x = "130.563" y = "261.168" width = "40.525" height = "40.523" } New-HTMLTag -Tag 'react' -Attributes $React } } function New-IconInfo { <# .SYNOPSIS This function is used for New-HTMLToast .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> [CmdletBinding()] param() $SvgAttributes = [ordered] @{version = "1.1" class = "toast__svg" xmlns = "http://www.w3.org/2000/svg" 'xmlns:xlink' = "http://www.w3.org/1999/xlink" x = "0px" y = "0px" viewBox = "0 0 32 32" style = "enable-background:new 0 0 32 32;" 'xml:space' = "preserve" } New-HTMLTag -Tag 'svg' -Attributes $SvgAttributes { $PathAttributes = @{d = "M10,16c1.105,0,2,0.895,2,2v8c0,1.105-0.895,2-2,2H8v4h16v-4h-1.992c-1.102,0-2-0.895-2-2L20,12H8 v4H10z" } New-HTMLTag -Tag 'path' -Attributes $PathAttributes New-HTMLTag -Tag 'circle' -Attributes @{cx = "16"; cy = "4"; r = "4" } } } function New-IconSuccess { <# .SYNOPSIS This function is used for New-HTMLToast .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> [CmdletBinding()] param() $SvgAttributes = [ordered] @{version = "1.1" class = "toast__svg" xmlns = "http://www.w3.org/2000/svg" 'xmlns:xlink' = "http://www.w3.org/1999/xlink" x = "0px" y = "0px" viewBox = "0 0 512 512" style = "enable-background:new 0 0 512 512;" 'xml:space' = "preserve" } New-HTMLTag -Tag 'svg' -Attributes $SvgAttributes { $PathAttributes = @{d = "M504.502,75.496c-9.997-9.998-26.205-9.998-36.204,0L161.594,382.203L43.702,264.311c-9.997-9.998-26.205-9.997-36.204,0 c-9.998,9.997-9.998,26.205,0,36.203l135.994,135.992c9.994,9.997,26.214,9.99,36.204,0L504.502,111.7 C514.5,101.703,514.499,85.494,504.502,75.496z" } New-HTMLTag -Tag 'path' -Attributes $PathAttributes } } function New-TableConditionalFormatting { [CmdletBinding()] param([string] $Options, [Array] $ConditionalFormatting, [string[]] $Header) if ($ConditionalFormatting.Count -gt 0) { foreach ($Formatting in $ConditionalFormatting) { if ($Formatting.Operator -eq 'gt') { $Formatting.Operator = '>' } elseif ($Formatting.Operator -eq 'lt') { $Formatting.Operator = '<' } elseif ($Formatting.Operator -eq 'eq') { $Formatting.Operator = '==' } elseif ($Formatting.Operator -eq 'le') { $Formatting.Operator = '<=' } elseif ($Formatting.Operator -eq 'ge') { $Formatting.Operator = '>=' } } $Condition1 = '"createdRow": function (row, data, dataIndex, column) {' $Condition3 = foreach ($Condition in $ConditionalFormatting) { $ConditionHeaderNr = $Header.ToLower().IndexOf($($Condition.Name.ToLower())) [string] $ColorJSDefinition = '' [string] $ColorBackgroundJSDefinition = '' if ($null -ne $Condition.Color) { $RGBColor = (ConvertFrom-Color -Color $Condition.Color) $C = @{"color" = $RGBColor } | ConvertTo-Json $ColorJSDefinition = ".css($C)" } if ($null -ne $Condition.BackgroundColor) { $RGBBackgroundColor = (ConvertFrom-Color -Color $Condition.BackgroundColor) $BG = @{"background-color" = $RGBBackgroundColor } | ConvertTo-Json $ColorBackgroundJSDefinition = ".css($BG)" } if ($null -eq $Condition.Type -or $Condition.Type -eq 'number') { "if (data[$ConditionHeaderNr] $($Condition.Operator) $($Condition.Value)) {" } elseif ($Condition.Type -eq 'string') { "if (data[$ConditionHeaderNr] $($Condition.Operator) '$($Condition.Value)') {" } elseif ($Condition.Type -eq 'date') { "if (new Date(data[$ConditionHeaderNr]) $($Condition.Operator) new Date('$($Condition.Value)')) {" } if ($null -ne $Condition.Row -and $Condition.Row -eq $true) { "`$(column)$($ColorJSDefinition)$($ColorBackgroundJSDefinition);" } else { "`$(column[$ConditionHeaderNr])$($ColorJSDefinition)$($ColorBackgroundJSDefinition);" } "}" } $Condition5 = '}' $Test = $Condition1 + $Condition3 + $Condition5 $Options = $Options -Replace ('"columnDefs": ""', $Test) } return $Options } function Out-HtmlView { <# .SYNOPSIS Small function that allows to send output to HTML .DESCRIPTION Small function that allows to send output to HTML. When displaying in HTML it allows data to output to EXCEL, CSV and PDF. It allows sorting, searching and so on. .PARAMETER Table Data you want to display .PARAMETER Title Title of HTML Window .PARAMETER DefaultSortColumn Sort by Column Name .PARAMETER DefaultSortIndex Sort by Column Index .EXAMPLE Get-Process | Select-Object -First 5 | Out-HtmlView .NOTES General notes #> [alias('Out-GridHtml', 'ohv')] [CmdletBinding()] param([Parameter(ValueFromPipeline = $true, Mandatory = $true)] $Table, [string[]] $PriorityProperties, [string] $Title = 'Out-HTMLView', [string[]] $DefaultSortColumn, [int[]] $DefaultSortIndex, [string] $FilePath, [switch] $DisablePaging, [switch] $PassThru, [switch]$Filtering, [ValidateSet('Top', 'Bottom', 'Both')][string]$FilteringLocation = 'Bottom', [alias('Search')][string]$Find, [switch] $InvokeHTMLTags, [switch] $DisableNewLine) Begin { $DataTable = [System.Collections.Generic.List[Object]]::new() if ($FilePath -eq '') { $FilePath = Get-FileName -Extension 'html' -Temporary } } Process { foreach ($T in $Table) { $DataTable.Add($T) } } End { if ($DataTable.Count -gt 0) { $Properties = $DataTable[0].PSObject.Properties.Name $RemainingProperties = foreach ($Property in $Properties) { if ($PriorityProperties -notcontains $Property) { $Property } } $AllProperties = $PriorityProperties + $RemainingProperties $DataTable = $DataTable | Select-Object -Property $AllProperties } New-HTML -FilePath $FilePath -UseCssLinks -UseJavaScriptLinks -TitleText $Title -ShowHTML { New-HTMLTable -DataTable $DataTable -DefaultSortColumn $DefaultSortColumn -DefaultSortIndex $DefaultSortIndex -DisablePaging:$DisablePaging -Filtering:$Filtering -FilteringLocation $FilteringLocation -Find $Find -InvokeHTMLTags:$InvokeHTMLTags -DisableNewLine:$DisableNewLine } if ($PassThru) { $DataTable } } } Function Save-HTML { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER FilePath Parameter description .PARAMETER HTML Parameter description .PARAMETER ShowReport Parameter description .EXAMPLE An example .NOTES General notes #> [CmdletBinding()] Param ([Parameter(Mandatory = $false)][string]$FilePath, [Parameter(Mandatory = $true)][Array] $HTML, [Parameter(Mandatory = $false)][switch]$ShowHTML, [ValidateSet('Unknown', 'String', 'Unicode', 'Byte', 'BigEndianUnicode', 'UTF8', 'UTF7', 'UTF32', 'Ascii', 'Default', 'Oem', 'BigEndianUTF32')] $Encoding = 'UTF8', [bool] $Supress = $true) if ([string]::IsNullOrEmpty($FilePath)) { $FilePath = Get-FileName -Temporary -Extension 'html' Write-Warning "Save-HTML - FilePath parameter $FilePath is empty, using Temporary $FilePath" } else { if (Test-Path -LiteralPath $FilePath) { Write-Warning "Save-HTML - Path $FilePath already exists. Report will be overwritten." } } Write-Verbose "Save-HTML - Saving HTML to file $FilePath" try { $HTML | Set-Content -LiteralPath $FilePath -Force -Encoding $Encoding if (-not $Supress) { $FilePath } } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning "Save-HTML - Failed with error: $ErrorMessage" } if ($ShowHTML) { try { Invoke-Item -LiteralPath $FilePath -ErrorAction Stop } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning "Save-HTML - couldn't open file $FilePath in a browser. Error: $ErrorMessage" } } } $Script:Configuration = [ordered] @{Features = [ordered] @{Default = @{Comment = 'Always Required Default Visual Settings' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\default.css" } } DefaultHeadings = @{Comment = 'Always Required Default Headings' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\headings.css" } } Accordion = @{Comment = 'Accordion' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\accordion-1.css" } } CodeBlocks = @{Comment = 'EnlighterJS CodeBlocks' Header = @{CssLink = 'https://evotec.xyz/wp-content/uploads/pswritehtml/enlighterjs.min.css' Css = "$PSScriptRoot\Resources\CSS\enlighterjs.min.css" JsLink = 'https://evotec.xyz/wp-content/uploads/pswritehtml/enlighterjs.min.js' JS = "$PSScriptRoot\Resources\JS\enlighterjs.min.js" } Footer = @{ } HeaderAlways = @{ } FooterAlways = @{JS = "$PSScriptRoot\Resources\JS\enlighterjs-footer.js" } } Charts = @{Comment = 'Charts JS' Header = @{JsLink = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js' } } ChartsApex = @{Comment = 'Apex Charts' Header = @{JsLink = 'https://cdn.jsdelivr.net/npm/apexcharts@latest' JS = "$PSScriptRoot\Resources\JS\apexcharts.min.js" } HeaderAlways = @{ } } Jquery = @{Comment = 'Jquery' Header = @{JsLink = 'http://code.jquery.com/jquery-3.3.1.min.js' Js = "$PSScriptRoot\Resources\JS\jquery-3.3.1.min.js" } } DataTables = @{Comment = 'DataTables' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\datatables.css" CssNoscript = "$PSScriptRoot\Resources\CSS\datatables.noscript.css" } Header = @{CssLink = 'https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/af-2.3.2/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/b-print-1.5.4/cr-1.5.0/fc-3.2.5/fh-3.1.4/kt-2.5.0/r-2.2.2/rg-1.1.0/rr-1.2.4/sc-1.5.0/sl-1.2.6/datatables.min.css' Css = "$PSScriptRoot\Resources\CSS\datatables.min.css" JsLink = "https://cdn.datatables.net/v/dt/jq-3.3.1/dt-1.10.18/af-2.3.2/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/b-print-1.5.4/cr-1.5.0/fc-3.2.5/fh-3.1.4/kt-2.5.0/r-2.2.2/rg-1.1.0/rr-1.2.4/sc-1.5.0/sl-1.2.6/datatables.min.js", "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js", "https://cdn.datatables.net/plug-ins/1.10.19/sorting/datetime-moment.js" JS = "$PSScriptRoot\Resources\JS\datatables.min.js", "$PSScriptRoot\Resources\JS\moment.min.js", "$PSScriptRoot\Resources\JS\datetime-moment.js" } } DataTablesPDF = @{Comment = 'DataTables PDF Features' Header = @{JsLink = 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js' Js = "$PSScriptRoot\Resources\JS\pdfmake.min.js", "$PSScriptRoot\Resources\JS\vfs_fonts.min.js" } } DataTablesExcel = @{Comment = 'DataTables Excel Features' Header = @{JsLink = 'https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js' JS = "$PSScriptRoot\Resources\JS\jszip.min.js" } } Fonts = @{Comment = 'Default fonts' HeaderAlways = @{CssLink = 'https://fonts.googleapis.com/css?family=Roboto|Hammersmith+One|Questrial|Oswald' } } FontsAwesome = @{Comment = 'Default fonts icons' HeaderAlways = @{CssLink = 'https://use.fontawesome.com/releases/v5.7.2/css/all.css' } } HideSection = @{Comment = 'Hide Section Code' HeaderAlways = @{JS = "$PSScriptRoot\Resources\JS\HideSection.js" } } Tabs = @{Comment = 'Elastic Tabs' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\tabs-elastic.css" } FooterAlways = @{JS = "$PSScriptRoot\Resources\JS\tabs-elastic.js" } } TimeLine = @{Comment = 'Timeline Simple' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\timeline-simple.css" } } StatusButtonical = @{Comment = 'Status Buttonical' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\status.css" } } Toast = @{Comment = 'Toasts Looking Messages' HeaderAlways = @{Css = "$PSScriptRoot\Resources\CSS\toasts.css" } } TuiGrid = @{Comment = 'Tui Grid' Header = @{Css = "$PSScriptRoot\Resources\CSS\tuigrid.css" CssLink = 'https://cdn.jsdelivr.net/npm/tui-grid@3.5.0/dist/tui-grid.css' } } } } function Set-Tag { [CmdletBinding()] param([System.Collections.IDictionary] $HtmlObject) $HTML = [System.Text.StringBuilder]::new() [void] $HTML.Append("<$($HtmlObject.Tag)") foreach ($Property in $HtmlObject.Attributes.Keys) { $PropertyValue = $HtmlObject.Attributes[$Property] if ($PropertyValue -is [System.Collections.IDictionary]) { $OutputSubProperties = foreach ($SubAttributes in $PropertyValue.Keys) { $SubPropertyValue = $PropertyValue[$SubAttributes] if ($null -ne $SubPropertyValue -and $SubPropertyValue -ne '') { "$($SubAttributes):$($SubPropertyValue)" } } $MyValue = $OutputSubProperties -join ';' if ($MyValue.Trim() -ne '') { [void] $HTML.Append(" $Property=`"$MyValue`"") } } else { if ($null -ne $PropertyValue -and $PropertyValue -ne '') { [void] $HTML.Append(" $Property=`"$PropertyValue`"") } } } if (($null -ne $HtmlObject.Value) -and ($HtmlObject.Value -ne '')) { [void] $HTML.Append(">") if ($HtmlObject.Value.Count -eq 1) { if ($HtmlObject.Value -is [System.Collections.IDictionary]) { [string] $NewObject = Set-Tag -HtmlObject ($HtmlObject.Value) [void] $HTML.Append($NewObject) } else { [void] $HTML.Append([string] $HtmlObject.Value) } } else { foreach ($Entry in $HtmlObject.Value) { if ($Entry -is [System.Collections.IDictionary]) { [string] $NewObject = Set-Tag -HtmlObject ($Entry) [void] $HTML.Append($NewObject) } else { [void] $HTML.AppendLine([string] $Entry) } } } [void] $HTML.Append("</$($HtmlObject.Tag)>") } else { if ($HtmlObject.SelfClosing) { [void] $HTML.Append("/>") } else { [void] $HTML.Append("></$($HtmlObject.Tag)>") } } $HTML.ToString() } Export-ModuleMember -Function @('New-HTML', 'New-HTMLAnchor', 'New-HTMLAnchorLink', 'New-HTMLAnchorName', 'New-HTMLChartArea', 'New-HTMLChartBar', 'New-HTMLChartDataSet', 'New-HTMLChartLine', 'New-HTMLChartRadial', 'New-HTMLChartSpark', 'New-HTMLCodeBlock', 'New-HTMLContainer', 'New-HTMLHeading', 'New-HTMLHorizontalLine', 'New-HTMLImage', 'New-HTMLList', 'New-HTMLListItem', 'New-HTMLLogo', 'New-HTMLMessage', 'New-HTMLPanel', 'New-HTMLResourceCSS', 'New-HTMLResourceJS', 'New-HTMLSection', 'New-HTMLSection1', 'New-HTMLSectionHeader', 'New-HTMLSpanStyle', 'New-HTMLStatus', 'New-HTMLStatusItem', 'New-HTMLSubSection', 'New-HTMLTab', 'New-HTMLTabHead', 'New-HTMLTable', 'New-HTMLTableCondition', 'New-HTMLTag', 'New-HTMLText', 'New-HTMLTimeline', 'New-HTMLTimelineItem', 'New-HTMLToast', 'Out-HtmlView', 'Save-HTML') -Alias @('New-CSS', 'New-HTMLColumn', 'New-HTMLContent', 'New-JavaScript', 'New-ResourceCSS', 'New-ResourceJS', 'ohv', 'Out-GridHtml') |