Private/Show-AACQueryResultView.ps1

function Show-AACQueryResultView {
    <#
    .SYNOPSIS
        Renders the rows of any KQL query as a Spectre.Console table - the
        view of Invoke-AACApplicationInsightQuery -Query.
    .DESCRIPTION
        The source and query, a row and column count, then a table of the
        rows: -PreferredColumn first (those the rows have), then the others,
        up to -MaxColumns (the rest are in the objects and the exports), long
        values shortened, numbers right-aligned. Every row is shown unless
        -MaxRows says otherwise; Invoke-AACPagedOutput pages them. Output
        goes straight to the Spectre console; wrap the call in
        Invoke-AACPagedOutput to page it.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [AllowEmptyCollection()]
        [object[]] $Row,

        [System.Collections.IDictionary] $Scope,

        # The columns to show first, e.g. a table's most useful ones.
        [string[]] $PreferredColumn,

        [string] $Title = 'Query results',

        [ValidateRange(1, 20)]
        [int] $MaxColumns = 8,

        # 0 (the default): every row.
        [ValidateRange(0, [int]::MaxValue)]
        [int] $MaxRows = 0
    )

    $escape = { param($Text) [Spectre.Console.Markup]::Escape([string]$Text) }
    $glyph = Get-AACGlyph
    $facts = [System.Collections.Generic.List[string]]::new()
    if ($script:AACSession) { $facts.Add("[white]$(& $escape $script:AACSession.Account)[/]") }
    if ($Scope) { foreach ($key in $Scope.Keys) { $facts.Add("$(& $escape $key): $(& $escape $Scope[$key])") } }
    Write-AACMarkup "[grey58]$($facts -join " $($glyph.Dot) ")[/]"
    [Spectre.Console.AnsiConsole]::WriteLine()

    if ($Row.Count -eq 0) {
        Show-AACPanel -Content '[bold]The query returned no rows.[/]' -BorderColor 'grey50' -AllowMarkup
        return
    }
    $columns = @($Row[0].PSObject.Properties.Name)
    Show-AACTileRow -Tile @(
        @{ Value = '{0:N0}' -f $Row.Count; Caption = 'rows'; Color = 'deepskyblue1' }
        @{ Value = '{0:N0}' -f $columns.Count; Caption = 'columns'; Color = 'mediumpurple2' }
    )
    [Spectre.Console.AnsiConsole]::WriteLine()

    $first = @(foreach ($name in $PreferredColumn) { $columns | Where-Object { $_ -eq $name } | Select-Object -First 1 })
    $shownColumns = @(@($first) + @($columns | Where-Object { $_ -notin $first }) | Select-Object -First $MaxColumns)
    $numeric = @{}
    foreach ($name in $shownColumns) {
        $numeric[$name] = @($Row | Select-Object -First 50 | Where-Object { $null -ne $_.$name -and [string]$_.$name -ne '' } | Where-Object { $_.$name -isnot [ValueType] -or $_.$name -is [bool] -or $_.$name -is [datetime] }).Count -eq 0
    }
    $table = [Spectre.Console.Table]::new()
    $table.Border = [Spectre.Console.TableBorder]::Rounded
    $table.BorderStyle = [Spectre.Console.Style]::Parse('deepskyblue3_1')
    $table.Expand = $true
    $note = if ($columns.Count -gt $shownColumns.Count) { " $($glyph.Dot) first $($shownColumns.Count) of $($columns.Count) columns" } else { '' }
    $shownRows = if ($MaxRows -gt 0) { @($Row | Select-Object -First $MaxRows) } else { $Row }
    $table.Title = [Spectre.Console.TableTitle]::new("[bold deepskyblue1]$($glyph.Bullet) $(& $escape $Title)[/] [grey58]$(if ($shownRows.Count -lt $Row.Count) { "$('{0:N0}' -f $shownRows.Count) of " })$('{0:N0}' -f $Row.Count) rows$note[/]")
    foreach ($name in $shownColumns) {
        $column = [Spectre.Console.TableColumn]::new("[grey62]$(& $escape $name)[/]")
        if ($numeric[$name]) { $column.Alignment = [Spectre.Console.Justify]::Right }
        $table.AddColumn($column) | Out-Null
    }
    foreach ($item in $shownRows) {
        $cells = foreach ($name in $shownColumns) {
            $value = $item.$name
            $text = if ($value -is [datetime]) { $value.ToLocalTime().ToString('yyyy-MM-dd HH:mm:ss') } elseif ($null -eq $value) { '' } else { [string]$value }
            if ($text.Length -gt 120) { $text = $text.Substring(0, 117) + '...' }
            [Spectre.Console.Markup]::new("$(if ($numeric[$name]) { '[bold]' } else { '[white]' })$(& $escape $text)[/]")
        }
        [Spectre.Console.TableExtensions]::AddRow($table, [Spectre.Console.Rendering.IRenderable[]]@($cells)) | Out-Null
    }
    [Spectre.Console.AnsiConsole]::Write($table)
}