mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-05 09:40:52 +03:00
feat(form-decompile,form-compile): блок свойств таблицы динамического списка (кластер DynamicList Table)
Таблица формы, привязанная к динамическому списку, несёт блок специфичных свойств, который платформа всегда эмитит (n=5079 на дин-список-таблицах, 0 на ValueTable). Компилятор (ps1+py v1.40): авто-эмиссия блока на дин-список-таблице (Emit-DynListTableBlock): - Group A (дефолт+override): AutoRefresh(false), AutoRefreshPeriod(60), Period(пустой Custom, константа), ChoiceFoldersAndItems(Items), RestoreCurrentRow(false), TopLevelParent(nil, константа), ShowRoot(true), AllowRootChoice(false), UpdateOnDataChange(Auto), AllowGettingCurrentRowURL(true). - Group B (условные): DefaultItem, UseAlternationRowColor, FileDragMode (+ существующие InitialTreeView/EnableStartDrag). - Group C: RowPictureDataPath (умный дефолт <Список>.DefaultPicture + override + suppress-маркер ""; ИСПРАВЛЕН баг — пустая строка больше не перезатирается дефолтом), RowsPicture, UserSettingsGroup. - Эвристика 11b.4 теперь обходит ВСЕ DynamicList-реквизиты (не только main) → блок эмитится и для не-main/вторичных списков. Внутренний маркер _dynList исключён из валидатора ключей. Декомпилятор (v0.22): захват блока с инверсией (gate = наличие <UpdateOnDataChange>): Group A — опускает значения = дефолту; Group B — захват при наличии; RowPictureDataPath — DefaultPicture опускается, кастом захватывается, отсутствие → "". Валидация: дин-блок round-trip CLEAN (мультимножество, GUID-норм.) на простом списке и на форме с кастомным RowPictureDataPath/RowsPicture/UserSettingsGroup; сертификация в 1С PASS; py==ps1 идентичны; регресс 33/33 ps+py; harness 9634→8300 (−14%), 0 fail; группа «67» (AutoRefresh/ShowRoot/UpdateOnDataChange/…) ушла из остатка, residual block-теги 47→5. Spec — раздел «Таблица динамического списка»; тест-кейсы перегенерированы. Хвост и соседний кластер (свойства Table на не-дин-список таблицах) — в BACKLOG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
15883a7e7c
commit
1d158e3218
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.39 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.40 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2342,6 +2342,11 @@ function Emit-Element {
|
||||
"excludedCommands"=1
|
||||
"choiceMode"=1;"initialTreeView"=1;"enableDrag"=1;"enableStartDrag"=1
|
||||
"rowPictureDataPath"=1;"tableAutofill"=1
|
||||
# dynamic-list table block
|
||||
"defaultItem"=1;"useAlternationRowColor"=1;"fileDragMode"=1;"autoRefresh"=1
|
||||
"autoRefreshPeriod"=1;"choiceFoldersAndItems"=1;"restoreCurrentRow"=1;"showRoot"=1
|
||||
"allowRootChoice"=1;"updateOnDataChange"=1;"allowGettingCurrentRowURL"=1
|
||||
"userSettingsGroup"=1;"rowsPicture"=1
|
||||
# calendar-specific
|
||||
"selectionMode"=1;"showCurrentDate"=1;"widthInMonths"=1;"heightInMonths"=1;"showMonthsPanel"=1
|
||||
# pages-specific
|
||||
@@ -2354,6 +2359,7 @@ function Emit-Element {
|
||||
"autofill"=1
|
||||
}
|
||||
foreach ($p in $el.PSObject.Properties) {
|
||||
if ($p.Name -like '_*') { continue } # внутренние маркеры (напр. _dynList)
|
||||
if (-not $knownKeys.ContainsKey($p.Name)) {
|
||||
Write-Warning "Element '$($el.$typeKey)': unknown key '$($p.Name)' — ignored. Check SKILL.md for valid keys."
|
||||
}
|
||||
@@ -2949,6 +2955,41 @@ function Emit-LabelField {
|
||||
X "$indent</LabelField>"
|
||||
}
|
||||
|
||||
# Блок свойств таблицы, привязанной к динамическому списку (Group A defaults + B/C).
|
||||
# Платформа всегда эмитит этот блок на дин-список-таблице; компилятор зеркалит дефолты,
|
||||
# DSL-ключ переопределяет; декомпилятор инвертирует (опускает значения = дефолту).
|
||||
function Emit-DynListTableBlock {
|
||||
param($el, [string]$indent)
|
||||
# Group B (условные опц.): defaultItem / useAlternationRowColor / fileDragMode
|
||||
if ($el.defaultItem -eq $true) { X "$indent<DefaultItem>true</DefaultItem>" }
|
||||
if ($el.useAlternationRowColor -eq $true) { X "$indent<UseAlternationRowColor>true</UseAlternationRowColor>" }
|
||||
if ($el.fileDragMode) { X "$indent<FileDragMode>$($el.fileDragMode)</FileDragMode>" }
|
||||
# Group A (гарант. блок, n=5079): дефолт + override
|
||||
$ar = if ($el.autoRefresh -eq $true) { "true" } else { "false" }
|
||||
X "$indent<AutoRefresh>$ar</AutoRefresh>"
|
||||
$arp = if ($el.PSObject.Properties["autoRefreshPeriod"] -and $null -ne $el.autoRefreshPeriod) { $el.autoRefreshPeriod } else { 60 }
|
||||
X "$indent<AutoRefreshPeriod>$arp</AutoRefreshPeriod>"
|
||||
X "$indent<Period>"
|
||||
X "$indent`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">Custom</v8:variant>"
|
||||
X "$indent`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
X "$indent`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
X "$indent</Period>"
|
||||
$cfi = if ($el.choiceFoldersAndItems) { $el.choiceFoldersAndItems } else { "Items" }
|
||||
X "$indent<ChoiceFoldersAndItems>$cfi</ChoiceFoldersAndItems>"
|
||||
$rcr = if ($el.restoreCurrentRow -eq $true) { "true" } else { "false" }
|
||||
X "$indent<RestoreCurrentRow>$rcr</RestoreCurrentRow>"
|
||||
X "$indent<TopLevelParent xsi:nil=`"true`"/>"
|
||||
$sr = if ($el.showRoot -eq $false) { "false" } else { "true" }
|
||||
X "$indent<ShowRoot>$sr</ShowRoot>"
|
||||
$arc = if ($el.allowRootChoice -eq $true) { "true" } else { "false" }
|
||||
X "$indent<AllowRootChoice>$arc</AllowRootChoice>"
|
||||
$uodc = if ($el.updateOnDataChange) { $el.updateOnDataChange } else { "Auto" }
|
||||
X "$indent<UpdateOnDataChange>$uodc</UpdateOnDataChange>"
|
||||
if ($el.userSettingsGroup) { X "$indent<UserSettingsGroup>$($el.userSettingsGroup)</UserSettingsGroup>" }
|
||||
$agcru = if ($el.allowGettingCurrentRowURL -eq $false) { "false" } else { "true" }
|
||||
X "$indent<AllowGettingCurrentRowURL>$agcru</AllowGettingCurrentRowURL>"
|
||||
}
|
||||
|
||||
function Emit-Table {
|
||||
param($el, [string]$name, [int]$id, [string]$indent)
|
||||
|
||||
@@ -2981,6 +3022,14 @@ function Emit-Table {
|
||||
if ($el.enableStartDrag -eq $true) { X "$inner<EnableStartDrag>true</EnableStartDrag>" }
|
||||
if ($el.enableDrag -eq $true) { X "$inner<EnableDrag>true</EnableDrag>" }
|
||||
if ($el.rowPictureDataPath) { X "$inner<RowPictureDataPath>$($el.rowPictureDataPath)</RowPictureDataPath>" }
|
||||
if ($el.rowsPicture) {
|
||||
X "$inner<RowsPicture>"
|
||||
X "$inner`t<xr:Ref>$($el.rowsPicture)</xr:Ref>"
|
||||
X "$inner`t<xr:LoadTransparent>false</xr:LoadTransparent>"
|
||||
X "$inner</RowsPicture>"
|
||||
}
|
||||
# Блок свойств дин-список-таблицы (помечена эвристикой 11b.4)
|
||||
if ($el.PSObject.Properties["_dynList"] -and $el._dynList) { Emit-DynListTableBlock -el $el -indent $inner }
|
||||
if ($el.viewStatusLocation) { X "$inner<ViewStatusLocation>$($el.viewStatusLocation)</ViewStatusLocation>" }
|
||||
if ($el.searchControlLocation) { X "$inner<SearchControlLocation>$($el.searchControlLocation)</SearchControlLocation>" }
|
||||
Emit-Layout -el $el -indent $inner -skipHeight
|
||||
@@ -3637,14 +3686,17 @@ function ApplyDynamicListTableHeuristic {
|
||||
param($el, [string]$listName, [bool]$hasMainTable)
|
||||
if ($null -eq $el) { return }
|
||||
if ($el.PSObject.Properties["table"] -and $null -ne $el.table -and "$($el.path)" -eq $listName) {
|
||||
# Маркер дин-список-таблицы → Emit-Table эмитит блок свойств (Group A defaults)
|
||||
$el | Add-Member -NotePropertyName "_dynList" -NotePropertyValue $true -Force
|
||||
if ($null -eq $el.PSObject.Properties["tableAutofill"]) {
|
||||
$el | Add-Member -NotePropertyName "tableAutofill" -NotePropertyValue $false -Force
|
||||
}
|
||||
if ($null -eq $el.PSObject.Properties["commandBarLocation"]) {
|
||||
$el | Add-Member -NotePropertyName "commandBarLocation" -NotePropertyValue "None" -Force
|
||||
}
|
||||
# DefaultPicture доступен только если у DynamicList есть основная таблица
|
||||
if ($hasMainTable -and ($null -eq $el.PSObject.Properties["rowPictureDataPath"] -or [string]::IsNullOrEmpty("$($el.rowPictureDataPath)"))) {
|
||||
# RowPictureDataPath: умный дефолт <Список>.DefaultPicture, если ключ ОТСУТСТВУЕТ
|
||||
# и есть основная таблица. Пустая строка (suppress-маркер) НЕ перезатирается.
|
||||
if ($hasMainTable -and ($null -eq $el.PSObject.Properties["rowPictureDataPath"])) {
|
||||
$el | Add-Member -NotePropertyName "rowPictureDataPath" -NotePropertyValue "$listName.DefaultPicture" -Force
|
||||
}
|
||||
}
|
||||
@@ -3731,24 +3783,21 @@ if ($def.attributes) {
|
||||
}
|
||||
}
|
||||
|
||||
# 11b.4: DynamicList → table heuristic
|
||||
# 11b.4: DynamicList → table heuristic (для ВСЕХ DynamicList-реквизитов, не только main)
|
||||
if ($def.attributes -and $def.elements) {
|
||||
$mainAttr = $null
|
||||
foreach ($attr in $def.attributes) {
|
||||
if ($attr.main -eq $true) { $mainAttr = $attr; break }
|
||||
}
|
||||
if ($mainAttr -and "$($mainAttr.type)" -eq "DynamicList") {
|
||||
if ("$($attr.type)" -ne "DynamicList") { continue }
|
||||
$mt = $null
|
||||
if ($mainAttr.PSObject.Properties["settings"] -and $null -ne $mainAttr.settings) {
|
||||
if ($mainAttr.settings -is [hashtable]) {
|
||||
if ($mainAttr.settings.ContainsKey("mainTable")) { $mt = $mainAttr.settings["mainTable"] }
|
||||
} elseif ($mainAttr.settings.PSObject.Properties["mainTable"]) {
|
||||
$mt = $mainAttr.settings.mainTable
|
||||
if ($attr.PSObject.Properties["settings"] -and $null -ne $attr.settings) {
|
||||
if ($attr.settings -is [hashtable]) {
|
||||
if ($attr.settings.ContainsKey("mainTable")) { $mt = $attr.settings["mainTable"] }
|
||||
} elseif ($attr.settings.PSObject.Properties["mainTable"]) {
|
||||
$mt = $attr.settings.mainTable
|
||||
}
|
||||
}
|
||||
$hasMt = -not [string]::IsNullOrEmpty("$mt")
|
||||
foreach ($el in $def.elements) {
|
||||
ApplyDynamicListTableHeuristic $el $mainAttr.name $hasMt
|
||||
ApplyDynamicListTableHeuristic $el $attr.name $hasMt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user