mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-06 11:40:20 +03:00
feat(form-decompile,form-compile): доступ по ролям — userVisible/view/edit/use (единый xr-механизм)
Кластер «доступ по ролям»: единый role-adjustable boolean платформы
(xr:Common + 0..N xr:Value name="Role.X") для четырёх владельцев одним
грамматиком значения:
- элемент → userVisible (<UserVisible>)
- реквизит → view, edit (<View>/<Edit>)
- команда → use (<Use>)
Значение DSL: скаляр false/true → голый <xr:Common>; объект
{ common, roles:{ Имя: bool } } → пер-ролевые исключения (три-state как в
конфигураторе: роль не указана → наследует common; указана → явный bool).
Имя роли forgiving: без префикса / Role. / Роль. → нормализуется в Role.
Отсутствие ключа = полный доступ (платформа тег не пишет) — дефолт не эмитим.
Декомпилятор инвертирует: голый Common → скаляр, есть Value → объект.
Компилятор: общий хелпер Emit-XrFlag / emit_xr_flag (ps1+py).
Порядок схемы: View → Edit после MainAttribute; Use после ToolTip до Action.
Раньше: userVisible умел только голый false (компилятор), декомпилятор не
захватывал ничего; view/edit/use не умел никто.
TOTAL diff lines выборки 2.17: 7911 → 7560 (-351), match 9 → 11.
Снапшоты attributes-types/commands сертифицированы в 1С (8.3.24);
регресс form-compile 33/33 зелёный на ps + python.
decompile v0.28, compile v1.47.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f34993b805
commit
d484a5b7ec
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.46 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.47 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2430,14 +2430,39 @@ function Emit-Element {
|
||||
}
|
||||
}
|
||||
|
||||
# Role-adjustable boolean (xr:Common + 0..N xr:Value name="Role.X").
|
||||
# Единый механизм платформы: UserVisible (элементы), View/Edit (атрибуты), Use (команды/кнопки).
|
||||
# Значение DSL: скаляр bool → только <xr:Common>; объект { common, roles:{ Имя: bool } } → +пер-ролевые исключения.
|
||||
# Имя роли принимаем с/без префикса "Role." (forgiving); на выход всегда с префиксом.
|
||||
function Emit-XrFlag {
|
||||
param([string]$tag, $val, [string]$indent)
|
||||
if ($null -eq $val) { return }
|
||||
if ($val -is [bool]) {
|
||||
X "$indent<$tag>"
|
||||
X "$indent`t<xr:Common>$(if ($val){'true'}else{'false'})</xr:Common>"
|
||||
X "$indent</$tag>"
|
||||
return
|
||||
}
|
||||
# объектная форма { common, roles }
|
||||
$common = if ($null -ne $val.common) { [bool]$val.common } else { $false }
|
||||
X "$indent<$tag>"
|
||||
X "$indent`t<xr:Common>$(if ($common){'true'}else{'false'})</xr:Common>"
|
||||
if ($val.roles) {
|
||||
foreach ($r in $val.roles.PSObject.Properties) {
|
||||
# Forgiving: принимаем имя без префикса, с "Role." или кириллическим "Роль." → нормализуем в "Role."
|
||||
$rname = "$($r.Name)" -replace '^(Role|Роль)\.', ''
|
||||
$rname = "Role.$rname"
|
||||
$rval = if ([bool]$r.Value) { 'true' } else { 'false' }
|
||||
X "$indent`t<xr:Value name=`"$rname`">$rval</xr:Value>"
|
||||
}
|
||||
}
|
||||
X "$indent</$tag>"
|
||||
}
|
||||
|
||||
function Emit-CommonFlags {
|
||||
param($el, [string]$indent)
|
||||
if ($el.visible -eq $false -or $el.hidden -eq $true) { X "$indent<Visible>false</Visible>" }
|
||||
if ($el.userVisible -eq $false) {
|
||||
X "$indent<UserVisible>"
|
||||
X "$indent`t<xr:Common>false</xr:Common>"
|
||||
X "$indent</UserVisible>"
|
||||
}
|
||||
if ($null -ne $el.userVisible) { Emit-XrFlag -tag 'UserVisible' -val $el.userVisible -indent $indent }
|
||||
if ($el.enabled -eq $false -or $el.disabled -eq $true) { X "$indent<Enabled>false</Enabled>" }
|
||||
if ($el.readOnly -eq $true) { X "$indent<ReadOnly>true</ReadOnly>" }
|
||||
}
|
||||
@@ -3526,6 +3551,9 @@ function Emit-Attributes {
|
||||
if ($attr.main -eq $true) {
|
||||
X "$inner<MainAttribute>true</MainAttribute>"
|
||||
}
|
||||
# Доступ по ролям: просмотр/редактирование (порядок схемы: View → Edit, после MainAttribute)
|
||||
if ($null -ne $attr.view) { Emit-XrFlag -tag 'View' -val $attr.view -indent $inner }
|
||||
if ($null -ne $attr.edit) { Emit-XrFlag -tag 'Edit' -val $attr.edit -indent $inner }
|
||||
$mainSaved = $false
|
||||
if ($attr.main -eq $true -and $attr.type) {
|
||||
$mainSaved = ("$($attr.type)") -match '^(CatalogObject|DocumentObject|ChartOfAccountsObject|ChartOfCalculationTypesObject|ChartOfCharacteristicTypesObject|ExchangePlanObject|BusinessProcessObject|TaskObject)\.' -or ("$($attr.type)") -match 'RecordManager\.'
|
||||
@@ -3647,6 +3675,9 @@ function Emit-Commands {
|
||||
Emit-MLText -tag "ToolTip" -text $cmd.tooltip -indent $inner
|
||||
}
|
||||
|
||||
# Доступность команды по ролям (после ToolTip, до Action)
|
||||
if ($null -ne $cmd.use) { Emit-XrFlag -tag 'Use' -val $cmd.use -indent $inner }
|
||||
|
||||
if ($cmd.action) {
|
||||
X "$inner<Action>$($cmd.action)</Action>"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.46 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.47 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -2059,13 +2059,36 @@ def emit_table_addition(lines, tag, table_name, name_suffix, src_type, indent):
|
||||
lines.append(f'{indent}</{tag}>')
|
||||
|
||||
|
||||
# Role-adjustable boolean (xr:Common + 0..N xr:Value name="Role.X").
|
||||
# Единый механизм платформы: UserVisible (элементы), View/Edit (атрибуты), Use (команды/кнопки).
|
||||
# Значение DSL: скаляр bool → только <xr:Common>; объект { common, roles:{ Имя: bool } } → +пер-ролевые исключения.
|
||||
# Имя роли принимаем с/без префикса "Role." (forgiving); на выход всегда с префиксом.
|
||||
def emit_xr_flag(lines, tag, val, indent):
|
||||
if val is None:
|
||||
return
|
||||
if isinstance(val, bool):
|
||||
lines.append(f"{indent}<{tag}>")
|
||||
lines.append(f"{indent}\t<xr:Common>{'true' if val else 'false'}</xr:Common>")
|
||||
lines.append(f"{indent}</{tag}>")
|
||||
return
|
||||
# объектная форма { common, roles }
|
||||
common = bool(val.get('common')) if val.get('common') is not None else False
|
||||
lines.append(f"{indent}<{tag}>")
|
||||
lines.append(f"{indent}\t<xr:Common>{'true' if common else 'false'}</xr:Common>")
|
||||
roles = val.get('roles')
|
||||
if roles:
|
||||
for rname, rval in roles.items():
|
||||
# Forgiving: имя без префикса, с "Role." или кириллическим "Роль." → нормализуем в "Role."
|
||||
rn = "Role." + re.sub(r'^(Role|Роль)\.', '', rname)
|
||||
lines.append(f"{indent}\t<xr:Value name=\"{rn}\">{'true' if rval else 'false'}</xr:Value>")
|
||||
lines.append(f"{indent}</{tag}>")
|
||||
|
||||
|
||||
def emit_common_flags(lines, el, indent):
|
||||
if el.get('visible') is False or el.get('hidden') is True:
|
||||
lines.append(f"{indent}<Visible>false</Visible>")
|
||||
if el.get('userVisible') is False:
|
||||
lines.append(f"{indent}<UserVisible>")
|
||||
lines.append(f"{indent}\t<xr:Common>false</xr:Common>")
|
||||
lines.append(f"{indent}</UserVisible>")
|
||||
if el.get('userVisible') is not None:
|
||||
emit_xr_flag(lines, 'UserVisible', el.get('userVisible'), indent)
|
||||
if el.get('enabled') is False or el.get('disabled') is True:
|
||||
lines.append(f"{indent}<Enabled>false</Enabled>")
|
||||
if el.get('readOnly') is True:
|
||||
@@ -3180,6 +3203,11 @@ def emit_attributes(lines, attrs, indent):
|
||||
|
||||
if attr.get('main') is True:
|
||||
lines.append(f'{inner}<MainAttribute>true</MainAttribute>')
|
||||
# Доступ по ролям: просмотр/редактирование (порядок схемы: View → Edit, после MainAttribute)
|
||||
if attr.get('view') is not None:
|
||||
emit_xr_flag(lines, 'View', attr.get('view'), inner)
|
||||
if attr.get('edit') is not None:
|
||||
emit_xr_flag(lines, 'Edit', attr.get('edit'), inner)
|
||||
main_saved = False
|
||||
if attr.get('main') is True and attr.get('type'):
|
||||
t = str(attr['type'])
|
||||
@@ -3285,6 +3313,10 @@ def emit_commands(lines, cmds, indent):
|
||||
if cmd.get('tooltip'):
|
||||
emit_mltext(lines, inner, 'ToolTip', cmd['tooltip'])
|
||||
|
||||
# Доступность команды по ролям (после ToolTip, до Action)
|
||||
if cmd.get('use') is not None:
|
||||
emit_xr_flag(lines, 'Use', cmd.get('use'), inner)
|
||||
|
||||
if cmd.get('action'):
|
||||
lines.append(f'{inner}<Action>{cmd["action"]}</Action>')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user