feat: changed lists columns

This commit is contained in:
Тимур Городецкий
2026-08-06 15:36:22 +05:00
24 changed files with 1704 additions and 497 deletions
+86 -39
View File
@@ -75,9 +75,20 @@ function Test-SiteFieldExists {
$SITE_COLUMN_GROUP = 'Портал заявок'
# Создаёт/обновляет СТОЛБЕЦ САЙТА (эталон) — один раз на весь сайт. Для Choice при
# повторе объединяет варианты (union), чтобы наборы разных форм не затирали друг друга.
# Lookup сюда НЕ попадает (эталоном быть не может — привязка к конкретному списку).
# Типы, которые НЕ делаем эталоном (столбцом сайта), а создаём столбцом списка:
# - Lookup (эталон привязан к одному списку, а Ticket у каждого свой);
# - Number с decimals и UserMulti (создаются через XML; web-level XML в PnP падает
# NRE, и это одноразовые поля конкретной формы — переиспользовать нечего).
function Test-NeedsListColumn {
param($Col)
return ($Col.type -eq 'Lookup') `
-or ($Col.type -eq 'Number' -and $null -ne $Col.decimals) `
-or ($Col.type -eq 'User' -and $Col.allowMultiple)
}
# Создаёт/обновляет СТОЛБЕЦ САЙТА (эталон) — один раз на весь сайт. Только простые
# типы (без XML). Для Choice при повторе объединяет варианты (union), чтобы наборы
# разных форм не затирали друг друга.
function Ensure-SiteColumn {
param($Col)
@@ -102,54 +113,89 @@ function Ensure-SiteColumn {
}
'Boolean' { Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type Boolean -Group $g | Out-Null }
'User' {
if ($Col.allowMultiple) {
$xml = "<Field Type='UserMulti' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' Mult='TRUE' Group='$(ConvertTo-XmlSafe $g)' />"
Add-PnPFieldFromXml -FieldXml $xml | Out-Null
}
else {
Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type User -Group $g | Out-Null
}
Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type User -Group $g | Out-Null
if ($Col.userSelectionMode) {
$mode = if ($Col.userSelectionMode -eq 'PeopleAndGroups') { 1 } else { 0 }
Set-PnPField -Identity $Col.internalName -Values @{ SelectionMode = $mode } | Out-Null
}
}
'Choice' { Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type Choice -Choices $Col.choices -Group $g | Out-Null }
'Number' {
if ($null -ne $Col.decimals) {
$xml = "<Field Type='Number' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' Decimals='$($Col.decimals)' Group='$(ConvertTo-XmlSafe $g)' />"
Add-PnPFieldFromXml -FieldXml $xml | Out-Null
}
else {
Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type Number -Group $g | Out-Null
}
}
'Number' { Add-PnPField -InternalName $Col.internalName -DisplayName $Col.title -Type Number -Group $g | Out-Null }
default { throw "Неизвестный тип столбца сайта '$($Col.type)'" }
}
Write-Host " [+эталон] $($Col.internalName) — «$($Col.title)» [$($Col.type)]" -ForegroundColor Green
}
# Обеспечивает колонку НА СПИСКЕ. Не-Lookup — из эталона (столбец сайта → подключить).
# Lookup — обычным столбцом списка (эталоном быть не может).
# Создаёт колонку прямо НА СПИСКЕ (для Lookup / XML-типов). Идемпотентно.
function Add-ListColumn {
param([string]$List, $Col)
if (Test-FieldExists -List $List -InternalName $Col.internalName) {
if ($Col.type -eq 'Choice' -and $Col.choices) {
try {
Set-PnPField -List $List -Identity $Col.internalName -Values @{ Choices = [string[]]$Col.choices } | Out-Null
Write-Host " [~] варианты обновлены: $($Col.internalName)" -ForegroundColor DarkGray
}
catch { Write-Warning " [!] $($Col.internalName): не удалось обновить варианты — $($_.Exception.Message)" }
}
else { Write-Host " [=] столбец списка есть: $($Col.internalName)" -ForegroundColor DarkGray }
return
}
try {
switch ($Col.type) {
'Text' { Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type Text -AddToDefaultView | Out-Null }
'Note' { Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type Note -AddToDefaultView | Out-Null }
'DateTime' {
Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type DateTime -AddToDefaultView | Out-Null
if ($Col.dateOnly) { Set-PnPField -List $List -Identity $Col.internalName -Values @{ DisplayFormat = 0; FriendlyDisplayFormat = 1 } | Out-Null }
}
'Boolean' { Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type Boolean -AddToDefaultView | Out-Null }
'User' {
if ($Col.allowMultiple) {
$xml = "<Field Type='UserMulti' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' Mult='TRUE' />"
Add-PnPFieldFromXml -List $List -FieldXml $xml | Out-Null
}
else {
Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type User -AddToDefaultView | Out-Null
}
if ($Col.userSelectionMode) {
$mode = if ($Col.userSelectionMode -eq 'PeopleAndGroups') { 1 } else { 0 }
Set-PnPField -List $List -Identity $Col.internalName -Values @{ SelectionMode = $mode } | Out-Null
}
}
'Choice' { Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type Choice -Choices $Col.choices -AddToDefaultView | Out-Null }
'Number' {
if ($null -ne $Col.decimals) {
$xml = "<Field Type='Number' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' Decimals='$($Col.decimals)' />"
Add-PnPFieldFromXml -List $List -FieldXml $xml | Out-Null
}
else {
Add-PnPField -List $List -InternalName $Col.internalName -DisplayName $Col.title -Type Number -AddToDefaultView | Out-Null
}
}
'Lookup' {
$src = Get-PnPList -Identity $Col.lookupList -ErrorAction Stop
$guid = $src.Id.ToString()
$show = if ($Col.lookupShowField) { $Col.lookupShowField } else { 'Title' }
$xml = "<Field Type='Lookup' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' ShowField='$show' List='{$guid}' />"
Add-PnPFieldFromXml -List $List -FieldXml $xml | Out-Null
}
default { throw "Неизвестный тип колонки '$($Col.type)'" }
}
if ($Col.required) { Set-PnPField -List $List -Identity $Col.internalName -Values @{ Required = $true } | Out-Null }
Write-Host " [+] столбец списка: $($Col.internalName) — «$($Col.title)» [$($Col.type)]" -ForegroundColor Green
}
catch { Write-Warning " [!] $($Col.internalName): $($_.Exception.Message)" }
}
# Обеспечивает колонку НА СПИСКЕ: простые типы — из эталона (столбец сайта →
# подключить), Lookup/XML-типы — обычным столбцом списка.
function Add-ColumnToList {
param([string]$List, $Col)
if ($Col.type -eq 'Lookup') {
if (Test-FieldExists -List $List -InternalName $Col.internalName) {
Write-Host " [=] lookup есть: $($Col.internalName)" -ForegroundColor DarkGray
return
}
try {
$src = Get-PnPList -Identity $Col.lookupList -ErrorAction Stop
$guid = $src.Id.ToString()
$show = if ($Col.lookupShowField) { $Col.lookupShowField } else { 'Title' }
$xml = "<Field Type='Lookup' DisplayName='$(ConvertTo-XmlSafe $Col.title)' Name='$($Col.internalName)' ShowField='$show' List='{$guid}' />"
Add-PnPFieldFromXml -List $List -FieldXml $xml | Out-Null
Write-Host " [+] lookup (столбец списка): $($Col.internalName)" -ForegroundColor Green
}
catch {
Write-Warning " [!] $($Col.internalName): $($_.Exception.Message)"
}
if (Test-NeedsListColumn -Col $Col) {
Add-ListColumn -List $List -Col $Col
return
}
@@ -162,13 +208,14 @@ function Add-ColumnToList {
return
}
# 2) подключить эталон к списку (если ещё не подключён)
# 2) подключить эталон к списку (если ещё не подключён). Без -AddToDefaultView:
# с параметром -Field он несовместим (другой набор параметров cmdlet).
if (Test-FieldExists -List $List -InternalName $Col.internalName) {
Write-Host " [=] уже на списке: $($Col.internalName)" -ForegroundColor DarkGray
}
else {
try {
Add-PnPField -List $List -Field $Col.internalName -AddToDefaultView | Out-Null
Add-PnPField -List $List -Field $Col.internalName | Out-Null
Write-Host " [+] подключён эталон: $($Col.internalName)" -ForegroundColor Green
}
catch {