From 07b2ec36afd5050d4bd33f1f64f28938498ec1a2 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 17:34:16 +0300 Subject: [PATCH 01/10] =?UTF-8?q?feat(meta-compile):=20=D0=B4=D0=B5=D1=84?= =?UTF-8?q?=D0=BE=D0=BB=D1=82=D1=8B=20QuickChoice=20=D0=BF=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=B3=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Catalog/CCT/CoA/CoCT/ExchangePlan: дефолт false (раньше true). Enum: дефолт true (теперь параметризовано). Цифры из acc_8.3.27 + erp_8.3.24 — у Catalog ~95% объектов QuickChoice=false, у Enum ~99% true. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../meta-compile/reference/types-basic.md | 2 +- .../meta-compile/scripts/meta-compile.ps1 | 19 ++++++++++++------- .../meta-compile/scripts/meta-compile.py | 19 ++++++++++++------- .../snapshots/batch/Catalogs/Валюты.xml | 2 +- .../catalog-basic/Catalogs/Валюты.xml | 2 +- .../Catalogs/Подразделения.xml | 2 +- .../snapshots/catalog-minimal/Catalogs/А.xml | 2 +- .../Catalogs/Контрагенты.xml | 2 +- .../catalog-tabparts/Catalogs/Товары.xml | 2 +- .../ChartsOfAccounts/Хозрасчетный.xml | 2 +- .../ВидыНачислений.xml | 2 +- .../ДополнительныеРеквизитыИСведения.xml | 2 +- .../ExchangePlans/ОбменСФилиалами.xml | 2 +- 13 files changed, 35 insertions(+), 25 deletions(-) diff --git a/.claude/skills/meta-compile/reference/types-basic.md b/.claude/skills/meta-compile/reference/types-basic.md index ad093af0..29a74b3b 100644 --- a/.claude/skills/meta-compile/reference/types-basic.md +++ b/.claude/skills/meta-compile/reference/types-basic.md @@ -18,7 +18,7 @@ | `checkUnique` | `false` | CheckUnique | | `defaultPresentation` | `AsDescription` | DefaultPresentation | | `subordinationUse` | `ToItems` | SubordinationUse | -| `quickChoice` | `true` | QuickChoice | +| `quickChoice` | `false` | QuickChoice | | `choiceMode` | `BothWays` | ChoiceMode | | `owners` | `[]` | Owners | | `attributes` | `[]` | → Attribute в ChildObjects | diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 2e863e2e..b2918df4 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -1,4 +1,4 @@ -# meta-compile v1.10 — Compile 1C metadata object from JSON +# meta-compile v1.11 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1129,7 +1129,7 @@ function Emit-CatalogProperties { X "$i" X "$iAuto" X "$iInDialog" - $quickChoice = if ($def.quickChoice -eq $false) { "false" } else { "true" } + $quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" } $choiceMode = Get-EnumProp "ChoiceMode" "choiceMode" "BothWays" X "$i$quickChoice" X "$i$choiceMode" @@ -1292,7 +1292,8 @@ function Emit-EnumProperties { Emit-StandardAttributes $i "Enum" X "$i" - X "$itrue" + $quickChoice = if ($def.quickChoice -eq $false) { "false" } else { "true" } + X "$i$quickChoice" X "$iBothWays" X "$i" X "$i" @@ -1663,7 +1664,8 @@ function Emit-ExchangePlanProperties { X "$i$includeExt" X "$i" - X "$itrue" + $quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" } + X "$i$quickChoice" X "$iBothWays" X "$i" X "$i`tExchangePlan.$objName.StandardAttribute.Description" @@ -1764,7 +1766,8 @@ function Emit-ChartOfCharacteristicTypesProperties { X "$i" X "$iAuto" X "$iInDialog" - X "$itrue" + $quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" } + X "$i$quickChoice" X "$iBothWays" X "$i" X "$i`tChartOfCharacteristicTypes.$objName.StandardAttribute.Description" @@ -1905,7 +1908,8 @@ function Emit-ChartOfAccountsProperties { X "$i" X "$iAuto" - X "$itrue" + $quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" } + X "$i$quickChoice" X "$iBothWays" X "$i" X "$i`tChartOfAccounts.$objName.StandardAttribute.Description" @@ -2021,7 +2025,8 @@ function Emit-ChartOfCalculationTypesProperties { X "$i" X "$iAuto" X "$iInDialog" - X "$itrue" + $quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" } + X "$i$quickChoice" X "$iBothWays" X "$i" X "$i`tChartOfCalculationTypes.$objName.StandardAttribute.Description" diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index ecf1e27c..196397e8 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-compile v1.10 — Compile 1C metadata object from JSON +# meta-compile v1.11 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -1024,7 +1024,7 @@ def emit_catalog_properties(indent): X(f'{i}') X(f'{i}Auto') X(f'{i}InDialog') - quick_choice = 'false' if defn.get('quickChoice') is False else 'true' + quick_choice = 'true' if defn.get('quickChoice') is True else 'false' choice_mode = get_enum_prop('ChoiceMode', 'choiceMode', 'BothWays') X(f'{i}{quick_choice}') X(f'{i}{choice_mode}') @@ -1157,7 +1157,8 @@ def emit_enum_properties(indent): X(f'{i}false') emit_standard_attributes(i, 'Enum') X(f'{i}') - X(f'{i}true') + quick_choice = 'false' if defn.get('quickChoice') is False else 'true' + X(f'{i}{quick_choice}') X(f'{i}BothWays') X(f'{i}') X(f'{i}') @@ -1471,7 +1472,8 @@ def emit_exchange_plan_properties(indent): X(f'{i}{distributed}') X(f'{i}{include_ext}') X(f'{i}') - X(f'{i}true') + quick_choice = 'true' if defn.get('quickChoice') is True else 'false' + X(f'{i}{quick_choice}') X(f'{i}BothWays') X(f'{i}') X(f'{i}\tExchangePlan.{obj_name}.StandardAttribute.Description') @@ -1557,7 +1559,8 @@ def emit_chart_of_characteristic_types_properties(indent): X(f'{i}') X(f'{i}Auto') X(f'{i}InDialog') - X(f'{i}true') + quick_choice = 'true' if defn.get('quickChoice') is True else 'false' + X(f'{i}{quick_choice}') X(f'{i}BothWays') X(f'{i}') X(f'{i}\tChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Description') @@ -1673,7 +1676,8 @@ def emit_chart_of_accounts_properties(indent): X(f'{i}') X(f'{i}') X(f'{i}Auto') - X(f'{i}true') + quick_choice = 'true' if defn.get('quickChoice') is True else 'false' + X(f'{i}{quick_choice}') X(f'{i}BothWays') X(f'{i}') X(f'{i}\tChartOfAccounts.{obj_name}.StandardAttribute.Description') @@ -1764,7 +1768,8 @@ def emit_chart_of_calculation_types_properties(indent): X(f'{i}') X(f'{i}Auto') X(f'{i}InDialog') - X(f'{i}true') + quick_choice = 'true' if defn.get('quickChoice') is True else 'false' + X(f'{i}{quick_choice}') X(f'{i}BothWays') X(f'{i}') X(f'{i}\tChartOfCalculationTypes.{obj_name}.StandardAttribute.Description') diff --git a/tests/skills/cases/meta-compile/snapshots/batch/Catalogs/Валюты.xml b/tests/skills/cases/meta-compile/snapshots/batch/Catalogs/Валюты.xml index e6edf1af..6c669c51 100644 --- a/tests/skills/cases/meta-compile/snapshots/batch/Catalogs/Валюты.xml +++ b/tests/skills/cases/meta-compile/snapshots/batch/Catalogs/Валюты.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Валюты.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-basic/Catalogs/Валюты.xml b/tests/skills/cases/meta-compile/snapshots/catalog-basic/Catalogs/Валюты.xml index e6edf1af..6c669c51 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-basic/Catalogs/Валюты.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-basic/Catalogs/Валюты.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Валюты.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-hierarchical/Catalogs/Подразделения.xml b/tests/skills/cases/meta-compile/snapshots/catalog-hierarchical/Catalogs/Подразделения.xml index f1cfe8a5..a37c6a46 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-hierarchical/Catalogs/Подразделения.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-hierarchical/Catalogs/Подразделения.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Подразделения.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-minimal/Catalogs/А.xml b/tests/skills/cases/meta-compile/snapshots/catalog-minimal/Catalogs/А.xml index 087d6edd..8a49fdf4 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-minimal/Catalogs/А.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-minimal/Catalogs/А.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.А.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-mixed-types/Catalogs/Контрагенты.xml b/tests/skills/cases/meta-compile/snapshots/catalog-mixed-types/Catalogs/Контрагенты.xml index 369b3a6f..8a0ff68d 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-mixed-types/Catalogs/Контрагенты.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-mixed-types/Catalogs/Контрагенты.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Контрагенты.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-tabparts/Catalogs/Товары.xml b/tests/skills/cases/meta-compile/snapshots/catalog-tabparts/Catalogs/Товары.xml index 09ff98e9..2d0410d5 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-tabparts/Catalogs/Товары.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-tabparts/Catalogs/Товары.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Товары.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/chart-of-accounts/ChartsOfAccounts/Хозрасчетный.xml b/tests/skills/cases/meta-compile/snapshots/chart-of-accounts/ChartsOfAccounts/Хозрасчетный.xml index 6b826fc2..264225e9 100644 --- a/tests/skills/cases/meta-compile/snapshots/chart-of-accounts/ChartsOfAccounts/Хозрасчетный.xml +++ b/tests/skills/cases/meta-compile/snapshots/chart-of-accounts/ChartsOfAccounts/Хозрасчетный.xml @@ -426,7 +426,7 @@ Auto - true + false BothWays ChartOfAccounts.Хозрасчетный.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml b/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml index ebc76ee0..580202c5 100644 --- a/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml +++ b/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml @@ -252,7 +252,7 @@ Auto InDialog - true + false BothWays ChartOfCalculationTypes.ВидыНачислений.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/chart-of-characteristic-types/ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения.xml b/tests/skills/cases/meta-compile/snapshots/chart-of-characteristic-types/ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения.xml index da7389fe..96f9fb02 100644 --- a/tests/skills/cases/meta-compile/snapshots/chart-of-characteristic-types/ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения.xml +++ b/tests/skills/cases/meta-compile/snapshots/chart-of-characteristic-types/ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения.xml @@ -277,7 +277,7 @@ Auto InDialog - true + false BothWays ChartOfCharacteristicTypes.ДополнительныеРеквизитыИСведения.StandardAttribute.Description diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами.xml index 4ef5524e..142f6198 100644 --- a/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами.xml +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами.xml @@ -226,7 +226,7 @@ true false - true + false BothWays ExchangePlan.ОбменСФилиалами.StandardAttribute.Description From b1e29253d5c657eb4ff749b5f3faaf90e5e01a15 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 18:43:26 +0300 Subject: [PATCH 02/10] =?UTF-8?q?feat(form-compile):=20RadioButtonField=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=BB=D0=BE=D0=B2=D0=B0=D1=80=D1=8C=20=D1=81?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=BD=D0=B8=D0=BC=D0=BE=D0=B2=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=D0=BE=D0=B2=20=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Поле переключателя с RadioButtonType (Auto/RadioButtons/Tumbler) и ChoiceList (массив value+presentation). Толерантно к написанию модели: русские имена тегов (ПолеПереключателя, RadioButtonField), ВидПереключателя по-русски (Авто/Переключатель/Тумблер), Перечисление.X.Y без EnumValue, синоним title для presentation, автогенерация презентации из имени значения. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/form-compile/SKILL.md | 34 ++- .../form-compile/scripts/form-compile.ps1 | 268 +++++++++++++++++- .../form-compile/scripts/form-compile.py | 213 +++++++++++++- .../cases/form-compile/radio-auto-enum.json | 45 +++ .../cases/form-compile/radio-synonyms.json | 44 +++ .../form-compile/radio-tumbler-strings.json | 36 +++ .../radio-auto-enum/Configuration.xml | 253 +++++++++++++++++ .../DataProcessors/ТестРадио.xml | 68 +++++ .../ТестРадио/Ext/ManagerModule.bsl | 0 .../ТестРадио/Ext/ObjectModule.bsl | 0 .../DataProcessors/ТестРадио/Forms/Форма.xml | 22 ++ .../ТестРадио/Forms/Форма/Ext/Form.xml | 78 +++++ .../ТестРадио/Forms/Форма/Ext/Form/Module.bsl | 19 ++ .../radio-auto-enum/Enums/СпособыКурса.xml | 121 ++++++++ .../Enums/СпособыКурса/Ext/ManagerModule.bsl | 0 .../Ext/ClientApplicationInterface.xml | 18 ++ .../radio-auto-enum/Languages/Русский.xml | 16 ++ .../radio-synonyms/Configuration.xml | 253 +++++++++++++++++ .../DataProcessors/ТестСинонимы.xml | 68 +++++ .../ТестСинонимы/Ext/ManagerModule.bsl | 0 .../ТестСинонимы/Ext/ObjectModule.bsl | 0 .../ТестСинонимы/Forms/Форма.xml | 22 ++ .../ТестСинонимы/Forms/Форма/Ext/Form.xml | 73 +++++ .../Forms/Форма/Ext/Form/Module.bsl | 19 ++ .../radio-synonyms/Enums/СпособыКурса.xml | 121 ++++++++ .../Enums/СпособыКурса/Ext/ManagerModule.bsl | 0 .../Ext/ClientApplicationInterface.xml | 18 ++ .../radio-synonyms/Languages/Русский.xml | 16 ++ .../radio-tumbler-strings/Configuration.xml | 252 ++++++++++++++++ .../DataProcessors/ТестТумблер.xml | 72 +++++ .../ТестТумблер/Ext/ManagerModule.bsl | 0 .../ТестТумблер/Ext/ObjectModule.bsl | 0 .../ТестТумблер/Forms/Форма.xml | 22 ++ .../ТестТумблер/Forms/Форма/Ext/Form.xml | 71 +++++ .../Forms/Форма/Ext/Form/Module.bsl | 19 ++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../Languages/Русский.xml | 16 ++ 37 files changed, 2282 insertions(+), 13 deletions(-) create mode 100644 tests/skills/cases/form-compile/radio-auto-enum.json create mode 100644 tests/skills/cases/form-compile/radio-synonyms.json create mode 100644 tests/skills/cases/form-compile/radio-tumbler-strings.json create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/Configuration.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form/Module.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-auto-enum/Languages/Русский.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/Configuration.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form/Module.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-synonyms/Languages/Русский.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Configuration.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form/Module.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Languages/Русский.xml diff --git a/.claude/skills/form-compile/SKILL.md b/.claude/skills/form-compile/SKILL.md index 79a4a3b0..3a2dd1cf 100644 --- a/.claude/skills/form-compile/SKILL.md +++ b/.claude/skills/form-compile/SKILL.md @@ -64,6 +64,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | `"group"` | UsualGroup | `"horizontal"` / `"vertical"` / `"alwaysHorizontal"` / `"alwaysVertical"` / `"collapsible"` | | `"input"` | InputField | имя элемента | | `"check"` | CheckBoxField | имя | +| `"radio"` | RadioButtonField | имя | | `"label"` | LabelDecoration | имя (текст задаётся через `title`) | | `"labelField"` | LabelField | имя | | `"table"` | Table | имя | @@ -97,7 +98,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile **input / picField**: `OnChange`, `StartChoice`, `ChoiceProcessing`, `AutoComplete`, `TextEditEnd`, `Clearing`, `Creating`, `EditTextChange` -**check**: `OnChange` +**check / radio**: `OnChange` **table**: `OnStartEdit`, `OnEditEnd`, `OnChange`, `Selection`, `ValueChoice`, `BeforeAddRow`, `BeforeDeleteRow`, `AfterDeleteRow`, `BeforeRowChange`, `BeforeEditEnd`, `OnActivateRow`, `OnActivateCell`, `Drag`, `DragStart`, `DragCheck`, `DragEnd` @@ -135,6 +136,37 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | `path` | DataPath | | `titleLocation` | Размещение заголовка | +### Поле переключателя (radio) + +Радиокнопки или тумблер для выбора одного значения из списка. + +| Ключ | Описание | Пример | +|------|----------|--------| +| `path` | DataPath — привязка к реквизиту | `"СпособКурса"` | +| `radioButtonType` | Вид переключателя | `"Auto"` (по умолчанию), `"RadioButtons"`, `"Tumbler"` | +| `columnsCount` | Число колонок раскладки | `1`, `2`, ... | +| `titleLocation` | Размещение заголовка | по умолчанию `"none"` | +| `choiceList` | Список вариантов: массив `{value, presentation}` | см. ниже | + +`choiceList[*]`: + +| Ключ | Описание | +|------|----------| +| `value` | Значение варианта. Строка/число/булево; для перечисления — `"Enum.ИмяТипа.EnumValue.ИмяЗначения"` | +| `presentation` | Текст рядом с переключателем. Строка (русский) либо объект `{ru, en, ...}` для мультиязычности | + +```json +{ + "radio": "СпособКурса", + "path": "Объект.СпособУстановкиКурса", + "radioButtonType": "Auto", + "choiceList": [ + { "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } }, + { "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" } + ] +} +``` + ### Надпись-декорация (label) | Ключ | Описание | diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index e821095d..9e2871ce 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.15 — Compile 1C managed form from JSON or object metadata +# form-compile v1.16 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1774,6 +1774,7 @@ function Get-ElementName { $script:knownEvents = @{ "input" = @("OnChange","StartChoice","ChoiceProcessing","AutoComplete","TextEditEnd","Clearing","Creating","EditTextChange") "check" = @("OnChange") + "radio" = @("OnChange") "label" = @("Click","URLProcessing") "labelField"= @("OnChange","StartChoice","ChoiceProcessing","Click","URLProcessing","Clearing") "table" = @("Selection","BeforeAddRow","AfterDeleteRow","BeforeDeleteRow","OnActivateRow","OnEditEnd","OnStartEdit","BeforeRowChange","BeforeEditEnd","ValueChoice","OnActivateCell","OnActivateField","Drag","DragStart","DragCheck","DragEnd","OnGetDataAtServer","BeforeLoadUserSettingsAtServer","OnUpdateUserSettingSetAtServer","OnChange") @@ -1826,9 +1827,43 @@ function Emit-Companion { function Emit-Element { param($el, [string]$indent) - # Silent synonyms: commandBar -> cmdBar, autoCommandBar -> autoCmdBar - # (autoCmdBar inside def.elements is normally extracted in pre-pass; this is a safety net for nested cases) - $synonyms = @{ "commandBar" = "cmdBar"; "autoCommandBar" = "autoCmdBar" } + # Silent synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio). + # Maps any synonym to canonical short DSL key. + $synonyms = @{ + "commandBar" = "cmdBar" + "autoCommandBar" = "autoCmdBar" + "КоманднаяПанель" = "cmdBar" + "InputField" = "input" + "ПолеВвода" = "input" + "CheckBoxField" = "check" + "ПолеФлажка" = "check" + "RadioButtonField" = "radio" + "ПолеПереключателя" = "radio" + "radioButton" = "radio" + "PictureField" = "picField" + "ПолеКартинки" = "picField" + "LabelField" = "labelField" + "ПолеНадписи" = "labelField" + "CalendarField" = "calendar" + "ПолеКалендаря" = "calendar" + "LabelDecoration" = "label" + "Надпись" = "label" + "PictureDecoration" = "picture" + "Картинка" = "picture" + "UsualGroup" = "group" + "Группа" = "group" + "ОбычнаяГруппа" = "group" + "Pages" = "pages" + "ГруппаСтраниц" = "pages" + "Page" = "page" + "Страница" = "page" + "Table" = "table" + "Таблица" = "table" + "Button" = "button" + "Кнопка" = "button" + "Popup" = "popup" + "ВсплывающееМеню" = "popup" + } foreach ($pair in $synonyms.GetEnumerator()) { if ($null -ne $el.PSObject.Properties[$pair.Key] -and $null -eq $el.PSObject.Properties[$pair.Value]) { $val = $el.($pair.Key) @@ -1841,7 +1876,7 @@ function Emit-Element { $typeKey = $null $xmlTag = $null - foreach ($key in @("group","input","check","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) { + foreach ($key in @("group","input","check","radio","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) { if ($el.$key -ne $null) { $typeKey = $key break @@ -1856,8 +1891,10 @@ function Emit-Element { # Validate known keys — warn about typos and unknown properties $knownKeys = @{ # type keys - "group"=1;"input"=1;"check"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1 + "group"=1;"input"=1;"check"=1;"radio"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1 "button"=1;"picture"=1;"picField"=1;"calendar"=1;"cmdBar"=1;"popup"=1 + # radio-specific + "radioButtonType"=1;"choiceList"=1;"columnsCount"=1 # naming & binding "name"=1;"path"=1;"title"=1 # visibility & state @@ -1903,6 +1940,7 @@ function Emit-Element { "group" { Emit-Group -el $el -name $name -id $id -indent $indent } "input" { Emit-Input -el $el -name $name -id $id -indent $indent } "check" { Emit-Check -el $el -name $name -id $id -indent $indent } + "radio" { Emit-Radio -el $el -name $name -id $id -indent $indent } "label" { Emit-Label -el $el -name $name -id $id -indent $indent } "labelField" { Emit-LabelField -el $el -name $name -id $id -indent $indent } "table" { Emit-Table -el $el -name $name -id $id -indent $indent } @@ -2099,6 +2137,224 @@ function Emit-Check { X "$indent" } +# Maps Russian/English root of a typed reference path to canonical English root. +# Used to normalize ChoiceList values like "Перечисление.X.Y" → "Enum.X.EnumValue.Y". +$script:refRootSynonyms = @{ + "Перечисление" = "Enum" + "Справочник" = "Catalog" + "Документ" = "Document" + "ПланСчетов" = "ChartOfAccounts" + "ПланВидовХарактеристик" = "ChartOfCharacteristicTypes" + "ПланВидовРасчета" = "ChartOfCalculationTypes" + "ПланВидовРасчёта" = "ChartOfCalculationTypes" + "ПланОбмена" = "ExchangePlan" + "БизнесПроцесс" = "BusinessProcess" + "Задача" = "Task" + "РегистрСведений" = "InformationRegister" + "РегистрНакопления" = "AccumulationRegister" + "РегистрБухгалтерии" = "AccountingRegister" + "РегистрРасчета" = "CalculationRegister" + "РегистрРасчёта" = "CalculationRegister" +} +$script:enumValueSynonyms = @("EnumValue","ЗначениеПеречисления") + +# Normalize a choiceList item value: returns @{ XsiType = "..."; Text = "..." } +function Normalize-ChoiceValue { + param($value) + + # Booleans + if ($value -is [bool]) { + return @{ XsiType = "xs:boolean"; Text = if ($value) { "true" } else { "false" } } + } + # Numbers (int / decimal / double) + if ($value -is [int] -or $value -is [long] -or $value -is [double] -or $value -is [decimal]) { + return @{ XsiType = "xs:decimal"; Text = "$value" } + } + + $s = "$value" + if ([string]::IsNullOrEmpty($s)) { + return @{ XsiType = "xs:string"; Text = "" } + } + + # Try to detect typed reference path: ".[..]" + $parts = $s -split '\.' + if ($parts.Count -ge 2) { + $root = $parts[0] + $canonRoot = $null + if ($script:refRootSynonyms.ContainsKey($root)) { $canonRoot = $script:refRootSynonyms[$root] } + elseif ($script:refRootSynonyms.Values -contains $root) { $canonRoot = $root } + + if ($canonRoot) { + $typeName = $parts[1] + $normalized = $null + + if ($canonRoot -eq "Enum") { + if ($parts.Count -eq 2) { + # "Enum.X" alone — not a value, treat as string + } elseif ($parts.Count -eq 3) { + # "Enum.X.Y" — insert .EnumValue. + $normalized = "Enum.$typeName.EnumValue.$($parts[2])" + } else { + # "Enum.X..Y..." — replace member with EnumValue (handles ЗначениеПеречисления too) + $member = $parts[2] + if ($script:enumValueSynonyms -contains $member) { + $rest = $parts[3..($parts.Count-1)] -join '.' + $normalized = "Enum.$typeName.EnumValue.$rest" + } else { + $rest = $parts[2..($parts.Count-1)] -join '.' + $normalized = "Enum.$typeName.EnumValue.$rest" + } + } + } else { + # Other ref roots: just translate root, keep tail as-is + if ($parts.Count -ge 3) { + $tail = $parts[1..($parts.Count-1)] -join '.' + $normalized = "$canonRoot.$tail" + } + } + + if ($normalized) { + return @{ XsiType = "xr:DesignTimeRef"; Text = $normalized } + } + } + } + + return @{ XsiType = "xs:string"; Text = $s } +} + +# Emit Presentation block for a choiceList item. +# Accepts string (ru only), or hashtable/PSCustomObject {ru, en, ...}. +# Empty/null → emits empty . +function Emit-ChoicePresentation { + param($pres, [string]$indent) + if ($null -eq $pres -or ($pres -is [string] -and [string]::IsNullOrEmpty($pres))) { + X "$indent" + return + } + + $pairs = @() + if ($pres -is [string]) { + $pairs += ,@("ru", $pres) + } elseif ($pres -is [hashtable] -or $pres -is [System.Collections.IDictionary]) { + foreach ($k in $pres.Keys) { $pairs += ,@("$k", "$($pres[$k])") } + } elseif ($pres.PSObject -and $pres.PSObject.Properties) { + foreach ($p in $pres.PSObject.Properties) { $pairs += ,@("$($p.Name)", "$($p.Value)") } + } else { + $pairs += ,@("ru", "$pres") + } + + X "$indent" + foreach ($pair in $pairs) { + X "$indent`t" + X "$indent`t`t$($pair[0])" + X "$indent`t`t$(Esc-Xml $pair[1])" + X "$indent`t" + } + X "$indent" +} + +function Emit-Radio { + param($el, [string]$name, [int]$id, [string]$indent) + + X "$indent" + $inner = "$indent`t" + + if ($el.path) { X "$inner$($el.path)" } + + Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path) + Emit-CommonFlags -el $el -indent $inner + + # TitleLocation default is None for radio (matches typical configurator behavior) + $tl = if ($el.titleLocation) { + switch ("$($el.titleLocation)") { + "none" { "None" } + "left" { "Left" } + "right" { "Right" } + "top" { "Top" } + "bottom" { "Bottom" } + default { "$($el.titleLocation)" } + } + } else { "None" } + X "$inner$tl" + + # RadioButtonType: Auto | RadioButtons | Tumbler. Accept synonyms. + $rbtRaw = if ($el.radioButtonType) { "$($el.radioButtonType)".Trim() } else { "Auto" } + $rbt = switch -Regex ($rbtRaw.ToLower()) { + '^(auto|авто)$' { "Auto"; break } + '^(radiobuttons?|переключатель|радио)$' { "RadioButtons"; break } + '^(tumbler|тумблер)$' { "Tumbler"; break } + default { $rbtRaw } + } + X "$inner$rbt" + + if ($null -ne $el.columnsCount) { + X "$inner$($el.columnsCount)" + } + + # ChoiceList + if ($el.choiceList -and $el.choiceList.Count -gt 0) { + X "$inner" + $itemIndent = "$inner`t" + foreach ($item in $el.choiceList) { + # Pull value (and tolerate Russian synonym "значение") + $valRaw = $null + if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) { + if ($item.Contains("value")) { $valRaw = $item["value"] } + elseif ($item.Contains("значение")) { $valRaw = $item["значение"] } + } else { + if ($item.PSObject.Properties["value"]) { $valRaw = $item.value } + elseif ($item.PSObject.Properties["значение"]) { $valRaw = $item."значение" } + } + + # Pull presentation (presentation OR title synonym) + $presRaw = $null + $hasPres = $false + if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) { + if ($item.Contains("presentation")) { $presRaw = $item["presentation"]; $hasPres = $true } + elseif ($item.Contains("представление")) { $presRaw = $item["представление"]; $hasPres = $true } + elseif ($item.Contains("title")) { $presRaw = $item["title"]; $hasPres = $true } + } else { + if ($item.PSObject.Properties["presentation"]) { $presRaw = $item.presentation; $hasPres = $true } + elseif ($item.PSObject.Properties["представление"]) { $presRaw = $item."представление"; $hasPres = $true } + elseif ($item.PSObject.Properties["title"]) { $presRaw = $item.title; $hasPres = $true } + } + + $norm = Normalize-ChoiceValue -value $valRaw + + # Auto-derive presentation if missing + if (-not $hasPres) { + if ($norm.XsiType -eq "xr:DesignTimeRef") { + $tail = ($norm.Text -split '\.')[-1] + $presRaw = Title-FromName -name $tail + } elseif ($norm.XsiType -eq "xs:string") { + $presRaw = $norm.Text + } else { + $presRaw = $norm.Text + } + } + + X "$itemIndent" + $valIndent = "$itemIndent`t" + X "$valIndent" + X "$valIndent0" + X "$valIndent" + Emit-ChoicePresentation -pres $presRaw -indent "$valIndent`t" + X "$valIndent`t$(Esc-Xml $norm.Text)" + X "$valIndent" + X "$itemIndent" + } + X "$inner" + } + + # Companions + Emit-Companion -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner + Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner + + Emit-Events -el $el -elementName $name -indent $inner -typeKey "radio" + + X "$indent" +} + function Emit-Label { param($el, [string]$name, [int]$id, [string]$indent) diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 9dc4bc35..164eef17 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.15 — Compile 1C managed form from JSON or object metadata +# form-compile v1.16 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1314,6 +1314,7 @@ EVENT_SUFFIX_MAP = { KNOWN_EVENTS = { "input": ["OnChange", "StartChoice", "ChoiceProcessing", "AutoComplete", "TextEditEnd", "Clearing", "Creating", "EditTextChange"], "check": ["OnChange"], + "radio": ["OnChange"], "label": ["Click", "URLProcessing"], "labelField": ["OnChange", "StartChoice", "ChoiceProcessing", "Click", "URLProcessing", "Clearing"], "table": ["Selection", "BeforeAddRow", "AfterDeleteRow", "BeforeDeleteRow", "OnActivateRow", "OnEditEnd", "OnStartEdit", "BeforeRowChange", "BeforeEditEnd", "ValueChoice", "OnActivateCell", "OnActivateField", "Drag", "DragStart", "DragCheck", "DragEnd", "OnGetDataAtServer", "BeforeLoadUserSettingsAtServer", "OnUpdateUserSettingSetAtServer", "OnChange"], @@ -1337,8 +1338,9 @@ KNOWN_FORM_EVENTS = [ ] KNOWN_KEYS = { - "group", "input", "check", "label", "labelField", "table", "pages", "page", + "group", "input", "check", "radio", "label", "labelField", "table", "pages", "page", "button", "picture", "picField", "calendar", "cmdBar", "popup", + "radioButtonType", "choiceList", "columnsCount", "name", "path", "title", "visible", "hidden", "enabled", "disabled", "readOnly", "userVisible", "on", "handlers", @@ -1359,9 +1361,145 @@ KNOWN_KEYS = { "rowPictureDataPath", "tableAutofill", } -TYPE_KEYS = ["group", "input", "check", "label", "labelField", "table", "pages", "page", +TYPE_KEYS = ["group", "input", "check", "radio", "label", "labelField", "table", "pages", "page", "button", "picture", "picField", "calendar", "cmdBar", "popup"] +# Synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio) +ELEMENT_TYPE_SYNONYMS = { + "commandBar": "cmdBar", + "autoCommandBar": "autoCmdBar", + "КоманднаяПанель": "cmdBar", + "InputField": "input", + "ПолеВвода": "input", + "CheckBoxField": "check", + "ПолеФлажка": "check", + "RadioButtonField": "radio", + "ПолеПереключателя": "radio", + "radioButton": "radio", + "PictureField": "picField", + "ПолеКартинки": "picField", + "LabelField": "labelField", + "ПолеНадписи": "labelField", + "CalendarField": "calendar", + "ПолеКалендаря": "calendar", + "LabelDecoration": "label", + "Надпись": "label", + "PictureDecoration": "picture", + "Картинка": "picture", + "UsualGroup": "group", + "Группа": "group", + "ОбычнаяГруппа": "group", + "Pages": "pages", + "ГруппаСтраниц": "pages", + "Page": "page", + "Страница": "page", + "Table": "table", + "Таблица": "table", + "Button": "button", + "Кнопка": "button", + "Popup": "popup", + "ВсплывающееМеню": "popup", +} + +# Maps Russian/English root of typed reference path to canonical English root +REF_ROOT_SYNONYMS = { + "Перечисление": "Enum", + "Справочник": "Catalog", + "Документ": "Document", + "ПланСчетов": "ChartOfAccounts", + "ПланВидовХарактеристик": "ChartOfCharacteristicTypes", + "ПланВидовРасчета": "ChartOfCalculationTypes", + "ПланВидовРасчёта": "ChartOfCalculationTypes", + "ПланОбмена": "ExchangePlan", + "БизнесПроцесс": "BusinessProcess", + "Задача": "Task", + "РегистрСведений": "InformationRegister", + "РегистрНакопления": "AccumulationRegister", + "РегистрБухгалтерии": "AccountingRegister", + "РегистрРасчета": "CalculationRegister", + "РегистрРасчёта": "CalculationRegister", +} +ENUM_VALUE_SYNONYMS = {"EnumValue", "ЗначениеПеречисления"} + + +def normalize_choice_value(value): + """Returns dict {xsi_type, text} for a choiceList item value.""" + if isinstance(value, bool): + return {"xsi_type": "xs:boolean", "text": "true" if value else "false"} + if isinstance(value, (int, float)): + return {"xsi_type": "xs:decimal", "text": str(value)} + + s = "" if value is None else str(value) + if not s: + return {"xsi_type": "xs:string", "text": ""} + + parts = s.split(".") + if len(parts) >= 2: + root = parts[0] + canon_root = None + if root in REF_ROOT_SYNONYMS: + canon_root = REF_ROOT_SYNONYMS[root] + elif root in REF_ROOT_SYNONYMS.values(): + canon_root = root + + if canon_root: + type_name = parts[1] + normalized = None + if canon_root == "Enum": + if len(parts) == 3: + normalized = f"Enum.{type_name}.EnumValue.{parts[2]}" + elif len(parts) >= 4: + member = parts[2] + if member in ENUM_VALUE_SYNONYMS: + rest = ".".join(parts[3:]) + else: + rest = ".".join(parts[2:]) + normalized = f"Enum.{type_name}.EnumValue.{rest}" + else: + if len(parts) >= 3: + tail = ".".join(parts[1:]) + normalized = f"{canon_root}.{tail}" + + if normalized: + return {"xsi_type": "xr:DesignTimeRef", "text": normalized} + + return {"xsi_type": "xs:string", "text": s} + + +def emit_choice_presentation(lines, pres, indent): + """Accepts None/empty → ; str → ru only; dict → multi-lang.""" + if pres is None or (isinstance(pres, str) and pres == ""): + lines.append(f"{indent}") + return + + if isinstance(pres, str): + pairs = [("ru", pres)] + elif isinstance(pres, dict): + pairs = [(str(k), str(v)) for k, v in pres.items()] + else: + pairs = [("ru", str(pres))] + + lines.append(f"{indent}") + for lang, content in pairs: + lines.append(f"{indent}\t") + lines.append(f"{indent}\t\t{lang}") + lines.append(f"{indent}\t\t{esc_xml(content)}") + lines.append(f"{indent}\t") + lines.append(f"{indent}") + + +def normalize_radio_button_type(raw): + if not raw: + return "Auto" + s = str(raw).strip().lower() + if s in ("auto", "авто"): + return "Auto" + if s in ("radiobutton", "radiobuttons", "переключатель", "радио"): + return "RadioButtons" + if s in ("tumbler", "тумблер"): + return "Tumbler" + return str(raw).strip() + def get_handler_name(element_name, event_name): suffix = EVENT_SUFFIX_MAP.get(event_name) @@ -1623,9 +1761,8 @@ def emit_type(lines, type_str, indent): # --- Element emitters --- def emit_element(lines, el, indent): - # Silent synonyms (safety net; top-level autoCmdBar is normally extracted in pre-pass) - _synonyms = {'commandBar': 'cmdBar', 'autoCommandBar': 'autoCmdBar'} - for src, dst in _synonyms.items(): + # Silent synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio) + for src, dst in ELEMENT_TYPE_SYNONYMS.items(): if src in el and dst not in el: el[dst] = el.pop(src) @@ -1651,6 +1788,7 @@ def emit_element(lines, el, indent): 'group': emit_group, 'input': emit_input, 'check': emit_check, + 'radio': emit_radio_button_field, 'label': emit_label, 'labelField': emit_label_field, 'table': emit_table, @@ -1807,6 +1945,69 @@ def emit_check(lines, el, name, eid, indent): lines.append(f'{indent}') +def emit_radio_button_field(lines, el, name, eid, indent): + lines.append(f'{indent}') + inner = f'{indent}\t' + + if el.get('path'): + lines.append(f'{inner}{el["path"]}') + + emit_title(lines, el, name, inner, auto=not el.get('path')) + emit_common_flags(lines, el, inner) + + tl_raw = el.get('titleLocation') + if tl_raw: + loc_map = {'none': 'None', 'left': 'Left', 'right': 'Right', 'top': 'Top', 'bottom': 'Bottom'} + tl = loc_map.get(str(tl_raw), str(tl_raw)) + else: + tl = 'None' + lines.append(f'{inner}{tl}') + + rbt = normalize_radio_button_type(el.get('radioButtonType')) + lines.append(f'{inner}{rbt}') + + if el.get('columnsCount') is not None: + lines.append(f'{inner}{el["columnsCount"]}') + + choice_list = el.get('choiceList') or [] + if choice_list: + lines.append(f'{inner}') + item_indent = f'{inner}\t' + for item in choice_list: + if not isinstance(item, dict): + continue + val_raw = item.get('value', item.get('значение')) + has_pres = any(k in item for k in ('presentation', 'представление', 'title')) + pres_raw = item.get('presentation', item.get('представление', item.get('title'))) + + norm = normalize_choice_value(val_raw) + + if not has_pres: + if norm['xsi_type'] == 'xr:DesignTimeRef': + tail = norm['text'].split('.')[-1] + pres_raw = title_from_name(tail) + else: + pres_raw = norm['text'] + + lines.append(f'{item_indent}') + val_indent = f'{item_indent}\t' + lines.append(f'{val_indent}') + lines.append(f'{val_indent}0') + lines.append(f'{val_indent}') + emit_choice_presentation(lines, pres_raw, f'{val_indent}\t') + lines.append(f'{val_indent}\t{esc_xml(norm["text"])}') + lines.append(f'{val_indent}') + lines.append(f'{item_indent}') + lines.append(f'{inner}') + + emit_companion(lines, 'ContextMenu', f'{name}КонтекстноеМеню', inner) + emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner) + + emit_events(lines, el, name, inner, 'radio') + + lines.append(f'{indent}') + + def emit_label(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' diff --git a/tests/skills/cases/form-compile/radio-auto-enum.json b/tests/skills/cases/form-compile/radio-auto-enum.json new file mode 100644 index 00000000..b9389c1b --- /dev/null +++ b/tests/skills/cases/form-compile/radio-auto-enum.json @@ -0,0 +1,45 @@ +{ + "name": "RadioButtonField Auto + ссылки на перечисление с мультиязычной презентацией", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Enum", "name": "СпособыКурса", "values": [ + { "name": "Авто" }, { "name": "Ручной" } + ]}, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "DataProcessor", "name": "ТестРадио", "attributes": [ + { "name": "СпособКурса", "type": "EnumRef.СпособыКурса" } + ]}, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "form-add/scripts/form-add", + "args": { "-ObjectPath": "{workDir}/DataProcessors/ТестРадио.xml", "-FormName": "Форма" } + } + ], + "params": { "outputPath": "DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml", + "input": { + "title": "Радио — Auto + Enum", + "attributes": [ + { "name": "Объект", "type": "DataProcessorObject.ТестРадио", "main": true }, + { "name": "СпособКурса", "type": "EnumRef.СпособыКурса" } + ], + "elements": [ + { + "radio": "СпособКурса", + "path": "СпособКурса", + "title": "Способ курса", + "radioButtonType": "Auto", + "columnsCount": 1, + "choiceList": [ + { "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } }, + { "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" } + ] + } + ] + } +} diff --git a/tests/skills/cases/form-compile/radio-synonyms.json b/tests/skills/cases/form-compile/radio-synonyms.json new file mode 100644 index 00000000..74a92b8b --- /dev/null +++ b/tests/skills/cases/form-compile/radio-synonyms.json @@ -0,0 +1,44 @@ +{ + "name": "RadioButtonField — синонимы (русские ключи, Перечисление., title вместо presentation)", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Enum", "name": "СпособыКурса", "values": [ + { "name": "Авто" }, { "name": "Ручной" } + ]}, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "DataProcessor", "name": "ТестСинонимы", "attributes": [ + { "name": "СпособКурса", "type": "EnumRef.СпособыКурса" } + ]}, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "form-add/scripts/form-add", + "args": { "-ObjectPath": "{workDir}/DataProcessors/ТестСинонимы.xml", "-FormName": "Форма" } + } + ], + "params": { "outputPath": "DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml", + "input": { + "title": "Радио — синонимы", + "attributes": [ + { "name": "Объект", "type": "DataProcessorObject.ТестСинонимы", "main": true }, + { "name": "СпособКурса", "type": "EnumRef.СпособыКурса" } + ], + "elements": [ + { + "ПолеПереключателя": "СпособКурса", + "path": "СпособКурса", + "title": "Способ курса", + "radioButtonType": "Переключатель", + "choiceList": [ + { "value": "Перечисление.СпособыКурса.Авто", "title": "Автоматически" }, + { "value": "Перечисление.СпособыКурса.Ручной", "title": "Вручную" } + ] + } + ] + } +} diff --git a/tests/skills/cases/form-compile/radio-tumbler-strings.json b/tests/skills/cases/form-compile/radio-tumbler-strings.json new file mode 100644 index 00000000..19accbb6 --- /dev/null +++ b/tests/skills/cases/form-compile/radio-tumbler-strings.json @@ -0,0 +1,36 @@ +{ + "name": "RadioButtonField Tumbler + строковые значения с автогенерацией презентации", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "DataProcessor", "name": "ТестТумблер", "attributes": [ + { "name": "ОтборСтрок", "type": "string(50)" } + ]}, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "form-add/scripts/form-add", + "args": { "-ObjectPath": "{workDir}/DataProcessors/ТестТумблер.xml", "-FormName": "Форма" } + } + ], + "params": { "outputPath": "DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml", + "input": { + "title": "Радио — Tumbler", + "attributes": [ + { "name": "Объект", "type": "DataProcessorObject.ТестТумблер", "main": true }, + { "name": "ОтборСтрок", "type": "string(50)" } + ], + "elements": [ + { + "radio": "ОтборСтрок", + "path": "ОтборСтрок", + "radioButtonType": "Tumbler", + "choiceList": [ + { "value": "Рекомендуемые" }, + { "value": "Все" } + ] + } + ] + } +} diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Configuration.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Configuration.xml new file mode 100644 index 00000000..e67bb82b --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + СпособыКурса + ТестРадио + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио.xml new file mode 100644 index 00000000..78fb5410 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио.xml @@ -0,0 +1,68 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + ТестРадио + + + ru + Тест радио + + + + false + DataProcessor.ТестРадио.Form.Форма + + false + + + + + + + СпособКурса + + + ru + Способ курса + + + + + d5p1:EnumRef.СпособыКурса + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + +
Форма
+
+
+
diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ObjectModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма.xml new file mode 100644 index 00000000..dffeea01 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма.xml @@ -0,0 +1,22 @@ + + +
+ + Форма + + + ru + Форма + + + + Managed + false + + PlatformApplication + MobilePlatformApplication + + + +
+
\ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..31d5522f --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml @@ -0,0 +1,78 @@ + +
+ + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Радио — Auto + Enum</v8:content> + </v8:item> + + false + + + + СпособКурса + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Способ курса</v8:content> + </v8:item> + + None + Auto + 1 + + + + 0 + + + + ru + Автоматически + + + en + Automatic + + + Enum.СпособыКурса.EnumValue.Авто + + + + + 0 + + + + ru + вручную + + + Enum.СпособыКурса.EnumValue.Ручной + + + + + + + + + + + cfg:DataProcessorObject.ТестРадио + + true + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Способ курса</v8:content> + </v8:item> + + + cfg:EnumRef.СпособыКурса + + + + diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form/Module.bsl b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form/Module.bsl new file mode 100644 index 00000000..8ead4cec --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form/Module.bsl @@ -0,0 +1,19 @@ +#Область ОбработчикиСобытийФормы + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовФормы + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +#КонецОбласти + +#Область ОбработчикиОповещений + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса.xml new file mode 100644 index 00000000..f55fded3 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса.xml @@ -0,0 +1,121 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + + СпособыКурса + + + ru + Способы курса + + + + false + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + true + BothWays + + + + + + + + Auto + + + + + Авто + + + ru + Авто + + + + + + + + Ручной + + + ru + Ручной + + + + + + + + diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Enums/СпособыКурса/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Ext/ClientApplicationInterface.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Languages/Русский.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/Configuration.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Configuration.xml new file mode 100644 index 00000000..1eb33e88 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + СпособыКурса + ТестСинонимы + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы.xml new file mode 100644 index 00000000..841accc1 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы.xml @@ -0,0 +1,68 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + ТестСинонимы + + + ru + Тест синонимы + + + + false + DataProcessor.ТестСинонимы.Form.Форма + + false + + + + + + + СпособКурса + + + ru + Способ курса + + + + + d5p1:EnumRef.СпособыКурса + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + +
Форма
+
+
+
diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ObjectModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма.xml new file mode 100644 index 00000000..dffeea01 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма.xml @@ -0,0 +1,22 @@ + + +
+ + Форма + + + ru + Форма + + + + Managed + false + + PlatformApplication + MobilePlatformApplication + + + +
+
\ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..6a2903ae --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form.xml @@ -0,0 +1,73 @@ + +
+ + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Радио — синонимы</v8:content> + </v8:item> + + false + + + + СпособКурса + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Способ курса</v8:content> + </v8:item> + + None + RadioButtons + + + + 0 + + + + ru + Автоматически + + + Enum.СпособыКурса.EnumValue.Авто + + + + + 0 + + + + ru + Вручную + + + Enum.СпособыКурса.EnumValue.Ручной + + + + + + + + + + + cfg:DataProcessorObject.ТестСинонимы + + true + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Способ курса</v8:content> + </v8:item> + + + cfg:EnumRef.СпособыКурса + + + + diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form/Module.bsl b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form/Module.bsl new file mode 100644 index 00000000..8ead4cec --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/DataProcessors/ТестСинонимы/Forms/Форма/Ext/Form/Module.bsl @@ -0,0 +1,19 @@ +#Область ОбработчикиСобытийФормы + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовФормы + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +#КонецОбласти + +#Область ОбработчикиОповещений + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса.xml new file mode 100644 index 00000000..f55fded3 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса.xml @@ -0,0 +1,121 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + + СпособыКурса + + + ru + Способы курса + + + + false + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + true + BothWays + + + + + + + + Auto + + + + + Авто + + + ru + Авто + + + + + + + + Ручной + + + ru + Ручной + + + + + + + + diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Enums/СпособыКурса/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/Ext/ClientApplicationInterface.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-synonyms/Languages/Русский.xml b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-synonyms/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Configuration.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Configuration.xml new file mode 100644 index 00000000..db203c52 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ТестТумблер + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер.xml new file mode 100644 index 00000000..a63b7a5e --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер.xml @@ -0,0 +1,72 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + ТестТумблер + + + ru + Тест тумблер + + + + false + DataProcessor.ТестТумблер.Form.Форма + + false + + + + + + + ОтборСтрок + + + ru + Отбор строк + + + + + xs:string + + 50 + Variable + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + +
Форма
+
+
+
diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ObjectModule.bsl b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма.xml new file mode 100644 index 00000000..dffeea01 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма.xml @@ -0,0 +1,22 @@ + + +
+ + Форма + + + ru + Форма + + + + Managed + false + + PlatformApplication + MobilePlatformApplication + + + +
+
\ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..f6919e89 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form.xml @@ -0,0 +1,71 @@ + +
+ + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Радио — Tumbler</v8:content> + </v8:item> + + false + + + + ОтборСтрок + None + Tumbler + + + + 0 + + + + ru + Рекомендуемые + + + Рекомендуемые + + + + + 0 + + + + ru + Все + + + Все + + + + + + + + + + + cfg:DataProcessorObject.ТестТумблер + + true + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Отбор строк</v8:content> + </v8:item> + + + xs:string + + 50 + Variable + + + + + diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form/Module.bsl b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form/Module.bsl new file mode 100644 index 00000000..8ead4cec --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/DataProcessors/ТестТумблер/Forms/Форма/Ext/Form/Module.bsl @@ -0,0 +1,19 @@ +#Область ОбработчикиСобытийФормы + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовФормы + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +#КонецОбласти + +#Область ОбработчикиОповещений + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Ext/ClientApplicationInterface.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Languages/Русский.xml b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/radio-tumbler-strings/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file From dc0382cc0662c2f8438e19b8e2a81e60ed9e3949 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 18:43:33 +0300 Subject: [PATCH 03/10] =?UTF-8?q?chore(tests):=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=81=D0=BD=D0=B0=D0=BF=D1=88?= =?UTF-8?q?=D0=BE=D1=82=D1=8B=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20meta-comp?= =?UTF-8?q?ile=20QuickChoice=20defaults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Снапшоты ссылочных реквизитов теперь содержат QuickChoice=false в соответствии с дефолтами по реальным конфигам (см. 07b2ec3). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../snapshots/catalog-item-simple/Catalogs/Валюты.xml | 2 +- .../snapshots/catalog-list-simple/Catalogs/Валюты.xml | 2 +- .../ChartsOfCharacteristicTypes/ВидыНоменклатуры.xml | 2 +- .../ChartsOfAccounts/Хозрасчетный.xml | 2 +- .../ChartsOfAccounts/Хозрасчетный.xml | 2 +- .../exchangeplan-item-simple/ExchangePlans/ОбменДанными.xml | 2 +- .../form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады.xml | 2 +- .../form-compile/snapshots/catalog-form/Catalogs/Товары.xml | 2 +- .../snapshots/dynamic-list-form/Catalogs/Товары.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты.xml index e1457298..07d20430 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-item-simple/Catalogs/Валюты.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Валюты.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты.xml b/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты.xml index ffcbc093..f60aebda 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/catalog-list-simple/Catalogs/Валюты.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Валюты.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры.xml b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры.xml index 69d9f332..09f69c39 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/ccoct-item-simple/ChartsOfCharacteristicTypes/ВидыНоменклатуры.xml @@ -277,7 +277,7 @@ Auto InDialog - true + false BothWays ChartOfCharacteristicTypes.ВидыНоменклатуры.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный.xml b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный.xml index 55c09e6f..898933b6 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-item-simple/ChartsOfAccounts/Хозрасчетный.xml @@ -426,7 +426,7 @@ Auto - true + false BothWays ChartOfAccounts.Хозрасчетный.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный.xml b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный.xml index 6ec0ad82..2145608e 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/chartofaccounts-list-simple/ChartsOfAccounts/Хозрасчетный.xml @@ -426,7 +426,7 @@ Auto - true + false BothWays ChartOfAccounts.Хозрасчетный.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными.xml b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными.xml index 2058d710..6ff4bd34 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/exchangeplan-item-simple/ExchangePlans/ОбменДанными.xml @@ -226,7 +226,7 @@ false false - true + false BothWays ExchangePlan.ОбменДанными.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады.xml b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады.xml index 71395fdd..c346e75b 100644 --- a/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады.xml +++ b/tests/skills/cases/form-compile/snapshots/auto-cmd-bar/Catalogs/Бригады.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Бригады.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары.xml b/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары.xml index a29ddd70..53dd9147 100644 --- a/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары.xml +++ b/tests/skills/cases/form-compile/snapshots/catalog-form/Catalogs/Товары.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Товары.StandardAttribute.Description diff --git a/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары.xml b/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары.xml index f51c2bff..fc0e9a99 100644 --- a/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары.xml +++ b/tests/skills/cases/form-compile/snapshots/dynamic-list-form/Catalogs/Товары.xml @@ -287,7 +287,7 @@ Auto InDialog - true + false BothWays Catalog.Товары.StandardAttribute.Description From 5690c82ab8da05a4bdd8c477d2075c4db7416c50 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 18:45:00 +0300 Subject: [PATCH 04/10] =?UTF-8?q?docs(form-dsl-spec):=20radio=20(RadioButt?= =?UTF-8?q?onField)=20=D0=B2=20=D1=81=D0=BF=D0=B5=D1=86=D0=B8=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=D1=86=D0=B8=D0=B8=20DSL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/form-dsl-spec.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index e847354d..32e11c3b 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -199,6 +199,35 @@ | `path` | string | DataPath | | `titleLocation` | string | Расположение заголовка | +#### radio — RadioButtonField + +```json +{ + "radio": "СпособКурса", + "path": "Объект.СпособУстановкиКурса", + "radioButtonType": "Auto", + "choiceList": [ + { "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": "автоматически" }, + { "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": { "ru": "вручную", "en": "manual" } } + ] +} +``` + +| Свойство | Тип | Описание | +|----------|-----|----------| +| `path` | string | DataPath | +| `radioButtonType` | string | `Auto` (по умолчанию), `RadioButtons`, `Tumbler` | +| `columnsCount` | int | Число колонок раскладки | +| `titleLocation` | string | Расположение заголовка (компилятор подставляет `None`, если не задан) | +| `choiceList` | array | Варианты выбора: массив `{ value, presentation }` | + +`choiceList[*]`: + +| Свойство | Тип | Описание | +|----------|-----|----------| +| `value` | string/number/bool | Значение варианта. Для перечисления — `"Enum.ИмяТипа.EnumValue.ИмяЗначения"` (xsi:type автоматически: `xr:DesignTimeRef` / `xs:string` / `xs:decimal` / `xs:boolean`) | +| `presentation` | string или object | Текст рядом с переключателем. Строка → ru; объект `{ru, en, ...}` → мультиязык. Если не задано — выводится из имени значения | + #### label — LabelDecoration ```json @@ -437,6 +466,7 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs | UsualGroup | ExtendedTooltip | | InputField | ContextMenu, ExtendedTooltip | | CheckBoxField | ContextMenu, ExtendedTooltip | +| RadioButtonField | ContextMenu, ExtendedTooltip | | LabelDecoration | ContextMenu, ExtendedTooltip | | LabelField | ContextMenu, ExtendedTooltip | | PictureDecoration | ContextMenu, ExtendedTooltip | From 60de083a057e0698c7a3c3090bf3824962cff979 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 18:48:29 +0300 Subject: [PATCH 05/10] =?UTF-8?q?docs(1c-form-spec):=20RadioButtonField=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D1=91=D0=BD=20=D0=B2?= =?UTF-8?q?=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8=D0=BA=D1=83?= =?UTF-8?q?=20(~8.5%=20=D1=84=D0=BE=D1=80=D0=BC=20=D0=91=D0=9F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Замер по acc_8.3.24: 658 из 7723 форм содержат RadioButtonField (всего 1389 элементов). Раньше ошибочно числился среди не встреченных. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/1c-form-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/1c-form-spec.md b/docs/1c-form-spec.md index df8724bf..40663740 100644 --- a/docs/1c-form-spec.md +++ b/docs/1c-form-spec.md @@ -1199,6 +1199,7 @@ ChildItems | Popup | ~40% | | PictureDecoration | ~40% | | PictureField | ~15% | +| RadioButtonField | ~8.5% | | CalendarField | ~5% | --- @@ -1207,7 +1208,6 @@ ChildItems Следующие элементы управления существуют в платформе, но не использованы в БП 3.0: -- `RadioButtonField` - `TrackBarField` - `ProgressBarField` - `TextDocumentField` From 6c60398406f8f7b65056210d1da3ec5388156f3f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 3 May 2026 19:41:43 +0300 Subject: [PATCH 06/10] =?UTF-8?q?feat(form-compile):=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE-=D0=B2=D0=B8=D0=B4=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D1=82=D1=83=20=D0=90=D0=9A=D0=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Кнопки внутри cmdBar/autoCmdBar/popup автоматически получают CommandBarButton (или CommandBarHyperlink при type="hyperlink") — указывать вид вручную не нужно. Резолвер прощающий: принимает и короткие DSL-формы, и XML-имена в любом контексте. Пример «Диалог загрузки файла» в SKILL.md и тест-кейс file-dialog переведены на нативный паттерн с autoCmdBar вместо отдельной горизонтальной группы кнопок внизу формы. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/form-compile/SKILL.md | 8 ++- .../form-compile/scripts/form-compile.ps1 | 55 ++++++++++++---- .../form-compile/scripts/form-compile.py | 51 ++++++++++++--- .../cases/form-compile/file-dialog.json | 2 +- .../Бригады/Forms/ФормаСписка/Ext/Form.xml | 1 + .../Команды/Forms/Форма/Ext/Form.xml | 2 + .../ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml | 63 +++++++++---------- .../Тест/Forms/Форма/Ext/Form.xml | 2 + 8 files changed, 125 insertions(+), 59 deletions(-) diff --git a/.claude/skills/form-compile/SKILL.md b/.claude/skills/form-compile/SKILL.md index 3a2dd1cf..75d068b2 100644 --- a/.claude/skills/form-compile/SKILL.md +++ b/.claude/skills/form-compile/SKILL.md @@ -228,7 +228,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | `command` | Имя команды формы → `Form.Command.Имя` | | `stdCommand` | Стандартная команда: `"Close"` → `Form.StandardCommand.Close`; с точкой: `"Товары.Add"` → `Form.Item.Товары.StandardCommand.Add` | | `defaultButton: true` | Кнопка по умолчанию | -| `type` | `"usual"`, `"hyperlink"`, `"commandBar"` | +| `type` | `"usual"`, `"hyperlink"`. По умолчанию `"usual"`. Конкретный XML-вид (UsualButton/Hyperlink/CommandBarButton/CommandBarHyperlink) подставляется автоматически по контексту | | `picture` | Картинка кнопки | | `representation` | `"Auto"`, `"Text"`, `"Picture"`, `"PictureAndText"` | | `locationInCommandBar` | `"Auto"`, `"InCommandBar"`, `"InAdditionalSubmenu"` | @@ -259,6 +259,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile ]} ``` +Кнопки основных действий формы и подменю размещают здесь, а не в отдельной группе на форме. Отдельной кнопкой в layout — только если она логически привязана к конкретному полю или группе. + ### Выпадающее меню (popup) | Ключ | Описание | @@ -401,9 +403,9 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile { "check": "ПерваяСтрокаЗаголовок", "path": "ПерваяСтрокаЗаголовок" } ]}, { "input": "Результат", "path": "Результат", "multiLine": true, "height": 8, "readOnly": true, "title": "Лог" }, - { "group": "horizontal", "name": "ГруппаКнопок", "children": [ + { "autoCmdBar": "ФормаКоманднаяПанель", "children": [ { "button": "Загрузить", "command": "Загрузить", "defaultButton": true }, - { "button": "Закрыть", "stdCommand": "Close" } + { "button": "Закрыть", "stdCommand": "Close" } ]} ], "attributes": [ diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 9e2871ce..975ea90e 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.16 — Compile 1C managed form from JSON or object metadata +# form-compile v1.17 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1825,7 +1825,7 @@ function Emit-Companion { } function Emit-Element { - param($el, [string]$indent) + param($el, [string]$indent, [bool]$inCmdBar = $false) # Silent synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio). # Maps any synonym to canonical short DSL key. @@ -1946,7 +1946,7 @@ function Emit-Element { "table" { Emit-Table -el $el -name $name -id $id -indent $indent } "pages" { Emit-Pages -el $el -name $name -id $id -indent $indent } "page" { Emit-Page -el $el -name $name -id $id -indent $indent } - "button" { Emit-Button -el $el -name $name -id $id -indent $indent } + "button" { Emit-Button -el $el -name $name -id $id -indent $indent -inCmdBar $inCmdBar } "picture" { Emit-PictureDecoration -el $el -name $name -id $id -indent $indent } "picField" { Emit-PictureField -el $el -name $name -id $id -indent $indent } "calendar" { Emit-Calendar -el $el -name $name -id $id -indent $indent } @@ -2538,19 +2538,48 @@ function Emit-Page { } function Emit-Button { - param($el, [string]$name, [int]$id, [string]$indent) + param($el, [string]$name, [int]$id, [string]$indent, [bool]$inCmdBar = $false) X "$indent 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 bcfe9ada..e023bcb8 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 @@ -7,16 +7,30 @@ false - + + + + + + ПриСозданииНаСервере - + Horizontal - + - + ИмяФайла <v8:item> @@ -30,21 +44,21 @@ <v8:content>Выберите файл...</v8:content> </v8:item> </InputHint> - <ContextMenu name="ИмяФайлаКонтекстноеМеню" id="4"/> - <ExtendedTooltip name="ИмяФайлаРасширеннаяПодсказка" id="5"/> + <ContextMenu name="ИмяФайлаКонтекстноеМеню" id="8"/> + <ExtendedTooltip name="ИмяФайлаРасширеннаяПодсказка" id="9"/> <Events> <Event name="StartChoice">ИмяФайлаНачалоВыбора</Event> </Events> </InputField> - <CheckBoxField name="ПерваяСтрокаЗаголовок" id="6"> + <CheckBoxField name="ПерваяСтрокаЗаголовок" id="10"> <DataPath>ПерваяСтрокаЗаголовок</DataPath> <TitleLocation>Right</TitleLocation> - <ContextMenu name="ПерваяСтрокаЗаголовокКонтекстноеМеню" id="7"/> - <ExtendedTooltip name="ПерваяСтрокаЗаголовокРасширеннаяПодсказка" id="8"/> + <ContextMenu name="ПерваяСтрокаЗаголовокКонтекстноеМеню" id="11"/> + <ExtendedTooltip name="ПерваяСтрокаЗаголовокРасширеннаяПодсказка" id="12"/> </CheckBoxField> </ChildItems> </UsualGroup> - <InputField name="Результат" id="9"> + <InputField name="Результат" id="13"> <DataPath>Результат</DataPath> <Title> <v8:item> @@ -56,33 +70,18 @@ <MultiLine>true</MultiLine> <AutoMaxWidth>false</AutoMaxWidth> <Height>8</Height> - <ContextMenu name="РезультатКонтекстноеМеню" id="10"/> - <ExtendedTooltip name="РезультатРасширеннаяПодсказка" id="11"/> + <ContextMenu name="РезультатКонтекстноеМеню" id="14"/> + <ExtendedTooltip name="РезультатРасширеннаяПодсказка" id="15"/> </InputField> - <UsualGroup name="ГруппаКнопок" id="12"> - <Group>Horizontal</Group> - <ExtendedTooltip name="ГруппаКнопокРасширеннаяПодсказка" id="13"/> - <ChildItems> - <Button name="Загрузить" id="14"> - <CommandName>Form.Command.Загрузить</CommandName> - <DefaultButton>true</DefaultButton> - <ExtendedTooltip name="ЗагрузитьРасширеннаяПодсказка" id="15"/> - </Button> - <Button name="Закрыть" id="16"> - <CommandName>Form.StandardCommand.Close</CommandName> - <ExtendedTooltip name="ЗакрытьРасширеннаяПодсказка" id="17"/> - </Button> - </ChildItems> - </UsualGroup> </ChildItems> <Attributes> - <Attribute name="Объект" id="18"> + <Attribute name="Объект" id="16"> <Type> <v8:Type>cfg:DataProcessorObject.ЗагрузкаИзФайла</v8:Type> </Type> <MainAttribute>true</MainAttribute> </Attribute> - <Attribute name="ИмяФайла" id="19"> + <Attribute name="ИмяФайла" id="17"> <Title> <v8:item> <v8:lang>ru</v8:lang> @@ -97,7 +96,7 @@ </v8:StringQualifiers> </Type> </Attribute> - <Attribute name="ПерваяСтрокаЗаголовок" id="20"> + <Attribute name="ПерваяСтрокаЗаголовок" id="18"> <Title> <v8:item> <v8:lang>ru</v8:lang> @@ -108,7 +107,7 @@ <v8:Type>xs:boolean</v8:Type> </Type> </Attribute> - <Attribute name="Результат" id="21"> + <Attribute name="Результат" id="19"> <Title> <v8:item> <v8:lang>ru</v8:lang> @@ -125,7 +124,7 @@ </Attribute> </Attributes> <Commands> - <Command name="Загрузить" id="22"> + <Command name="Загрузить" id="20"> <Title> <v8:item> <v8:lang>ru</v8:lang> 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 3d2e6f3b..7347dec6 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 @@ -10,6 +10,7 @@ <AutoCommandBar name="ФормаКоманднаяПанель" id="-1"> <ChildItems> <Button name="Кн1" id="1"> + <Type>CommandBarButton</Type> <CommandName>Form.Command.Кн1</CommandName> <ExtendedTooltip name="Кн1РасширеннаяПодсказка" id="2"/> </Button> @@ -24,6 +25,7 @@ <CommandBar name="ДопПанель" id="6"> <ChildItems> <Button name="Кн2" id="7"> + <Type>CommandBarButton</Type> <CommandName>Form.Command.Кн2</CommandName> <ExtendedTooltip name="Кн2РасширеннаяПодсказка" id="8"/> </Button> From 3d80191ca7aada3929794618140b23bd97466183 Mon Sep 17 00:00:00 2001 From: Nick Shirokov <nick_4312@mail.ru> Date: Sun, 3 May 2026 19:58:36 +0300 Subject: [PATCH 07/10] =?UTF-8?q?feat(form-compile):=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20maxWidth/maxHeight=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20input=20=D0=B8=20label?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлены численные maxWidth/maxHeight (XML <MaxWidth>/<MaxHeight>) — типичный приём для ограничения растяжения поля при autoMaxWidth: false. До этого DSL знал только булев autoMaxWidth, и ограничить ширину числом было невозможно. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --- .claude/skills/form-compile/SKILL.md | 3 ++- .claude/skills/form-compile/scripts/form-compile.ps1 | 7 ++++++- .claude/skills/form-compile/scripts/form-compile.py | 11 ++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.claude/skills/form-compile/SKILL.md b/.claude/skills/form-compile/SKILL.md index 75d068b2..8ed65552 100644 --- a/.claude/skills/form-compile/SKILL.md +++ b/.claude/skills/form-compile/SKILL.md @@ -126,7 +126,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | `skipOnInput: true` | Пропускать при обходе Tab | | | `inputHint` | Подсказка в пустом поле | `"Введите наименование..."` | | `width` / `height` | Размер | числа | -| `autoMaxWidth: false` | Отключить авто-ширину | для фиксированных полей | +| `autoMaxWidth: false` | Снять авто-ограничение ширины (поле растянется) | | +| `maxWidth` / `maxHeight` | Жёсткое ограничение размера | числа; обычно вместе с `autoMaxWidth: false` | | `horizontalStretch: true` | Растягивать по ширине | | ### Чекбокс (check) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 975ea90e..e745f072 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.17 — Compile 1C managed form from JSON or object metadata +# form-compile v1.18 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1904,6 +1904,7 @@ function Emit-Element { # layout "titleLocation"=1;"representation"=1;"width"=1;"height"=1 "horizontalStretch"=1;"verticalStretch"=1;"autoMaxWidth"=1;"autoMaxHeight"=1 + "maxWidth"=1;"maxHeight"=1 # input-specific "multiLine"=1;"passwordMode"=1;"choiceButton"=1;"clearButton"=1 "spinButton"=1;"dropListButton"=1;"markIncomplete"=1;"skipOnInput"=1;"inputHint"=1 @@ -2095,7 +2096,9 @@ function Emit-Input { } elseif ($el.multiLine -eq $true) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" } + if ($null -ne $el.maxWidth) { X "$inner<MaxWidth>$($el.maxWidth)</MaxWidth>" } if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" } + if ($null -ne $el.maxHeight) { X "$inner<MaxHeight>$($el.maxHeight)</MaxHeight>" } if ($el.width) { X "$inner<Width>$($el.width)</Width>" } if ($el.height) { X "$inner<Height>$($el.height)</Height>" } if ($el.horizontalStretch -eq $true) { X "$inner<HorizontalStretch>true</HorizontalStretch>" } @@ -2376,7 +2379,9 @@ function Emit-Label { if ($el.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" } if ($el.autoMaxWidth -eq $false) { X "$inner<AutoMaxWidth>false</AutoMaxWidth>" } + if ($null -ne $el.maxWidth) { X "$inner<MaxWidth>$($el.maxWidth)</MaxWidth>" } if ($el.autoMaxHeight -eq $false) { X "$inner<AutoMaxHeight>false</AutoMaxHeight>" } + if ($null -ne $el.maxHeight) { X "$inner<MaxHeight>$($el.maxHeight)</MaxHeight>" } if ($el.width) { X "$inner<Width>$($el.width)</Width>" } if ($el.height) { X "$inner<Height>$($el.height)</Height>" } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 1045fb0b..e94c5da4 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.17 — Compile 1C managed form from JSON or object metadata +# form-compile v1.18 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1346,6 +1346,7 @@ KNOWN_KEYS = { "on", "handlers", "titleLocation", "representation", "width", "height", "horizontalStretch", "verticalStretch", "autoMaxWidth", "autoMaxHeight", + "maxWidth", "maxHeight", "multiLine", "passwordMode", "choiceButton", "clearButton", "spinButton", "dropListButton", "markIncomplete", "skipOnInput", "inputHint", "hyperlink", @@ -1903,8 +1904,12 @@ def emit_input(lines, el, name, eid, indent): lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>') elif el.get('multiLine') is True: lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>') + if el.get('maxWidth') is not None: + lines.append(f'{inner}<MaxWidth>{el["maxWidth"]}</MaxWidth>') if el.get('autoMaxHeight') is False: lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>') + if el.get('maxHeight') is not None: + lines.append(f'{inner}<MaxHeight>{el["maxHeight"]}</MaxHeight>') if el.get('width'): lines.append(f'{inner}<Width>{el["width"]}</Width>') if el.get('height'): @@ -2031,8 +2036,12 @@ def emit_label(lines, el, name, eid, indent): lines.append(f'{inner}<Hyperlink>true</Hyperlink>') if el.get('autoMaxWidth') is False: lines.append(f'{inner}<AutoMaxWidth>false</AutoMaxWidth>') + if el.get('maxWidth') is not None: + lines.append(f'{inner}<MaxWidth>{el["maxWidth"]}</MaxWidth>') if el.get('autoMaxHeight') is False: lines.append(f'{inner}<AutoMaxHeight>false</AutoMaxHeight>') + if el.get('maxHeight') is not None: + lines.append(f'{inner}<MaxHeight>{el["maxHeight"]}</MaxHeight>') if el.get('width'): lines.append(f'{inner}<Width>{el["width"]}</Width>') if el.get('height'): From ebf92a87808044d65e9dfa6bfd2532268c9d0716 Mon Sep 17 00:00:00 2001 From: Nick Shirokov <nick_4312@mail.ru> Date: Sun, 3 May 2026 20:07:18 +0300 Subject: [PATCH 08/10] =?UTF-8?q?feat(form-compile):=20=D1=81=D0=B2=D0=BE?= =?UTF-8?q?=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20collapsed=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=81=D0=B2=D0=BE=D1=80=D0=B0=D1=87=D0=B8=D0=B2=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=D1=85=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлен ключ collapsed (для group=collapsible) → <Collapsed>true</Collapsed>: группа создаётся уже свёрнутой. Раньше DSL умел только включать сворачиваемое поведение, но начальное состояние задать было нельзя. Также уточнено описание united: оно про выравнивание левого края полей ввода (сквозное/локальное), а не про объединение рамок группы. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --- .claude/skills/form-compile/SKILL.md | 3 ++- .claude/skills/form-compile/scripts/form-compile.ps1 | 5 +++-- .claude/skills/form-compile/scripts/form-compile.py | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.claude/skills/form-compile/SKILL.md b/.claude/skills/form-compile/SKILL.md index 8ed65552..6e0f8ffc 100644 --- a/.claude/skills/form-compile/SKILL.md +++ b/.claude/skills/form-compile/SKILL.md @@ -183,7 +183,8 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | Ключ | Описание | |------|----------| | `showTitle: true` | Показывать заголовок группы | -| `united: false` | Не объединять рамку | +| `united: false` | Левый край полей ввода выравнивается только в пределах этой группы (по умолчанию `true` — сквозное выравнивание по самому длинному заголовку, в т.ч. с соседними группами) | +| `collapsed: true` | Только для `"group": "collapsible"` — группа создаётся свёрнутой | | `representation` | `"none"`, `"normal"`, `"weak"`, `"strong"` | | `children: [...]` | Вложенные элементы | diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index e745f072..8a3cd3f9 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.18 — Compile 1C managed form from JSON or object metadata +# form-compile v1.19 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1911,7 +1911,7 @@ function Emit-Element { # label/hyperlink "hyperlink"=1 # group-specific - "showTitle"=1;"united"=1 + "showTitle"=1;"united"=1;"collapsed"=1 # hierarchy "children"=1;"columns"=1 # table-specific @@ -2022,6 +2022,7 @@ function Emit-Group { if ($groupVal -eq "collapsible") { X "$inner<Group>Vertical</Group>" X "$inner<Behavior>Collapsible</Behavior>" + if ($el.collapsed -eq $true) { X "$inner<Collapsed>true</Collapsed>" } } # Representation diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index e94c5da4..a0afda00 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.18 — Compile 1C managed form from JSON or object metadata +# form-compile v1.19 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1350,7 +1350,7 @@ KNOWN_KEYS = { "multiLine", "passwordMode", "choiceButton", "clearButton", "spinButton", "dropListButton", "markIncomplete", "skipOnInput", "inputHint", "hyperlink", - "showTitle", "united", + "showTitle", "united", "collapsed", "children", "columns", "changeRowSet", "changeRowOrder", "header", "footer", "commandBarLocation", "searchStringLocation", @@ -1833,6 +1833,8 @@ def emit_group(lines, el, name, eid, indent): if group_val == 'collapsible': lines.append(f'{inner}<Group>Vertical</Group>') lines.append(f'{inner}<Behavior>Collapsible</Behavior>') + if el.get('collapsed') is True: + lines.append(f'{inner}<Collapsed>true</Collapsed>') # Representation if el.get('representation'): From f3466e19fdc37954c030e48daabcc192f0098fe7 Mon Sep 17 00:00:00 2001 From: Nick Shirokov <nick_4312@mail.ru> Date: Sun, 3 May 2026 20:10:10 +0300 Subject: [PATCH 09/10] =?UTF-8?q?docs(form-patterns):=20=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20form-c?= =?UTF-8?q?ompile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Архетипы «Форма обработки» и «Мастер»: кнопки действий перенесены с нижней горизонтальной группы на главную АКП формы (autoCmdBar) - Конвенция «ГруппаКнопок» заменена на «ФормаКоманднаяПанель» - Принцип компоновки №3: уточнено, что кнопки идут на АКП - Сворачиваемые группы: исправлен пример — корректный DSL (group: collapsible, collapsed: true) вместо несуществующих ключей behavior/collapsed на vertical-группе - Полный пример формы обработки переписан под autoCmdBar - Из свойств мастера убран commandBarLocation: None (не нужен, когда мы сами наполняем АКП) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --- .claude/skills/form-patterns/SKILL.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.claude/skills/form-patterns/SKILL.md b/.claude/skills/form-patterns/SKILL.md index 6c4bf3e8..81d2a483 100644 --- a/.claude/skills/form-patterns/SKILL.md +++ b/.claude/skills/form-patterns/SKILL.md @@ -41,9 +41,9 @@ allowed-tools: [] ├─ Информационные надписи (label, hyperlink) Рабочая область ├─ Таблица данных или Pages с вкладками -Кнопки действий -├─ Выполнить / Применить (defaultButton) -├─ Закрыть (stdCommand: Close) +Главная АКП формы (autoCmdBar) +├─ Выполнить / Применить (defaultButton: true) +└─ Закрыть (stdCommand: Close) ``` **События:** OnCreateAtServer, OnOpen, NotificationProcessing @@ -90,12 +90,12 @@ allowed-tools: [] ├─ Шаг1: описание + параметры ├─ Шаг2: основная работа └─ Шаг3: результат -Кнопки (horizontal) -├─ Назад (command), Далее (command, defaultButton), Выполнить (command) +Главная АКП формы (autoCmdBar) +├─ Назад, Далее (defaultButton: true), Выполнить └─ Закрыть (stdCommand: Close) ``` -**Свойства:** windowOpeningMode=LockOwnerWindow, commandBarLocation=None +**Свойства:** windowOpeningMode=LockOwnerWindow --- @@ -111,7 +111,7 @@ allowed-tools: [] | Номер+Дата | `ГруппаНомерДата` | horizontal | | Подвал | `ГруппаПодвал` | vertical | | Итоги | `ГруппаИтоги` | horizontal | -| Кнопки | `ГруппаКнопок` | horizontal | +| Главная АКП формы | `ФормаКоманднаяПанель` | autoCmdBar | | Страницы | `ГруппаСтраницы` / `Страницы` | pages | | Предупреждение | `ГруппаПредупреждение` | horizontal, visible:false | | Доп. секция | `ГруппаДополнительно` / `ГруппаПрочее` | vertical, collapse | @@ -150,7 +150,7 @@ allowed-tools: [] 1. **Порядок чтения.** Сверху вниз, слева направо. Самое важное — вверху. 2. **Двухколоночная шапка.** Основные реквизиты слева (контрагент, склад), организационные справа (организация, подразделение). -3. **Кнопки действий внизу.** Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя. +3. **Кнопки действий — на главной АКП формы** (`autoCmdBar`), не в отдельной группе на форме. Главная кнопка — `defaultButton: true`. Закрыть — всегда последняя. 4. **Таблицы — основная область.** Табличные части занимают большую часть формы, обычно на Pages. 5. **Итоги рядом с таблицей.** В подвале, горизонтальная группа, все поля readOnly. 6. **Фильтры — отдельная зона.** Над списком, alwaysHorizontal, пара «флажок + поле» на каждый фильтр. @@ -166,8 +166,8 @@ allowed-tools: [] Для необязательных секций (подписи, дополнительно, прочее): ```json -{ "group": "vertical", "name": "ГруппаПодписи", "title": "Подписи", - "behavior": "Collapsible", "collapsed": true, "children": [...] } +{ "group": "collapsible", "name": "ГруппаПодписи", "title": "Подписи", + "collapsed": true, "children": [...] } ``` ### Баннер-предупреждение @@ -233,7 +233,7 @@ allowed-tools: [] { "input": "ДанныеКоличество", "path": "Объект.Данные.Количество", "on": ["OnChange"] }, { "input": "ДанныеСумма", "path": "Объект.Данные.Сумма", "readOnly": true } ]}, - { "group": "horizontal", "name": "ГруппаКнопок", "children": [ + { "autoCmdBar": "ФормаКоманднаяПанель", "children": [ { "button": "Загрузить", "command": "Загрузить", "title": "Загрузить из файла", "defaultButton": true }, { "button": "Очистить", "command": "Очистить", "title": "Очистить таблицу" }, { "button": "Закрыть", "stdCommand": "Close" } From 4f9d9aee97b65e58c3b247f23ef55985ca558d58 Mon Sep 17 00:00:00 2001 From: Nick Shirokov <nick_4312@mail.ru> Date: Mon, 4 May 2026 11:48:35 +0300 Subject: [PATCH 10/10] =?UTF-8?q?feat(form-compile):=20=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=BF=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D0=BD=D0=BE=D0=BA=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D1=86=D1=8B=20(ColumnGroup)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Новый DSL-ключ columnGroup со значением-ориентацией horizontal/vertical/inCell для элемента <ColumnGroup> внутри columns таблицы. Поддерживает вложение, showTitle/showInHeader/width, тихие синонимы ColumnGroup и ГруппаКолонок. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --- .claude/skills/form-compile/SKILL.md | 30 +++++++++++ .../form-compile/scripts/form-compile.ps1 | 53 +++++++++++++++++-- .../form-compile/scripts/form-compile.py | 47 ++++++++++++++-- docs/form-dsl-spec.md | 29 +++++++++- .../cases/form-compile/column-group.json | 40 ++++++++++++++ 5 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 tests/skills/cases/form-compile/column-group.json diff --git a/.claude/skills/form-compile/SKILL.md b/.claude/skills/form-compile/SKILL.md index 6e0f8ffc..564a56fb 100644 --- a/.claude/skills/form-compile/SKILL.md +++ b/.claude/skills/form-compile/SKILL.md @@ -62,6 +62,7 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | DSL ключ | XML элемент | Значение ключа | |--------------|-------------------|---------------------------------------------------| | `"group"` | UsualGroup | `"horizontal"` / `"vertical"` / `"alwaysHorizontal"` / `"alwaysVertical"` / `"collapsible"` | +| `"columnGroup"` | ColumnGroup | `"horizontal"` / `"vertical"` / `"inCell"` — только внутри `columns` таблицы | | `"input"` | InputField | имя элемента | | `"check"` | CheckBoxField | имя | | `"radio"` | RadioButtonField | имя | @@ -210,6 +211,35 @@ powershell.exe -NoProfile -File .claude/skills/form-compile/scripts/form-compile | `rowPictureDataPath` | Путь к картинке строки (напр. `"Список.DefaultPicture"`) | | `tableAutofill: false` | Управление Autofill внутреннего AutoCommandBar | +Колонки можно группировать через `columnGroup` (см. ниже). + +### Группа колонок (columnGroup) + +Используется только внутри `columns` таблицы. Значение ключа задаёт ориентацию: `"horizontal"`, `"vertical"`, `"inCell"` (склеивает колонки в одну ячейку шапки). Допускается вложение `columnGroup` в `columnGroup`. + +| Ключ | Описание | +|------|----------| +| `name` | Имя элемента (рекомендуется задавать явно) | +| `title` | Заголовок группы | +| `showTitle: false` | Скрыть заголовок | +| `showInHeader: true/false` | Показывать ли группу в шапке таблицы | +| `width` | Ширина | +| `horizontalStretch: false` | Растягивание | +| `children: [...]` | Колонки внутри группы (`input`, `labelField`, `picField`, вложенный `columnGroup` …) | + +```json +{ "table": "Список", "path": "Список", "columns": [ + { "columnGroup": "horizontal", "name": "ГруппаДата", "title": "Срок", "children": [ + { "input": "СрокИсполнения", "path": "Список.СрокИсполнения" }, + { "labelField": "Просрочено", "path": "Список.Просрочено" } + ]}, + { "columnGroup": "inCell", "name": "ГруппаИсполнитель", "showInHeader": true, "children": [ + { "input": "Исполнитель", "path": "Список.Исполнитель" } + ]}, + { "input": "Комментарий", "path": "Список.Комментарий" } +]} +``` + ### Страницы (pages + page) | Ключ (pages) | Описание | diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 8a3cd3f9..1e2ca8aa 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.19 — Compile 1C managed form from JSON or object metadata +# form-compile v1.20 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1853,6 +1853,8 @@ function Emit-Element { "UsualGroup" = "group" "Группа" = "group" "ОбычнаяГруппа" = "group" + "ColumnGroup" = "columnGroup" + "ГруппаКолонок" = "columnGroup" "Pages" = "pages" "ГруппаСтраниц" = "pages" "Page" = "page" @@ -1876,7 +1878,7 @@ function Emit-Element { $typeKey = $null $xmlTag = $null - foreach ($key in @("group","input","check","radio","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) { + foreach ($key in @("columnGroup","group","input","check","radio","label","labelField","table","pages","page","button","picture","picField","calendar","cmdBar","popup")) { if ($el.$key -ne $null) { $typeKey = $key break @@ -1891,8 +1893,10 @@ function Emit-Element { # Validate known keys — warn about typos and unknown properties $knownKeys = @{ # type keys - "group"=1;"input"=1;"check"=1;"radio"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1 + "group"=1;"columnGroup"=1;"input"=1;"check"=1;"radio"=1;"label"=1;"labelField"=1;"table"=1;"pages"=1;"page"=1 "button"=1;"picture"=1;"picField"=1;"calendar"=1;"cmdBar"=1;"popup"=1 + # columnGroup-specific + "showInHeader"=1 # radio-specific "radioButtonType"=1;"choiceList"=1;"columnsCount"=1 # naming & binding @@ -1939,6 +1943,7 @@ function Emit-Element { switch ($typeKey) { "group" { Emit-Group -el $el -name $name -id $id -indent $indent } + "columnGroup" { Emit-ColumnGroup -el $el -name $name -id $id -indent $indent } "input" { Emit-Input -el $el -name $name -id $id -indent $indent } "check" { Emit-Check -el $el -name $name -id $id -indent $indent } "radio" { Emit-Radio -el $el -name $name -id $id -indent $indent } @@ -2060,6 +2065,48 @@ function Emit-Group { X "$indent</UsualGroup>" } +function Emit-ColumnGroup { + param($el, [string]$name, [int]$id, [string]$indent) + + X "$indent<ColumnGroup name=`"$name`" id=`"$id`">" + $inner = "$indent`t" + + Emit-Title -el $el -name $name -indent $inner + + # Group orientation (horizontal / vertical / inCell — последнее только здесь) + $groupVal = "$($el.columnGroup)" + $orientation = switch ($groupVal) { + "horizontal" { "Horizontal" } + "vertical" { "Vertical" } + "inCell" { "InCell" } + default { $null } + } + if ($orientation) { X "$inner<Group>$orientation</Group>" } + + if ($el.showTitle -eq $false) { X "$inner<ShowTitle>false</ShowTitle>" } + if ($null -ne $el.showInHeader) { + $shVal = if ($el.showInHeader) { "true" } else { "false" } + X "$inner<ShowInHeader>$shVal</ShowInHeader>" + } + if ($el.width) { X "$inner<Width>$($el.width)</Width>" } + + Emit-CommonFlags -el $el -indent $inner + + # Companion: ExtendedTooltip + Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner + + # Children + if ($el.children -and $el.children.Count -gt 0) { + X "$inner<ChildItems>" + foreach ($child in $el.children) { + Emit-Element -el $child -indent "$inner`t" + } + X "$inner</ChildItems>" + } + + X "$indent</ColumnGroup>" +} + function Emit-Input { param($el, [string]$name, [int]$id, [string]$indent) diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index a0afda00..992c83f3 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.19 — Compile 1C managed form from JSON or object metadata +# form-compile v1.20 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1338,8 +1338,9 @@ KNOWN_FORM_EVENTS = [ ] KNOWN_KEYS = { - "group", "input", "check", "radio", "label", "labelField", "table", "pages", "page", + "group", "columnGroup", "input", "check", "radio", "label", "labelField", "table", "pages", "page", "button", "picture", "picField", "calendar", "cmdBar", "popup", + "showInHeader", "radioButtonType", "choiceList", "columnsCount", "name", "path", "title", "visible", "hidden", "enabled", "disabled", "readOnly", "userVisible", @@ -1362,7 +1363,7 @@ KNOWN_KEYS = { "rowPictureDataPath", "tableAutofill", } -TYPE_KEYS = ["group", "input", "check", "radio", "label", "labelField", "table", "pages", "page", +TYPE_KEYS = ["columnGroup", "group", "input", "check", "radio", "label", "labelField", "table", "pages", "page", "button", "picture", "picField", "calendar", "cmdBar", "popup"] # Synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio) @@ -1390,6 +1391,8 @@ ELEMENT_TYPE_SYNONYMS = { "UsualGroup": "group", "Группа": "group", "ОбычнаяГруппа": "group", + "ColumnGroup": "columnGroup", + "ГруппаКолонок": "columnGroup", "Pages": "pages", "ГруппаСтраниц": "pages", "Page": "page", @@ -1787,6 +1790,7 @@ def emit_element(lines, el, indent, in_cmd_bar=False): emitters = { 'group': emit_group, + 'columnGroup': emit_column_group, 'input': emit_input, 'check': emit_check, 'radio': emit_radio_button_field, @@ -1870,6 +1874,43 @@ def emit_group(lines, el, name, eid, indent): lines.append(f'{indent}</UsualGroup>') +def emit_column_group(lines, el, name, eid, indent): + lines.append(f'{indent}<ColumnGroup name="{name}" id="{eid}">') + inner = f'{indent}\t' + + emit_title(lines, el, name, inner) + + group_val = str(el.get('columnGroup', '')) + orientation_map = { + 'horizontal': 'Horizontal', + 'vertical': 'Vertical', + 'inCell': 'InCell', + } + orientation = orientation_map.get(group_val) + if orientation: + lines.append(f'{inner}<Group>{orientation}</Group>') + + if el.get('showTitle') is False: + lines.append(f'{inner}<ShowTitle>false</ShowTitle>') + if el.get('showInHeader') is not None: + sh_val = 'true' if el['showInHeader'] else 'false' + lines.append(f'{inner}<ShowInHeader>{sh_val}</ShowInHeader>') + if el.get('width'): + lines.append(f'{inner}<Width>{el["width"]}</Width>') + + emit_common_flags(lines, el, inner) + + emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner) + + if el.get('children') and len(el['children']) > 0: + lines.append(f'{inner}<ChildItems>') + for child in el['children']: + emit_element(lines, child, f'{inner}\t') + lines.append(f'{inner}</ChildItems>') + + lines.append(f'{indent}</ColumnGroup>') + + def emit_input(lines, el, name, eid, indent): lines.append(f'{indent}<InputField name="{name}" id="{eid}">') inner = f'{indent}\t' diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 32e11c3b..b887549f 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -268,7 +268,7 @@ | Свойство | Тип | Описание | |----------|-----|----------| | `path` | string | DataPath | -| `columns` | array | Колонки (элементы input/check/labelField/picField) | +| `columns` | array | Колонки (элементы input/check/labelField/picField, либо `columnGroup` для группировки) | | `representation` | string | `List`, `Tree`, `HierarchicalList` | | `changeRowSet` | bool | Разрешить добавление/удаление строк | | `changeRowOrder` | bool | Разрешить перемещение строк | @@ -278,6 +278,33 @@ | `commandBarLocation` | string | `None`, `Top`, `Bottom`, `Auto` | | `searchStringLocation` | string | `None`, `Top`, `Bottom`, `CommandBar`, `Auto` | +#### columnGroup — ColumnGroup + +Группа колонок таблицы. Используется только внутри `columns` таблицы. Допускается вложение `columnGroup` в `columnGroup`. + +```json +{ "table": "Список", "path": "Список", "columns": [ + { "columnGroup": "horizontal", "name": "ГруппаДата", "title": "Срок", "children": [ + { "input": "ДатаНачала", "path": "Список.ДатаНачала" }, + { "input": "ДатаОкончания", "path": "Список.ДатаОкончания" } + ]}, + { "columnGroup": "inCell", "name": "ГруппаИсполнитель", "showInHeader": true, "children": [ + { "input": "Исполнитель", "path": "Список.Исполнитель" } + ]} +]} +``` + +| Свойство | Тип | Описание | +|----------|-----|----------| +| `columnGroup` | string | Ориентация: `horizontal`, `vertical`, `inCell` (склейка колонок в одной ячейке шапки) | +| `name` | string | Имя элемента (рекомендуется задавать явно) | +| `title` | string/object | Заголовок группы | +| `showTitle` | bool | Показывать заголовок | +| `showInHeader` | bool | Показывать в шапке таблицы | +| `width` | int | Ширина | +| `horizontalStretch` | bool | Растягивание | +| `children` | array | Колонки внутри группы | + #### pages / page — Pages / Page ```json diff --git a/tests/skills/cases/form-compile/column-group.json b/tests/skills/cases/form-compile/column-group.json new file mode 100644 index 00000000..6243fc13 --- /dev/null +++ b/tests/skills/cases/form-compile/column-group.json @@ -0,0 +1,40 @@ +{ + "name": "Форма с группировкой колонок таблицы", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "DataProcessor", "name": "Задачи" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "form-add/scripts/form-add", + "args": { "-ObjectPath": "{workDir}/DataProcessors/Задачи.xml", "-FormName": "Форма" } + } + ], + "params": { "outputPath": "DataProcessors/Задачи/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Задачи/Forms/Форма/Ext/Form.xml", + "input": { + "title": "Список задач", + "elements": [ + { "table": "Список", "path": "Список", "columns": [ + { "input": "Наименование", "path": "Список.Наименование" }, + { "columnGroup": "horizontal", "name": "ГруппаСрок", "title": "Срок", "children": [ + { "input": "ДатаНачала", "path": "Список.ДатаНачала" }, + { "input": "ДатаОкончания", "path": "Список.ДатаОкончания" } + ]}, + { "columnGroup": "inCell", "name": "ГруппаИсполнитель", "showInHeader": true, "children": [ + { "input": "Исполнитель", "path": "Список.Исполнитель" } + ]} + ]} + ], + "attributes": [ + { "name": "Объект", "type": "DataProcessorObject.Задачи", "main": true }, + { "name": "Список", "type": "ValueTable", "columns": [ + { "name": "Наименование", "type": "string(150)" }, + { "name": "ДатаНачала", "type": "date" }, + { "name": "ДатаОкончания", "type": "date" }, + { "name": "Исполнитель", "type": "string(100)" } + ]} + ] + } +}