From cb3dda0d534ce53c81238c8a70357557fd5194db Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Fri, 12 Jun 2026 14:06:19 +0300 Subject: [PATCH] =?UTF-8?q?feat(form-decompile,form-compile):=20=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D0=B5=D0=B2=D0=BE=D0=B9=20=D0=B4=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=83=D0=BF=20=D0=BA=D0=BE=D0=BB=D0=BE=D0=BD=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B5=D0=BA=D0=B2=D0=B8=D0=B7=D0=B8=D1=82=D0=B0=20(View/?= =?UTF-8?q?Edit=20xr-=D1=84=D0=BB=D0=B0=D0=B3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раундтрип терял / на колонках реквизита (колонка ValueTable/ValueTree с ): ролевой доступ вида falsetrue (напр. НастройкиУчетаЗарплаты/ФормаДополнительныхДанных — колонки РайонныйКоэффициент/Ссылка). Механизм xr-флага уже был у самого реквизита (View/Edit) и userVisible — у колонок не подключён. decompile (Decompile-AttrColumn): захват view/edit через Decompile-XrFlag (bool | {common,roles}). compile (Emit-AttrColumn, ps1+py): эмиссия / через Emit-XrFlag после FunctionalOptions. (Колонки идут своим путём Decompile-AttrColumn, не через GENERIC_SCALARS — коллизии ключа edit нет.) Корпус (acc+erp 8.3.24): из 282591 колонок — 14 с , 21 с (редко, но реально). Верификация: таргет-раундтрип 72 форм с колоночными View/Edit → категория закрыта (0 LOST; остаток — другие категории content/right). Регресс form-compile 43/43 (ps1+py); 1С-cert кейса table (колоночные View common-only и Edit с ролью грузятся в платформу). spec обновлён. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 5 ++++- .claude/skills/form-compile/scripts/form-compile.py | 7 ++++++- .claude/skills/form-decompile/scripts/form-decompile.ps1 | 5 ++++- docs/form-dsl-spec.md | 2 +- .../table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml | 7 +++++++ tests/skills/cases/form-compile/table.json | 4 ++-- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 26801c0c..9f246900 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.130 — Compile 1C managed form from JSON or object metadata +# form-compile v1.131 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -4849,6 +4849,9 @@ function Emit-AttrColumn { if ($col.title) { Emit-MLText -tag "Title" -text $col.title -indent "$indent`t" } Emit-Type -typeStr "$($col.type)" -indent "$indent`t" 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" } + if ($null -ne $col.edit) { Emit-XrFlag -tag 'Edit' -val $col.edit -indent "$indent`t" } X "$indent" } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 79972c46..c1e0e01e 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.130 — Compile 1C managed form from JSON or object metadata +# form-compile v1.131 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -4563,6 +4563,11 @@ def emit_attr_column(lines, col, indent): emit_mltext(lines, f'{indent}\t', 'Title', col['title']) emit_type(lines, str(col.get('type', '')), f'{indent}\t') emit_functional_options(lines, col.get('functionalOptions'), f'{indent}\t') + # Ролевой доступ колонки (View/Edit) — xr-флаг, как у самого реквизита + if col.get('view') is not None: + emit_xr_flag(lines, 'View', col['view'], f'{indent}\t') + if col.get('edit') is not None: + emit_xr_flag(lines, 'Edit', col['edit'], f'{indent}\t') lines.append(f'{indent}') diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index dbea6847..98879c43 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.104 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.105 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -985,6 +985,9 @@ function Decompile-AttrColumn { $cty = Decompile-Type ($c.SelectSingleNode("lf:Type", $ns)); if ($cty) { $co['type'] = $cty } $ctNode = $c.SelectSingleNode("lf:Title", $ns); if ($ctNode) { $t = Get-LangText $ctNode; if ($null -ne $t) { $co['title'] = $t } } $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 } + $ce = Decompile-XrFlag $c 'Edit'; if ($null -ne $ce) { $co['edit'] = $ce } return $co } diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 6c8df28d..5842831c 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -847,7 +847,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и | `savedData` | bool | Сохраняемые данные (``). **`false`** → суппресс авто-вывода компилятора (main-реквизит объектного типа Catalog/Document/ChartOf*/ExchangePlan/BusinessProcess/Task Object + RecordManager → `SavedData=true`). Нет ключа → авто-вывод | | `save` | bool/string/array | Сохранение значения в пользовательских настройках (`…`). `true` → `имя`; строка/массив строк → под-поля с авто-префиксом `имя.` (путь с точкой / UUID `1/0:…` / совпадающее с именем — берётся как есть). Нет ключа или `false` → не эмитится. Пример периода: `["Период","EndDate","StartDate","Variant"]` | | `fillCheck` | bool/string | Проверка заполнения реквизита (``). `true` → `ShowError` (единственное значение в схеме); строка → verbatim. Синоним `fillChecking`. (`` в схеме нет — был багом) | -| `columns` | array | Колонки для ValueTable/ValueTree (`{ name, type, title?, functionalOptions?, useAlways? }`) | +| `columns` | array | Колонки для ValueTable/ValueTree (`{ name, type, title?, functionalOptions?, view?, edit?, useAlways? }`). `view`/`edit` — ролевой доступ колонки (``/`` xr-флаг, тот же формат `bool \| {common, roles}`, что у реквизита, §4.1c; редкое) | | `additionalColumns` | array | Доп. колонки табличных частей объекта: `[{ table: "Объект.ТабЧасть", columns: [] }]`. У главного реквизита-объекта; `` — та же грамматика, что у `columns`. Эмитятся в `` после прямых колонок | | `settings` | object | Настройки динамического списка (только `type: "DynamicList"`) | | `planner` | object | Design-time конфигурация планировщика (только `type: "pl:Planner"`, ``). См. ниже | 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 81ac249b..c17839d6 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 @@ -133,6 +133,9 @@ Date + + false + @@ -143,6 +146,10 @@ Any + + false + true + diff --git a/tests/skills/cases/form-compile/table.json b/tests/skills/cases/form-compile/table.json index 663c5f63..e9ec0470 100644 --- a/tests/skills/cases/form-compile/table.json +++ b/tests/skills/cases/form-compile/table.json @@ -36,8 +36,8 @@ "attributes": [ { "name": "Объект", "type": "DataProcessorObject.Таблица", "main": true }, { "name": "Данные", "type": "ValueTable", "useAlways": ["Сумма"], "columns": [ - { "name": "Дата", "type": "date", "useAlways": true }, - { "name": "Сумма", "type": "decimal(15,2)" }, + { "name": "Дата", "type": "date", "useAlways": true, "view": false }, + { "name": "Сумма", "type": "decimal(15,2)", "edit": { "common": false, "roles": { "a1b2c3d4-1111-2222-3333-444455556666": true } } }, { "name": "Комментарий", "type": "string(200)" }, { "name": "Объект", "type": "AnyRef" }, { "name": "Источник", "type": "CatalogRef" }