скрипт
This commit is contained in:
@@ -10,6 +10,17 @@
|
||||
2) при необходимости переименовывает колонку Title;
|
||||
3) обеспечивает колонки.
|
||||
|
||||
Имена списков НУМЕРОВАННЫЕ: «<Форма> <N> — данные» / «<Форма> <N> — согласование».
|
||||
Номер собирает сам скрипт из имени в манифесте (см. Get-NumberedListTitle) — в
|
||||
манифестах имена остаются без номера, чтобы номер не дублировался по 14 манифестам
|
||||
и ссылкам lookupList. Нумерация нужна под архивацию: когда список данных упирается
|
||||
в порог элементов, рядом создаётся следующая пара с номером N+1.
|
||||
|
||||
Перед основным проходом идёт разовая МИГРАЦИЯ имён (только при -ListNumber 1):
|
||||
существующие списки со старым безномерным именем переименовываются в «… 1 — …».
|
||||
Переименовывается только Title — server-relative URL списка при этом НЕ меняется,
|
||||
поэтому ссылки на список (request_type.list_id в approval-route) остаются валидными.
|
||||
|
||||
Колонки — через СТОЛБЦЫ САЙТА (эталоны):
|
||||
- не-Lookup колонка сначала создаётся как столбец сайта (группа «Портал заявок»),
|
||||
один раз на весь сайт, затем ПОДКЛЮЧАЕТСЯ к списку по ссылке. Так одинаковые
|
||||
@@ -40,17 +51,31 @@
|
||||
.PARAMETER FormsRoot
|
||||
Папка с формами. По умолчанию — src/webparts/requestPortal/forms.
|
||||
|
||||
.PARAMETER ListNumber
|
||||
Номер пары списков. 1 — текущие (рабочие) списки; 2, 3 … — следующие пары под
|
||||
архивацию. Миграция безномерных имён выполняется только при 1.
|
||||
|
||||
.PARAMETER SkipRename
|
||||
Не выполнять миграцию имён существующих списков (только создание/колонки).
|
||||
|
||||
.EXAMPLE
|
||||
./Provision-Lists.ps1 -SiteUrl "https://tnsukz.sharepoint.com/sites/requests" `
|
||||
-ClientId "7459c965-5ed4-4673-8140-0ab8faf9db64" -Tenant "tnsukz.onmicrosoft.com" `
|
||||
-Thumbprint "AABBCC...."
|
||||
|
||||
.EXAMPLE
|
||||
# Следующая пара списков под архивацию, без миграции имён.
|
||||
./Provision-Lists.ps1 -SiteUrl "..." -ClientId "..." -Tenant "..." -Thumbprint "..." `
|
||||
-ListNumber 2
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$SiteUrl,
|
||||
[Parameter(Mandatory = $true)][string]$ClientId,
|
||||
[Parameter(Mandatory = $true)][string]$Tenant,
|
||||
[Parameter(Mandatory = $true)][string]$Thumbprint,
|
||||
[string]$FormsRoot = "$PSScriptRoot/../src/webparts/requestPortal/forms"
|
||||
[string]$FormsRoot = "$PSScriptRoot/../src/webparts/requestPortal/forms",
|
||||
[ValidateRange(1, 999)][int]$ListNumber = 1,
|
||||
[switch]$SkipRename
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
@@ -61,6 +86,30 @@ function ConvertTo-XmlSafe {
|
||||
return $Value.Replace('&', '&').Replace('<', '<').Replace('>', '>').Replace("'", ''').Replace('"', '"')
|
||||
}
|
||||
|
||||
# Имя списка по конвенции: «<Форма> — данные» / «<Форма> — согласование».
|
||||
$LIST_TITLE_PATTERN = '^(?<base>.+?)\s*—\s*(?<suffix>данные|согласование)\s*$'
|
||||
|
||||
# Имя в манифесте → нумерованное «<Форма> <N> — <суффикс>».
|
||||
#
|
||||
# Номер ставится ПЕРЕД суффиксом, и это не косметика: и портал
|
||||
# (features/myRequests/myRequests.service.ts), и админка маршрутов
|
||||
# (approval-route/frontend/.../requestManageService.ts) выводят имя списка
|
||||
# согласования из имени списка данных регексом /\s*—\s*данные\s*$/, привязанным к
|
||||
# КОНЦУ строки. «… — данные 1» этот регекс не матчит, и список согласования просто
|
||||
# перестаёт находиться.
|
||||
#
|
||||
# Идемпотентно: уже нумерованное имя не получает второй номер, а перенумеровывается.
|
||||
function Get-NumberedListTitle {
|
||||
param([string]$Title, [int]$Number)
|
||||
|
||||
$m = [regex]::Match($Title, $LIST_TITLE_PATTERN)
|
||||
if (-not $m.Success) {
|
||||
throw "Имя списка «$Title» не по конвенции «<Форма> — данные|согласование» — номер поставить некуда"
|
||||
}
|
||||
$base = $m.Groups['base'].Value -replace '\s+\d+$', ''
|
||||
return "$base $Number — $($m.Groups['suffix'].Value)"
|
||||
}
|
||||
|
||||
# Есть ли колонка НА СПИСКЕ (list-scope).
|
||||
function Test-FieldExists {
|
||||
param([string]$List, [string]$InternalName)
|
||||
@@ -175,7 +224,12 @@ function Add-ListColumn {
|
||||
}
|
||||
}
|
||||
'Lookup' {
|
||||
$src = Get-PnPList -Identity $Col.lookupList -ErrorAction Stop
|
||||
# lookupList в манифесте — безномерное имя, целевой список тоже нумерован.
|
||||
# Кросс-формные lookup'ы (WorkplaceSetup.SourceHire → «Прием на работу … — данные»)
|
||||
# при этом предполагают ОДИН И ТОТ ЖЕ номер у обеих форм — при появлении
|
||||
# реальных архивных пар это место придётся пересмотреть.
|
||||
$lookupTitle = Get-NumberedListTitle -Title $Col.lookupList -Number $ListNumber
|
||||
$src = Get-PnPList -Identity $lookupTitle -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}' />"
|
||||
@@ -239,9 +293,41 @@ if (-not $manifests) {
|
||||
return
|
||||
}
|
||||
|
||||
# Проход 0: миграция безномерных имён на «… 1 — …». Отдельным проходом ДО основного —
|
||||
# так порядок обхода манифестов не важен: к моменту разрешения Lookup'а (по имени
|
||||
# списка-источника) все списки уже переименованы.
|
||||
#
|
||||
# Переименовывается только Title. URL списка при переименовании Title в SharePoint не
|
||||
# меняется, поэтому request_type.list_id (server-relative URL) в approval-route
|
||||
# трогать не нужно.
|
||||
if ($ListNumber -eq 1 -and -not $SkipRename) {
|
||||
Write-Host "`n=== Миграция имён списков на «… 1 — …» ===" -ForegroundColor Cyan
|
||||
foreach ($manifest in $manifests) {
|
||||
$def = Get-Content -Path $manifest.FullName -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$legacyTitle = $def.dataListTitle
|
||||
$targetTitle = Get-NumberedListTitle -Title $legacyTitle -Number 1
|
||||
|
||||
if (Get-PnPList -Identity $targetTitle -ErrorAction SilentlyContinue) {
|
||||
Write-Host " [=] уже нумерован: «$targetTitle»" -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
if (-not (Get-PnPList -Identity $legacyTitle -ErrorAction SilentlyContinue)) {
|
||||
Write-Host " [ ] нет списка «$legacyTitle» — создастся ниже как «$targetTitle»" -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
try {
|
||||
Set-PnPList -Identity $legacyTitle -Title $targetTitle | Out-Null
|
||||
Write-Host " [~] «$legacyTitle» → «$targetTitle»" -ForegroundColor Yellow
|
||||
}
|
||||
catch {
|
||||
Write-Warning " [!] не удалось переименовать «$legacyTitle»: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($manifest in $manifests) {
|
||||
$def = Get-Content -Path $manifest.FullName -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
$listTitle = $def.dataListTitle
|
||||
$listTitle = Get-NumberedListTitle -Title $def.dataListTitle -Number $ListNumber
|
||||
Write-Host "`n=== Форма: $($manifest.Directory.Name) → список «$listTitle» ===" -ForegroundColor Cyan
|
||||
|
||||
# 1) Список (идемпотентно)
|
||||
|
||||
Reference in New Issue
Block a user