#!/usr/bin/env bash # Shared presentation helpers. No Proxmox operations belong in this file. TAPM_UI_INIT() { TAPM_UI_RESET='' TAPM_UI_BOLD='' TAPM_UI_MUTED='' TAPM_UI_ACCENT='' TAPM_UI_SUCCESS='' TAPM_UI_WARNING='' TAPM_UI_ERROR='' TAPM_UI_SELECTED='' if [[ -t 1 && "${TERM:-dumb}" != dumb && -z "${NO_COLOR+x}" ]]; then TAPM_UI_RESET=$'\e[0m' TAPM_UI_BOLD=$'\e[1m' TAPM_UI_MUTED=$'\e[90m' TAPM_UI_ACCENT=$'\e[96m' TAPM_UI_SUCCESS=$'\e[32m' TAPM_UI_WARNING=$'\e[33m' TAPM_UI_ERROR=$'\e[31m' TAPM_UI_SELECTED=$'\e[1;36m' fi TAPM_UI_WIDTH="${COLUMNS:-80}" if [[ -t 1 && "${TERM:-dumb}" != dumb ]]; then TAPM_UI_WIDTH="$(tput cols 2>/dev/null)" || TAPM_UI_WIDTH="${COLUMNS:-80}" fi [[ "$TAPM_UI_WIDTH" =~ ^[0-9]+$ ]] || TAPM_UI_WIDTH=80 (( TAPM_UI_WIDTH > 75 )) && TAPM_UI_WIDTH=75 (( TAPM_UI_WIDTH < 20 )) && TAPM_UI_WIDTH=20 return 0 } TAPM_UI_PLAIN() { # Existing menus embed ANSI colors in a few labels; styling is centralized here. printf '%s' "$1" | sed -E $'s/\033\\[[0-9;]*[[:alpha:]]//g' } TAPM_UI_TEXT() { local style="$1" text="$2" line while IFS= read -r line; do printf ' %s%s%s\n' "$style" "$line" "$TAPM_UI_RESET" done < <(printf '%s\n' "$text" | fold -s -w "$((TAPM_UI_WIDTH - 2))") } TAPM_UI_RULE() { local rule printf -v rule '%*s' "$((TAPM_UI_WIDTH - 2))" '' TAPM_UI_TEXT "$TAPM_UI_MUTED" "${rule// /-}" } TAPM_UI_SHORTCUTS() { local key description length used=0 gap='' printf ' ' while (( $# >= 2 )); do key="$1" description="$2" shift 2 length=$((${#key} + 1 + ${#description})) if (( used > 0 && used + 3 + length > TAPM_UI_WIDTH - 2 )); then printf '\n ' used=0 gap='' fi printf '%s%s%s%s %s' "$gap" "$TAPM_UI_ACCENT" "$key" "$TAPM_UI_RESET" "$description" used=$((used + ${#gap} + length)) gap=' ' done printf '\n' } TAPM_UI_TASK() { TAPM_UI_TEXT "$TAPM_UI_ACCENT" "Starting: $(TAPM_UI_PLAIN "$1")" TAPM_UI_RULE printf '\n' } TAPM_UI_MENU_META() { local title="$1" value="$2" TAPM_UI_KIND=task TAPM_UI_HINT='' case "$title:$value" in 'Main Menu:'*|'Host Configuration & Recovery:post_install'|'Storage, ISOs & Backups:virtio'|\ 'Host Configuration & Recovery:services'|'TAPM Management:branches'|\ 'TAPM Host Profile:customize'|'Storage, ISOs & Backups:vzdump'|\ 'TAPM Host Profile:restore'|'Proxmox Backup Settings:restore'|\ 'Monitoring & Agents:notifications'|'Proxmox Notifications:policy') TAPM_UI_KIND=submenu ;; 'Select ISO Storage:'*|'Restore TAPM Host Configuration Backup:'*|\ 'Switch TAPM Git Branch:'*|'Proxmox Backup Settings:'*|\ 'Update Notification Policy:'*) TAPM_UI_KIND=choice ;; 'Customize TAPM Host Profile:'*) [[ "$value" == apply ]] || TAPM_UI_KIND=choice ;; 'TAPM Management:install_update') # The update banner is printed after the user confirms installation. TAPM_UI_KIND=choice ;; esac case "$value" in back|quit) TAPM_UI_KIND=navigation ;; esac case "$title:$value" in 'Cluster & High Availability:maintenance') TAPM_UI_HINT='This host: eligible guests migrate; local-storage guests shut down gracefully.' ;; 'Cluster & High Availability:keepalived') TAPM_UI_HINT='Deploy or reconfigure Keepalived across cluster hosts.' ;; 'Storage, ISOs & Backups:iso_nfs') TAPM_UI_HINT='Create an LXC NFS server and register shared ISO storage.' ;; 'Storage, ISOs & Backups:orphan_disks') TAPM_UI_HINT='Read-only cluster scan with optional CSV export.' ;; 'Cluster & High Availability:cpu') TAPM_UI_HINT='Analyze migration compatibility; review before applying a CPU model.' ;; 'Host Configuration & Recovery:services') TAPM_UI_HINT='Restart Proxmox management services on this host.' ;; 'Storage, ISOs & Backups:vzdump') TAPM_UI_HINT='Set backup bandwidth and I/O priority on this host.' ;; 'Proxmox Notifications:policy') TAPM_UI_HINT='Choose all updates, Proxmox VE version updates only, or no update alerts.' ;; 'TAPM Management:install_update') TAPM_UI_HINT='Update TAPM on online cluster nodes, or on this standalone host.' ;; esac } TAPM_UI_MENU_ROW() { local number="$1" label="$2" active="$3" marker=' ' style='' suffix='' label="$(TAPM_UI_PLAIN "$label")" [[ "$TAPM_UI_KIND" == submenu ]] && suffix=' >' if (( active )); then marker='>' style="$TAPM_UI_SELECTED" fi TAPM_UI_TEXT "$style" "$marker $number $label$suffix" }