Functions/Public/Write-Action.ps1
|
<#
================================================================================ ORION DESIGN - POWERSHELL UI FRAMEWORK | Write-Action Function ================================================================================ Author: Sune Alexandersen Narud Date: February 4, 2026 Module: OrionDesign v2.1.2 Category: Interactive Display Dependencies: OrionDesign Theme System, Global Width Configuration FUNCTION PURPOSE: Writes an action description with three modes: 1. Standard mode: No newline, pairs with Write-ActionResult for status completion 2. Complete mode (-Complete): Standalone output with optional icons, status, duration 3. Right-aligned mode (-RightAlign): Standalone right-aligned text (implies -Complete) THEME INTEGRATION: Uses theme 'Action' color for standard mode text (defaults to Text color if not set). Supports all theme colors for status-based coloring in Complete mode. HLD INTEGRATION: ┌─ ACTION MODES ──────┐ ┌─ ACTION DISPLAY ─┐ ┌─ OUTPUT ─┐ │ Standard Mode │◄──►│ Left-aligned │───►│ Action │ │ • Pairs w/ Result │ │ With margins │ │ Line │ │ • No Newline │ │ Color Support │ │ Partial │ ├─────────────────────┤ ├──────────────────┤ ├──────────┤ │ Complete Mode │◄──►│ Standalone │───►│ Full │ │ • Icons & Status │ │ Rich Details │ │ Result │ │ • Duration/Subtext │ │ Multi-line │ │ Block │ ├─────────────────────┤ ├──────────────────┤ ├──────────┤ │ RightAlign Mode │◄──►│ Right-aligned │───►│ Single │ │ • Implies Complete │ │ With margins │ │ Line │ └─────────────────────┘ └──────────────────┘ └──────────┘ ================================================================================ #> <# .SYNOPSIS Writes an action description, either preparing for Write-ActionResult, as a complete standalone result, or right-aligned. .DESCRIPTION The Write-Action function has three modes: STANDARD MODE (default): Displays an action description left-aligned without a newline. Designed to pair with Write-ActionResult for real-time status lines. The text length and right margin are stored for Write-ActionResult to calculate alignment. Uses theme 'Action' color (or falls back to 'Text' color). COMPLETE MODE (-Complete): Displays a standalone result with optional icons, status colors, duration, subtext, and additional details. Use this for summarized action outcomes. RIGHT-ALIGNED MODE (-RightAlign): Displays text right-aligned to OrionMaxWidth with margins. Automatically implies -Complete mode. Useful for standalone right-aligned output. .PARAMETER Text The action description to display. .PARAMETER Color The color for the action text. Defaults to theme 'Action' color. In Complete mode with -Status, the text is colored by status instead. .PARAMETER Indent Number of spaces for left margin (and right margin for Write-ActionResult alignment). Defaults to 1. Use -Indent 0 for no indentation. .PARAMETER RightAlign Switch to right-align the text to OrionMaxWidth. Automatically implies -Complete mode (outputs with newline). Uses Indent value as both left reference and right margin. .PARAMETER Complete Switch to enable Complete mode. Outputs a standalone result with newline and optional rich details. .PARAMETER Status (Complete mode) The status type for color coding. Valid values: - 'Success' - Green text - 'Failed' - Red text - 'Warning' - Yellow text - 'Info' - Cyan/Accent text - 'Running' - Accent text - 'Pending' - Muted text .PARAMETER Duration (Complete mode) The time taken to complete the action. .PARAMETER Details (Complete mode) Additional details about the action result. .PARAMETER FailureReason (Complete mode) Failure message if the action failed. .PARAMETER Suggestion (Complete mode) Suggested next steps or remediation. .PARAMETER Subtext (Complete mode) Additional subtext (e.g., "items", "users") displayed after the main text in muted color. .PARAMETER ShowIcon (Complete mode) Switch to display the status icon. .PARAMETER ShowStatus (Complete mode) Switch to display the status text (e.g., "SUCCESS", "FAILED"). .PARAMETER NoNewLine (Complete mode) Prevents newline after main result. Details/FailureReason/Suggestion are not shown. .EXAMPLE Write-Action "Connecting to database" Write-ActionResult "Connected" Standard mode - displays with automatic right-alignment and margins: Connecting to database Connected .EXAMPLE Write-Action "Loading configuration" -Indent 0 Write-ActionResult "OK!" Standard mode with no indentation: Loading configuration OK! .EXAMPLE Write-Action "Deploy Database" -Complete -Status Success -Duration "00:02:15" -ShowIcon Complete mode - standalone result with icon and duration: ✅ Deploy Database in 00:02:15 .EXAMPLE Write-Action "142" -Complete -Status Success -Subtext "tables updated" -ShowIcon Complete mode with subtext: ✅ 142 tables updated .EXAMPLE Write-Action "Connect to API" -Complete -Status Failed -FailureReason "Connection timeout" -Suggestion "Check network" -ShowIcon Complete mode with failure details: ❌ Connect to API 💥 Error: Connection timeout 💡 Suggestion: Check network .EXAMPLE Write-Action "Processing" -Indent 4 Write-ActionResult "Done" Standard mode with 4-space indentation: Processing Done .EXAMPLE Write-Action "Completed successfully" -RightAlign Right-aligned mode (implies Complete): Completed successfully .NOTES Standard mode: Pairs with Write-ActionResult for real-time status reporting. - Uses theme 'Action' color for text - Stores text length and right margin for Write-ActionResult alignment - Default indent of 1 space (use -Indent 0 for no margin) Complete mode: Use for standalone action summaries with rich formatting. Right-aligned mode: Use -RightAlign for standalone right-aligned text. - Automatically implies -Complete mode - Respects Indent value as right margin #> function Write-Action { [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory, ParameterSetName = 'Default', Position = 0)][string]$Text, [string]$Color = "", [int]$Indent = 1, [switch]$RightAlign, [switch]$Complete, # Complete mode parameters [ValidateSet('Success', 'Failed', 'Warning', 'Info', 'Running', 'Pending')] [string]$Status = "", [string]$Duration = "", [string]$Details = "", [string]$FailureReason = "", [string]$Suggestion = "", [string]$Subtext = "", [switch]$ShowIcon, [switch]$ShowStatus, [switch]$NoNewLine, [Parameter(Mandatory, ParameterSetName = 'Demo')] [switch]$Demo ) if ($Demo) { $renderCodeBlock = { param([string[]]$Lines) $innerWidth = ($Lines | Measure-Object -Property Length -Maximum).Maximum + 4 $bar = '─' * $innerWidth Write-Host ' # Code' -ForegroundColor DarkGray Write-Host " ┌$bar┐" -ForegroundColor DarkGray foreach ($line in $Lines) { $padded = (" $line").PadRight($innerWidth) Write-Host " │" -ForegroundColor DarkGray -NoNewline Write-Host $padded -ForegroundColor Green -NoNewline Write-Host '│' -ForegroundColor DarkGray } Write-Host " └$bar┘" -ForegroundColor DarkGray Write-Host '' } Write-Host '' Write-Host ' Write-Action Demo' -ForegroundColor Cyan Write-Host ' =================' -ForegroundColor DarkGray Write-Host '' Write-Host ' [Standard Mode] pairs with Write-ActionResult' -ForegroundColor Yellow Write-Host '' & $renderCodeBlock @('Write-Action "Connecting to database"', 'Write-ActionResult "Connected"') Write-Action -Text 'Connecting to database'; Write-ActionResult -Text 'Connected' & $renderCodeBlock @('Write-Action "Loading configuration"', 'Write-ActionResult "File not found"') Write-Action -Text 'Loading configuration'; Write-ActionResult -Text 'File not found' Write-Host '' Write-Host ' [Complete Mode] standalone output with status' -ForegroundColor Yellow Write-Host '' & $renderCodeBlock @("Write-Action 'Deploy Database' -Complete -Status Success -ShowIcon -Duration '00:02:15'") Write-Action -Text 'Deploy Database' -Complete -Status Success -ShowIcon -Duration '00:02:15' & $renderCodeBlock @("Write-Action 'Validate Schema' -Complete -Status Failed -ShowIcon -FailureReason 'Column mismatch'") Write-Action -Text 'Validate Schema' -Complete -Status Failed -ShowIcon -FailureReason 'Column mismatch' return } # Use theme colors if available if (-not $script:Theme) { $script:Theme = @{ Accent = 'Cyan' Success = 'Green' Warning = 'Yellow' Error = 'Red' Text = 'White' Muted = 'DarkGray' Action = 'White' Result = 'Cyan' UseAnsi = $true } if ($psISE) { $script:Theme.UseAnsi = $false } } # Build indentation string $indentString = if ($Indent -gt 0) { ' ' * $Indent } else { '' } # Use global max width if not set if (-not $script:OrionMaxWidth) { $script:OrionMaxWidth = 100 } # RightAlign implies Complete mode if ($RightAlign) { $Complete = $true } if ($Complete) { # ===== COMPLETE MODE ===== # Standalone output with optional icons, status, duration, details $maxContentWidth = $script:OrionMaxWidth - $indentString.Length - 10 # Status icons and colors $statusInfo = switch ($Status) { 'Success' { @{ Icon = "✅"; Color = $script:Theme.Success } } 'Failed' { @{ Icon = "❌"; Color = $script:Theme.Error } } 'Warning' { @{ Icon = "⚠️ "; Color = $script:Theme.Warning } } 'Info' { @{ Icon = "ℹ️ "; Color = $script:Theme.Accent } } 'Running' { @{ Icon = "🔄"; Color = $script:Theme.Accent } } 'Pending' { @{ Icon = "⏳"; Color = $script:Theme.Muted } } default { @{ Icon = ""; Color = $script:Theme.Text } } } # Ensure we have a valid color if (-not $statusInfo.Color) { $statusInfo.Color = $script:Theme.Text } # Determine text color $textColor = if ($Color) { $Color } elseif ($Status) { $statusInfo.Color } else { $script:Theme.Text } # Handle RightAlign in Complete mode if ($RightAlign) { # Right-align: calculate padding to push text to the right with margin $rightMargin = $Indent $totalLength = $Text.Length + $rightMargin $padding = $script:OrionMaxWidth - $totalLength if ($padding -gt 0) { Write-Host (" " * $padding) -NoNewline } Write-Host "$Text" -ForegroundColor $textColor return } # Main result line Write-Host $indentString -NoNewline if ($ShowIcon -and $statusInfo.Icon) { Write-Host "$($statusInfo.Icon) " -NoNewline } Write-Host "$Text" -ForegroundColor $textColor -NoNewline # Status text if ($ShowStatus -and $Status) { Write-Host " - " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $Status.ToUpper() -ForegroundColor $statusInfo.Color -NoNewline } # Subtext if ($Subtext) { Write-Host " $Subtext" -ForegroundColor $script:Theme.Muted -NoNewline } # Duration if ($Duration) { Write-Host " in " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host "$Duration" -ForegroundColor $script:Theme.Muted -NoNewline } # End main line if (-not $NoNewLine) { Write-Host } # Additional details (only if newline is allowed) if (-not $NoNewLine) { if ($Details) { $displayDetails = if ($Details.Length -gt $maxContentWidth) { $Details.Substring(0, $maxContentWidth - 3) + "..." } else { $Details } Write-Host "$indentString 📋 $displayDetails" -ForegroundColor $script:Theme.Text } if ($FailureReason) { $displayFailure = if ($FailureReason.Length -gt $maxContentWidth) { $FailureReason.Substring(0, $maxContentWidth - 3) + "..." } else { $FailureReason } Write-Host "$indentString 💥 Error: $displayFailure" -ForegroundColor $script:Theme.Error } if ($Suggestion) { $displaySuggestion = if ($Suggestion.Length -gt $maxContentWidth) { $Suggestion.Substring(0, $maxContentWidth - 3) + "..." } else { $Suggestion } Write-Host "$indentString 💡 Suggestion: $displaySuggestion" -ForegroundColor $script:Theme.Warning } } } else { # ===== STANDARD MODE ===== # No newline, pairs with Write-ActionResult # Use Action color for descriptions (falls back to Text if Action not defined) $actionColor = if ($script:Theme.Action) { $script:Theme.Action } else { $script:Theme.Text } $textColor = if ($Color) { $Color } else { $actionColor } # Store the actual text length (including indent) for Write-ActionResult to calculate alignment $script:LastActionTextLength = $indentString.Length + $Text.Length # Store right margin (same as left indent) for Write-ActionResult $script:LastActionRightMargin = $Indent # Output without newline Write-Host "$indentString$Text" -NoNewline -ForegroundColor $textColor } } |