diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 2acd8ce1..398d6ebd 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.162 — Compile 1C managed form from JSON or object metadata +# form-compile v1.163 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -3754,6 +3754,9 @@ function Emit-Group { X "$inner$repr" } + # Использование текущей строки группы (после Representation, порядок XSD) + if ($el.currentRowUse) { X "$inner$($el.currentRowUse)" } + # ShowTitle if ($null -ne $el.showTitle) { X "$inner$(if ($el.showTitle){'true'}else{'false'})" } # Заголовок свёрнутого представления (collapsible/popup) — мультиязычный текст @@ -4869,6 +4872,8 @@ function Emit-PictureField { if ($el.hyperlink -eq $true) { X "$innertrue" } Emit-Layout -el $el -indent $inner + # EnableDrag — фактическое значение (поле картинки перетаскиваемо; декомпилятор ловит generic-ом) + if ($null -ne $el.enableDrag) { X "$inner$(if ($el.enableDrag){'true'}else{'false'})" } # FooterDataPath / FooterText — общие cell-свойства колонки (как у input/labelField) if ($el.footerDataPath) { X "$inner$(Esc-Xml "$($el.footerDataPath)")" } @@ -5118,6 +5123,9 @@ function Emit-AttrColumn { X "$indent" if ($col.title) { Emit-MLText -tag "Title" -text $col.title -indent "$indent`t" } Emit-Type -typeStr "$($col.type)" -indent "$indent`t" + # Проверка заполнения колонки → (как у реквизита; bool true→ShowError / строка verbatim) + $cfcRaw = if ($null -ne $col.PSObject.Properties['fillCheck']) { $col.fillCheck } elseif ($null -ne $col.PSObject.Properties['fillChecking']) { $col.fillChecking } else { $null } + if ($null -ne $cfcRaw) { $cfcv = if ($cfcRaw -is [bool]) { if ($cfcRaw) { 'ShowError' } else { $null } } else { "$cfcRaw" }; if ($cfcv) { X "$indent`t$cfcv" } } Emit-FunctionalOptions -fo $col.functionalOptions -indent "$indent`t" # Ролевой доступ колонки (View/Edit) — xr-флаг, как у самого реквизита if ($null -ne $col.view) { Emit-XrFlag -tag 'View' -val $col.view -indent "$indent`t" } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index cec8db74..f0a22f64 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.162 — Compile 1C managed form from JSON or object metadata +# form-compile v1.163 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -3856,6 +3856,10 @@ def emit_group(lines, el, name, eid, indent): repr_val = repr_map.get(str(el['representation']), str(el['representation'])) lines.append(f'{inner}{repr_val}') + # Использование текущей строки группы (после Representation, порядок XSD) + if el.get('currentRowUse'): + lines.append(f'{inner}{el["currentRowUse"]}') + # ShowTitle if el.get('showTitle') is not None: lines.append(f'{inner}{"true" if el["showTitle"] else "false"}') @@ -4600,6 +4604,9 @@ def emit_picture_field(lines, el, name, eid, indent): lines.append(f'{inner}true') emit_layout(lines, el, inner) + # EnableDrag — фактическое значение (поле картинки перетаскиваемо; декомпилятор ловит generic-ом) + if el.get('enableDrag') is not None: + lines.append(f'{inner}{"true" if el["enableDrag"] else "false"}') # FooterDataPath / FooterText — общие cell-свойства колонки (как у input/labelField) if el.get('footerDataPath'): @@ -4844,6 +4851,12 @@ def emit_attr_column(lines, col, indent): if col.get('title'): emit_mltext(lines, f'{indent}\t', 'Title', col['title']) emit_type(lines, str(col.get('type', '')), f'{indent}\t') + # Проверка заполнения колонки → (как у реквизита; bool true→ShowError / строка verbatim) + cfc = col.get('fillCheck') if col.get('fillCheck') is not None else col.get('fillChecking') + if cfc is not None: + cfcv = ('ShowError' if cfc else None) if isinstance(cfc, bool) else str(cfc) + if cfcv: + lines.append(f'{indent}\t{cfcv}') emit_functional_options(lines, col.get('functionalOptions'), f'{indent}\t') # Ролевой доступ колонки (View/Edit) — xr-флаг, как у самого реквизита if col.get('view') is not None: diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index cc4d0765..8c793974 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.137 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.138 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -1126,6 +1126,7 @@ function Decompile-AttrColumn { $co = [ordered]@{}; $co['name'] = $c.GetAttribute("name") $cty = Decompile-Type ($c.SelectSingleNode("lf:Type", $ns)); if ($cty) { $co['type'] = $cty } $ctNode = $c.SelectSingleNode("lf:Title", $ns); if ($ctNode) { $t = Get-LangTextWS $ctNode; if ($null -ne $t) { $co['title'] = $t } } + $cfc = Get-Child $c 'FillCheck'; if ($cfc) { $co['fillCheck'] = $cfc } # проверка заполнения колонки (как у реквизита) $cfo = Decompile-FunctionalOptions $c; if ($cfo) { $co['functionalOptions'] = $cfo } # Ролевой доступ колонки (View/Edit) — xr-флаг, как у самого реквизита (bool | {common,roles}) $cv = Decompile-XrFlag $c 'View'; if ($null -ne $cv) { $co['view'] = $cv } @@ -1871,6 +1872,7 @@ function Decompile-Element { $rep = Get-Child $node 'Representation' if ($rep) { $repmap=@{'None'='none';'NormalSeparation'='normal';'WeakSeparation'='weak';'StrongSeparation'='strong'}; if ($repmap.ContainsKey($rep)) { $obj['representation']=$repmap[$rep] } else { $obj['representation']=$rep } } $st = Get-Child $node 'ShowTitle'; if ($null -ne $st) { $obj['showTitle'] = ($st -eq 'true') } # факт. значение (явный true тоже) + $cru = Get-Child $node 'CurrentRowUse'; if ($cru) { $obj['currentRowUse'] = $cru } # использование текущей строки группы $crt = $node.SelectSingleNode("lf:CollapsedRepresentationTitle", $ns); if ($crt) { $ct = Get-LangText $crt; if ($null -ne $ct -and $ct -ne '') { $obj['collapsedTitle'] = $ct } } if ((Get-Child $node 'United') -eq 'false') { $obj['united'] = $false } if ((Get-Child $node 'Collapsed') -eq 'true') { $obj['collapsed'] = $true } @@ -2498,7 +2500,7 @@ $titleNode = $root.SelectSingleNode("lf:Title", $ns) if ($titleNode) { $t = Get-LangText $titleNode; if ($null -ne $t) { $dsl['title'] = $t } } # properties (прямые скаляры под
, PascalCase → camelCase) -$KNOWN_FORM_PROPS = @('AutoTitle','ReportResult','DetailsData','ReportFormType','AutoShowState','ReportResultViewMode','ViewModeApplicationOnSetReportResult','WindowOpeningMode','CommandBarLocation','SaveDataInSettings','AutoSaveDataInSettings','AutoTime','UsePostingMode','RepostOnWrite','AutoURL','AutoFillCheck','Customizable','EnterKeyBehavior','VerticalScroll','Width','Height','Group','UseForFoldersAndItems','SaveWindowSettings','ScalingMode','VerticalSpacing','VariantAppearance','ShowCloseButton','HorizontalAlign','ChildrenAlign','ShowTitle','ConversationsRepresentation','CollapseItemsByImportanceVariant','GroupList','ChildItemsWidth','VerticalAlign','HorizontalSpacing','CustomSettingsFolder','SettingsStorage') +$KNOWN_FORM_PROPS = @('AutoTitle','ReportResult','DetailsData','ReportFormType','AutoShowState','ReportResultViewMode','ViewModeApplicationOnSetReportResult','WindowOpeningMode','CommandBarLocation','SaveDataInSettings','AutoSaveDataInSettings','AutoTime','UsePostingMode','RepostOnWrite','AutoURL','AutoFillCheck','Customizable','EnterKeyBehavior','VerticalScroll','Width','Height','Group','UseForFoldersAndItems','SaveWindowSettings','ScalingMode','VerticalSpacing','VariantAppearance','ShowCloseButton','HorizontalAlign','ChildrenAlign','ShowTitle','ConversationsRepresentation','CollapseItemsByImportanceVariant','GroupList','ChildItemsWidth','VerticalAlign','HorizontalSpacing','CustomSettingsFolder','SettingsStorage','Enabled') $props = [ordered]@{} foreach ($pn in $KNOWN_FORM_PROPS) { $v = Get-Child $root $pn diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index c0d5b66d..fe5c688e 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -59,6 +59,7 @@ | `usePostingMode` | `` | `Auto`, `Postings`, `Movements` | | `repostOnWrite` | `` | `true` / `false` | | `autoURL` | `` | `true` / `false` | +| `enabled` | `` | `true` / `false` — доступность всей формы (редкое; форма-уровень) | | `autoFillCheck` | `` | `true` / `false` | | `customizable` | `` | `true` / `false` | | `enterKeyBehavior` | `` | `DefaultButton`, `NewLine` | @@ -372,6 +373,7 @@ companion-панели с собственным контентом. Оба не | `children` | array | Вложенные элементы | | `showTitle` | bool | Показывать заголовок группы | | `representation` | string | `none`, `normal`, `weak`, `strong` | +| `currentRowUse` | string | Использование текущей строки группы (``: `DontUse`/`Use`/…) — редкое | | `united` | bool | Объединение | #### input — InputField @@ -857,7 +859,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и | `savedData` | bool | Сохраняемые данные (``). **`false`** → суппресс авто-вывода компилятора (main-реквизит объектного типа Catalog/Document/ChartOf*/ExchangePlan/BusinessProcess/Task Object + RecordManager → `SavedData=true`). Нет ключа → авто-вывод | | `save` | bool/string/array | Сохранение значения в пользовательских настройках (`…`). `true` → `имя`; строка/массив строк → под-поля с авто-префиксом `имя.` (путь с точкой / ссылка вида `N/M` или `N/M:…` / совпадающее с именем — берётся как есть). Нет ключа или `false` → не эмитится. Пример периода: `["Период","EndDate","StartDate","Variant"]`. **Многоуровневый путь** (напр. `КомпоновщикНастроек.Settings.Filter`) хранится ПОЛНЫМ (декомпилятор снимает префикс `имя.` только у простого под-поля без точки — иначе компилятор по dot-правилу не реинъектит префикс) | | `fillCheck` | bool/string | Проверка заполнения реквизита (``). `true` → `ShowError` (единственное значение в схеме); строка → verbatim. Синоним `fillChecking`. (`` в схеме нет — был багом) | -| `columns` | array | Колонки для ValueTable/ValueTree (`{ name, type, title?, functionalOptions?, view?, edit?, useAlways? }`). `view`/`edit` — ролевой доступ колонки (``/`` xr-флаг, тот же формат `bool \| {common, roles}`, что у реквизита, §4.1c; редкое) | +| `columns` | array | Колонки для ValueTable/ValueTree (`{ name, type, title?, fillCheck?, functionalOptions?, view?, edit?, useAlways? }`). `fillCheck` — проверка заполнения колонки (как у реквизита: `true`→`ShowError` / строка). `view`/`edit` — ролевой доступ колонки (``/`` xr-флаг, тот же формат `bool \| {common, roles}`, что у реквизита, §4.1c; редкое) | | `additionalColumns` | array | Доп. колонки табличных частей объекта: `[{ table: "Объект.ТабЧасть", columns: [] }]`. У главного реквизита-объекта; `` — та же грамматика, что у `columns`. Эмитятся в `` после прямых колонок | | `settings` | object | Настройки динамического списка (только `type: "DynamicList"`) | | `planner` | object | Design-time конфигурация планировщика (только `type: "pl:Planner"`, ``). См. ниже |