mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-15 02:14:57 +03:00
feat(form-decompile,form-compile): InputField availableTypes + typeDomainEnabled (ограничение доступных типов)
Раундтрип терял блок ограничения типов у поля ввода на составном/характеристика-типе: <TypeDomainEnabled> + <AvailableTypes> (напр. ЯндексМаркетВитринаФулфилмент/РегламентноеЗадание — поле ИмяПользователя с AvailableTypes=xs:string Length=0 Variable). Корпус (acc+erp 8.3.24): AvailableTypes встречается в 18 местах, ВСЕ — на InputField (полное покрытие scope). Содержимое — стандартный 1С type-description (<v8:Type>+qualifiers), тот же формат, что у реквизитов → переиспользуем существующий механизм типов: - decompile: Decompile-Type на узле <AvailableTypes> → компактная DSL-строка (одиночная/мультитип "a | b") - compile (ps1+py): Emit-Type с tag='AvailableTypes' (сам разбирает мультитип); TypeDomainEnabled — bool pass-through availableTypes — формат типа реквизита (§Типы): одиночный или составной через "|". Верификация: таргет-раундтрип всех 17 форм с AvailableTypes → 15 match, остаток 6 строк в 2 формах — ДРУГИЕ категории (ExtendedTooltip/Value), не AvailableTypes; целевая форма match (было 8 → 0). Регресс form-compile 43/43 (ps1+py); 1С-cert кейса input-fields (поле с мультитип AvailableTypes грузится в платформу). spec обновлён. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.127 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.128 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -3640,6 +3640,10 @@ function Emit-Input {
|
||||
)) {
|
||||
if ($null -ne $el.($p[0])) { X "$inner<$($p[1])>$(if ($el.($p[0])){'true'}else{'false'})</$($p[1])>" }
|
||||
}
|
||||
# Ограничение доступных типов (поле на составном типе): домен типов + явный набор.
|
||||
# availableTypes — формат типа реквизита (§type); Emit-Type сам разбирает мультитип "a | b".
|
||||
if ($null -ne $el.typeDomainEnabled) { X "$inner<TypeDomainEnabled>$(if ($el.typeDomainEnabled){'true'}else{'false'})</TypeDomainEnabled>" }
|
||||
if ($el.availableTypes) { Emit-Type -typeStr $el.availableTypes -indent $inner -tag 'AvailableTypes' }
|
||||
# InputField-специфичные value-скаляры
|
||||
foreach ($p in @(
|
||||
@('choiceForm','ChoiceForm'), @('choiceHistoryOnInput','ChoiceHistoryOnInput'),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.127 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.128 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -3728,6 +3728,12 @@ def emit_input(lines, el, name, eid, indent):
|
||||
('quickChoice', 'QuickChoice'), ('autoChoiceIncomplete', 'AutoChoiceIncomplete')):
|
||||
if el.get(key) is not None:
|
||||
lines.append(f'{inner}<{tag}>{"true" if el[key] else "false"}</{tag}>')
|
||||
# Ограничение доступных типов (поле на составном типе): домен типов + явный набор.
|
||||
# availableTypes — формат типа реквизита (§type); emit_type сам разбирает мультитип "a | b".
|
||||
if el.get('typeDomainEnabled') is not None:
|
||||
lines.append(f'{inner}<TypeDomainEnabled>{"true" if el["typeDomainEnabled"] else "false"}</TypeDomainEnabled>')
|
||||
if el.get('availableTypes'):
|
||||
emit_type(lines, el['availableTypes'], inner, tag='AvailableTypes')
|
||||
# InputField-специфичные value-скаляры
|
||||
for key, tag in (('choiceForm', 'ChoiceForm'), ('choiceHistoryOnInput', 'ChoiceHistoryOnInput'),
|
||||
('choiceFoldersAndItems', 'ChoiceFoldersAndItems'), ('footerDataPath', 'FooterDataPath')):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v1.01 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v1.02 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -1651,6 +1651,10 @@ function Decompile-Element {
|
||||
} else { $obj[$key] = $txt }
|
||||
}
|
||||
}
|
||||
# Ограничение доступных типов (поле на составном/характеристика-типе): домен типов + явный набор.
|
||||
# availableTypes — тот же формат типа, что у реквизитов (§type), захват через Decompile-Type.
|
||||
$tde = Get-Child $node 'TypeDomainEnabled'; if ($null -ne $tde) { $obj['typeDomainEnabled'] = (To-Bool $tde) }
|
||||
$atNode = $node.SelectSingleNode("lf:AvailableTypes", $ns); if ($atNode) { $at = Decompile-Type $atNode; if ($at) { $obj['availableTypes'] = $at } }
|
||||
$cbr = Get-Child $node 'ChoiceButtonRepresentation'; if ($cbr) { $obj['choiceButtonRepresentation'] = $cbr }
|
||||
$cbp = Get-PictureRef $node 'ChoiceButtonPicture'; if ($null -ne $cbp) { $obj['choiceButtonPicture'] = $cbp }
|
||||
if ((Get-Child $node 'TextEdit') -eq 'false') { $obj['textEdit'] = $false }
|
||||
|
||||
@@ -407,6 +407,8 @@ companion-панели с собственным контентом. Оба не
|
||||
| `choiceFoldersAndItems` | string | Выбор групп и элементов (`<ChoiceFoldersAndItems>`): `Items`, `Folders`, `FoldersAndItems` |
|
||||
| `fixingInTable` | string | Фиксация колонки в таблице (`<FixingInTable>`): `Left`, `Right`, `None`. Так же у `labelField` и др. полей |
|
||||
| `footerDataPath` | string | DataPath подвала колонки таблицы (`<FooterDataPath>`) |
|
||||
| `availableTypes` | string | Ограничение доступных типов поля на составном/характеристика-типе (`<AvailableTypes>`). Формат типа реквизита (§«Типы»): одиночный (`string`, `CatalogRef.Валюты`) или составной через `\|` (`string \| boolean \| decimal(10,2)`). Редкое (~18 в корпусе, только InputField) |
|
||||
| `typeDomainEnabled` | bool | Включён ли домен типов (`<TypeDomainEnabled>`); обычно `false` при заданном `availableTypes`. Захват «как есть» |
|
||||
| `choiceButtonRepresentation` | string | `ShowInInputField`, `ShowInDropList`, `ShowInDropListAndInInputField` |
|
||||
| `minValue` / `maxValue` | number/string | Мин./макс. значение (`<MinValue>`/`<MaxValue>` с обязательным `xsi:type`). **JSON-число → `xs:decimal`, строка → `xs:string`** (тип сохраняется декомпилятором через тип JSON-значения) |
|
||||
| `width` | int | Ширина |
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
{ "check": "Флаг", "path": "Флаг", "title": "Включено", "warningOnEdit": { "ru": "Изменение флага требует подтверждения", "en": "Confirm flag change" }, "extendedTooltip": { "width": 45 } },
|
||||
{ "check": "ФлагПлатформенный", "path": "ФлагПлатформенный", "title": "Слева", "titleLocation": "" },
|
||||
{ "check": "ФлагЯвный", "path": "ФлагЯвный", "title": "Сверху", "titleLocation": "top" },
|
||||
{ "check": "ФлагТумблер", "path": "ФлагТумблер", "title": "Тумблер", "checkBoxType": "switcher", "format": "БЛ=Нет; БИ=Да" }
|
||||
{ "check": "ФлагТумблер", "path": "ФлагТумблер", "title": "Тумблер", "checkBoxType": "switcher", "format": "БЛ=Нет; БИ=Да" },
|
||||
{ "input": "ПолеСоставное", "path": "ПолеСоставное", "title": "Ограничение типов", "typeDomainEnabled": false, "availableTypes": "string | boolean" }
|
||||
],
|
||||
"attributes": [
|
||||
{ "name": "Объект", "type": "DataProcessorObject.ПоляВвода", "main": true },
|
||||
@@ -67,7 +68,8 @@
|
||||
{ "name": "ФлагЯвный", "type": "boolean" },
|
||||
{ "name": "ФлагТумблер", "type": "boolean" },
|
||||
{ "name": "ЧисловоеПоле", "type": "number(10,2)" },
|
||||
{ "name": "ДатаПоля", "type": "dateTime" }
|
||||
{ "name": "ДатаПоля", "type": "dateTime" },
|
||||
{ "name": "ПолеСоставное", "type": "string | boolean" }
|
||||
],
|
||||
"conditionalAppearance": [
|
||||
{ "selection": ["ОбычноеПоле"], "filter": ["ЧисловоеПоле > 100"], "appearance": { "ЦветФона": "style:FormBackColor", "Текст": "Плоский текст" },
|
||||
|
||||
+51
-15
@@ -427,15 +427,35 @@
|
||||
<ContextMenu name="ФлагТумблерКонтекстноеМеню" id="41"/>
|
||||
<ExtendedTooltip name="ФлагТумблерРасширеннаяПодсказка" id="42"/>
|
||||
</CheckBoxField>
|
||||
<InputField name="ПолеСоставное" id="43">
|
||||
<DataPath>ПолеСоставное</DataPath>
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Ограничение типов</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
<TypeDomainEnabled>false</TypeDomainEnabled>
|
||||
<AvailableTypes>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</AvailableTypes>
|
||||
<ContextMenu name="ПолеСоставноеКонтекстноеМеню" id="44"/>
|
||||
<ExtendedTooltip name="ПолеСоставноеРасширеннаяПодсказка" id="45"/>
|
||||
</InputField>
|
||||
</ChildItems>
|
||||
<Attributes>
|
||||
<Attribute name="Объект" id="43">
|
||||
<Attribute name="Объект" id="46">
|
||||
<Type>
|
||||
<v8:Type>cfg:DataProcessorObject.ПоляВвода</v8:Type>
|
||||
</Type>
|
||||
<MainAttribute>true</MainAttribute>
|
||||
</Attribute>
|
||||
<Attribute name="ОбычноеПоле" id="44">
|
||||
<Attribute name="ОбычноеПоле" id="47">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -450,7 +470,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="МногострочноеПоле" id="45">
|
||||
<Attribute name="МногострочноеПоле" id="48">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -465,7 +485,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеПароля" id="46">
|
||||
<Attribute name="ПолеПароля" id="49">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -480,7 +500,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеСКнопками" id="47">
|
||||
<Attribute name="ПолеСКнопками" id="50">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -495,7 +515,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеСписокВыбора" id="48">
|
||||
<Attribute name="ПолеСписокВыбора" id="51">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -510,7 +530,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеПодсказка" id="49">
|
||||
<Attribute name="ПолеПодсказка" id="52">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -525,7 +545,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеСвязи" id="50">
|
||||
<Attribute name="ПолеСвязи" id="53">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -540,7 +560,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеСвязиКратко" id="51">
|
||||
<Attribute name="ПолеСвязиКратко" id="54">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -555,7 +575,7 @@
|
||||
</v8:StringQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="Флаг" id="52">
|
||||
<Attribute name="Флаг" id="55">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -566,7 +586,7 @@
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ФлагПлатформенный" id="53">
|
||||
<Attribute name="ФлагПлатформенный" id="56">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -577,7 +597,7 @@
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ФлагЯвный" id="54">
|
||||
<Attribute name="ФлагЯвный" id="57">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -588,7 +608,7 @@
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ФлагТумблер" id="55">
|
||||
<Attribute name="ФлагТумблер" id="58">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -599,7 +619,7 @@
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ЧисловоеПоле" id="56">
|
||||
<Attribute name="ЧисловоеПоле" id="59">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -615,7 +635,7 @@
|
||||
</v8:NumberQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ДатаПоля" id="57">
|
||||
<Attribute name="ДатаПоля" id="60">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
@@ -629,6 +649,22 @@
|
||||
</v8:DateQualifiers>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<Attribute name="ПолеСоставное" id="61">
|
||||
<Title>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Поле составное</v8:content>
|
||||
</v8:item>
|
||||
</Title>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</Type>
|
||||
</Attribute>
|
||||
<ConditionalAppearance>
|
||||
<dcsset:item>
|
||||
<dcsset:selection>
|
||||
|
||||
Reference in New Issue
Block a user