Skip to content

Commit

Permalink
Merge b1faeee into cb38614
Browse files Browse the repository at this point in the history
  • Loading branch information
dataflake committed Apr 9, 2019
2 parents cb38614 + b1faeee commit 65d3fe5
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 75 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -27,6 +27,9 @@ Features
Other changes
+++++++++++++

- Make showing the ZMI modal add dialog configurable per product
(`#535 <https://github.com/zopefoundation/Zope/issues/535>`_)

- Added a few Zope 4 ZMI screenshots to the documentation
(`#378 <https://github.com/zopefoundation/Zope/issues/378>`_)

Expand Down
7 changes: 7 additions & 0 deletions docs/zope4/migration/code.rst
Expand Up @@ -65,6 +65,13 @@ Example to use the info icon (i in a circle)::

zmi_icon = 'fas fa-info-circle'

A few Zope products provide content that can be added in the ZMI without
showing a dialog to collect data such as an id or title. These will now
default to showing the new modal dialog as well. You can prevent that by
adding another class variable::

zmi_show_add_dialog = False

.. _`zmi.styles` : https://github.com/zopefoundation/Zope/tree/master/src/zmi/styles
.. _`available icons` : https://fontawesome.com/icons?d=gallery&m=free
Expand Down
158 changes: 85 additions & 73 deletions src/App/dtml/manage_navbar.dtml
@@ -1,84 +1,96 @@
<dtml-unless "'manage_menu' in REQUEST['URL']">

<header class="navbar navbar-nav navbar-expand navbar-dark flex-row bd-navbar">
<div id="toggle_tabs" class="collapsed"
role="button"
data-toggle="collapse"
data-target="#tabs_items"
aria-controls="tabs_items" aria-expanded="false" aria-label="Toggle Tab-Navigation">
<i class="fa fa-bars"></i>
</div>
<a class="navbar-brand" href="http://www.zope.org" target="_blank">
<span class="product">ZOPE 4.0</span>
</a>
<ul class="navbar-nav flex-row ml-sm-auto d-flex">
<dtml-let authuser="REQUEST.get('AUTHENTICATED_USER', 'not logged-in')">
<li id="zmi-authenticated_user" class="form-inline zmi-authenticated_user" title="Logged in as: <dtml-var "str(authuser)">">
<span class="zmi-label"><dtml-var "str(authuser)"></span>
</li>
</dtml-let>
<li id="toggle_menu" class="form-inline desktop hidden-xs"
title="Show/Hide Tree Menu of the Navigation Context"
data-title_inactive="STATUS INACTIVE: Tree Menu Button is only active on List Views. Navigate up a level to show the tree view again."
data-is_folderish="<dtml-var "(manage_main != manage) and 1 or 0">"
><a href="<dtml-var "(manage_main != manage) and './' or '../'">manage?came_from=<dtml-var URL>" target="_parent" onclick="javascript:if ( manage_menu ) {window.parent.frames[0].menu_toggle();return false;} else { return true; }">
<i class="fa fa-sitemap"></i>
</a>
</li>
<li class="form-inline zmi-cp">
<a title="Control Panel"
href="/Control_Panel/manage_main" target="_self">
<i class="fa fa-cog"></i> <span class="zmi-label">Control&nbsp;Panel</span>
</a>
</li>
<li class="form-inline zmi-addItemSelect">
<form method="get" class="form-group">
<label for="addItemSelect" class="ml-2 sr-only">Select type to add</label>
<select id="addItemSelect" name=":action"
<dtml-if "aq_explicit"
><dtml-if "hasattr(aq_explicit, 'filtered_meta_types')"
>class="form-control-sm" title="Select type to add"
onchange="addItem( elm=this, base_url='<dtml-var "REQUEST.get('URL1','')">'); this.selectedIndex = 0;"
<dtml-else
>class="form-control-sm disabled" title="No type to add" disabled="disabled"
</dtml-if>
</dtml-if>
><option value="" selected="selected">Select type to add</option>
<dtml-if "hasattr(aq_explicit, 'filtered_meta_types')"
><dtml-in filtered_meta_types mapping sort=name
><dtml-if action
><option value="&dtml.html_quote-action;">&dtml-name;</option>
</dtml-if>
</dtml-in>
</dtml-if>
</select>
</form>
</li>
</ul>
<div id="toggle_tabs" class="collapsed"
role="button"
data-toggle="collapse"
data-target="#tabs_items"
aria-controls="tabs_items" aria-expanded="false"
aria-label="Toggle Tab-Navigation">
<i class="fa fa-bars"></i>
</div>
<a class="navbar-brand" href="http://www.zope.org" target="_blank">
<span class="product">ZOPE 4.0</span>
</a>
<ul class="navbar-nav flex-row ml-sm-auto d-flex">

<a href="manage_zmi_logout" title="Logout" class="ml-4">
<i class="fas fa-sign-out-alt"></i>
</a>
<dtml-let authuser="REQUEST.get('AUTHENTICATED_USER', 'not logged-in')">
<li id="zmi-authenticated_user" class="form-inline zmi-authenticated_user"
title="Logged in as: <dtml-var "str(authuser)">">
<span class="zmi-label"><dtml-var "str(authuser)"></span>
</li>
</dtml-let>

<li id="toggle_menu" class="form-inline desktop hidden-xs"
title="Show/Hide Tree Menu of the Navigation Context"
data-title_inactive="STATUS INACTIVE: Tree Menu Button is only active on List Views. Navigate up a level to show the tree view again."
data-is_folderish="<dtml-var "(manage_main != manage) and 1 or 0">">
<a href="<dtml-var "(manage_main != manage) and './' or '../'">manage?came_from=&dtml-URL;"
target="_parent" onclick="javascript:if ( manage_menu ) {window.parent.frames[0].menu_toggle();return false;} else { return true; }">
<i class="fa fa-sitemap"></i>
</a>
</li>

<li class="form-inline zmi-cp">
<a title="Control Panel"
href="/Control_Panel/manage_main" target="_self">
<i class="fa fa-cog"></i>
<span class="zmi-label">Control&nbsp;Panel</span>
</a>
</li>

<li class="form-inline zmi-addItemSelect">
<form method="get" class="form-group">
<label for="addItemSelect" class="ml-2 sr-only">Select type to add</label>
<select id="addItemSelect" name=":action"
<dtml-if "aq_explicit"><dtml-if "hasattr(aq_explicit, 'filtered_meta_types')"
>class="form-control-sm" title="Select type to add"
onchange="addItem( elm=this, base_url='<dtml-var "REQUEST.get('URL1','')">'); this.selectedIndex = 0;"
<dtml-else
>class="form-control-sm disabled" title="No type to add" disabled="disabled"
</dtml-if>
</dtml-if>
><option value="" selected="selected">Select type to add</option>

<dtml-if "hasattr(aq_explicit, 'filtered_meta_types')">
<dtml-in filtered_meta_types mapping sort=name>
<dtml-if action>
<option data-dialog="&dtml-zmi_show_add_dialog;"
value="&dtml.html_quote-action;">&dtml-name;</option>
</dtml-if>
</dtml-in>
</dtml-if>

</select>
</form>
</li>
</ul>

<a href="manage_zmi_logout" title="Logout" class="ml-4">
<i class="fas fa-sign-out-alt"></i>
</a>

</header>

<!-- ZMI-MODAL DIALOG -->
<div class="modal fade" id="zmi-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
... Loading Form ...
</div>
<div class="modal-footer">
&nbsp;
</div>
</div>
</div>
<div class="modal fade" id="zmi-modal" tabindex="-1" role="dialog"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
... Loading Form ...
</div>
<div class="modal-footer">
&nbsp;
</div>
</div>
</div>
</div>

</dtml-unless>
7 changes: 7 additions & 0 deletions src/OFS/ObjectManager.py
Expand Up @@ -274,6 +274,13 @@ def all_meta_types(self, interfaces=None):
if container_filter(self):
meta_types.append(entry)

# Synthesize a new key into each item that decides whether to show
# the modal add dialog in the Zope 4 ZMI
for mt in meta_types:
want_modal = getattr(mt.get('instance', None),
'zmi_show_add_dialog', True)
mt['zmi_show_add_dialog'] = 'modal' if want_modal else ''

return meta_types

def _subobject_permissions(self):
Expand Down
1 change: 1 addition & 0 deletions src/OFS/SimpleItem.py
Expand Up @@ -117,6 +117,7 @@ class Item(
"""A common base class for simple, non-container objects."""

zmi_icon = 'far fa-file'
zmi_show_add_dialog = True

security = ClassSecurityInfo()

Expand Down
11 changes: 11 additions & 0 deletions src/OFS/tests/testObjectManager.py
Expand Up @@ -135,6 +135,17 @@ def checkPermission(self, permission, object, context):
noSecurityManager()
setSecurityPolicy(oldPolicy)

def test_all_meta_types_adds_zmi_modal(self):
om = self._makeOne()
om.meta_types = ({'name': 'Foo'}, {'name': 'Bar'}, {'name': 'Baz'})
amt = om.all_meta_types()
for mt in [x for x in amt if x['name'] in ('foo', 'bar', 'baz')]:
self.assertEqual(mt['zmi_show_add_dialog'], 'modal')

# Pick an example that will be different
for mt in [x for x in amt if x['name'] == 'Virtual Host Monster']:
self.assertEqual(mt['zmi_show_add_dialog'], '')

def test_setObject_set_owner_with_no_user(self):
om = self._makeOne()
newSecurityManager(None, None)
Expand Down
1 change: 1 addition & 0 deletions src/Products/SiteAccess/VirtualHostMonster.py
Expand Up @@ -24,6 +24,7 @@ class VirtualHostMonster(Persistent, Item, Implicit):

meta_type = 'Virtual Host Monster'
zmi_icon = 'fa fa-code-branch'
zmi_show_add_dialog = False
priority = 25

id = 'virtual_hosting'
Expand Down
4 changes: 2 additions & 2 deletions src/zmi/styles/resources/zmi_base.js
Expand Up @@ -11,7 +11,8 @@ function isURL(str) {
// NAVBAR-FUNCTIONS

// [1] Add New Object Item (with Modal Dialog)
function addItem( elm, base_url, zmi_dialog='modal') {
function addItem( elm, base_url ) {
var zmi_dialog = elm.options[elm.selectedIndex].getAttribute('data-dialog');
// e.g. manage_addProduct/OFSP/folderAdd
var url_action = elm.options[elm.selectedIndex].value;
// http://localhost/myfolder/manage_addProduct/OFSP/folderAdd
Expand All @@ -31,7 +32,6 @@ function addItem( elm, base_url, zmi_dialog='modal') {
'manage_addRegistry',
'manage_addUserFolder',
'manage_addErrorLog',
'manage_addVirtualHostMonster',
'addPluggableAuthService',
],
'product':[
Expand Down

0 comments on commit 65d3fe5

Please sign in to comment.