Skip to content

Commit

Permalink
Merge branch 'members-view-roster'
Browse files Browse the repository at this point in the history
Conflicts:
	src/ploneintranet/workspace/browser/configure.zcml
  • Loading branch information
Adam Forsythe-Cheasley committed Jun 26, 2014
2 parents ad012c5 + 3bdbeb4 commit 4295d41
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 140 deletions.
9 changes: 9 additions & 0 deletions src/ploneintranet/workspace/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
i18n_domain="ploneintranet.workspace">

<include package="plone.app.portlets" />
<include package="collective.workspace" />

<browser:page
name="policies"
Expand Down Expand Up @@ -47,6 +48,14 @@
permission="zope2.View"
/>

<browser:page
name="update_roster"
for="ploneintranet.workspace.workspacefolder.IWorkspaceFolder"
class=".roster.EditRoster"
attribute="update_roster"
permission="collective.workspace.ManageRoster"
/>

<browser:viewlet
name="ploneintranet.workspace.join"
manager="plone.app.layout.viewlets.interfaces.IAboveContentTitle"
Expand Down
116 changes: 0 additions & 116 deletions src/ploneintranet/workspace/browser/roster-edit.pt

This file was deleted.

40 changes: 25 additions & 15 deletions src/ploneintranet/workspace/browser/roster.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from plone.memoize.instance import memoize, clearafter
from zope.component import getMultiAdapter
from Products.CMFPlone.utils import safe_unicode
from Products.CMFCore.utils import _checkPermission as checkPermission
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from plone.protect import CheckAuthenticator, PostOnly
from Products.Five import BrowserView
Expand All @@ -15,25 +16,26 @@ class EditRoster(BrowserView):
Based on the @@sharing tab from plone.app.workflow
"""

index = ViewPageTemplateFile('roster-edit.pt')
index = ViewPageTemplateFile('templates/roster-edit.pt')

def __call__(self):
"""Perform the update and redirect if necessary, or render the page
"""
self.handle_form()
return self.index()

def handle_form(self):
def update_roster(self, REQUEST=None):
"""
If workspace is team managed, users can add/remove participants.
Any user with the manage workspace permission can add/remove
participants and admins.
"""
CheckAuthenticator(self.request)
PostOnly(self.request)
form = self.request.form
submitted = form.get('form.submitted', False)
save_button = form.get('form.button.Save', None) is not None
if submitted and save_button:
CheckAuthenticator(self.request)
PostOnly(self.request)
entries = form.get('entries', [])
self.update_users(entries)
api.portal.show_message(message=_(u'Roster updated.'),
request=self.request)
entries = form.get('entries', [])
self.update_users(entries)
api.portal.show_message(message=_(u'Roster updated.'),
request=self.request)
return self.request.response.redirect(
'%s/@@edit-roster' % self.context.absolute_url())

@clearafter
def update_users(self, entries):
Expand All @@ -42,7 +44,6 @@ def update_users(self, entries):
members = ws.members

for entry in entries:

id = entry['id']
is_member = bool(entry.get('member'))
is_admin = bool(entry.get('admin'))
Expand Down Expand Up @@ -102,3 +103,12 @@ def existing_users(self):
)

return info

def can_manage_workspace(self):
"""
does this user have permission to manage the workspace
"""
return checkPermission(
"ploneintranet.workspace: Manage workspace",
self.context,
)
124 changes: 124 additions & 0 deletions src/ploneintranet/workspace/browser/templates/roster-edit.pt
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en"
metal:use-macro="context/main_template/macros/master"
i18n:domain="plone">

<head>
</head>

<body>
<metal:main fill-slot="main"
tal:define="context_state context/@@plone_context_state;
user_cannot_manage python:
not view.can_manage_workspace();
">

<h1 class="documentFirstHeading"
i18n:translate="heading_edit_roster">
Edit roster for
<q tal:content="context/Title" i18n:name="folder">title</q>
</h1>

<div tal:replace="structure provider:plone.abovecontentbody"
tal:condition="not:ajax_load" />

<div id="content-core">
<form method="post"
tal:attributes="action string:${context/absolute_url}/@@edit-roster">

<input type="hidden" name="form.submitted:boolean" value="True" />

<div class="field">
<input type="text"
id="edit-roster-user-search"
size="30"
name="search_term"
title="Search for a user"
placeholder="Search for a user"
i18n:attributes="title; placeholder"
tal:attributes="value request/search_term|nothing"
class="searchField"
value=""
/>
<input type="submit"
id="edit-roster-search-button"
name="form.button.SearchUsers"
value="Search users"
class="searchButton allowMultiSubmit"
i18n:attributes="value label_search"
/>
</div>
</form>

<form method="post"
tal:attributes="action string:${context/absolute_url}/@@update_roster">
<div id="edit-roster-container">
<table metal:define-macro="edit-roster" id="edit-roster"
class="listing"
summary="Current users"
tal:define="users view/users;"
i18n:attributes="summary rostered-users;">

<thead metal:define-macro="edit-roster-head" id="edit-roster-head">
<tr>
<th i18n:translate="label_name">Name</th>
<th class="nosort">Participant</th>
<th class="nosort">Workspace Admin</th>
</tr>
</thead>

<tbody metal:define-macro="edit-roster-settings" id="edit-roster-settings">
<tal:entries repeat="user users">
<tr tal:define="oddrow repeat/user/odd;
is_admin user/admin | nothing;
is_member user/member | nothing"
tal:attributes="class python:oddrow and 'odd' or 'even'">
<td>
<span tal:replace="user/title" />
<input
type="hidden"
name="entries.id:records"
tal:attributes="value user/id"
/>
<input
type="hidden"
name="entries.type:records"
value="user"
/>
</td>
<td class="listingCheckbox">
<input class="noborder"
type="checkbox"
value="1"
name="entries.member:records"
tal:attributes="checked is_member;
disabled is_admin"
/>
<input type="hidden"
name="entries.member:records"
value="1"
tal:condition="is_admin" />
</td>
<td class="listingCheckbox">
<input class="noborder"
type="checkbox"
value="1"
name="entries.admin:records"
tal:attributes="checked is_admin;
disabled user_cannot_manage;"
/>
</td>
</tr>
</tal:entries>
</tbody>
</table>
</div>

<input id="edit-roster-save-button" class="context allowMultiSubmit" type="submit" name="form.button.Save" value="Save" i18n:attributes="value label_save" />
<input tal:replace="structure context/@@authenticator/authenticator" />

</form>
</div>
</metal:main>
</body>
</html>
2 changes: 1 addition & 1 deletion src/ploneintranet/workspace/overrides.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
name="edit-roster"
for="collective.workspace.interfaces.IHasWorkspace"
class=".browser.roster.EditRoster"
permission="cmf.ModifyPortalContent"
permission="collective.workspace.ViewRoster"
/>

</configure>
12 changes: 4 additions & 8 deletions src/ploneintranet/workspace/tests/test_roster.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from plone import api
from ploneintranet.workspace.tests.base import BaseTestCase
from ploneintranet.workspace.tests.base import FunctionalBaseTestCase
from ploneintranet.workspace.browser.roster import EditRoster
from zope.component import getMultiAdapter
from zExceptions import Forbidden
from collective.workspace.interfaces import IWorkspace
Expand Down Expand Up @@ -74,18 +75,13 @@ def test_index(self):
html
)

def test_handle_form(self):
self.request.form['form.submitted'] = True
self.request.form['form.button.Save'] = True
view = getMultiAdapter(
(self.workspace, self.request),
name='edit-roster'
)
def test_update_roster(self):
er = EditRoster(self.workspace, self.request)
# This will give forbidden - see browser test
# for further tests of this
self.assertRaises(
Forbidden,
view.handle_form,
er.update_roster,
)

def test_existing_users(self):
Expand Down

0 comments on commit 4295d41

Please sign in to comment.