feat(skd-compile): implicit viewMode=Normal + user-settings на FilterItemGroup и axis

Платформа эмитит <viewMode>Normal</viewMode> автоматически когда у
элемента есть <userSettingID> (это сигнал пользовательской настройки).
Теперь compile делает то же:
- filter item, dataParameters item, conditionalAppearance item, table
  axis (column/row/point/series) — все эмитят Normal если userSettingID
  задан и явный viewMode не указан

Кроме того: FilterItemGroup теперь поддерживает свой viewMode /
userSettingID / presentation / userSettingPresentation (наравне с
обычными filter items).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-22 17:45:15 +03:00
parent 49f17ef5fd
commit f9774d799c
6 changed files with 101 additions and 25 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.42 — Compile 1C DCS from JSON
# skd-compile v1.44 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -1954,6 +1954,21 @@ function Emit-FilterItem {
Emit-FilterItem -item $sub -indent "$indent`t"
}
}
if ($item.presentation) {
Emit-MLText -tag "dcsset:presentation" -text $item.presentation -indent "$indent`t"
}
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if ($item.viewMode -or $item.userSettingID) {
$gvm = if ($item.viewMode) { "$($item.viewMode)" } else { 'Normal' }
X "$indent`t<dcsset:viewMode>$(Esc-Xml $gvm)</dcsset:viewMode>"
}
if ($item.userSettingID) {
$guid = if ("$($item.userSettingID)" -eq "auto") { New-Guid-String } else { "$($item.userSettingID)" }
X "$indent`t<dcsset:userSettingID>$(Esc-Xml $guid)</dcsset:userSettingID>"
}
if ($item.userSettingPresentation) {
Emit-MLText -tag "dcsset:userSettingPresentation" -text $item.userSettingPresentation -indent "$indent`t"
}
X "$indent</dcsset:item>"
return
}
@@ -1994,8 +2009,10 @@ function Emit-FilterItem {
Emit-MLText -tag "dcsset:presentation" -text $item.presentation -indent "$indent`t"
}
if ($item.viewMode) {
X "$indent`t<dcsset:viewMode>$(Esc-Xml "$($item.viewMode)")</dcsset:viewMode>"
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if ($item.viewMode -or $item.userSettingID) {
$vm = if ($item.viewMode) { "$($item.viewMode)" } else { 'Normal' }
X "$indent`t<dcsset:viewMode>$(Esc-Xml $vm)</dcsset:viewMode>"
}
if ($item.userSettingID) {
@@ -2174,9 +2191,10 @@ function Emit-ConditionalAppearance {
X "$indent`t`t<dcsset:presentation xsi:type=`"xs:string`">$(Esc-Xml "$($ca.presentation)")</dcsset:presentation>"
}
# ViewMode
if ($ca.viewMode) {
X "$indent`t`t<dcsset:viewMode>$(Esc-Xml "$($ca.viewMode)")</dcsset:viewMode>"
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if ($ca.viewMode -or $ca.userSettingID) {
$cvm = if ($ca.viewMode) { "$($ca.viewMode)" } else { 'Normal' }
X "$indent`t`t<dcsset:viewMode>$(Esc-Xml $cvm)</dcsset:viewMode>"
}
# UserSettingID
@@ -2296,8 +2314,10 @@ function Emit-DataParameters {
}
}
if ($dp.viewMode) {
X "$indent`t`t<dcsset:viewMode>$(Esc-Xml "$($dp.viewMode)")</dcsset:viewMode>"
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if ($dp.viewMode -or $dp.userSettingID) {
$dvm = if ($dp.viewMode) { "$($dp.viewMode)" } else { 'Normal' }
X "$indent`t`t<dcsset:viewMode>$(Esc-Xml $dvm)</dcsset:viewMode>"
}
if ($dp.userSettingID) {
@@ -2448,9 +2468,15 @@ function Emit-UserFields {
}
# Shared emitter for table column/row and chart point/series.
# Emits groupItems, filter, order, selection, outputParameters — each conditional on JSON presence.
# Emits name?, groupItems, filter, order, selection, outputParameters, viewMode?,
# userSettingID?, userSettingPresentation? — каждое условно по присутствию в JSON.
# Параметр $emitName управляет тем, эмитить ли <name> внутри блока: для row caller
# уже эмитит name отдельно (исторический порядок), для остальных — здесь.
function Emit-TableAxisBlock {
param($block, [string]$indent)
param($block, [string]$indent, [bool]$emitName = $true)
if ($emitName -and $block.name) {
X "$indent<dcsset:name>$(Esc-Xml "$($block.name)")</dcsset:name>"
}
$gb = if ($block.groupBy) { $block.groupBy } else { $block.groupFields }
Emit-GroupItems -groupBy $gb -indent $indent
if ($block.filter) {
@@ -2465,6 +2491,16 @@ function Emit-TableAxisBlock {
if ($block.outputParameters) {
Emit-OutputParameters -params $block.outputParameters -indent $indent
}
if ($block.viewMode) {
X "$indent<dcsset:viewMode>$(Esc-Xml "$($block.viewMode)")</dcsset:viewMode>"
}
if ($block.userSettingID) {
$uid = if ("$($block.userSettingID)" -eq "auto") { New-Guid-String } else { "$($block.userSettingID)" }
X "$indent<dcsset:userSettingID>$(Esc-Xml $uid)</dcsset:userSettingID>"
}
if ($block.userSettingPresentation) {
Emit-MLText -tag "dcsset:userSettingPresentation" -text $block.userSettingPresentation -indent $indent
}
}
function Emit-StructureItem {
@@ -2539,9 +2575,6 @@ function Emit-StructureItem {
if ($item.rows) {
foreach ($row in $item.rows) {
X "$indent`t<dcsset:row>"
if ($row.name) {
X "$indent`t`t<dcsset:name>$(Esc-Xml "$($row.name)")</dcsset:name>"
}
Emit-TableAxisBlock -block $row -indent "$indent`t`t"
X "$indent`t</dcsset:row>"
}
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.42 — Compile 1C DCS from JSON
# skd-compile v1.44 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -1626,6 +1626,17 @@ def emit_filter_item(lines, item, indent):
if parsed.get('viewMode'):
sub['viewMode'] = parsed['viewMode']
emit_filter_item(lines, sub, f'{indent}\t')
if item.get('presentation'):
emit_mltext(lines, f'{indent}\t', 'dcsset:presentation', item['presentation'])
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if item.get('viewMode') or item.get('userSettingID'):
gvm = str(item['viewMode']) if item.get('viewMode') else 'Normal'
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(gvm)}</dcsset:viewMode>')
if item.get('userSettingID'):
guid = new_uuid() if str(item['userSettingID']) == 'auto' else str(item['userSettingID'])
lines.append(f'{indent}\t<dcsset:userSettingID>{esc_xml(guid)}</dcsset:userSettingID>')
if item.get('userSettingPresentation'):
emit_mltext(lines, f'{indent}\t', 'dcsset:userSettingPresentation', item['userSettingPresentation'])
lines.append(f'{indent}</dcsset:item>')
return
@@ -1662,8 +1673,10 @@ def emit_filter_item(lines, item, indent):
if item.get('presentation'):
emit_mltext(lines, f'{indent}\t', 'dcsset:presentation', item["presentation"])
if item.get('viewMode'):
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(item["viewMode"]))}</dcsset:viewMode>')
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if item.get('viewMode') or item.get('userSettingID'):
vm = str(item['viewMode']) if item.get('viewMode') else 'Normal'
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(vm)}</dcsset:viewMode>')
if item.get('userSettingID'):
uid = new_uuid() if str(item['userSettingID']) == 'auto' else str(item['userSettingID'])
@@ -1814,9 +1827,10 @@ def emit_conditional_appearance(lines, items, indent, block_view_mode=None):
if ca.get('presentation'):
lines.append(f'{indent}\t\t<dcsset:presentation xsi:type="xs:string">{esc_xml(str(ca["presentation"]))}</dcsset:presentation>')
# ViewMode
if ca.get('viewMode'):
lines.append(f'{indent}\t\t<dcsset:viewMode>{esc_xml(str(ca["viewMode"]))}</dcsset:viewMode>')
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if ca.get('viewMode') or ca.get('userSettingID'):
cvm = str(ca['viewMode']) if ca.get('viewMode') else 'Normal'
lines.append(f'{indent}\t\t<dcsset:viewMode>{esc_xml(cvm)}</dcsset:viewMode>')
# UserSettingID
if ca.get('userSettingID'):
@@ -1907,8 +1921,10 @@ def emit_data_parameters(lines, items, indent):
else:
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:string">{esc_xml(str(val))}</dcscor:value>')
if dp.get('viewMode'):
lines.append(f'{indent}\t\t<dcsset:viewMode>{esc_xml(str(dp["viewMode"]))}</dcsset:viewMode>')
# Platform always emits viewMode when userSettingID is present (implicit Normal).
if dp.get('viewMode') or dp.get('userSettingID'):
dvm = str(dp['viewMode']) if dp.get('viewMode') else 'Normal'
lines.append(f'{indent}\t\t<dcsset:viewMode>{esc_xml(dvm)}</dcsset:viewMode>')
if dp.get('userSettingID'):
uid = new_uuid() if str(dp['userSettingID']) == 'auto' else str(dp['userSettingID'])
@@ -2028,8 +2044,15 @@ def emit_user_fields(lines, items, indent):
lines.append(f'{indent}</dcsset:userFields>')
def emit_table_axis_block(lines, block, indent):
"""Shared emitter for table column/row and chart point/series."""
def emit_table_axis_block(lines, block, indent, emit_name=True):
"""Shared emitter for table column/row and chart point/series.
Emits name?, groupItems, filter, order, selection, outputParameters,
viewMode?, userSettingID?, userSettingPresentation? — each conditional on
presence in JSON.
"""
if emit_name and block.get('name'):
lines.append(f'{indent}<dcsset:name>{esc_xml(str(block["name"]))}</dcsset:name>')
gb = block.get('groupBy') or block.get('groupFields')
emit_group_items(lines, gb, indent)
if block.get('filter'):
@@ -2040,6 +2063,13 @@ def emit_table_axis_block(lines, block, indent):
emit_selection(lines, block['selection'], indent)
if block.get('outputParameters'):
emit_output_parameters(lines, block['outputParameters'], indent)
if block.get('viewMode'):
lines.append(f'{indent}<dcsset:viewMode>{esc_xml(str(block["viewMode"]))}</dcsset:viewMode>')
if block.get('userSettingID'):
uid = new_uuid() if str(block['userSettingID']) == 'auto' else str(block['userSettingID'])
lines.append(f'{indent}<dcsset:userSettingID>{esc_xml(uid)}</dcsset:userSettingID>')
if block.get('userSettingPresentation'):
emit_mltext(lines, indent, 'dcsset:userSettingPresentation', block['userSettingPresentation'])
def emit_structure_item(lines, item, indent):
@@ -2097,8 +2127,6 @@ def emit_structure_item(lines, item, indent):
if item.get('rows'):
for row in item['rows']:
lines.append(f'{indent}\t<dcsset:row>')
if row.get('name'):
lines.append(f'{indent}\t\t<dcsset:name>{esc_xml(str(row["name"]))}</dcsset:name>')
emit_table_axis_block(lines, row, f'{indent}\t\t')
lines.append(f'{indent}\t</dcsset:row>')
@@ -165,6 +165,7 @@
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
@@ -175,37 +176,44 @@
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Флаг</dcscor:parameter>
<dcscor:value xsi:type="xs:boolean">true</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Сумма</dcscor:parameter>
<dcscor:value xsi:type="xs:decimal">0</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-004</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Ставка</dcscor:parameter>
<dcscor:value xsi:type="xs:decimal">13.5</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-005</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Метка</dcscor:parameter>
<dcscor:value xsi:type="xs:string">ТестовоеЗначение</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-006</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:use>false</dcscor:use>
<dcscor:parameter>ПустаяСтрока</dcscor:parameter>
<dcscor:value xsi:nil="true"/>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-007</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Валюта</dcscor:parameter>
<dcscor:value xsi:type="dcscor:DesignTimeValue">Справочник.Валюты.EmptyRef</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-008</dcsset:userSettingID>
</dcscor:item>
</dcsset:dataParameters>
@@ -132,6 +132,7 @@
<dcsset:use>false</dcsset:use>
<dcsset:left xsi:type="dcscor:Field">Организация</dcsset:left>
<dcsset:comparisonType>Equal</dcsset:comparisonType>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
</dcsset:item>
</dcsset:filter>
@@ -143,6 +144,7 @@
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
</dcscor:item>
</dcsset:dataParameters>
@@ -130,6 +130,7 @@
<dcsset:use>false</dcsset:use>
<dcsset:left xsi:type="dcscor:Field">Организация</dcsset:left>
<dcsset:comparisonType>Equal</dcsset:comparisonType>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
</dcsset:item>
<dcsset:item xsi:type="dcsset:FilterItemComparison">
@@ -150,6 +151,7 @@
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
</dcscor:item>
</dcsset:dataParameters>
@@ -297,6 +297,7 @@
<dcsset:use>false</dcsset:use>
<dcsset:left xsi:type="dcscor:Field">Организация</dcsset:left>
<dcsset:comparisonType>Equal</dcsset:comparisonType>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-001</dcsset:userSettingID>
</dcsset:item>
<dcsset:item xsi:type="dcsset:FilterItemGroup">
@@ -359,11 +360,13 @@
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Активные</dcscor:parameter>
<dcscor:value xsi:type="xs:boolean">true</dcscor:value>
<dcsset:viewMode>Normal</dcsset:viewMode>
<dcsset:userSettingID>UUID-004</dcsset:userSettingID>
</dcscor:item>
</dcsset:dataParameters>