public/controls/New-UiCredential.ps1
|
function New-UiCredential { <# .SYNOPSIS Creates a credential input consisting of username and password fields. .DESCRIPTION Creates a pair of input fields for capturing credentials. The username field is a standard text input, while the password field is masked. In -Action blocks, the hydrated variable contains a PSCredential object. .PARAMETER Variable The variable name to register. The hydrated variable contains PSCredential. .PARAMETER Label Optional label displayed above the credential fields. Defaults to "Credentials". .PARAMETER UserLabel Label for the username field. Defaults to "Username". .PARAMETER PasswordLabel Label for the password field. Defaults to "Password". .PARAMETER DefaultUsername Default value for the username field. .PARAMETER EnabledWhen Conditional enabling based on another control's state. Accepts either: - A variable name string (e.g., 'evalVCSA') - enables when that control is truthy - A scriptblock (e.g., { $evalPhoton -or $evalAlma }) - enables when expression is true Truthy values: CheckBox=checked, TextBox=non-empty, ComboBox=has selection. .PARAMETER ClearIfDisabled When used with -EnabledWhen, clears the credential fields when the control becomes disabled. By default, values are preserved when disabled. .PARAMETER SubmitButton Name of a registered button to trigger when Enter is pressed in the password field. The button must be created with -Variable to register it for lookup. Works with both New-UiButton and New-UiActionCard buttons. .PARAMETER WPFProperties Hashtable of additional WPF properties to apply to the container. .EXAMPLE New-UiCredential -Variable 'creds' -Label 'Remote Computer Credentials' # In -Action: $creds contains PSCredential .EXAMPLE New-UiCredential -Variable 'adminCreds' -DefaultUsername 'Administrator' .EXAMPLE New-UiCredential -Variable 'sshCreds' -Label 'SSH Credentials' -EnabledWhen 'useSSH' # Enabled only when the 'useSSH' toggle is checked #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Variable, [string]$Label = 'Credentials', [string]$UserLabel = 'Username', [string]$PasswordLabel = 'Password', [string]$DefaultUsername = '', [object]$EnabledWhen, [switch]$ClearIfDisabled, [Parameter()] [string]$SubmitButton, [hashtable]$WPFProperties ) $session = Assert-UiSession -CallerName 'New-UiCredential' Write-Debug "Creating credential input '$Variable'" $colors = Get-ThemeColors $container = [System.Windows.Controls.StackPanel]::new() $container.Orientation = 'Vertical' $container.Margin = [System.Windows.Thickness]::new(0, 0, 0, 8) if ($Label) { $groupLabel = [System.Windows.Controls.TextBlock]::new() $groupLabel.Text = $Label $groupLabel.FontWeight = 'SemiBold' $groupLabel.Foreground = ConvertTo-UiBrush $colors.ControlFg $groupLabel.Margin = [System.Windows.Thickness]::new(0, 0, 0, 8) $groupLabel.Tag = 'ControlFgBrush' [PsUi.ThemeEngine]::RegisterElement($groupLabel) [void]$container.Children.Add($groupLabel) } $fieldsPanel = [System.Windows.Controls.Grid]::new() $fieldsPanel.ColumnDefinitions.Add([System.Windows.Controls.ColumnDefinition]::new()) $fieldsPanel.ColumnDefinitions.Add([System.Windows.Controls.ColumnDefinition]::new()) $fieldsPanel.ColumnDefinitions[0].Width = [System.Windows.GridLength]::new(1, 'Star') $fieldsPanel.ColumnDefinitions[1].Width = [System.Windows.GridLength]::new(1, 'Star') $userContainer = [System.Windows.Controls.StackPanel]::new() $userContainer.Orientation = 'Vertical' $userContainer.Margin = [System.Windows.Thickness]::new(0, 0, 8, 0) [System.Windows.Controls.Grid]::SetColumn($userContainer, 0) $userLabelCtrl = [System.Windows.Controls.TextBlock]::new() $userLabelCtrl.Text = $UserLabel $userLabelCtrl.Foreground = ConvertTo-UiBrush $colors.ControlFg $userLabelCtrl.Margin = [System.Windows.Thickness]::new(0, 0, 0, 4) $userLabelCtrl.Tag = 'ControlFgBrush' [PsUi.ThemeEngine]::RegisterElement($userLabelCtrl) [void]$userContainer.Children.Add($userLabelCtrl) $userBox = [System.Windows.Controls.TextBox]::new() $userBox.Text = $DefaultUsername $userBox.Height = 32 Set-TextBoxStyle -TextBox $userBox [void]$userContainer.Children.Add($userBox) $passContainer = [System.Windows.Controls.StackPanel]::new() $passContainer.Orientation = 'Vertical' $passContainer.Margin = [System.Windows.Thickness]::new(8, 0, 0, 0) [System.Windows.Controls.Grid]::SetColumn($passContainer, 1) $passLabelCtrl = [System.Windows.Controls.TextBlock]::new() $passLabelCtrl.Text = $PasswordLabel $passLabelCtrl.Foreground = ConvertTo-UiBrush $colors.ControlFg $passLabelCtrl.Margin = [System.Windows.Thickness]::new(0, 0, 0, 4) $passLabelCtrl.Tag = 'ControlFgBrush' [PsUi.ThemeEngine]::RegisterElement($passLabelCtrl) [void]$passContainer.Children.Add($passLabelCtrl) $passBox = [System.Windows.Controls.PasswordBox]::new() $passBox.Height = 32 Set-TextBoxStyle -PasswordBox $passBox [void]$passContainer.Children.Add($passBox) [void]$fieldsPanel.Children.Add($userContainer) [void]$fieldsPanel.Children.Add($passContainer) [void]$container.Children.Add($fieldsPanel) # Tag wrapper for FormLayout unwrapping (when label exists) if ($Label) { Set-UiFormControlTag -Wrapper $container -Label $groupLabel -Control $fieldsPanel } # Wrapper that holds references to both controls for Get-UiValue $credentialWrapper = [PSCustomObject]@{ PSTypeName = 'PsUi.CredentialControl' UsernameBox = $userBox PasswordBox = $passBox VariableName = $Variable } # Store the wrapper in Variables (AddControlSafe requires FrameworkElement) # Validation and hydration check for PsUi.CredentialControl type Write-Debug "Storing credential wrapper as '$Variable'" $session.Variables[$Variable] = $credentialWrapper # Register conditional enabling if specified if ($EnabledWhen) { Register-UiCondition -TargetControl $container -Condition $EnabledWhen -ClearIfDisabled:$ClearIfDisabled } # Wire up Enter key on password field to trigger submit button if ($SubmitButton) { $btnName = $SubmitButton $passBox.Add_KeyDown({ param($sender, $keyArgs) if ($keyArgs.Key -eq [System.Windows.Input.Key]::Return) { # Only trigger if password has content if ([string]::IsNullOrWhiteSpace($sender.Password)) { return } $sess = [PsUi.SessionManager]::Current if (!$sess) { return } # Look up registered button and trigger its click $btn = $sess.GetRegisteredButton($btnName) if ($btn -and $btn.IsEnabled) { $btn.RaiseEvent([System.Windows.RoutedEventArgs]::new([System.Windows.Controls.Primitives.ButtonBase]::ClickEvent)) $keyArgs.Handled = $true } } }.GetNewClosure()) } # Apply custom WPF properties if specified if ($WPFProperties) { Set-UiProperties -Control $container -Properties $WPFProperties } # Add to current parent Write-Debug "Adding credential fields to parent" [void]$session.CurrentParent.Children.Add($container) return $container } |