Skip to content

Commit

Permalink
Merge branch '2.x' into speed-up-analysis-verification
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonski authored Nov 26, 2024
2 parents 1e66ecf + 9538a48 commit 5235291
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 79 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Changelog
------------------

- #2643 Improve performance of analysis verification
- #2645 Tabbed content view
- #2624 Added "Maximum holding time" setting to services and analyses
- #2637 Do not remove inactive services from profiles and templates
- #2642 Fix Attribute Error in Upgrade Step 2619
Expand Down
23 changes: 2 additions & 21 deletions src/senaite/core/browser/dexterity/templates/container.pt
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,8 @@
<metal:main fill-slot="content-core">
<metal:content-core define-macro="content-core">

<tal:block repeat="widget view/widgets/values|nothing">
<tal:block tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',)">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</tal:block>

<fieldset tal:repeat="group view/groups|nothing"
tal:attributes="id python:''.join((group.prefix, 'groups.', group.__name__)).replace('.', '-')">
<legend tal:content="group/label" />
<tal:block tal:repeat="widget group/widgets/values">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</fieldset>

<!-- hide contents listing -->
<fieldset id="folder-listing" tal:condition="python:False">
<legend i18n:translate="" i18n:domain="plone">Contents</legend>
<tal:block define="view nocall:context/folder_listing; listing_macro view/macros/listing|view/index/macros/listing">
<metal:use_macro use-macro="listing_macro" />
</tal:block>
</fieldset>
<!-- Render widgets in tabs -->
<tal:tabs tal:replace="structure view/render_widget_tabs"/>

</metal:content-core>
</metal:main>
Expand Down
15 changes: 2 additions & 13 deletions src/senaite/core/browser/dexterity/templates/item.pt
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,8 @@
<metal:main fill-slot="content-core">
<metal:content-core define-macro="content-core">

<tal:block repeat="widget view/widgets/values|nothing">
<tal:block tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',)">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</tal:block>

<div tal:repeat="group view/groups|nothing"
tal:attributes="id python:''.join((group.prefix, 'groups.', group.__name__)).replace('.', '-')">
<legend class="mt-2 border-top border-bottom" tal:content="group/label" />
<tal:block tal:repeat="widget group/widgets/values|nothing">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</div>
<!-- Render widgets in tabs -->
<tal:tabs tal:replace="structure view/render_widget_tabs"/>

</metal:content-core>
</metal:main>
Expand Down
84 changes: 84 additions & 0 deletions src/senaite/core/browser/dexterity/templates/tabs.pt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<div tal:define="groups view/groups | nothing;
enable_form_tabbing view/enable_form_tabbing | python:True;
default_fieldset_label view/default_fieldset_label | string:'General';
has_groups python:bool(groups);">

<!-- Tab view toggle -->
<div class="d-flex flex-row-reverse"
tal:condition="has_groups">
<!-- shows all contents on one page -->
<a href="#"
tal:condition="python:enable_form_tabbing"
tal:attributes="href string:${context/absolute_url}?enable_form_tabbing=0;"
title="">
<i class="fas fa-expand"></i>
</a>
<!-- shows contents in tabs -->
<a href="#"
tal:condition="python:not enable_form_tabbing"
tal:attributes="href string:${context/absolute_url}?enable_form_tabbing=1;"
title="">
<i class="fas fa-compress"></i>
</a>
</div>

<!-- navigation tabs -->
<ul class="nav nav-tabs mb-2" role="tablist"
tal:condition="python: has_groups and enable_form_tabbing">

<!-- primary tab -->
<li class="nav-item" role="presentation">
<a tal:content="default_fieldset_label"
tal:attributes="class python:'nav-link active'"
id="default-tab"
href="#default"
data-toggle="tab"
role="tab">
Label
</a>
</li>
<!-- secondary tabs -->
<li tal:repeat="group groups" class="nav-item" role="presentation">
<a tal:define="normalizeString nocall:context/@@plone/normalizeString;
fieldset_label group/label;
fieldset_name python:getattr(group, '__name__', False) or getattr(group.label, 'default', False) or fieldset_label;
fieldset_name python:normalizeString(fieldset_name);
has_errors group/widgets/errors|nothing"
tal:attributes="id string:${fieldset_name}-tab;
href string:#${fieldset_name};
class python:has_errors and 'nav-link text-danger' or 'nav-link'"
tal:content="fieldset_label"
data-toggle="tab"
role="tab">
Label
</a>
</li>
</ul>

<!-- tab content -->
<div class="tab-content">
<!-- Primary fieldsets -->
<div class="tab-pane active" id="default" role="tabpanel">
<tal:block repeat="widget view/widgets/values|nothing">
<tal:block tal:condition="python:widget.__name__ not in ('IBasic.title', 'IBasic.description', 'title', 'description',)">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</tal:block>
</div>
<!-- Secondary fieldsets -->
<tal:block tal:repeat="group groups" condition="has_groups">
<div class="tab-pane" role="tabpanel"
tal:define="normalizeString nocall:context/@@plone/normalizeString;
fieldset_label group/label;
fieldset_name python:getattr(group, '__name__', False) or getattr(group.label, 'default', False) or fieldset_label;
fieldset_name python:normalizeString(fieldset_name);"
tal:attributes="id string:${fieldset_name};
class python:'tab-pane' if enable_form_tabbing else 'd-block';
data-fieldset fieldset_name;">
<tal:block tal:repeat="widget group/widgets/values">
<tal:widget tal:replace="structure widget/@@ploneform-render-widget"/>
</tal:block>
</div>
</tal:block>
</div>
</div>
125 changes: 80 additions & 45 deletions src/senaite/core/browser/dexterity/templates/widget.pt
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,94 @@
data-fieldname widget/name;
id string:formfield-${widget/id};">

<div for=""
<!-- EDIT MODE -->
<tal:edit_mode condition="python:view.is_input_mode()">
<div for=""
class="horizontal font-weight-bold"
tal:attributes="for widget/id"
tal:condition="python: not hidden and widget.label">
<span i18n:translate="" tal:replace="widget/label">label</span>
<span i18n:translate="" tal:replace="widget/label">label</span>

<span class="required horizontal" title="Required"
tal:condition="python:widget.required and widget.mode == 'input'"
i18n:attributes="title title_required;">&nbsp;</span>
</div>
<span class="required horizontal" title="Required"
tal:condition="python:widget.required and widget.mode == 'input'"
i18n:attributes="title title_required;">&nbsp;</span>
</div>

<div class="fieldErrorBox"
tal:content="structure error/render|nothing">
Error
</div>
<div class="fieldErrorBox"
tal:content="structure error/render|nothing">
Error
</div>

<span class="formHelp text-secondary text-muted"
tal:define="description python: getattr(widget, 'description', widget.field.description)"
i18n:translate=""
tal:content="structure description"
tal:condition="python:description and not hidden">
field description
</span>
<span class="formHelp text-secondary text-muted"
tal:define="description python: getattr(widget, 'description', widget.field.description)"
i18n:translate=""
tal:content="structure description"
tal:condition="python:description and not hidden">
field description
</span>

<!-- widget insert mode -->
<div class="input-group input-group-sm d-flex"
style="width:auto"
tal:attributes="class python:widget_css_class"
tal:define="prefix python:view.get_prepend_text();
appendix python:view.get_append_text()"
tal:condition="python:view.is_input_mode()">
<div tal:condition="python:prefix" class="input-group-prepend">
<span class="input-group-text" tal:content="structure python:prefix"/>
</div>
<input type="text"
tal:replace="structure widget/render"
metal:define-slot="widget" />
<div tal:condition="python:appendix" class="input-group-append">
<span class="input-group-text" tal:content="structure python:appendix"/>
<div class="input-group input-group-sm d-flex"
style="width:auto"
tal:attributes="class python:widget_css_class"
tal:define="prefix python:view.get_prepend_text();
appendix python:view.get_append_text()">
<div tal:condition="python:prefix" class="input-group-prepend">
<span class="input-group-text" tal:content="structure python:prefix"/>
</div>
<input type="text"
tal:replace="structure widget/render"
metal:define-slot="widget" />
<div tal:condition="python:appendix" class="input-group-append">
<span class="input-group-text" tal:content="structure python:appendix"/>
</div>
</div>
</div>
</tal:edit_mode>


<!-- VIEW MODE -->
<tal:view_mode condition="python:view.is_view_mode()">

<table class="table table-borderless table-hover table-sm">
<colgroup>
<col style="min-width:100px;max-width:200px;">
<col style="width:100%">
</colgroup>
<tr>
<td>
<div for=""
class="horizontal font-weight-bold"
tal:attributes="for widget/id"
tal:condition="python: not hidden and widget.label">

<span tal:define="description python: getattr(widget, 'description', widget.field.description)"
tal:attributes="title python:description"
data-toggle="tooltip"
data-html="true">
<span i18n:translate="" tal:replace="widget/label">label</span>
</span>


<span class="required horizontal" title="Required"
tal:condition="python:widget.required and widget.mode == 'input'"
i18n:attributes="title title_required;">&nbsp;</span>
</div>

</td>
<td>
<div tal:define="prefix python:view.get_prepend_text();
appendix python:view.get_append_text()">
<!-- field prefix -->
<span tal:content="structure python:prefix" class="field-prefix"></span>
<input type="text"
tal:replace="structure widget/render"
metal:define-slot="widget" />
<!-- field appendix -->
<span tal:content="structure python:appendix" class="field-prefix"></span>
</div>

<!-- widget view mode -->
<div tal:define="prefix python:view.get_prepend_text();
appendix python:view.get_append_text()"
tal:condition="python:view.is_view_mode()">
<!-- field prefix -->
<span tal:content="structure python:prefix" class="field-prefix"></span>
<input type="text"
tal:replace="structure widget/render"
metal:define-slot="widget" />
<!-- field appendix -->
<span tal:content="structure python:appendix" class="field-prefix"></span>
</div>
</td>
</tr>
</table>
</tal:view_mode>

</div>
13 changes: 13 additions & 0 deletions src/senaite/core/browser/dexterity/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import plone.z3cform.templates
import senaite.core.browser.dexterity
import z3c.form.interfaces
from bika.lims import senaiteMessageFactory as _
from plone.app.z3cform.views import Macros
from plone.app.z3cform.views import RenderWidget
from plone.dexterity.browser.edit import DefaultEditView
Expand Down Expand Up @@ -195,11 +196,23 @@ class SenaiteDefaultView(DefaultView):
"""The default view for Dexterity content.
This uses a WidgetsView and renders all widgets in display mode.
"""
tabs_template = ViewPageTemplateFile("templates/tabs.pt")

def __init__(self, context, request):
super(SenaiteDefaultView, self).__init__(context, request)
self.context = context
self.request = request
self.enable_form_tabbing = self.get_default_form_tabbing()
self.default_fieldset_label = _("General")

def get_default_form_tabbing(self):
tabbing = self.request.get("enable_form_tabbing", "1")
if tabbing.lower() in ["0", "no"]:
return False
return True

def render_widget_tabs(self):
return self.tabs_template()


class SenaiteDefaultEditView(DefaultEditView):
Expand Down

0 comments on commit 5235291

Please sign in to comment.