45 |
45 |
from wcs.variables import LazyFieldVar
|
46 |
46 |
from wcs.workflows import ActionsTracingEvolutionPart, WorkflowStatusItem, item_classes, template_on_formdata
|
47 |
47 |
|
48 |
|
from ..qommon import _, errors, ezt, force_str, get_cfg, misc, ngettext, ods
|
|
48 |
from ..qommon import _, errors, ezt, force_str, get_cfg, misc, ngettext, ods, template
|
49 |
49 |
from ..qommon.afterjobs import AfterJob
|
50 |
50 |
from ..qommon.backoffice.listing import pagination_links
|
51 |
51 |
from ..qommon.backoffice.menu import html_top
|
... | ... | |
778 |
778 |
|
779 |
779 |
|
780 |
780 |
class FormPage(Directory):
|
|
781 |
do_not_call_in_templates = True
|
781 |
782 |
_q_exports = [
|
782 |
783 |
'',
|
783 |
784 |
'live',
|
... | ... | |
3493 |
3494 |
raise errors.AccessForbiddenError()
|
3494 |
3495 |
if self.filled.is_draft():
|
3495 |
3496 |
raise errors.AccessForbiddenError()
|
3496 |
|
charset = get_publisher().site_charset
|
3497 |
3497 |
get_response().breadcrumb.append(('inspect', _('Data Inspector')))
|
3498 |
3498 |
self.html_top(self.formdef.name)
|
3499 |
|
r = TemplateIO(html=True)
|
3500 |
|
r += htmltext('<div id="appbar">')
|
3501 |
|
r += htmltext('<h2>%s</h2>') % _('Data Inspector')
|
3502 |
|
r += htmltext('<span class="actions">')
|
|
3499 |
|
|
3500 |
context = {}
|
|
3501 |
|
|
3502 |
context['actions'] = actions = []
|
|
3503 |
|
3503 |
3504 |
if self.formdef._names == 'formdefs':
|
3504 |
3505 |
if get_publisher().get_backoffice_root().is_accessible('forms'):
|
3505 |
|
r += htmltext(' <a href="%s">%s</a>') % (self.formdef.get_admin_url(), _('View Form'))
|
|
3506 |
actions.append({'url': self.formdef.get_admin_url(), 'label': _('View Form')})
|
3506 |
3507 |
elif self.formdef._names == 'carddefs':
|
3507 |
3508 |
if get_publisher().get_backoffice_root().is_accessible('cards'):
|
3508 |
|
r += htmltext(' <a href="%s">%s</a>') % (self.formdef.get_admin_url(), _('View Card'))
|
|
3509 |
actions.append({'url': self.formdef.get_admin_url(), 'label': _('View Card')})
|
3509 |
3510 |
if get_publisher().get_backoffice_root().is_accessible('workflows'):
|
3510 |
|
r += htmltext(' <a href="%s">%s</a>') % (
|
3511 |
|
self.formdef.workflow.get_admin_url(),
|
3512 |
|
_('View Workflow'),
|
3513 |
|
)
|
3514 |
|
r += htmltext('</span>')
|
3515 |
|
r += htmltext('</div>')
|
|
3511 |
actions.append({'url': self.formdef.workflow.get_admin_url(), 'label': _('View Workflow')})
|
3516 |
3512 |
|
3517 |
|
r += get_session().display_message()
|
|
3513 |
context['html_form'] = self.test_tools_form()
|
|
3514 |
context['view'] = self
|
3518 |
3515 |
|
3519 |
|
r += htmltext('<div id="inspect-test-tools" class="section">')
|
3520 |
|
r += htmltext('<h2>%s</h2>') % _('Test tools')
|
3521 |
|
r += htmltext('<div>')
|
3522 |
|
form = self.test_tools_form()
|
3523 |
|
r += form.render()
|
3524 |
|
r += htmltext('<div id="test-tool-result">')
|
3525 |
|
r += self.test_tool_result()
|
3526 |
|
r += htmltext('</div>')
|
3527 |
|
r += htmltext('</div></div>')
|
|
3516 |
context['has_tracing'] = False
|
|
3517 |
for evolution in self.filled.evolution or []:
|
|
3518 |
if evolution.parts and any(isinstance(x, ActionsTracingEvolutionPart) for x in evolution.parts):
|
|
3519 |
context['has_tracing'] = True
|
|
3520 |
break
|
|
3521 |
|
|
3522 |
context['has_markers_stack'] = bool('_markers_stack' in (self.filled.workflow_data or {}))
|
|
3523 |
self.relations = list(self.filled.iter_target_datas())
|
|
3524 |
context['has_relations'] = bool(self.relations)
|
3528 |
3525 |
|
3529 |
|
r += htmltext('<div id="inspect-variables" class="section">')
|
3530 |
|
r += htmltext('<h2>%s</h2>') % _('Variables')
|
3531 |
|
r += htmltext('<ul class="form-inspector biglist">')
|
|
3526 |
return template.QommonTemplateResponse(
|
|
3527 |
templates=['wcs/backoffice/formdata-inspect.html'], context=context
|
|
3528 |
)
|
3532 |
3529 |
|
|
3530 |
def inspect_variables(self):
|
|
3531 |
r = TemplateIO(html=True)
|
|
3532 |
charset = get_publisher().site_charset
|
3533 |
3533 |
substvars = CompatibilityNamesDict()
|
3534 |
3534 |
substvars.update(self.filled.get_substitution_variables())
|
3535 |
3535 |
|
... | ... | |
3620 |
3620 |
if not isinstance(v, str):
|
3621 |
3621 |
r += htmltext(' <span class="type">(%s)</span>') % get_type_name(v)
|
3622 |
3622 |
r += htmltext('</div></li>')
|
3623 |
|
r += htmltext('</div>')
|
|
3623 |
return r.getvalue()
|
3624 |
3624 |
|
|
3625 |
def inspect_functions(self):
|
|
3626 |
r = TemplateIO(html=True)
|
3625 |
3627 |
# assigned functions
|
3626 |
3628 |
if self.formdef.workflow.roles:
|
3627 |
3629 |
workflow = self.formdef.workflow
|
3628 |
|
r += htmltext('<div id="inspect-functions" class="section">')
|
3629 |
|
r += htmltext('<h2>%s</h2></li>\n') % _('Functions')
|
3630 |
|
r += htmltext('<ul class="form-inspector biglist">')
|
3631 |
3630 |
for key, label in (workflow.roles or {}).items():
|
3632 |
3631 |
r += htmltext('<li><span class="label">%s</span>') % label
|
3633 |
3632 |
r += htmltext('<div class="value">')
|
... | ... | |
3649 |
3648 |
r += htmltext('<span class="unset">%s</span>') % _('unset')
|
3650 |
3649 |
r += htmltext('</div>')
|
3651 |
3650 |
r += htmltext('</li>\n')
|
3652 |
|
r += htmltext('</ul>')
|
3653 |
|
r += htmltext('</div>')
|
3654 |
|
|
3655 |
|
has_tracing = False
|
3656 |
|
for evolution in self.filled.evolution or []:
|
3657 |
|
if evolution.parts and any(isinstance(x, ActionsTracingEvolutionPart) for x in evolution.parts):
|
3658 |
|
has_tracing = True
|
3659 |
|
break
|
|
3651 |
return r.getvalue()
|
3660 |
3652 |
|
3661 |
|
if has_tracing:
|
3662 |
|
action_classes = {x.key: x.description for x in item_classes}
|
3663 |
|
r += htmltext('<div id="inspect-timeline" class="section">')
|
3664 |
|
r += htmltext('<h2>%s</h2></li>\n') % _('Actions Tracing')
|
3665 |
|
r += htmltext('<ul class="form-inspector biglist">')
|
3666 |
|
wf_status = None
|
3667 |
|
status_admin_base_url = '#'
|
3668 |
|
last_event_line = None
|
3669 |
|
for evolution in self.filled.evolution:
|
3670 |
|
if evolution.status and evolution.status != wf_status:
|
3671 |
|
for part in evolution.parts or []:
|
3672 |
|
if isinstance(part, ActionsTracingEvolutionPart):
|
3673 |
|
if part.actions:
|
3674 |
|
r += (
|
3675 |
|
htmltext('<li><span class="event">%s</span></li>')
|
3676 |
|
% part.get_event_label()
|
3677 |
|
)
|
3678 |
|
last_event_line = part
|
3679 |
|
break
|
3680 |
|
try:
|
3681 |
|
status = self.filled.formdef.workflow.get_status(evolution.status)
|
3682 |
|
status_label = status.name
|
3683 |
|
status_admin_base_url = status.get_admin_url()
|
3684 |
|
except KeyError:
|
3685 |
|
status_label = _('Unavailable status (%s)') % evolution.status
|
3686 |
|
status_admin_base_url = '#missing'
|
3687 |
|
r += htmltext(
|
3688 |
|
'<li><span class="datetime">%s</span> '
|
3689 |
|
'<a class="tracing-link" href="%s"><strong>%s</strong></a></li>'
|
3690 |
|
) % (
|
3691 |
|
time.strftime('%Y-%m-%d %H:%M:%S', evolution.time) if evolution.time else '-',
|
3692 |
|
status_admin_base_url,
|
3693 |
|
status_label,
|
3694 |
|
)
|
3695 |
|
if evolution.status:
|
3696 |
|
wf_status = evolution.status
|
|
3653 |
def inspect_tracing(self):
|
|
3654 |
r = TemplateIO(html=True)
|
|
3655 |
action_classes = {x.key: x.description for x in item_classes}
|
|
3656 |
wf_status = None
|
|
3657 |
status_admin_base_url = '#'
|
|
3658 |
last_event_line = None
|
|
3659 |
for evolution in self.filled.evolution:
|
|
3660 |
if evolution.status and evolution.status != wf_status:
|
3697 |
3661 |
for part in evolution.parts or []:
|
3698 |
3662 |
if isinstance(part, ActionsTracingEvolutionPart):
|
3699 |
|
if part.actions and part != last_event_line:
|
3700 |
|
last_event_line = part
|
|
3663 |
if part.actions:
|
3701 |
3664 |
r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label()
|
3702 |
|
for action_ts, action_key, action_id in part.actions:
|
3703 |
|
action_label = action_classes.get(action_key, action_key)
|
3704 |
|
try:
|
3705 |
|
url = '%sitems/%s/' % (
|
3706 |
|
part.get_base_url(self.filled.formdef.workflow, wf_status),
|
3707 |
|
action_id,
|
3708 |
|
)
|
3709 |
|
except KeyError:
|
3710 |
|
url = '#missing-%s' % action_id
|
3711 |
|
r += htmltext(
|
3712 |
|
'<li><span class="datetime">%s</span> '
|
3713 |
|
'<a class="tracing-link" href="%s">%s</a></li>'
|
3714 |
|
) % (
|
3715 |
|
action_ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
|
3716 |
|
url,
|
3717 |
|
action_label,
|
|
3665 |
last_event_line = part
|
|
3666 |
break
|
|
3667 |
try:
|
|
3668 |
status = self.filled.formdef.workflow.get_status(evolution.status)
|
|
3669 |
status_label = status.name
|
|
3670 |
status_admin_base_url = status.get_admin_url()
|
|
3671 |
except KeyError:
|
|
3672 |
status_label = _('Unavailable status (%s)') % evolution.status
|
|
3673 |
status_admin_base_url = '#missing'
|
|
3674 |
r += htmltext(
|
|
3675 |
'<li><span class="datetime">%s</span> '
|
|
3676 |
'<a class="tracing-link" href="%s"><strong>%s</strong></a></li>'
|
|
3677 |
) % (
|
|
3678 |
time.strftime('%Y-%m-%d %H:%M:%S', evolution.time) if evolution.time else '-',
|
|
3679 |
status_admin_base_url,
|
|
3680 |
status_label,
|
|
3681 |
)
|
|
3682 |
if evolution.status:
|
|
3683 |
wf_status = evolution.status
|
|
3684 |
for part in evolution.parts or []:
|
|
3685 |
if isinstance(part, ActionsTracingEvolutionPart):
|
|
3686 |
if part.actions and part != last_event_line:
|
|
3687 |
last_event_line = part
|
|
3688 |
r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label()
|
|
3689 |
for action_ts, action_key, action_id in part.actions:
|
|
3690 |
action_label = action_classes.get(action_key, action_key)
|
|
3691 |
try:
|
|
3692 |
url = '%sitems/%s/' % (
|
|
3693 |
part.get_base_url(self.filled.formdef.workflow, wf_status),
|
|
3694 |
action_id,
|
3718 |
3695 |
)
|
|
3696 |
except KeyError:
|
|
3697 |
url = '#missing-%s' % action_id
|
|
3698 |
r += htmltext(
|
|
3699 |
'<li><span class="datetime">%s</span> '
|
|
3700 |
'<a class="tracing-link" href="%s">%s</a></li>'
|
|
3701 |
) % (
|
|
3702 |
action_ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
|
|
3703 |
url,
|
|
3704 |
action_label,
|
|
3705 |
)
|
|
3706 |
return r.getvalue()
|
3719 |
3707 |
|
3720 |
|
r += htmltext('</ul>')
|
3721 |
|
r += htmltext('</div>')
|
|
3708 |
def inspect_markers_stack(self):
|
|
3709 |
r = TemplateIO(html=True)
|
|
3710 |
for marker in reversed(self.filled.workflow_data['_markers_stack']):
|
|
3711 |
status = self.filled.get_status(marker['status_id'])
|
|
3712 |
if status:
|
|
3713 |
r += htmltext('<li><span class="status">%s</span></li>') % status.name
|
|
3714 |
else:
|
|
3715 |
r += htmltext('<li><span class="status">%s</span></li>') % _('Unknown')
|
|
3716 |
return r.getvalue()
|
3722 |
3717 |
|
3723 |
|
# markers stack
|
3724 |
|
if '_markers_stack' in (self.filled.workflow_data or {}):
|
3725 |
|
r += htmltext('<div id="inspect-markers" class="section">')
|
3726 |
|
r += htmltext('<h2>%s</h2>') % _('Markers Stack')
|
3727 |
|
r += htmltext('<ul class="form-inspector biglist">')
|
3728 |
|
for marker in reversed(self.filled.workflow_data['_markers_stack']):
|
3729 |
|
status = self.filled.get_status(marker['status_id'])
|
3730 |
|
if status:
|
3731 |
|
r += htmltext('<li><span class="status">%s</span></li>') % status.name
|
3732 |
|
else:
|
3733 |
|
r += htmltext('<li><span class="status">%s</span></li>') % _('Unknown')
|
3734 |
|
r += htmltext('</ul>')
|
3735 |
|
r += htmltext('</div>')
|
|
3718 |
def inspect_relations(self):
|
|
3719 |
r = TemplateIO(html=True)
|
|
3720 |
children = self.relations
|
3736 |
3721 |
|
3737 |
|
children = list(self.filled.iter_target_datas())
|
3738 |
|
if children:
|
3739 |
|
r += htmltext('<div id="inspect-related" class="section">')
|
3740 |
|
r += htmltext('<h2>%s</h2>') % _('Related Forms/Cards')
|
3741 |
|
r += htmltext('<ul class="form-inspector biglist">')
|
3742 |
|
for child, origin in children:
|
3743 |
|
if isinstance(child, str):
|
3744 |
|
r += htmltext('<li><a href="">%s (%s)</a></li>') % (child, origin)
|
3745 |
|
else:
|
3746 |
|
r += htmltext('<li><a href="%s">%s (%s)</a></li>') % (
|
3747 |
|
child.get_url(backoffice=True),
|
3748 |
|
child.get_display_name(),
|
3749 |
|
origin,
|
3750 |
|
)
|
3751 |
|
r += htmltext('</ul>')
|
3752 |
|
r += htmltext('</div>')
|
|
3722 |
for child, origin in children:
|
|
3723 |
if isinstance(child, str):
|
|
3724 |
r += htmltext('<li><a href="">%s (%s)</a></li>') % (child, origin)
|
|
3725 |
else:
|
|
3726 |
r += htmltext('<li><a href="%s">%s (%s)</a></li>') % (
|
|
3727 |
child.get_url(backoffice=True),
|
|
3728 |
child.get_display_name(),
|
|
3729 |
origin,
|
|
3730 |
)
|
3753 |
3731 |
|
3754 |
3732 |
return r.getvalue()
|
3755 |
3733 |
|