From b0ab8fe2b05f70f201c46238ffbc04dd8aa23f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20K=C5=82ys?= Date: Sat, 3 Oct 2026 21:13:41 +0200 Subject: [PATCH 1/5] Fix report rendering, filtering and export data preservation --- Private/ChartsAll/New-ApexChart.ps1 | 18 +- Private/ConvertFrom-HTMLTextLink.ps1 | 13 + Private/ConvertTo-HTMLScriptJson.ps1 | 22 ++ Private/New-InternalDiagram.ps1 | 6 +- Private/New-TableServerSide.ps1 | 9 +- Private/Protect-HTMLScriptData.ps1 | 11 + Private/Resolve-HTMLMarkdownImages.ps1 | 40 +++ Private/Tables/Add-TableContent.ps1 | 108 +------ Private/Tables/Add-TableFiltering.ps1 | 182 ++++-------- Private/Tables/Add-TableRowGrouping.ps1 | 54 +--- Private/Tables/Add-TableState.ps1 | 85 ------ Private/Tables/Convert-TableRowGrouping.ps1 | 82 ++--- Private/Tables/Get-TableExportScript.ps1 | 27 ++ Private/Tables/Get-TableInlineStyles.ps1 | 62 ++++ .../New-TableConditionalFormattingInline.ps1 | 6 +- Private/Tables/Set-TableButtons.ps1 | 144 +++++++++ Public/New-HTMLCalendar.ps1 | 2 +- Public/New-HTMLCarousel.ps1 | 2 +- Public/New-HTMLDiagram.ps1 | 6 +- Public/New-HTMLGage.ps1 | 4 +- Public/New-HTMLMap.ps1 | 2 +- Public/New-HTMLMarkdown.ps1 | 29 +- Public/New-HTMLOrgChart.ps1 | 2 +- Public/New-HTMLQRCode.ps1 | 4 +- Public/New-HTMLTab.ps1 | 7 +- Public/New-HTMLTabPanel.ps1 | 2 +- Public/New-HTMLTable.ps1 | 281 ++++-------------- Public/New-HTMLTableStyle.ps1 | 5 +- Public/New-HTMLText.ps1 | 44 +-- Public/New-HTMLTree.ps1 | 2 +- Public/New-HTMLWinBox.ps1 | 2 +- Public/New-NavTopMenu.ps1 | 7 +- Public/New-TableButtonCSV.ps1 | 9 +- Public/New-TableButtonExcel.ps1 | 9 +- Public/New-TableHeader.ps1 | 11 + Resources/JS/pswritehtml-table-export.js | 91 ++++++ Resources/JS/tabbisNavigation.js | 64 ++++ Tests/ReportCorrectness.Tests.ps1 | 127 ++++++++ readme.md | 21 ++ 39 files changed, 881 insertions(+), 721 deletions(-) create mode 100644 Private/ConvertFrom-HTMLTextLink.ps1 create mode 100644 Private/ConvertTo-HTMLScriptJson.ps1 create mode 100644 Private/Protect-HTMLScriptData.ps1 create mode 100644 Private/Resolve-HTMLMarkdownImages.ps1 delete mode 100644 Private/Tables/Add-TableState.ps1 create mode 100644 Private/Tables/Get-TableExportScript.ps1 create mode 100644 Private/Tables/Get-TableInlineStyles.ps1 create mode 100644 Private/Tables/Set-TableButtons.ps1 create mode 100644 Resources/JS/pswritehtml-table-export.js create mode 100644 Resources/JS/tabbisNavigation.js create mode 100644 Tests/ReportCorrectness.Tests.ps1 diff --git a/Private/ChartsAll/New-ApexChart.ps1 b/Private/ChartsAll/New-ApexChart.ps1 index 02307d07..7c2ce5a7 100644 --- a/Private/ChartsAll/New-ApexChart.ps1 +++ b/Private/ChartsAll/New-ApexChart.ps1 @@ -1,4 +1,4 @@ -function New-ApexChart { +function New-ApexChart { <# .SYNOPSIS Creates a new ApexChart with the specified options and events. @@ -53,19 +53,19 @@ function New-ApexChart { # Convert Dictionary to JSON and return chart within SCRIPT tag # Make sure to return with additional empty string Remove-EmptyValue -Hashtable $Options -Recursive -Rerun 2 - $JSON = $Options | ConvertTo-JsonLiteral -Depth 5 -AdvancedReplace @{ '.' = '\.'; '$' = '\$' } - # replaces stuff for TImeLineCharts - $JSON = $JSON.Replace('"new Date(', 'new Date(').Replace(').getTime()"', ').getTime()') + $JSON = $Options | ConvertTo-HTMLScriptJson -Depth 20 # We replace Events on JSON because there's no other way that I can think of if ($Options.chart.events) { - $JSON = $JSON -replace ('"events":"EventsReplaceMe"', $Events) + $JSON = [regex]::Replace($JSON, '"events"\s*:\s*"EventsReplaceMe"', { $Events }) } - $JSON = $JSON | ForEach-Object { [System.Text.RegularExpressions.Regex]::Unescape($_) } - "var options = $JSON" - "var chart = new ApexCharts(document.querySelector('#$ID'), + # Timeline producers return date expressions as data. Parse their date + # argument without evaluating text or unescaping the whole JSON object. + 'if (options.chart.type === "rangeBar") { options.series.forEach(function (series) { series.data.forEach(function (point) { if (Array.isArray(point.y)) { point.y = point.y.map(function (value) { var match = typeof value === "string" && /^new Date\(''([\s\S]*)''\)\.getTime\(\)$/.exec(value); return match ? new Date(match[1]).getTime() : value; }); } }); }); }' + $IDJson = ConvertTo-HTMLScriptJson -InputObject $Options.chart.id -Compress + "var chart = new ApexCharts(document.getElementById($IDJson), options );" "chart.render();" @@ -73,4 +73,4 @@ function New-ApexChart { $Div # we need to move it to the end of the code therefore using additional vesel $Script:HTMLSchema.Charts.Add($Script) -} \ No newline at end of file +} diff --git a/Private/ConvertFrom-HTMLTextLink.ps1 b/Private/ConvertFrom-HTMLTextLink.ps1 new file mode 100644 index 00000000..837756b9 --- /dev/null +++ b/Private/ConvertFrom-HTMLTextLink.ps1 @@ -0,0 +1,13 @@ +function ConvertFrom-HTMLTextLink { + <# + .SYNOPSIS + Converts inline text links with independently captured labels and balanced destinations. + #> + [CmdletBinding()] + param([AllowEmptyString()][string] $Text) + $Pattern = '\[(?