Private/ConvertTo-DhTileJson.ps1
|
function ConvertTo-DhTileJson { <# .SYNOPSIS Serialise one normalised summary tile (from Add-DhSummary) to JSON. .DESCRIPTION v2.2.0 - single source for the tile JSON. Until 2.2.0 Export-DhDashboard carried two hand-synchronised copies of this code: one for the top-of-page strip and one for per-panel 'summarystrip' blocks. Add a tile key HERE and both paths get it. Optional groups (delta, sparkline, caption, gauge fields, verdict, action) are emitted only when they apply, so a plain tile stays small. #> [CmdletBinding()] [OutputType([string])] param([Parameter(Mandatory)] [System.Collections.IDictionary] $Item) $s = $Item $val = if ($null -eq $s.Value) { 'null' } ` elseif ($s.Value -is [bool]) { $s.Value.ToString().ToLower() } ` elseif ($s.Value -is [int] -or $s.Value -is [long] -or $s.Value -is [double] -or $s.Value -is [float] -or $s.Value -is [decimal]) { [string]$s.Value } ` else { ConvertTo-DhJsonString ([string]$s.Value) } $dec = if ($s.Contains('Decimals') -and $s.Decimals -ge 0) { $s.Decimals } else { -1 } # Trend / delta (v1.4 F1) - only when Previous or an explicit Trend is supplied $deltaJson = '' $hasPrev = $s.Contains('Previous') -and $null -ne $s.Previous $hasTrend = $s.Contains('Trend') -and $s.Trend -ne 'auto' if ($hasPrev -or $hasTrend) { $prevJson = if ($hasPrev) { [string]$s.Previous } else { 'null' } $trendStr = if ($s.Contains('Trend') -and $s.Trend) { [string]$s.Trend } else { 'auto' } $tigJson = if ($null -ne $s.TrendIsGood) { ([bool]$s.TrendIsGood).ToString().ToLower() } else { 'null' } $dfStr = if ($s.Contains('DeltaFormat') -and $s.DeltaFormat) { [string]$s.DeltaFormat } else { 'both' } $deltaJson = ",`"previous`":$prevJson,`"trend`":$(ConvertTo-DhJsonString $trendStr),`"trendIsGood`":$tigJson,`"deltaFormat`":$(ConvertTo-DhJsonString $dfStr)" } # Sparkline (v1.4 F2) - only when the series is non-empty $sparkJson = '' if ($s.Contains('Sparkline') -and $s.Sparkline -and @($s.Sparkline).Count -gt 0) { $sparkValues = ((@($s.Sparkline) | ForEach-Object { [string]$_ }) -join ',') $sparkMinJson = if ($null -ne $s.SparklineMin) { [string]$s.SparklineMin } else { 'null' } $sparkMaxJson = if ($null -ne $s.SparklineMax) { [string]$s.SparklineMax } else { 'null' } $sparkStyle = if ($s.Contains('SparklineStyle') -and $s.SparklineStyle) { [string]$s.SparklineStyle } else { 'line' } $sparkJson = ",`"sparkline`":[$sparkValues],`"sparklineMin`":$sparkMinJson,`"sparklineMax`":$sparkMaxJson,`"sparklineStyle`":$(ConvertTo-DhJsonString $sparkStyle)" } # Tile style (v1.4 F3 + F4) - always emitted; 'tile' is the standard renderer $styleStr = if ($s.Contains('Style') -and $s.Style) { [string]$s.Style } else { 'tile' } $styleJson = ",`"style`":$(ConvertTo-DhJsonString $styleStr)" # Caption: bignumber (v1.4) and verdict (v2.2.0) $captionJson = '' if ($styleStr -in 'bignumber', 'verdict' -and $s.Contains('Caption') -and -not [string]::IsNullOrWhiteSpace([string]$s.Caption)) { $captionJson = ",`"caption`":$(ConvertTo-DhJsonString $s.Caption)" } # Gauge fields $gaugeJson = '' if ($styleStr -eq 'gauge') { $minJson = if ($null -ne $s.Min) { [string]$s.Min } else { '0' } $maxJson = if ($null -ne $s.Max) { [string]$s.Max } else { '100' } $unitStr = if ($s.Contains('Unit') -and $s.Unit) { [string]$s.Unit } else { '' } if ($s.Contains('Thresholds') -and @($s.Thresholds).Count -gt 0) { $thItems = (@($s.Thresholds) | ForEach-Object { $th = $_ $minPart = if ($th.Contains('Min')) { "`"min`":$([string]$th.Min)," } else { '' } $maxPart = if ($th.Contains('Max')) { "`"max`":$([string]$th.Max)," } else { '' } "{$minPart$maxPart`"class`":$(ConvertTo-DhJsonString $th.Class)}" }) -join ',' $thJson = ",`"thresholds`":[$thItems]" } else { $thJson = ',"thresholds":[]' } # ragNoData (v1.4 F13) - the gauge paints itself cell-nodata on a missing value $rndJson = if ($s.Contains('RagNoData') -and $s.RagNoData) { ',"ragNoData":true' } else { '' } $gaugeJson = ",`"min`":$minJson,`"max`":$maxJson,`"unit`":$(ConvertTo-DhJsonString $unitStr)$thJson$rndJson" } # Verdict severity counts (v2.2.0) - fixed key order, zero counts omitted $verdictJson = '' if ($styleStr -eq 'verdict' -and $s.Contains('Counts') -and $s.Counts) { $parts = foreach ($k in 'critical', 'warning', 'info', 'ok') { if ($s.Counts.Contains($k) -and [int]$s.Counts[$k] -gt 0) { "`"$k`":$([int]$s.Counts[$k])" } } $verdictJson = ",`"counts`":{$(@($parts) -join ',')}" } # Per-tile Action (v1.4.2 - click-to-jump) $actionJson = '' if ($s.Contains('Action') -and $null -ne $s.Action) { $a = $s.Action $actionJson = ",`"action`":{`"label`":$(ConvertTo-DhJsonString $a.Label),`"tableId`":$(ConvertTo-DhJsonString $a.TableId),`"filter`":$(ConvertTo-DhJsonString $a.Filter),`"url`":$(ConvertTo-DhJsonString $a.Url)}" } "{`"label`":$(ConvertTo-DhJsonString $s.Label),`"value`":$val,`"icon`":$(ConvertTo-DhJsonString $s.Icon),`"subLabel`":$(ConvertTo-DhJsonString $s.SubLabel),`"class`":$(ConvertTo-DhJsonString $s.Class),`"format`":$(ConvertTo-DhJsonString $s.Format),`"locale`":$(ConvertTo-DhJsonString $s.Locale),`"decimals`":$dec,`"currency`":$(ConvertTo-DhJsonString $s.Currency)$styleJson$captionJson$gaugeJson$verdictJson$deltaJson$sparkJson$actionJson}" } |