mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-25 14:11:02 +03:00
feat(form-decompile,form-compile): поля диаграмм из ring-3 (Chart/Gantt/GraphicalSchema/Planner/Period/Dendrogram)
Снят fast-fail на 6 chart-полях. Все — простые скелеты (как document/gauge), кроме GanttChart с вложенной <Table> (ключ ganttTable, переиспользует Decompile/Emit-Element — устранена коллизия тип-ключа table). Типы реквизитов уже в special-type ns-карте (d5p1:Chart/GanttChart/FlowchartContextType/ GeographicalSchema, pl:Planner) + v8:StandardPeriod. Edit/WarningOnEditRepresentation у GraphicalSchema — через готовые GENERIC_SCALARS. Guard: реквизит с design-time конфигом диаграммы/планировщика (<Settings xsi:type="d4p1:GanttChart"/"pl:Planner"/…> — третий вид Settings после TypeDescription/DynamicList) → честный fail-ring3 (не теряем молча). Planner несёт Settings всегда; Chart/Gantt — при настройке. Поля без Settings (диаграмма из кода/график-схема/период/дендрограмма/гео) роундтрипятся полностью. Выборка 2.17: ring3 4→0 (весь ring3 разобран!). Кейс chart-fields (chart+graphicalSchema+period+ganttChart с ganttTable) сертифицирован в 1С. Зеркало py байт-в-байт. Регресс 41/41 (ps1+py). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5ebc02d0b3
commit
29f288fe1d
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.101 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.103 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2564,6 +2564,18 @@ function Emit-Element {
|
||||
"ПолеИндикатора" = "progressBar"
|
||||
"TrackBarField" = "trackBar"
|
||||
"ПолеПолосыРегулирования" = "trackBar"
|
||||
"ChartField" = "chart"
|
||||
"ПолеДиаграммы" = "chart"
|
||||
"GanttChartField" = "ganttChart"
|
||||
"ПолеДиаграммыГанта" = "ganttChart"
|
||||
"GraphicalSchemaField" = "graphicalSchema"
|
||||
"ПолеГрафическойСхемы" = "graphicalSchema"
|
||||
"PlannerField" = "planner"
|
||||
"ПолеПланировщика" = "planner"
|
||||
"PeriodField" = "periodField"
|
||||
"ПолеПериода" = "periodField"
|
||||
"DendrogramField" = "dendrogram"
|
||||
"ПолеДендрограммы" = "dendrogram"
|
||||
}
|
||||
foreach ($pair in $synonyms.GetEnumerator()) {
|
||||
if ($null -ne $el.PSObject.Properties[$pair.Key] -and $null -eq $el.PSObject.Properties[$pair.Value]) {
|
||||
@@ -2596,7 +2608,7 @@ function Emit-Element {
|
||||
# у popup/button/cmdBar. Тип-ключ владельца (popup/button/…) должен выиграть.
|
||||
# pages/page ПЕРЕД group: у Page/Pages ключ 'group' — это направление раскладки детей
|
||||
# (<Group>Horizontal</Group>), а не тип UsualGroup. Реальная UsualGroup ключа page/pages не несёт.
|
||||
foreach ($key in @("columnGroup","buttonGroup","pages","page","group","input","check","radio","label","labelField","table","button","calendar","cmdBar","popup","searchString","viewStatus","searchControl","picField","picture","spreadsheet","html","textDoc","formattedDoc","progressBar","trackBar")) {
|
||||
foreach ($key in @("columnGroup","buttonGroup","pages","page","group","input","check","radio","label","labelField","table","button","calendar","cmdBar","popup","searchString","viewStatus","searchControl","picField","picture","spreadsheet","html","textDoc","formattedDoc","progressBar","trackBar","chart","ganttChart","graphicalSchema","planner","periodField","dendrogram")) {
|
||||
if ($el.$key -ne $null) {
|
||||
$typeKey = $key
|
||||
break
|
||||
@@ -2613,8 +2625,9 @@ function Emit-Element {
|
||||
# type keys
|
||||
"group"=1;"columnGroup"=1;"buttonGroup"=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
|
||||
# спец-поля (документ/датчик) — тип-ключи + типоспец. скаляры
|
||||
# спец-поля (документ/датчик/диаграмма) — тип-ключи + типоспец. скаляры
|
||||
"spreadsheet"=1;"html"=1;"textDoc"=1;"formattedDoc"=1;"progressBar"=1;"trackBar"=1
|
||||
"chart"=1;"ganttChart"=1;"graphicalSchema"=1;"planner"=1;"periodField"=1;"dendrogram"=1;"ganttTable"=1
|
||||
"showPercent"=1;"largeStep"=1;"markingStep"=1;"step"=1
|
||||
"horizontalScrollBar"=1;"viewScalingMode"=1;"output"=1;"selectionShowMode"=1;"protection"=1
|
||||
"edit"=1;"showGrid"=1;"showGroups"=1;"showHeaders"=1;"showRowAndColumnNames"=1;"showCellNames"=1
|
||||
@@ -2739,6 +2752,12 @@ function Emit-Element {
|
||||
"formattedDoc" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "FormattedDocumentField" -typeKey "formattedDoc" }
|
||||
"progressBar" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "ProgressBarField" -typeKey "progressBar" }
|
||||
"trackBar" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "TrackBarField" -typeKey "trackBar" }
|
||||
"chart" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "ChartField" -typeKey "chart" }
|
||||
"graphicalSchema" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "GraphicalSchemaField" -typeKey "graphicalSchema" }
|
||||
"planner" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "PlannerField" -typeKey "planner" }
|
||||
"periodField" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "PeriodField" -typeKey "periodField" }
|
||||
"dendrogram" { Emit-SimpleField -el $el -name $name -id $id -indent $indent -xmlTag "DendrogramField" -typeKey "dendrogram" }
|
||||
"ganttChart" { Emit-GanttChart -el $el -name $name -id $id -indent $indent }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4302,6 +4321,26 @@ function Emit-SimpleField {
|
||||
X "$indent</$xmlTag>"
|
||||
}
|
||||
|
||||
# GanttChartField — скелет поля + вложенная <Table> (полноценная таблица, через Emit-Element).
|
||||
# Порядок (по корпусу): path/title/flags/titleLocation/layout/appearance, companions, Table, events.
|
||||
function Emit-GanttChart {
|
||||
param($el, [string]$name, [int]$id, [string]$indent)
|
||||
X "$indent<GanttChartField name=`"$name`" id=`"$id`"$(DI-Attr $el)>"
|
||||
$inner = "$indent`t"
|
||||
if ($el.path) { X "$inner<DataPath>$($el.path)</DataPath>" }
|
||||
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
Emit-Layout -el $el -indent $inner
|
||||
Emit-Appearance -el $el -indent $inner -profile 'field'
|
||||
Emit-CompanionPanel -tag "ContextMenu" -name "${name}КонтекстноеМеню" -indent $inner -panel $el.contextMenu
|
||||
Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner -content $el.extendedTooltip
|
||||
# Вложенная таблица диаграммы Ганта (стандартный Table — переиспользуем Emit-Element)
|
||||
if ($el.ganttTable) { Emit-Element -el $el.ganttTable -indent $inner }
|
||||
Emit-Events -el $el -elementName $name -indent $inner -typeKey "ganttChart"
|
||||
X "$indent</GanttChartField>"
|
||||
}
|
||||
|
||||
function Emit-CommandBar {
|
||||
param($el, [string]$name, [int]$id, [string]$indent)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.101 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.103 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -1832,8 +1832,9 @@ KNOWN_KEYS = {
|
||||
"choiceForm", "choiceHistoryOnInput", "footerDataPath", "minValue", "maxValue",
|
||||
# Button — пометка toggle-кнопки
|
||||
"checked",
|
||||
# спец-поля (документ/датчик) — тип-ключи + типоспец. скаляры
|
||||
# спец-поля (документ/датчик/диаграмма) — тип-ключи + типоспец. скаляры
|
||||
"spreadsheet", "html", "textDoc", "formattedDoc", "progressBar", "trackBar",
|
||||
"chart", "ganttChart", "graphicalSchema", "planner", "periodField", "dendrogram", "ganttTable",
|
||||
"showPercent", "largeStep", "markingStep", "step",
|
||||
"horizontalScrollBar", "viewScalingMode", "output", "selectionShowMode", "protection",
|
||||
"edit", "showGrid", "showGroups", "showHeaders", "showRowAndColumnNames", "showCellNames",
|
||||
@@ -1853,7 +1854,8 @@ KNOWN_KEYS = {
|
||||
# (<Group>Horizontal</Group>), а не тип UsualGroup. Реальная UsualGroup ключа page/pages не несёт.
|
||||
TYPE_KEYS = ["columnGroup", "buttonGroup", "pages", "page", "group", "input", "check", "radio", "label", "labelField", "table",
|
||||
"button", "calendar", "cmdBar", "popup", "searchString", "viewStatus", "searchControl", "picField", "picture",
|
||||
"spreadsheet", "html", "textDoc", "formattedDoc", "progressBar", "trackBar"]
|
||||
"spreadsheet", "html", "textDoc", "formattedDoc", "progressBar", "trackBar",
|
||||
"chart", "ganttChart", "graphicalSchema", "planner", "periodField", "dendrogram"]
|
||||
|
||||
# Synonyms: model often writes XML name or Russian (ПолеПереключателя/RadioButtonField → radio)
|
||||
ELEMENT_TYPE_SYNONYMS = {
|
||||
@@ -1919,6 +1921,18 @@ ELEMENT_TYPE_SYNONYMS = {
|
||||
"ПолеИндикатора": "progressBar",
|
||||
"TrackBarField": "trackBar",
|
||||
"ПолеПолосыРегулирования": "trackBar",
|
||||
"ChartField": "chart",
|
||||
"ПолеДиаграммы": "chart",
|
||||
"GanttChartField": "ganttChart",
|
||||
"ПолеДиаграммыГанта": "ganttChart",
|
||||
"GraphicalSchemaField": "graphicalSchema",
|
||||
"ПолеГрафическойСхемы": "graphicalSchema",
|
||||
"PlannerField": "planner",
|
||||
"ПолеПланировщика": "planner",
|
||||
"PeriodField": "periodField",
|
||||
"ПолеПериода": "periodField",
|
||||
"DendrogramField": "dendrogram",
|
||||
"ПолеДендрограммы": "dendrogram",
|
||||
}
|
||||
|
||||
# Тип-синонимы, применяемые ТОЛЬКО к строковому значению (имя элемента); объект/массив
|
||||
@@ -3163,6 +3177,12 @@ def emit_element(lines, el, indent, in_cmd_bar=False):
|
||||
'formattedDoc': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'FormattedDocumentField', 'formattedDoc'),
|
||||
'progressBar': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'ProgressBarField', 'progressBar'),
|
||||
'trackBar': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'TrackBarField', 'trackBar'),
|
||||
'chart': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'ChartField', 'chart'),
|
||||
'graphicalSchema': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'GraphicalSchemaField', 'graphicalSchema'),
|
||||
'planner': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'PlannerField', 'planner'),
|
||||
'periodField': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'PeriodField', 'periodField'),
|
||||
'dendrogram': lambda lines, el, name, eid, indent: emit_simple_field(lines, el, name, eid, indent, 'DendrogramField', 'dendrogram'),
|
||||
'ganttChart': emit_gantt_chart,
|
||||
}
|
||||
|
||||
emitter = emitters.get(type_key)
|
||||
@@ -3952,6 +3972,27 @@ def emit_simple_field(lines, el, name, eid, indent, xml_tag, type_key):
|
||||
lines.append(f'{indent}</{xml_tag}>')
|
||||
|
||||
|
||||
def emit_gantt_chart(lines, el, name, eid, indent):
|
||||
# GanttChartField — скелет поля + вложенная <Table> (полноценная таблица, через emit_element).
|
||||
lines.append(f'{indent}<GanttChartField name="{name}" id="{eid}"{di_attr(el)}>')
|
||||
inner = f'{indent}\t'
|
||||
if el.get('path'):
|
||||
lines.append(f'{inner}<DataPath>{el["path"]}</DataPath>')
|
||||
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||
emit_common_flags(lines, el, inner)
|
||||
if el.get('titleLocation'):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
emit_layout(lines, el, inner)
|
||||
emit_appearance(lines, el, inner, 'field')
|
||||
emit_companion_panel(lines, 'ContextMenu', f'{name}КонтекстноеМеню', inner, el.get('contextMenu'))
|
||||
emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner, el.get('extendedTooltip'))
|
||||
# Вложенная таблица диаграммы Ганта (стандартный Table — переиспользуем emit_element)
|
||||
if el.get('ganttTable'):
|
||||
emit_element(lines, el['ganttTable'], inner)
|
||||
emit_events(lines, el, name, inner, 'ganttChart')
|
||||
lines.append(f'{indent}</GanttChartField>')
|
||||
|
||||
|
||||
def emit_calendar(lines, el, name, eid, indent):
|
||||
lines.append(f'{indent}<CalendarField name="{name}" id="{eid}"{di_attr(el)}>')
|
||||
inner = f'{indent}\t'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.77 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.79 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -147,6 +147,15 @@ function Fail-Ring3 {
|
||||
}
|
||||
# ConditionalAppearance со scope (привязка к области) пока не воспроизводим — fail-ring3 только в этом случае.
|
||||
foreach ($el in $xmlDoc.SelectNodes("//*[local-name()='ConditionalAppearance']/*[local-name()='item']/*[local-name()='scope'][node()]")) { Fail-Ring3 -kind "ConditionalAppearance со scope" -loc "form/ConditionalAppearance/item/scope" }
|
||||
# Реквизит с design-time конфигурацией (<Settings> chart-типа: Диаграмма/ДиаграммаГанта/… —
|
||||
# d4p1:GanttChart и т.п.). Поддержаны только TypeDescription (valueType) и DynamicList; прочие
|
||||
# (встроенная конфигурация диаграммы) пока НЕ воспроизводим → честный скип, чтобы не потерять молча.
|
||||
foreach ($s in $xmlDoc.SelectNodes("//*[local-name()='Attribute']/*[local-name()='Settings']")) {
|
||||
$st = $s.GetAttribute("type", $NS_XSI)
|
||||
if ($st -and $st -notmatch 'TypeDescription$' -and $st -notmatch 'DynamicList$') {
|
||||
Fail-Ring3 -kind "Attribute>Settings типа '$st' (design-time конфигурация, напр. диаграмма)" -loc "Attribute/Settings"
|
||||
}
|
||||
}
|
||||
|
||||
# --- 1c. Compact JSON serializer (созвучно skd-decompile: 2-проб. indent, inline в пределах lineLimit) ---
|
||||
function Convert-StringToJsonLiteral {
|
||||
@@ -1187,7 +1196,9 @@ $ELEMENT_KEY = @{
|
||||
'Table'='table'; 'Pages'='pages'; 'Page'='page'; 'Button'='button'; 'CommandBar'='cmdBar'; 'Popup'='popup';
|
||||
'SearchStringAddition'='searchString'; 'ViewStatusAddition'='viewStatus'; 'SearchControlAddition'='searchControl';
|
||||
'SpreadSheetDocumentField'='spreadsheet'; 'HTMLDocumentField'='html'; 'TextDocumentField'='textDoc';
|
||||
'FormattedDocumentField'='formattedDoc'; 'ProgressBarField'='progressBar'; 'TrackBarField'='trackBar'
|
||||
'FormattedDocumentField'='formattedDoc'; 'ProgressBarField'='progressBar'; 'TrackBarField'='trackBar';
|
||||
'ChartField'='chart'; 'GraphicalSchemaField'='graphicalSchema'; 'PlannerField'='planner';
|
||||
'PeriodField'='periodField'; 'DendrogramField'='dendrogram'; 'GanttChartField'='ganttChart'
|
||||
}
|
||||
|
||||
# Простые скаляры элемента (pass-through, зеркало $script:genericScalars компилятора). kind bool/value.
|
||||
@@ -1761,6 +1772,18 @@ function Decompile-Element {
|
||||
'FormattedDocumentField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'ProgressBarField' { Decompile-SimpleField $obj $node $name $key; Add-GaugeScalars $obj $node @('MinValue','MaxValue') }
|
||||
'TrackBarField' { Decompile-SimpleField $obj $node $name $key; Add-GaugeScalars $obj $node @('MinValue','MaxValue','LargeStep','MarkingStep','Step') }
|
||||
'ChartField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'GraphicalSchemaField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'PlannerField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'PeriodField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'DendrogramField' { Decompile-SimpleField $obj $node $name $key }
|
||||
'GanttChartField' {
|
||||
Decompile-SimpleField $obj $node $name $key
|
||||
# Вложенная <Table> (полноценная таблица) — переиспользуем общий Decompile-Element.
|
||||
# Ключ ganttTable (не 'table' — во избежание коллизии с тип-ключом таблицы в диспетчере).
|
||||
$tblNode = $node.SelectSingleNode("lf:Table", $ns)
|
||||
if ($tblNode) { $obj['ganttTable'] = Decompile-Element $tblNode }
|
||||
}
|
||||
}
|
||||
# DisplayImportance — атрибут открывающего тега (адаптивная важность отображения), захват «как есть».
|
||||
$di = $node.GetAttribute("DisplayImportance"); if ($di) { $obj['displayImportance'] = $di }
|
||||
|
||||
Reference in New Issue
Block a user