Refactor: Decouple BYO Apps UI logic into core modules

Moves the event handling and business logic for the "Bring Your Own Applications" feature from the main UI script into dedicated core modules.

This change improves code organization and separation of concerns by centralizing application-related functions and their corresponding event handlers. The main UI script is now cleaner and primarily responsible for UI initialization, enhancing overall code maintainability.
This commit is contained in:
rbalsleyMSFT
2025-06-19 15:19:35 -07:00
parent 12607cca44
commit 24ed20305f
3 changed files with 198 additions and 117 deletions
+35 -114
View File
@@ -187,121 +187,32 @@ $window.Add_Loaded({
$script:uiState.Controls.wingetPanel.Visibility = if ($script:uiState.Controls.chkInstallWingetApps.IsChecked) { 'Visible' } else { 'Collapsed' }
$script:uiState.Controls.wingetSearchPanel.Visibility = 'Collapsed' # Keep search hidden initially
# BYO Apps UI logic (Keep existing logic)
$script:uiState.Controls.btnBrowseAppSource.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select Application Source Folder"
if ($selectedPath) { $script:uiState.Controls.txtAppSource.Text = $selectedPath }
})
$script:uiState.Controls.btnAddApplication.Add_Click({
$name = $script:uiState.Controls.txtAppName.Text
$commandLine = $script:uiState.Controls.txtAppCommandLine.Text
$arguments = $script:uiState.Controls.txtAppArguments.Text
$source = $script:uiState.Controls.txtAppSource.Text
if ([string]::IsNullOrWhiteSpace($name) -or [string]::IsNullOrWhiteSpace($commandLine) -or [string]::IsNullOrWhiteSpace($arguments)) {
[System.Windows.MessageBox]::Show("Please fill in all fields (Name, Command Line, and Arguments)", "Missing Information", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
$listView = $script:uiState.Controls.lstApplications
$priority = 1
if ($listView.Items.Count -gt 0) {
$priority = ($listView.Items | Measure-Object -Property Priority -Maximum).Maximum + 1
}
$application = [PSCustomObject]@{ Priority = $priority; Name = $name; CommandLine = $commandLine; Arguments = $arguments; Source = $source; CopyStatus = "" }
$listView.Items.Add($application)
$script:uiState.Controls.txtAppName.Text = ""
$script:uiState.Controls.txtAppCommandLine.Text = ""
$script:uiState.Controls.txtAppArguments.Text = ""
$script:uiState.Controls.txtAppSource.Text = ""
Update-CopyButtonState -State $script:uiState
})
$script:uiState.Controls.btnSaveBYOApplications.Add_Click({
$saveDialog = New-Object Microsoft.Win32.SaveFileDialog
$saveDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
$saveDialog.DefaultExt = ".json"
$saveDialog.Title = "Save Application List"
$initialDir = $script:uiState.Controls.txtApplicationPath.Text
if ([string]::IsNullOrWhiteSpace($initialDir) -or -not (Test-Path $initialDir)) { $initialDir = $PSScriptRoot }
$saveDialog.InitialDirectory = $initialDir
$saveDialog.FileName = "UserAppList.json"
if ($saveDialog.ShowDialog()) { Save-BYOApplicationList -Path $saveDialog.FileName -State $script:uiState }
})
$script:uiState.Controls.btnLoadBYOApplications.Add_Click({
$openDialog = New-Object Microsoft.Win32.OpenFileDialog
$openDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
$openDialog.Title = "Import Application List"
$initialDir = $script:uiState.Controls.txtApplicationPath.Text
if ([string]::IsNullOrWhiteSpace($initialDir) -or -not (Test-Path $initialDir)) { $initialDir = $PSScriptRoot }
$openDialog.InitialDirectory = $initialDir
if ($openDialog.ShowDialog()) { Import-BYOApplicationList -Path $openDialog.FileName -State $script:uiState; Update-CopyButtonState -State $script:uiState }
})
$script:uiState.Controls.btnCopyBYOApps.Add_Click({
param($buttonSender, $clickEventArgs)
$appsToCopy = $script:uiState.Controls.lstApplications.Items | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Source) }
if (-not $appsToCopy) {
[System.Windows.MessageBox]::Show("No applications with a source path specified.", "Copy BYO Apps", "OK", "Information")
return
}
$buttonSender.IsEnabled = $false
$script:uiState.Controls.pbOverallProgress.Visibility = 'Visible'
$script:uiState.Controls.pbOverallProgress.Value = 0
$script:uiState.Controls.txtStatus.Text = "Starting BYO app copy..."
# Define necessary task-specific variables locally
$localAppsPath = $script:uiState.Controls.txtApplicationPath.Text
# Create hashtable for task-specific arguments
$taskArguments = @{
AppsPath = $localAppsPath
}
# Select only necessary properties before passing
$itemsToProcess = $appsToCopy | Select-Object Priority, Name, CommandLine, Arguments, Source
# Invoke the centralized parallel processing function
# Pass task type and task-specific arguments
Invoke-ParallelProcessing -ItemsToProcess $itemsToProcess `
-ListViewControl $script:uiState.Controls.lstApplications `
-IdentifierProperty 'Name' `
-StatusProperty 'CopyStatus' `
-TaskType 'CopyBYO' `
-TaskArguments $taskArguments `
-CompletedStatusText "Copied" `
-ErrorStatusPrefix "Error: " `
-WindowObject $window `
-MainThreadLogPath $script:uiState.LogFilePath
# Final status update (handled by Invoke-ParallelProcessing)
$script:uiState.Controls.pbOverallProgress.Visibility = 'Collapsed'
$buttonSender.IsEnabled = $true
})
$script:uiState.Controls.btnMoveTop.Add_Click({
Move-ListViewItemTop -ListView $script:uiState.Controls.lstApplications
})
$script:uiState.Controls.btnMoveUp.Add_Click({
Move-ListViewItemUp -ListView $script:uiState.Controls.lstApplications
})
$script:uiState.Controls.btnMoveDown.Add_Click({
Move-ListViewItemDown -ListView $script:uiState.Controls.lstApplications
})
$script:uiState.Controls.btnMoveBottom.Add_Click({
Move-ListViewItemBottom -ListView $script:uiState.Controls.lstApplications
})
# BYO Apps ListView setup (Keep existing logic, ensure CopyStatus column is handled)
# BYO Apps ListView setup (Keep existing logic, ensure CopyStatus column
$byoGridView = $script:uiState.Controls.lstApplications.View
if ($byoGridView -is [System.Windows.Controls.GridView]) {
$copyStatusColumnExists = $false
foreach ($col in $byoGridView.Columns) { if ($col.Header -eq "Copy Status") { $copyStatusColumnExists = $true; break } }
foreach ($col in $byoGridView.Columns) {
if ($col.Header -eq "Copy Status") {
$copyStatusColumnExists = $true; break
}
}
if (-not $copyStatusColumnExists) {
$actionColumnIndex = -1
for ($i = 0; $i -lt $byoGridView.Columns.Count; $i++) { if ($byoGridView.Columns[$i].Header -eq "Action") { $actionColumnIndex = $i; break } }
for ($i = 0; $i -lt $byoGridView.Columns.Count; $i++) {
if ($byoGridView.Columns[$i].Header -eq "Action") {
$actionColumnIndex = $i; break
}
}
$copyStatusColumn = New-Object System.Windows.Controls.GridViewColumn
$copyStatusColumn.Header = "Copy Status"; $copyStatusColumn.DisplayMemberBinding = New-Object System.Windows.Data.Binding("CopyStatus"); $copyStatusColumn.Width = 150
if ($actionColumnIndex -ge 0) { $byoGridView.Columns.Insert($actionColumnIndex, $copyStatusColumn) } else { $byoGridView.Columns.Add($copyStatusColumn) }
$copyStatusColumn.Header = "Copy Status"
$copyStatusColumn.DisplayMemberBinding = New-Object System.Windows.Data.Binding("CopyStatus")
$copyStatusColumn.Width = 150
if ($actionColumnIndex -ge 0) {
$byoGridView.Columns.Insert($actionColumnIndex, $copyStatusColumn)
}
else {
$byoGridView.Columns.Add($copyStatusColumn)
}
}
}
Update-CopyButtonState -State $script:uiState # Initial check
@@ -309,23 +220,33 @@ $window.Add_Loaded({
# General Browse Button Handlers (Keep existing logic)
$script:uiState.Controls.btnBrowseFFUDevPath.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select FFU Development Path"
if ($selectedPath) { $script:uiState.Controls.txtFFUDevPath.Text = $selectedPath }
if ($selectedPath) {
$script:uiState.Controls.txtFFUDevPath.Text = $selectedPath
}
})
$script:uiState.Controls.btnBrowseFFUCaptureLocation.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select FFU Capture Location"
if ($selectedPath) { $script:uiState.Controls.txtFFUCaptureLocation.Text = $selectedPath }
if ($selectedPath) {
$script:uiState.Controls.txtFFUCaptureLocation.Text = $selectedPath
}
})
$script:uiState.Controls.btnBrowseOfficePath.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select Office Path"
if ($selectedPath) { $script:uiState.Controls.txtOfficePath.Text = $selectedPath }
if ($selectedPath) {
$script:uiState.Controls.txtOfficePath.Text = $selectedPath
}
})
$script:uiState.Controls.btnBrowseDriversFolder.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select Drivers Folder"
if ($selectedPath) { $script:uiState.Controls.txtDriversFolder.Text = $selectedPath }
if ($selectedPath) {
$script:uiState.Controls.txtDriversFolder.Text = $selectedPath
}
})
$script:uiState.Controls.btnBrowsePEDriversFolder.Add_Click({
$selectedPath = Show-ModernFolderPicker -Title "Select PE Drivers Folder"
if ($selectedPath) { $script:uiState.Controls.txtPEDriversFolder.Text = $selectedPath }
if ($selectedPath) {
$script:uiState.Controls.txtPEDriversFolder.Text = $selectedPath
}
})
$script:uiState.Controls.btnBrowseDriversJsonPath.Add_Click({
$sfd = New-Object System.Windows.Forms.SaveFileDialog
@@ -28,7 +28,6 @@ function Remove-Application {
)
$listView = $State.Controls.lstApplications
# Remove the item with the specified priority
$itemToRemove = $listView.Items | Where-Object { $_.Priority -eq $priority } | Select-Object -First 1
if ($itemToRemove) {
@@ -40,6 +39,37 @@ function Remove-Application {
}
}
# Function to add a new BYO application from the UI
function Add-BYOApplication {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[psobject]$State
)
$name = $State.Controls.txtAppName.Text
$commandLine = $State.Controls.txtAppCommandLine.Text
$arguments = $State.Controls.txtAppArguments.Text
$source = $State.Controls.txtAppSource.Text
if ([string]::IsNullOrWhiteSpace($name) -or [string]::IsNullOrWhiteSpace($commandLine) -or [string]::IsNullOrWhiteSpace($arguments)) {
[System.Windows.MessageBox]::Show("Please fill in all fields (Name, Command Line, and Arguments)", "Missing Information", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
$listView = $State.Controls.lstApplications
$priority = 1
if ($listView.Items.Count -gt 0) {
$priority = ($listView.Items | Measure-Object -Property Priority -Maximum).Maximum + 1
}
$application = [PSCustomObject]@{ Priority = $priority; Name = $name; CommandLine = $commandLine; Arguments = $arguments; Source = $source; CopyStatus = "" }
$listView.Items.Add($application)
$State.Controls.txtAppName.Text = ""
$State.Controls.txtAppCommandLine.Text = ""
$State.Controls.txtAppArguments.Text = ""
$State.Controls.txtAppSource.Text = ""
Update-CopyButtonState -State $State
}
# Function to save BYO applications to JSON
function Save-BYOApplicationList {
[CmdletBinding()]
@@ -115,6 +145,53 @@ function Import-BYOApplicationList {
}
}
# Function to invoke the parallel copy process for BYO apps
function Invoke-CopyBYOApps {
param(
[psobject]$State,
[System.Windows.Controls.Button]$Button
)
$appsToCopy = $State.Controls.lstApplications.Items | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Source) }
if (-not $appsToCopy) {
[System.Windows.MessageBox]::Show("No applications with a source path specified.", "Copy BYO Apps", "OK", "Information")
return
}
$Button.IsEnabled = $false
$State.Controls.pbOverallProgress.Visibility = 'Visible'
$State.Controls.pbOverallProgress.Value = 0
$State.Controls.txtStatus.Text = "Starting BYO app copy..."
# Define necessary task-specific variables locally
$localAppsPath = $State.Controls.txtApplicationPath.Text
# Create hashtable for task-specific arguments
$taskArguments = @{
AppsPath = $localAppsPath
}
# Select only necessary properties before passing
$itemsToProcess = $appsToCopy | Select-Object Priority, Name, CommandLine, Arguments, Source
# Invoke the centralized parallel processing function
# Pass task type and task-specific arguments
Invoke-ParallelProcessing -ItemsToProcess $itemsToProcess `
-ListViewControl $State.Controls.lstApplications `
-IdentifierProperty 'Name' `
-StatusProperty 'CopyStatus' `
-TaskType 'CopyBYO' `
-TaskArguments $taskArguments `
-CompletedStatusText "Copied" `
-ErrorStatusPrefix "Error: " `
-WindowObject $State.Window `
-MainThreadLogPath $State.LogFilePath
# Final status update (handled by Invoke-ParallelProcessing)
$State.Controls.pbOverallProgress.Visibility = 'Collapsed'
$Button.IsEnabled = $true
}
# Function to copy a single BYO application (Modified for ForEach-Object -Parallel)
function Start-CopyBYOApplicationTask {
[CmdletBinding()]
@@ -254,6 +254,54 @@ function Register-EventHandlers {
if ($ofd.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $localState.Controls.txtAppListJsonPath.Text = $ofd.FileName }
})
$State.Controls.btnBrowseAppSource.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
$selectedPath = Show-ModernFolderPicker -Title "Select Application Source Folder"
if ($selectedPath) { $localState.Controls.txtAppSource.Text = $selectedPath }
})
$State.Controls.btnAddApplication.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Add-BYOApplication -State $localState
})
$State.Controls.btnSaveBYOApplications.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
$saveDialog = New-Object Microsoft.Win32.SaveFileDialog
$saveDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
$saveDialog.DefaultExt = ".json"
$saveDialog.Title = "Save Application List"
$initialDir = $localState.Controls.txtApplicationPath.Text
if ([string]::IsNullOrWhiteSpace($initialDir) -or -not (Test-Path $initialDir)) { $initialDir = $localState.FFUDevelopmentPath }
$saveDialog.InitialDirectory = $initialDir
$saveDialog.FileName = "UserAppList.json"
if ($saveDialog.ShowDialog()) { Save-BYOApplicationList -Path $saveDialog.FileName -State $localState }
})
$State.Controls.btnLoadBYOApplications.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
$openDialog = New-Object Microsoft.Win32.OpenFileDialog
$openDialog.Filter = "JSON files (*.json)|*.json|All files (*.*)|*.*"
$openDialog.Title = "Import Application List"
$initialDir = $localState.Controls.txtApplicationPath.Text
if ([string]::IsNullOrWhiteSpace($initialDir) -or -not (Test-Path $initialDir)) { $initialDir = $localState.FFUDevelopmentPath }
$openDialog.InitialDirectory = $initialDir
if ($openDialog.ShowDialog()) {
Import-BYOApplicationList -Path $openDialog.FileName -State $localState
Update-CopyButtonState -State $localState
}
})
$State.Controls.chkBringYourOwnApps.Add_Checked({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
@@ -298,7 +346,42 @@ function Register-EventHandlers {
-PostClearAction { Update-CopyButtonState -State $State }
})
$State.Controls.btnClearAppsScriptVariables.Add_Click({
$State.Controls.btnCopyBYOApps.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Invoke-CopyBYOApps -State $localState -Button $eventSource
})
$State.Controls.btnMoveTop.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Move-ListViewItemTop -ListView $localState.Controls.lstApplications
})
$State.Controls.btnMoveUp.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Move-ListViewItemUp -ListView $localState.Controls.lstApplications
})
$State.Controls.btnMoveDown.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Move-ListViewItemDown -ListView $localState.Controls.lstApplications
})
$State.Controls.btnMoveBottom.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag
Move-ListViewItemBottom -ListView $localState.Controls.lstApplications
})
$State.Controls.btnCheckWingetModule.Add_Click({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
$localState = $window.Tag