feat(tui): add fzf-based folder browser for export/import path prompts
Read-Host has no tab-completion (that's a top-level PSReadLine feature, not available to script prompts), so reuse the fzf dependency already required for menus to browse folders interactively instead: navigate into subfolders, go up with .., confirm current folder, or type a path manually. Falls back to plain Read-Host when fzf isn't installed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# macOS Intune Toolkit Changelog
|
||||
|
||||
## 2026-08-07 — v4.4.0 — Folder browser for Export/Import path prompts
|
||||
|
||||
### Added
|
||||
- **`Scripts/Private/Start-IntuneManagementTui.ps1`**
|
||||
- New `Select-FolderPath` helper: when `fzf` is available, the Export/Import root folder prompt (and the report flow's export/backup-root/output-dir prompts) becomes an interactive folder browser — navigate into subfolders, go up with `..`, confirm the current folder, or type a path manually. `Read-Host` alone has no tab-completion (that's a top-level PSReadLine feature, not available to script prompts), so this reuses the `fzf` dependency already required for menus instead of building custom completion.
|
||||
- Falls back to a plain `Read-Host` prompt when `fzf` isn't installed — no regression from prior behavior.
|
||||
|
||||
## 2026-08-07 — v4.3.1 — Fix redundant action prompt
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Cross-platform, headless Intune policy export/import with PowerShell.
|
||||
|
||||
**Current version:** `4.3.1` — see [`CHANGELOG_macOS_IntuneToolkit.md`](CHANGELOG_macOS_IntuneToolkit.md) for recent changes.
|
||||
**Current version:** `4.4.0` — see [`CHANGELOG_macOS_IntuneToolkit.md`](CHANGELOG_macOS_IntuneToolkit.md) for recent changes.
|
||||
|
||||
This repository is now CLI-first. The old WPF application surface has been removed from the repo. The supported workflow is:
|
||||
|
||||
|
||||
@@ -107,6 +107,41 @@ function Select-MenuItem
|
||||
return Show-NumberedMenu -Items $Items -Header $Header -Multi:$Multi
|
||||
}
|
||||
|
||||
function Select-FolderPath
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Prompt,
|
||||
[string]$StartPath = (Get-Location).Path
|
||||
)
|
||||
if(-not (Test-FzfAvailable))
|
||||
{
|
||||
return Read-Host $Prompt
|
||||
}
|
||||
|
||||
$current = if(Test-Path -LiteralPath $StartPath) { (Resolve-Path -LiteralPath $StartPath).Path } else { (Get-Location).Path }
|
||||
|
||||
while($true)
|
||||
{
|
||||
$entries = @("[Use this folder]", "[Type path manually]")
|
||||
$parent = Split-Path -Path $current -Parent
|
||||
if($parent) { $entries += ".." }
|
||||
$subdirs = Get-ChildItem -LiteralPath $current -Directory -ErrorAction SilentlyContinue | Sort-Object Name | ForEach-Object { "$($_.Name)/" }
|
||||
$entries += $subdirs
|
||||
|
||||
$choice = $entries | fzf --header="$Prompt [current: $current]"
|
||||
if(-not $choice) { return $null }
|
||||
|
||||
switch ($choice)
|
||||
{
|
||||
"[Use this folder]" { return $current }
|
||||
"[Type path manually]" { $typed = Read-Host "Enter path"; if(-not [string]::IsNullOrWhiteSpace($typed)) { return $typed }; continue }
|
||||
".." { $current = $parent; continue }
|
||||
default { $current = Join-Path $current ($choice.TrimEnd('/')); continue }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Read-YesNo
|
||||
{
|
||||
param(
|
||||
@@ -275,18 +310,18 @@ while($true)
|
||||
if([string]::IsNullOrWhiteSpace($tenantIdForReport)) { Write-Host "Tenant ID is required." -ForegroundColor Red; continue }
|
||||
}
|
||||
|
||||
$exportPath = Read-Host "Export path (where to save fresh data)"
|
||||
$exportPath = Select-FolderPath -Prompt "Select export path (where to save fresh data)"
|
||||
if([string]::IsNullOrWhiteSpace($exportPath)) { Write-Host "Export path is required." -ForegroundColor Red; continue }
|
||||
$backupRoot = $exportPath
|
||||
}
|
||||
else
|
||||
{
|
||||
$backupRoot = Read-Host "Backup root path (folder containing 'Settings Catalog', etc.)"
|
||||
$backupRoot = Select-FolderPath -Prompt "Select backup root (folder containing 'Settings Catalog', etc.)"
|
||||
if([string]::IsNullOrWhiteSpace($backupRoot)) { Write-Host "Backup root is required." -ForegroundColor Red; continue }
|
||||
if(-not (Test-Path $backupRoot)) { Write-Host "Path not found: $backupRoot" -ForegroundColor Red; continue }
|
||||
}
|
||||
|
||||
$outputDir = Read-Host "Enter output directory for reports"
|
||||
$outputDir = Select-FolderPath -Prompt "Select output directory for reports"
|
||||
if([string]::IsNullOrWhiteSpace($outputDir)) { Write-Host "Output directory is required." -ForegroundColor Red; continue }
|
||||
|
||||
$includeAssignmentsInSettings = $false
|
||||
@@ -358,8 +393,8 @@ while($true)
|
||||
if(-not $typeSelection) { continue }
|
||||
|
||||
# 4. Path
|
||||
$pathPrompt = if($action -eq "Export") { "Enter export root folder path" } else { "Enter import root folder path" }
|
||||
$path = Read-Host $pathPrompt
|
||||
$pathPrompt = if($action -eq "Export") { "Select export root folder" } else { "Select import root folder" }
|
||||
$path = Select-FolderPath -Prompt $pathPrompt
|
||||
if([string]::IsNullOrWhiteSpace($path)) { Write-Host "Path is required." -ForegroundColor Red; return $null }
|
||||
|
||||
# 5. Name Filter
|
||||
|
||||
Reference in New Issue
Block a user