From a59be4b914d6b2edccd1011c508361509dce3d00 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 16:51:43 +0300 Subject: [PATCH 1/7] =?UTF-8?q?fix(form-compile):=20SavedData=3Dtrue=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20object/RecordManager=20=D0=B3=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=80=D0=B5=D0=BA=D0=B2=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Без true платформа не маркирует форму как modified при изменении главного реквизита — confirmation dialog при Esc не появляется, canonical flow «изменил → Esc → Да» сломан. Правило выведено из реальной выгрузки acc 8.3.27: SavedData ставится только для редактируемых форм с типом *Object.X (Catalog/Document/ChartOf…/ ExchangePlan/BusinessProcess/Task) или *RecordManager.X. DynamicList/Report/ DataProcessor/ConstantsSet/RecordSet — не трогаем, отдаём решение DSL через явный savedData: true. Поднял версию до v1.10. Обновил 5 snapshot'ов (формы элементов/документа). Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 8 ++++++-- .claude/skills/form-compile/scripts/form-compile.py | 8 ++++++-- .../Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Forms/ФормаДокумента/Ext/Form.xml | 1 + .../ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml | 1 + 7 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 483a1bcf..e56459f0 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.9 — Compile 1C managed form from JSON or object metadata +# form-compile v1.10 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2464,7 +2464,11 @@ function Emit-Attributes { if ($attr.main -eq $true) { X "$innertrue" } - if ($attr.savedData -eq $true) { + $mainSaved = $false + if ($attr.main -eq $true -and $attr.type) { + $mainSaved = ("$($attr.type)") -match '^(CatalogObject|DocumentObject|ChartOfAccountsObject|ChartOfCalculationTypesObject|ChartOfCharacteristicTypesObject|ExchangePlanObject|BusinessProcessObject|TaskObject)\.' -or ("$($attr.type)") -match 'RecordManager\.' + } + if ($attr.savedData -eq $true -or $mainSaved) { X "$innertrue" } if ($attr.fillChecking) { diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 54f41a86..f945590f 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.9 — Compile 1C managed form from JSON or object metadata +# form-compile v1.10 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -2153,7 +2153,11 @@ def emit_attributes(lines, attrs, indent): if attr.get('main') is True: lines.append(f'{inner}true') - if attr.get('savedData') is True: + main_saved = False + if attr.get('main') is True and attr.get('type'): + t = str(attr['type']) + main_saved = bool(re.match(r'^(CatalogObject|DocumentObject|ChartOfAccountsObject|ChartOfCalculationTypesObject|ChartOfCharacteristicTypesObject|ExchangePlanObject|BusinessProcessObject|TaskObject)\.', t)) or ('RecordManager.' in t) + if attr.get('savedData') is True or main_saved: lines.append(f'{inner}true') if attr.get('fillChecking'): lines.append(f'{inner}{attr["fillChecking"]}') diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml index 222ebb09..76d47c0a 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml @@ -80,6 +80,7 @@ cfg:CatalogObject.Валюты true + true diff --git a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml index a0314456..627849bc 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml @@ -50,6 +50,7 @@ cfg:ChartOfCharacteristicTypesObject.ВидыНоменклатуры true + true diff --git a/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml index b42de34b..4629a4b4 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml @@ -242,6 +242,7 @@ cfg:DocumentObject.АктВыполненныхВнутреннихРабот true + true diff --git a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml index b07d0630..6881ccff 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml @@ -67,6 +67,7 @@ cfg:ExchangePlanObject.ОбменДанными true + true diff --git a/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml index c4f31cb2..b9f83d05 100644 --- a/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml @@ -37,6 +37,7 @@ cfg:CatalogObject.Товары true + true From e216db5734d6e9a77679c7dda6a476c129963809 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 16:59:31 +0300 Subject: [PATCH 2/7] =?UTF-8?q?fix(form-compile):=20default=20TitleLocatio?= =?UTF-8?q?n=3DRight=20=D0=B4=D0=BB=D1=8F=20CheckBoxField?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Платформенный default TitleLocation для CheckBoxField — Left, что почти никогда не соответствует UX-ожиданиям. В acc 8.3.27 для CheckBoxField: Right (явно): 811, без тега (=Left): 406, None: 140, Left: 14, Top: 3 — доминирующий паттерн «заголовок справа от флажка». Эмитим Right по умолчанию для check. Переопределяется через titleLocation: 'Left' / 'None' / 'Top' / 'Bottom'. v1.11. Обновил 5 snapshot'ов. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 7 +++---- .claude/skills/form-compile/scripts/form-compile.py | 6 +++--- .../Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml | 6 ++++++ .../Forms/ФормаДокумента/Ext/Form.xml | 1 + .../ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml | 1 + .../DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml | 1 + 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index e56459f0..1025494f 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.10 — Compile 1C managed form from JSON or object metadata +# form-compile v1.11 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2055,9 +2055,8 @@ function Emit-Check { Emit-Title -el $el -name $name -indent $inner Emit-CommonFlags -el $el -indent $inner - if ($el.titleLocation) { - X "$inner$($el.titleLocation)" - } + $tl = if ($el.titleLocation) { "$($el.titleLocation)" } else { "Right" } + X "$inner$tl" # Companions Emit-Companion -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index f945590f..a31c5e75 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.10 — Compile 1C managed form from JSON or object metadata +# form-compile v1.11 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1771,8 +1771,8 @@ def emit_check(lines, el, name, eid, indent): emit_title(lines, el, name, inner) emit_common_flags(lines, el, inner) - if el.get('titleLocation'): - lines.append(f'{inner}{el["titleLocation"]}') + tl = el.get('titleLocation') or 'Right' + lines.append(f'{inner}{tl}') # Companions emit_companion(lines, 'ContextMenu', f'{name}\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435\u041c\u0435\u043d\u044e', inner) diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml index 76d47c0a..8997770e 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml @@ -34,6 +34,7 @@ Объект.ЗагружаетсяИзИнтернета + Right diff --git a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml index fabbb749..8fca75b0 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml @@ -53,6 +53,7 @@ Объект.OffBalance + Right @@ -68,11 +69,13 @@ Объект.Валютный + Right Объект.Количественный + Right @@ -93,16 +96,19 @@ Объект.ExtDimensionTypes.TurnoversOnly + Right Объект.ExtDimensionTypes.Валютный + Right Объект.ExtDimensionTypes.Количественный + Right diff --git a/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml index 4629a4b4..2853805a 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/document-item-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаДокумента/Ext/Form.xml @@ -111,6 +111,7 @@ Объект.Исправление + Right diff --git a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml index 51a196ad..dbc07f33 100644 --- a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml @@ -38,6 +38,7 @@ ПерваяСтрокаЗаголовок + Right diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index b5e73f4d..60f1fabc 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -81,6 +81,7 @@ Включено + Right From 36cd63d8bbaf4ce20e9f2a14fd95fdced5317f02 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 17:22:48 +0300 Subject: [PATCH 3/7] =?UTF-8?q?fix(form-compile):=20AutoTitle=3Dfalse=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8E=20=D0=BF=D1=80=D0=B8=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=BC=20Title=20=D1=84=D0=BE=D1=80=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Когда у формы задан Title (через defn.title или properties.title), эмитим AutoTitle=false если пользователь явно его не указал. Иначе платформа добавляет суффикс синонима и получается двойной заголовок (Номенклатура: Номенклатура). В выгрузках ERP так делает ~95% форм с form-level Title. Снапшоты form-compile/form-compile-from-object обновлены под новое поведение. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../form-compile/scripts/form-compile.ps1 | 19 ++++++++++++++----- .../form-compile/scripts/form-compile.py | 15 +++++++++++---- .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Валюты/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Валюты/Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Forms/ФормаСчета/Ext/Form.xml | 1 + .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаЗаписи/Ext/Form.xml | 1 + .../КурсыВалют/Forms/ФормаЗаписи/Ext/Form.xml | 1 + .../Типы/Forms/Форма/Ext/Form.xml | 1 + .../Бригады/Forms/ФормаСписка/Ext/Form.xml | 1 + .../Товары/Forms/ФормаЭлемента/Ext/Form.xml | 1 + .../Команды/Forms/Форма/Ext/Form.xml | 1 + .../Товары/Forms/ФормаСписка/Ext/Form.xml | 1 + .../События/Forms/Форма/Ext/Form.xml | 1 + .../СГруппами/Forms/Форма/Ext/Form.xml | 1 + .../ПоляВвода/Forms/Форма/Ext/Form.xml | 1 + .../Минимальная/Forms/Форма/Ext/Form.xml | 1 + .../Тест/Forms/Форма/Ext/Form.xml | 1 + .../Таблица/Forms/Форма/Ext/Form.xml | 1 + 24 files changed, 47 insertions(+), 9 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 1025494f..599564ac 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.11 — Compile 1C managed form from JSON or object metadata +# form-compile v1.12 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2805,17 +2805,26 @@ if ($formTitle) { } # 12b. Properties (skip 'title' — handled above as multilingual) +# When form-level Title is set, default autoTitle=false (≈95% of ERP forms do this; +# otherwise platform appends synonym → "Title: Synonym" double-titles). +$propsClone = New-Object PSObject +$hasAutoTitle = $false +if ($def.properties) { + foreach ($p in $def.properties.PSObject.Properties) { + if ($p.Name -eq "autoTitle") { $hasAutoTitle = $true } + } +} +if ($formTitle -and -not $hasAutoTitle) { + $propsClone | Add-Member -NotePropertyName "autoTitle" -NotePropertyValue $false +} if ($def.properties) { - $propsClone = New-Object PSObject foreach ($p in $def.properties.PSObject.Properties) { if ($p.Name -ne "title") { $propsClone | Add-Member -NotePropertyName $p.Name -NotePropertyValue $p.Value } } - Emit-Properties -props $propsClone -indent "`t" -} else { - Emit-Properties -props $null -indent "`t" } +Emit-Properties -props $propsClone -indent "`t" # 12c. CommandSet (excluded commands) if ($def.excludedCommands -and $def.excludedCommands.Count -gt 0) { diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index a31c5e75..f6d1f965 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.11 — Compile 1C managed form from JSON or object metadata +# form-compile v1.12 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -2681,9 +2681,16 @@ def main(): emit_mltext(lines, '\t', 'Title', str(form_title)) # Properties (skip 'title' — handled above) - if defn.get('properties'): - props_clone = {k: v for k, v in defn['properties'].items() if k != 'title'} - emit_properties(lines, props_clone, '\t') + # When form-level Title is set, default autoTitle=false (≈95% of ERP forms do this; + # otherwise platform appends synonym → "Title: Synonym" double-titles). + props_src = defn.get('properties') or {} + props_clone = OrderedDict() + if form_title and 'autoTitle' not in props_src: + props_clone['autoTitle'] = False + for k, v in props_src.items(): + if k != 'title': + props_clone[k] = v + emit_properties(lines, props_clone, '\t') # CommandSet (excluded commands) if defn.get('excludedCommands') and len(defn['excludedCommands']) > 0: diff --git a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml index 54ff8a38..027f61c5 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Денежные средства + false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml index 8997770e..d1433d96 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты/Forms/ФормаЭлемента/Ext/Form.xml @@ -6,6 +6,7 @@ Валюты + false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты/Forms/ФормаСписка/Ext/Form.xml index ac356343..62d0f1c7 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Валюты + false
diff --git a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml index 627849bc..d0e0ce02 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры/Forms/ФормаЭлемента/Ext/Form.xml @@ -6,6 +6,7 @@ Виды номенклатуры + false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml index 8fca75b0..3597f6cf 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСчета/Ext/Form.xml @@ -6,6 +6,7 @@ Хозрасчетный + false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСписка/Ext/Form.xml index af82121a..43224411 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Хозрасчетный + false
diff --git a/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml index 314dfea3..47b6946e 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Акт выполненных внутренних работ + false
diff --git a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml index 6881ccff..18a0546b 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными/Forms/ФормаЭлемента/Ext/Form.xml @@ -6,6 +6,7 @@ Обмен данными + false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml index 0e1d23ef..6609ba2b 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Цены номенклатуры + false
diff --git a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-nonperiodic/InformationRegisters/АдресаМагазинов/Forms/ФормаЗаписи/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-nonperiodic/InformationRegisters/АдресаМагазинов/Forms/ФормаЗаписи/Ext/Form.xml index e0df2b8b..fb1644b8 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-nonperiodic/InformationRegisters/АдресаМагазинов/Forms/ФормаЗаписи/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-nonperiodic/InformationRegisters/АдресаМагазинов/Forms/ФормаЗаписи/Ext/Form.xml @@ -6,6 +6,7 @@ Адреса магазинов + falseLockOwnerWindow diff --git a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-periodic/InformationRegisters/КурсыВалют/Forms/ФормаЗаписи/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-periodic/InformationRegisters/КурсыВалют/Forms/ФормаЗаписи/Ext/Form.xml index f497c3df..6b67a02a 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-periodic/InformationRegisters/КурсыВалют/Forms/ФормаЗаписи/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-record-periodic/InformationRegisters/КурсыВалют/Forms/ФормаЗаписи/Ext/Form.xml @@ -6,6 +6,7 @@ Курсы валют + false LockOwnerWindow diff --git a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml index 182aea4d..ffa777f6 100644 --- a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml @@ -6,6 +6,7 @@ Разные типы + false diff --git a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml index a4fb4c16..7691c445 100644 --- a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml @@ -6,6 +6,7 @@ Бригады + false
diff --git a/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml index 2393fec5..820f90ab 100644 --- a/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml @@ -6,6 +6,7 @@ События + false ПриСозданииНаСервере diff --git a/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml index 3cf25ee8..ea8801a9 100644 --- a/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml @@ -6,6 +6,7 @@ Группы + false false diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index 60f1fabc..ce898f1c 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -6,6 +6,7 @@ Поля ввода + false diff --git a/tests/skills/cases/form-compile/snapshots/minimal/DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/minimal/DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml index 51cf9aff..9e065af0 100644 --- a/tests/skills/cases/form-compile/snapshots/minimal/DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/minimal/DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml @@ -6,5 +6,6 @@ Минимальная форма + false diff --git a/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml index a11fba9b..8e01c701 100644 --- a/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml @@ -6,6 +6,7 @@ Тест синонимов + false
From 76800fc92bf0777c98ec960dc8b6efdc8adb4e39 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 18:17:19 +0300 Subject: [PATCH 4/7] =?UTF-8?q?feat(form-compile):=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D0=B3=D0=B5=D0=BD=20Title=20=D0=B8=D0=B7=20=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=83=D0=B7=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B1=D0=B5=D0=B7=20=D0=B8=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D1=87=D0=BD=D0=B8=D0=BA=D0=B0=20=D1=81=D0=B8=D0=BD=D0=BE=D0=BD?= =?UTF-8?q?=D0=B8=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Реквизиты формы, команды, страницы, попапы и декорации теперь получают Title, сгенерированный из CamelCase-имени, если в DSL он не задан явно. Поля с path и кнопки с command по-прежнему опускают Title — синоним подхватится платформой. Главные реквизиты (Объект/Список/Запись с main=true) исключены. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../form-compile/scripts/form-compile.ps1 | 64 +++++++++++++------ .../form-compile/scripts/form-compile.py | 59 +++++++++++------ .../Типы/Forms/Форма/Ext/Form.xml | 24 +++++++ .../Бригады/Forms/ФормаСписка/Ext/Form.xml | 6 ++ .../Команды/Forms/Форма/Ext/Form.xml | 12 ++++ .../События/Forms/Форма/Ext/Form.xml | 12 ++++ .../ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml | 24 +++++++ .../СГруппами/Forms/Форма/Ext/Form.xml | 18 ++++++ .../ПоляВвода/Forms/Форма/Ext/Form.xml | 36 +++++++++++ .../Мастер/Forms/Форма/Ext/Form.xml | 24 +++++++ .../Тест/Forms/Форма/Ext/Form.xml | 18 ++++++ .../Таблица/Forms/Форма/Ext/Form.xml | 6 ++ 12 files changed, 267 insertions(+), 36 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 599564ac..b119988d 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.12 — Compile 1C managed form from JSON or object metadata +# form-compile v1.13 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1926,10 +1926,34 @@ function Emit-CommonFlags { if ($el.readOnly -eq $true) { X "$indenttrue" } } +function Title-FromName { + param([string]$name) + if (-not $name) { return '' } + $s = [regex]::Replace($name, '([А-ЯA-Z])([А-ЯA-Z][а-яa-z])', '$1 $2') + $s = [regex]::Replace($s, '([а-яa-z0-9])([А-ЯA-Z])', '$1 $2') + $parts = $s -split ' ' + if ($parts.Count -eq 0) { return $s } + $out = New-Object System.Collections.ArrayList + [void]$out.Add($parts[0]) + for ($i = 1; $i -lt $parts.Count; $i++) { + $p = $parts[$i] + if ($p.Length -gt 1 -and $p -ceq $p.ToUpper()) { + [void]$out.Add($p) + } else { + [void]$out.Add($p.ToLower()) + } + } + return ($out -join ' ') +} + function Emit-Title { - param($el, [string]$name, [string]$indent) - if ($el.title) { - Emit-MLText -tag "Title" -text "$($el.title)" -indent $indent + param($el, [string]$name, [string]$indent, [switch]$auto) + $title = $el.title + if (-not $title -and $auto -and $name) { + $title = Title-FromName -name $name + } + if ($title) { + Emit-MLText -tag "Title" -text "$title" -indent $indent } } @@ -2001,7 +2025,7 @@ function Emit-Input { if ($el.path) { X "$inner$($el.path)" } - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) Emit-CommonFlags -el $el -indent $inner if ($el.titleLocation) { @@ -2052,7 +2076,7 @@ function Emit-Check { if ($el.path) { X "$inner$($el.path)" } - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) Emit-CommonFlags -el $el -indent $inner $tl = if ($el.titleLocation) { "$($el.titleLocation)" } else { "Right" } @@ -2073,12 +2097,13 @@ function Emit-Label { X "$indent" $inner = "$indent`t" - if ($el.title) { + $labelTitle = if ($el.title) { "$($el.title)" } else { Title-FromName -name $name } + if ($labelTitle) { $formatted = if ($el.hyperlink -eq $true) { "true" } else { "false" } X "$inner" X "$inner`t<v8:item>" X "$inner`t`t<v8:lang>ru</v8:lang>" - X "$inner`t`t<v8:content>$(Esc-Xml "$($el.title)")</v8:content>" + X "$inner`t`t<v8:content>$(Esc-Xml "$labelTitle")</v8:content>" X "$inner`t</v8:item>" X "$inner" } @@ -2108,7 +2133,7 @@ function Emit-LabelField { if ($el.path) { X "$inner$($el.path)" } - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) Emit-CommonFlags -el $el -indent $inner if ($el.hyperlink -eq $true) { X "$innertrue" } @@ -2130,7 +2155,7 @@ function Emit-Table { if ($el.path) { X "$inner$($el.path)" } - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) Emit-CommonFlags -el $el -indent $inner if ($el.representation) { @@ -2219,7 +2244,7 @@ function Emit-Page { X "$indent" $inner = "$indent`t" - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto Emit-CommonFlags -el $el -indent $inner if ($el.group) { @@ -2278,7 +2303,8 @@ function Emit-Button { } } - Emit-Title -el $el -name $name -indent $inner + $btnAuto = -not ($el.command -or $el.stdCommand) + Emit-Title -el $el -name $name -indent $inner -auto:$btnAuto Emit-CommonFlags -el $el -indent $inner if ($el.defaultButton -eq $true) { X "$innertrue" } @@ -2368,7 +2394,7 @@ function Emit-Calendar { if ($el.path) { X "$inner$($el.path)" } - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) Emit-CommonFlags -el $el -indent $inner # Companions @@ -2408,7 +2434,7 @@ function Emit-Popup { X "$indent" $inner = "$indent`t" - Emit-Title -el $el -name $name -indent $inner + Emit-Title -el $el -name $name -indent $inner -auto Emit-CommonFlags -el $el -indent $inner if ($el.picture) { @@ -2449,8 +2475,9 @@ function Emit-Attributes { X "$indent`t" $inner = "$indent`t`t" - if ($attr.title) { - Emit-MLText -tag "Title" -text "$($attr.title)" -indent $inner + $attrTitle = if ($attr.title) { "$($attr.title)" } elseif ($attr.main -ne $true) { Title-FromName -name $attrName } else { '' } + if ($attrTitle) { + Emit-MLText -tag "Title" -text "$attrTitle" -indent $inner } # Type @@ -2542,8 +2569,9 @@ function Emit-Commands { X "$indent`t" $inner = "$indent`t`t" - if ($cmd.title) { - Emit-MLText -tag "Title" -text "$($cmd.title)" -indent $inner + $cmdTitle = if ($cmd.title) { "$($cmd.title)" } else { Title-FromName -name "$($cmd.name)" } + if ($cmdTitle) { + Emit-MLText -tag "Title" -text "$cmdTitle" -indent $inner } if ($cmd.action) { diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index f6d1f965..6682f143 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.12 — Compile 1C managed form from JSON or object metadata +# form-compile v1.13 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1414,9 +1414,27 @@ def emit_common_flags(lines, el, indent): lines.append(f"{indent}true") -def emit_title(lines, el, name, indent): - if el.get('title'): - emit_mltext(lines, indent, 'Title', str(el['title'])) +def title_from_name(name): + """СуммаДокумента → 'Сумма документа'. НДСВключен → 'НДС включен'.""" + if not name: + return '' + s = re.sub(r'([А-ЯA-Z])([А-ЯA-Z][а-яa-z])', r'\1 \2', name) + s = re.sub(r'([а-яa-z0-9])([А-ЯA-Z])', r'\1 \2', s) + parts = s.split(' ') + if not parts: + return s + out = [parts[0]] + for p in parts[1:]: + out.append(p if (len(p) > 1 and p.isupper()) else p.lower()) + return ' '.join(out) + + +def emit_title(lines, el, name, indent, auto=False): + title = el.get('title') + if not title and auto and name: + title = title_from_name(name) + if title: + emit_mltext(lines, indent, 'Title', str(title)) # --- Type emitter --- @@ -1712,7 +1730,7 @@ def emit_input(lines, el, name, eid, indent): if el.get('path'): lines.append(f'{inner}{el["path"]}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not el.get('path')) emit_common_flags(lines, el, inner) if el.get('titleLocation'): @@ -1768,7 +1786,7 @@ def emit_check(lines, el, name, eid, indent): if el.get('path'): lines.append(f'{inner}{el["path"]}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not el.get('path')) emit_common_flags(lines, el, inner) tl = el.get('titleLocation') or 'Right' @@ -1787,12 +1805,13 @@ def emit_label(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' - if el.get('title'): + label_title = el.get('title') or title_from_name(name) + if label_title: formatted = 'true' if el.get('hyperlink') is True else 'false' lines.append(f'{inner}') lines.append(f'{inner}\t<v8:item>') lines.append(f'{inner}\t\t<v8:lang>ru</v8:lang>') - lines.append(f'{inner}\t\t<v8:content>{esc_xml(str(el["title"]))}</v8:content>') + lines.append(f'{inner}\t\t<v8:content>{esc_xml(str(label_title))}</v8:content>') lines.append(f'{inner}\t</v8:item>') lines.append(f'{inner}') @@ -1825,7 +1844,7 @@ def emit_label_field(lines, el, name, eid, indent): if el.get('path'): lines.append(f'{inner}{el["path"]}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not el.get('path')) emit_common_flags(lines, el, inner) if el.get('hyperlink') is True: @@ -1847,7 +1866,7 @@ def emit_table(lines, el, name, eid, indent): if el.get('path'): lines.append(f'{inner}{el["path"]}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not el.get('path')) emit_common_flags(lines, el, inner) if el.get('representation'): @@ -1935,7 +1954,7 @@ def emit_page(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=True) emit_common_flags(lines, el, inner) if el.get('group'): @@ -1983,7 +2002,7 @@ def emit_button(lines, el, name, eid, indent): else: lines.append(f'{inner}Form.StandardCommand.{sc}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not (el.get('command') or el.get('stdCommand'))) emit_common_flags(lines, el, inner) if el.get('defaultButton') is True: @@ -2071,7 +2090,7 @@ def emit_calendar(lines, el, name, eid, indent): if el.get('path'): lines.append(f'{inner}{el["path"]}') - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=not el.get('path')) emit_common_flags(lines, el, inner) # Companions @@ -2106,7 +2125,7 @@ def emit_popup(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' - emit_title(lines, el, name, inner) + emit_title(lines, el, name, inner, auto=True) emit_common_flags(lines, el, inner) if el.get('picture'): @@ -2142,8 +2161,11 @@ def emit_attributes(lines, attrs, indent): lines.append(f'{indent}\t') inner = f'{indent}\t\t' - if attr.get('title'): - emit_mltext(lines, inner, 'Title', str(attr['title'])) + attr_title = attr.get('title') + if not attr_title and attr.get('main') is not True: + attr_title = title_from_name(attr_name) + if attr_title: + emit_mltext(lines, inner, 'Title', str(attr_title)) # Type if attr.get('type'): @@ -2223,8 +2245,9 @@ def emit_commands(lines, cmds, indent): lines.append(f'{indent}\t') inner = f'{indent}\t\t' - if cmd.get('title'): - emit_mltext(lines, inner, 'Title', str(cmd['title'])) + cmd_title = cmd.get('title') or title_from_name(str(cmd['name'])) + if cmd_title: + emit_mltext(lines, inner, 'Title', str(cmd_title)) if cmd.get('action'): lines.append(f'{inner}{cmd["action"]}') diff --git a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml index ffa777f6..2916c692 100644 --- a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml @@ -38,6 +38,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Строка</v8:content> + </v8:item> + xs:string @@ -47,6 +53,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Число</v8:content> + </v8:item> + xs:decimal @@ -57,6 +69,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Дата</v8:content> + </v8:item> + xs:dateTime @@ -65,6 +83,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Булево</v8:content> + </v8:item> + xs:boolean diff --git a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml index 7691c445..ba549f33 100644 --- a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml @@ -51,6 +51,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Изменить выделенные</v8:content> + </v8:item> + ИзменитьВыделенные diff --git a/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml index 5db50871..85aec738 100644 --- a/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml @@ -41,6 +41,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Результат</v8:content> + </v8:item> + xs:string @@ -52,6 +58,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Выполнить</v8:content> + </v8:item> + ВыполнитьОбработка Ctrl+Enter diff --git a/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml index 820f90ab..4621a24e 100644 --- a/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/events/DataProcessors/События/Forms/Форма/Ext/Form.xml @@ -50,6 +50,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Организация</v8:content> + </v8:item> + xs:string @@ -59,6 +65,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Период</v8:content> + </v8:item> + xs:dateTime diff --git a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml index dbc07f33..8a97cfdd 100644 --- a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml @@ -82,6 +82,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Имя файла</v8:content> + </v8:item> + xs:string @@ -91,11 +97,23 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Первая строка заголовок</v8:content> + </v8:item> + xs:boolean + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Результат</v8:content> + </v8:item> + xs:string @@ -107,6 +125,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Загрузить</v8:content> + </v8:item> + ЗагрузитьОбработка Ctrl+Enter diff --git a/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml index ea8801a9..6215e9b1 100644 --- a/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/groups/DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml @@ -74,6 +74,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле1</v8:content> + </v8:item> + xs:string @@ -83,6 +89,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле2</v8:content> + </v8:item> + xs:decimal @@ -93,6 +105,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле3</v8:content> + </v8:item> + xs:dateTime diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index ce898f1c..fd2ea9fe 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -95,6 +95,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Обычное поле</v8:content> + </v8:item> + xs:string @@ -104,6 +110,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Многострочное поле</v8:content> + </v8:item> + xs:string @@ -113,6 +125,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле пароля</v8:content> + </v8:item> + xs:string @@ -122,6 +140,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле с кнопками</v8:content> + </v8:item> + xs:string @@ -131,6 +155,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле подсказка</v8:content> + </v8:item> + xs:string @@ -140,6 +170,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Флаг</v8:content> + </v8:item> + xs:boolean diff --git a/tests/skills/cases/form-compile/snapshots/pages/DataProcessors/Мастер/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/pages/DataProcessors/Мастер/Forms/Форма/Ext/Form.xml index 7e55dee6..c5094674 100644 --- a/tests/skills/cases/form-compile/snapshots/pages/DataProcessors/Мастер/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/pages/DataProcessors/Мастер/Forms/Форма/Ext/Form.xml @@ -83,6 +83,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Параметр1</v8:content> + </v8:item> + xs:string @@ -92,6 +98,12 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Итог</v8:content> + </v8:item> + xs:string @@ -103,9 +115,21 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Назад</v8:content> + </v8:item> + НазадОбработка + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Далее</v8:content> + </v8:item> + ДалееОбработка diff --git a/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml index 8e01c701..3d2e6f3b 100644 --- a/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/synonyms/DataProcessors/Тест/Forms/Форма/Ext/Form.xml @@ -38,6 +38,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Поле</v8:content> + </v8:item> + xs:string @@ -49,9 +55,21 @@ + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Кн1</v8:content> + </v8:item> + Кн1 + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Кн2</v8:content> + </v8:item> + Кн2 diff --git a/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml index 54a0b7a5..e6882c9d 100644 --- a/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml @@ -44,6 +44,12 @@ true + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Данные</v8:content> + </v8:item> + v8:ValueTable From fc19df604bf44dfe2026c2d26a721e82b1e4e865 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 18:17:24 +0300 Subject: [PATCH 5/7] =?UTF-8?q?chore(tests):=20--help=20=D0=B2=20runner=20?= =?UTF-8?q?=D0=B8=20verify-snapshots,=20=D1=81=D0=B8=D0=BD=D1=85=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Чтобы --help/-h/? не запускали полный прогон тестов. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/skills/README.md | 16 +++++++++++++++- tests/skills/runner.mjs | 24 +++++++++++++++++++++++- tests/skills/verify-snapshots.mjs | 22 +++++++++++++++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/tests/skills/README.md b/tests/skills/README.md index cadf6aa1..feb94049 100644 --- a/tests/skills/README.md +++ b/tests/skills/README.md @@ -14,10 +14,23 @@ node tests/skills/runner.mjs --verbose # подробн node tests/skills/runner.mjs --update-snapshots # обновить эталоны node tests/skills/runner.mjs --runtime python # запуск на PY-версиях node tests/skills/runner.mjs --json report.json # JSON-отчёт +node tests/skills/runner.mjs --concurrency 4 # ограничить параллельность +node tests/skills/runner.mjs --with-validation # + платформенная валидация +node tests/skills/runner.mjs --help # полный список опций ``` Exit code: 0 = все прошли, 1 = есть падения. +### Платформенная верификация снапшотов + +```bash +node tests/skills/verify-snapshots.mjs --skill form-compile # один навык +node tests/skills/verify-snapshots.mjs --case table # один кейс +node tests/skills/verify-snapshots.mjs --help # полный список опций +``` + +Перепрогоняет навык из DSL кейса и грузит результат в 1С — отлавливает случаи, когда снапшоты обновили, но платформа уже не принимает выход. + ## Что делать при падении 1. Смотри **case id** в выводе — это путь к файлу кейса (можно перезапустить: `node runner.mjs `) @@ -194,7 +207,8 @@ node tests/skills/runner.mjs cases/meta-compile/enum --update-snapshots # од ``` tests/skills/ - runner.mjs # тест-раннер + runner.mjs # тест-раннер (snapshot-сравнение) + verify-snapshots.mjs # платформенная верификация снапшотов README.md # этот файл .cache/ # кэш фикстур (в .gitignore) cases/ diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs index cafe95df..fd0b228e 100644 --- a/tests/skills/runner.mjs +++ b/tests/skills/runner.mjs @@ -18,11 +18,32 @@ const CACHE = resolve(ROOT, '.cache'); // ─── CLI args ─────────────────────────────────────────────────────────────── +function printHelp() { + console.log(`skill-test-runner — Snapshot-based regression tests for 1C skill scripts + +Usage: + node tests/skills/runner.mjs [filter] [options] + +Arguments: + filter Substring to match case id (e.g. "form-compile" or "form-compile/table") + +Options: + --update-snapshots Overwrite snapshot files with current actual output + --runtime Which script port to run (default: powershell) + --json Write JSON report to + --concurrency Number of parallel workers (default: cpu count) + --with-validation Run platform validation (1cv8 design checks) after compile + -v, --verbose Verbose output + -h, --help, /? Show this help and exit +`); +} + function parseArgs(argv) { - const args = { filter: null, updateSnapshots: false, runtime: 'powershell', jsonReport: null, verbose: false, concurrency: cpus().length, withValidation: false }; + const args = { filter: null, updateSnapshots: false, runtime: 'powershell', jsonReport: null, verbose: false, concurrency: cpus().length, withValidation: false, help: false }; const rest = argv.slice(2); for (let i = 0; i < rest.length; i++) { const a = rest[i]; + if (a === '-h' || a === '--help' || a === '/?' || a === '/help' || a === '?') { args.help = true; continue; } if (a === '--update-snapshots') { args.updateSnapshots = true; continue; } if (a === '--runtime' && rest[i + 1]) { args.runtime = rest[++i]; continue; } if (a === '--json' && rest[i + 1]) { args.jsonReport = rest[++i]; continue; } @@ -1020,6 +1041,7 @@ function printIntegrationReport(results, opts) { async function main() { const opts = parseArgs(process.argv); + if (opts.help) { printHelp(); return; } mkdirSync(CACHE, { recursive: true }); // Load platform context for platform-dependent tests diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index 89b420a7..887f1f33 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -23,11 +23,30 @@ const REPORT_DIR = resolve(REPO_ROOT, 'debug/snapshot-verify'); // ─── CLI args ─────────────────────────────────────────────────────────────── +function printHelp() { + console.log(`verify-snapshots — Platform verification of skill test snapshots + +Reruns skill scripts from test-case DSL, then loads results into 1C platform. + +Usage: + node tests/skills/verify-snapshots.mjs [options] + +Options: + --skill Run only cases for the given skill (e.g. form-compile) + --case Run only the case with this name + --runtime Which script port to run (default: powershell) + --keep Keep generated work directories on disk after run + -v, --verbose Verbose output + -h, --help, /? Show this help and exit +`); +} + function parseArgs(argv) { - const args = { skill: null, caseName: null, runtime: 'powershell', keep: false, verbose: false }; + const args = { skill: null, caseName: null, runtime: 'powershell', keep: false, verbose: false, help: false }; const rest = argv.slice(2); for (let i = 0; i < rest.length; i++) { const a = rest[i]; + if (a === '-h' || a === '--help' || a === '/?' || a === '/help' || a === '?') { args.help = true; continue; } if (a === '--skill' && rest[i + 1]) { args.skill = rest[++i]; continue; } if (a === '--case' && rest[i + 1]) { args.caseName = rest[++i]; continue; } if (a === '--runtime' && rest[i + 1]) { args.runtime = rest[++i]; continue; } @@ -1034,6 +1053,7 @@ function writeReport(results) { async function main() { const opts = parseArgs(process.argv); + if (opts.help) { printHelp(); return; } const v8ctx = loadV8Context(); if (!v8ctx) { From 8ad5d80f7f81315cc518681ddd676599cc12777a Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 18:39:29 +0300 Subject: [PATCH 6/7] =?UTF-8?q?feat(form-compile):=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D0=BF=D0=BE=D0=B4=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20RowPictureDataPath=20=D0=B4=D0=BB=D1=8F=20Dynami?= =?UTF-8?q?cList=20=D1=81=20MainTable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document/InformationRegister/AccumulationRegister List-генераторы теперь прописывают `Список.DefaultPicture` (как делает ERP/БП в 594/600 форм списка документов). Плюс fallback в эвристике DynamicList-таблицы: если у главного реквизита есть `settings.mainTable`, поле подставляется автоматически и для ручного DSL. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../form-compile/scripts/form-compile.ps1 | 24 +++++++++++++++---- .../form-compile/scripts/form-compile.py | 16 +++++++++---- .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Forms/ФормаСписка/Ext/Form.xml | 1 + .../Бригады/Forms/ФормаСписка/Ext/Form.xml | 1 + .../Товары/Forms/ФормаСписка/Ext/Form.xml | 1 + 7 files changed, 37 insertions(+), 8 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index b119988d..563f60a9 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.13 — Compile 1C managed form from JSON or object metadata +# form-compile v1.14 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -668,6 +668,7 @@ function Generate-DocumentListDSL($meta, [hashtable]$p) { $tableEl = [ordered]@{ table = "Список"; path = "Список" + rowPictureDataPath = "Список.DefaultPicture" commandBarLocation = "None" tableAutofill = $false columns = $columns @@ -1003,6 +1004,7 @@ function Generate-InformationRegisterListDSL($meta, [hashtable]$p) { $tableEl = [ordered]@{ table = "Список"; path = "Список" + rowPictureDataPath = "Список.DefaultPicture" commandBarLocation = "None" tableAutofill = $false columns = $columns @@ -1060,6 +1062,7 @@ function Generate-AccumulationRegisterListDSL($meta, [hashtable]$p) { $tableEl = [ordered]@{ table = "Список"; path = "Список" + rowPictureDataPath = "Список.DefaultPicture" commandBarLocation = "None" tableAutofill = $false columns = $columns @@ -2680,7 +2683,7 @@ function HasCmdBarRecursive { } function ApplyDynamicListTableHeuristic { - param($el, [string]$listName) + 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) { if ($null -eq $el.PSObject.Properties["tableAutofill"]) { @@ -2689,9 +2692,13 @@ function ApplyDynamicListTableHeuristic { 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)"))) { + $el | Add-Member -NotePropertyName "rowPictureDataPath" -NotePropertyValue "$listName.DefaultPicture" -Force + } } if ($el.PSObject.Properties["children"] -and $el.children) { - foreach ($child in $el.children) { ApplyDynamicListTableHeuristic $child $listName } + foreach ($child in $el.children) { ApplyDynamicListTableHeuristic $child $listName $hasMainTable } } } @@ -2780,8 +2787,17 @@ if ($def.attributes -and $def.elements) { if ($attr.main -eq $true) { $mainAttr = $attr; break } } if ($mainAttr -and "$($mainAttr.type)" -eq "DynamicList") { + $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 + } + } + $hasMt = -not [string]::IsNullOrEmpty("$mt") foreach ($el in $def.elements) { - ApplyDynamicListTableHeuristic $el $mainAttr.name + ApplyDynamicListTableHeuristic $el $mainAttr.name $hasMt } } } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 6682f143..18db6cb4 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.13 — Compile 1C managed form from JSON or object metadata +# form-compile v1.14 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -625,6 +625,7 @@ def generate_document_list_dsl(meta, p): table_el = OrderedDict([ ('table', '\u0421\u043f\u0438\u0441\u043e\u043a'), ('path', '\u0421\u043f\u0438\u0441\u043e\u043a'), + ('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'), ('commandBarLocation', 'None'), ('tableAutofill', False), ('columns', columns), @@ -938,6 +939,7 @@ def generate_information_register_list_dsl(meta, p): table_el = OrderedDict([ ('table', '\u0421\u043f\u0438\u0441\u043e\u043a'), ('path', '\u0421\u043f\u0438\u0441\u043e\u043a'), + ('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'), ('commandBarLocation', 'None'), ('tableAutofill', False), ('columns', columns_list), @@ -996,6 +998,7 @@ def generate_accumulation_register_list_dsl(meta, p): table_el = OrderedDict([ ('table', '\u0421\u043f\u0438\u0441\u043e\u043a'), ('path', '\u0421\u043f\u0438\u0441\u043e\u043a'), + ('rowPictureDataPath', '\u0421\u043f\u0438\u0441\u043e\u043a.DefaultPicture'), ('commandBarLocation', 'None'), ('tableAutofill', False), ('columns', columns_list), @@ -2599,7 +2602,7 @@ def main(): return True return False - def _apply_dlist_table_heuristic(el, list_name): + def _apply_dlist_table_heuristic(el, list_name, has_main_table): if not isinstance(el, dict): return if el.get('table') is not None and str(el.get('path', '')) == list_name: @@ -2607,9 +2610,12 @@ def main(): el['tableAutofill'] = False if 'commandBarLocation' not in el: el['commandBarLocation'] = 'None' + # DefaultPicture доступен только если у DynamicList есть основная таблица + if has_main_table and not el.get('rowPictureDataPath'): + el['rowPictureDataPath'] = f'{list_name}.DefaultPicture' if isinstance(el.get('children'), list): for child in el['children']: - _apply_dlist_table_heuristic(child, list_name) + _apply_dlist_table_heuristic(child, list_name, has_main_table) def _is_object_like_type(t): if not t: @@ -2674,8 +2680,10 @@ def main(): if isinstance(defn.get('attributes'), list) and isinstance(defn.get('elements'), list): main_attr = next((a for a in defn['attributes'] if isinstance(a, dict) and a.get('main') is True), None) if main_attr and str(main_attr.get('type', '')) == 'DynamicList': + settings = main_attr.get('settings') or {} + has_mt = bool(isinstance(settings, dict) and settings.get('mainTable')) for el in defn['elements']: - _apply_dlist_table_heuristic(el, main_attr.get('name', '')) + _apply_dlist_table_heuristic(el, main_attr.get('name', ''), has_mt) # 1b.5: Compute main AutoCommandBar Autofill (B3) def _compute_main_acb_autofill(): diff --git a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml index 027f61c5..e468df18 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства/Forms/ФормаСписка/Ext/Form.xml @@ -12,6 +12,7 @@
СписокNone + Список.DefaultPicture false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml index 47b6946e..f05414f2 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/document-list-medium/Documents/АктВыполненныхВнутреннихРабот/Forms/ФормаСписка/Ext/Form.xml @@ -12,6 +12,7 @@
СписокNone + Список.DefaultPicture false diff --git a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml index 6609ba2b..e9e718db 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/inforeg-list-periodic/InformationRegisters/ЦеныНоменклатуры/Forms/ФормаСписка/Ext/Form.xml @@ -12,6 +12,7 @@
СписокNone + Список.DefaultPicture false diff --git a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml index ba549f33..80a0188a 100644 --- a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады/Forms/ФормаСписка/Ext/Form.xml @@ -20,6 +20,7 @@
СписокNone + Список.DefaultPicture false diff --git a/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml index ae9280d5..cebb5741 100644 --- a/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары/Forms/ФормаСписка/Ext/Form.xml @@ -12,6 +12,7 @@
СписокNone + Список.DefaultPicture false From b4514dc350e71291591f02b935d0a8f9c0e2cabb Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 2 May 2026 19:05:50 +0300 Subject: [PATCH 7/7] =?UTF-8?q?feat(form-compile):=20AutoMaxWidth=3Dfalse?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8E=20=D0=B4=D0=BB=D1=8F=20multiLine=20InputField?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В реальных формах ERP/БП у ~60% многострочных полей ввода явно стоит АвтоМаксимальнаяШирина=Ложь. Теперь form-compile проставляет это автоматически при multiLine: true, если пользователь не задал autoMaxWidth явно. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 9 +++++++-- .claude/skills/form-compile/scripts/form-compile.py | 7 +++++-- .../DataProcessors/Команды/Forms/Форма/Ext/Form.xml | 1 + .../ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml | 1 + .../DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml | 1 + 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 563f60a9..e821095d 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.14 — Compile 1C managed form from JSON or object metadata +# form-compile v1.15 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2051,7 +2051,12 @@ function Emit-Input { if ($el.dropListButton -eq $true) { X "$innertrue" } if ($el.markIncomplete -eq $true) { X "$innertrue" } if ($el.skipOnInput -eq $true) { X "$innertrue" } - if ($el.autoMaxWidth -eq $false) { X "$innerfalse" } + $hasAmw = $el.PSObject.Properties.Name -contains 'autoMaxWidth' + if ($hasAmw) { + if ($el.autoMaxWidth -eq $false) { X "$innerfalse" } + } elseif ($el.multiLine -eq $true) { + X "$innerfalse" + } if ($el.autoMaxHeight -eq $false) { X "$innerfalse" } if ($el.width) { X "$inner$($el.width)" } if ($el.height) { X "$inner$($el.height)" } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 18db6cb4..9dc4bc35 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.14 — Compile 1C managed form from JSON or object metadata +# form-compile v1.15 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1757,7 +1757,10 @@ def emit_input(lines, el, name, eid, indent): lines.append(f'{inner}true') if el.get('skipOnInput') is True: lines.append(f'{inner}true') - if el.get('autoMaxWidth') is False: + if 'autoMaxWidth' in el: + if el['autoMaxWidth'] is False: + lines.append(f'{inner}false') + elif el.get('multiLine') is True: lines.append(f'{inner}false') if el.get('autoMaxHeight') is False: lines.append(f'{inner}false') diff --git a/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml index 85aec738..ee98000f 100644 --- a/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/commands/DataProcessors/Команды/Forms/Форма/Ext/Form.xml @@ -28,6 +28,7 @@ Результат true true + false 8 diff --git a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml index 8a97cfdd..bcfe9ada 100644 --- a/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/file-dialog/DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml @@ -54,6 +54,7 @@ true true + false 8 diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index fd2ea9fe..d07eaea2 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -29,6 +29,7 @@ true + false 5