Add src/ui.ps1
This commit is contained in:
196
src/ui.ps1
Normal file
196
src/ui.ps1
Normal file
@@ -0,0 +1,196 @@
|
||||
function Publish-Checkboxes {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Page,
|
||||
[string]$Column,
|
||||
[string]$Group
|
||||
)
|
||||
|
||||
function Escape-HtmlAttr {
|
||||
param([string]$s)
|
||||
if ([string]::IsNullOrEmpty($s)) { return '' }
|
||||
$s = $s -replace "(`r`n|`r|`n)", ' '
|
||||
$s = $s -replace '&','&'
|
||||
$s = $s -replace '"','"'
|
||||
$s = $s -replace "'",'''
|
||||
$s = $s -replace '<','<'
|
||||
$s = $s -replace '>','>'
|
||||
return $s
|
||||
}
|
||||
|
||||
function Escape-HtmlText {
|
||||
param([string]$s)
|
||||
if ([string]::IsNullOrEmpty($s)) { return '' }
|
||||
$s = $s -replace '&','&'
|
||||
$s = $s -replace '<','<'
|
||||
$s = $s -replace '>','>'
|
||||
return $s
|
||||
}
|
||||
|
||||
$tasks = $Global:SamyTasks | Where-Object Page -EQ $Page
|
||||
|
||||
if (-not [string]::IsNullOrEmpty($Column)) {
|
||||
$tasks = $tasks | Where-Object Column -EQ $Column
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrEmpty($Group)) {
|
||||
if ($Group -eq 'tweaks') {
|
||||
$tasks = $tasks | Where-Object {
|
||||
-not ($_.PSObject.Properties.Name -contains 'Group') -or
|
||||
[string]$_.Group -eq '' -or
|
||||
[string]$_.Group -eq 'tweaks'
|
||||
}
|
||||
}
|
||||
else {
|
||||
$tasks = $tasks | Where-Object {
|
||||
($_.PSObject.Properties.Name -contains 'Group') -and
|
||||
([string]$_.Group -eq $Group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(
|
||||
$tasks | ForEach-Object {
|
||||
|
||||
$taskId = $_.Id
|
||||
$rawTooltip = if ($_.PSObject.Properties.Name -contains 'Tooltip' -and $_.Tooltip) { [string]$_.Tooltip } else { [string]$_.Label }
|
||||
$tooltipText = Escape-HtmlAttr $rawTooltip
|
||||
$tooltipAttr = if ([string]::IsNullOrWhiteSpace($tooltipText)) { '' } else { " title=`"$tooltipText`"" }
|
||||
|
||||
$labelText = Escape-HtmlText ([string]$_.Label)
|
||||
|
||||
$taskIdAttr = Escape-HtmlAttr ([string]$taskId)
|
||||
$nameAttr = Escape-HtmlAttr ([string]$_.Name)
|
||||
$colAttr = Escape-HtmlAttr ([string]$Column)
|
||||
|
||||
$groupValue = ''
|
||||
if ($_.PSObject.Properties.Name -contains 'Group' -and $_.Group) { $groupValue = [string]$_.Group }
|
||||
$groupAttr = Escape-HtmlAttr $groupValue
|
||||
$groupDataAttr = if ([string]::IsNullOrWhiteSpace($groupAttr)) { '' } else { " data-group=""$groupAttr""" }
|
||||
|
||||
$html = "<label$tooltipAttr><input type=""checkbox"" id=""$taskIdAttr"" name=""$nameAttr"" data-column=""$colAttr""$groupDataAttr> $labelText</label>"
|
||||
|
||||
if ($_.SubOptions) {
|
||||
|
||||
$subHtml = (
|
||||
$_.SubOptions | ForEach-Object {
|
||||
|
||||
$type = if ($_.PSObject.Properties.Name -contains 'Type' -and $_.Type) { [string]$_.Type } else { 'checkbox' }
|
||||
|
||||
if ($type -eq 'text') {
|
||||
$subId = Escape-HtmlAttr ([string]$_.Id)
|
||||
$subLabel = Escape-HtmlText ([string]$_.Label)
|
||||
$ph = if ($_.PSObject.Properties.Name -contains 'Placeholder') { Escape-HtmlAttr ([string]$_.Placeholder) } else { '' }
|
||||
$help = if ($_.PSObject.Properties.Name -contains 'Help') { Escape-HtmlText ([string]$_.Help) } else { '' }
|
||||
|
||||
@"
|
||||
<div style="margin-left:20px; margin-top:6px;">
|
||||
<label for="$subId">$subLabel</label>
|
||||
<input type="text" id="$subId" placeholder="$ph" />
|
||||
<small style="display:block; margin-top:4px;">$help</small>
|
||||
</div>
|
||||
"@
|
||||
}
|
||||
else {
|
||||
$subLabel = Escape-HtmlText ([string]$_.Label)
|
||||
$subTaskIdClass = Escape-HtmlAttr ([string]$taskId)
|
||||
$subValueAttr = Escape-HtmlAttr ([string]$_.Value)
|
||||
|
||||
"<label style=""margin-left:20px; display:block;"">
|
||||
<input type=""checkbox"" class=""sub-option-$subTaskIdClass"" name=""$subValueAttr"" value=""$subValueAttr""> $subLabel
|
||||
</label>"
|
||||
}
|
||||
}
|
||||
) -join "`n"
|
||||
|
||||
$html += @"
|
||||
<div id="$(Escape-HtmlAttr ([string]$taskId))OptionsContainer" style="display:none; margin-top:4px;">
|
||||
$subHtml
|
||||
</div>
|
||||
"@
|
||||
}
|
||||
|
||||
$html
|
||||
}
|
||||
) -join "`n"
|
||||
}
|
||||
|
||||
function Get-ModuleVersionHtml {
|
||||
$mod = Get-Module -ListAvailable -Name SVSMSP | Sort-Object Version -Descending | Select-Object -First 1
|
||||
|
||||
$branchDisplay = switch ($Script:SamyBranch.ToLower()) {
|
||||
'main' { 'Main / Stable' }
|
||||
'beta' { 'Beta' }
|
||||
default { $Script:SamyBranch }
|
||||
}
|
||||
|
||||
if ($mod) {
|
||||
return "<div style='color:#bbb; font-size:0.9em; margin-top:1em;'>
|
||||
Module Version: $($mod.Version)<br>
|
||||
UI Branch: $branchDisplay
|
||||
</div>"
|
||||
}
|
||||
|
||||
return "<div style='color:#f66;'>SVSMSP_Module not found</div>"
|
||||
}
|
||||
|
||||
function Get-UIHtml {
|
||||
param([string]$Page = 'onboard')
|
||||
if (-not $Page) { $Page = 'onboard' }
|
||||
|
||||
$onboardLeft = Publish-Checkboxes -Page 'onboard' -Column 'left'
|
||||
$onboardRightApps = Publish-Checkboxes -Page 'onboard' -Column 'right' -Group 'apps'
|
||||
$onboardRightTweaks = Publish-Checkboxes -Page 'onboard' -Column 'right' -Group 'tweaks'
|
||||
$offboard = Publish-Checkboxes -Page 'offboard' -Column ''
|
||||
$devices = Publish-Checkboxes -Page 'devices' -Column ''
|
||||
|
||||
$tasksJson = @(
|
||||
$Global:SamyTasks | ForEach-Object {
|
||||
[pscustomobject]@{
|
||||
id = [string]$_.Id
|
||||
handler = "/$([string]$_.Name)"
|
||||
label = [string]$_.Label
|
||||
}
|
||||
}
|
||||
) | ConvertTo-Json -Depth 4
|
||||
|
||||
$tasksJsAll = $tasksJson
|
||||
|
||||
$cssContent = Get-RemoteText -Url $Script:SamyCssUrl
|
||||
$jsContent = Get-RemoteText -Url $Script:SamyJsUrl
|
||||
$htmlTemplate = Get-RemoteText -Url $Script:SamyHtmlUrl
|
||||
|
||||
if (-not $htmlTemplate) {
|
||||
Write-LogHybrid "UI template download failed. Returning minimal error page." Error UI -LogToEvent
|
||||
return "<html><body style='font-family:Segoe UI; padding:20px; background:#111; color:#ddd;'>
|
||||
<h2>SAMY UI template unavailable</h2>
|
||||
<p>Could not download samy.html from repo.</p>
|
||||
</body></html>"
|
||||
}
|
||||
|
||||
if ($cssContent) {
|
||||
$cssContent += @"
|
||||
/* SAMY background override injected by script */
|
||||
.sidebar::after {
|
||||
background-image: url('$Script:SamyBgLogoUrl') !important;
|
||||
}
|
||||
"@
|
||||
}
|
||||
|
||||
$html = $htmlTemplate
|
||||
$html = $html.Replace('{{CssContent}}', $cssContent)
|
||||
$html = $html.Replace('{{JsContent}}', $jsContent)
|
||||
$html = $html.Replace('{{SamyFaviconUrl}}', $Script:SamyFaviconUrl)
|
||||
$html = $html.Replace('{{SamyTopLogoUrl}}', $Script:SamyTopLogoUrl)
|
||||
$html = $html.Replace('{{SamyHintText}}', $Script:SamyHintText)
|
||||
|
||||
$html = $html.Replace('{{moduleVersion}}', (Get-ModuleVersionHtml))
|
||||
$html = $html.Replace('{{onboardLeftColumn}}', $onboardLeft)
|
||||
$html = $html.Replace('{{onboardRightApps}}', $onboardRightApps)
|
||||
$html = $html.Replace('{{onboardRightTweaks}}', $onboardRightTweaks)
|
||||
$html = $html.Replace('{{offboardCheckboxes}}', $offboard)
|
||||
$html = $html.Replace('{{devicesCheckboxes}}', $devices)
|
||||
$html = $html.Replace('{{tasksJsAll}}', $tasksJsAll)
|
||||
$html = $html.Replace('{{defaultPage}}', $Page)
|
||||
|
||||
return $html
|
||||
}
|
||||
Reference in New Issue
Block a user