collective.workspace 4.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- collective/workspace/__init__.py +22 -0
- collective/workspace/adapters.py +21 -0
- collective/workspace/browser.py +172 -0
- collective/workspace/catalog.py +15 -0
- collective/workspace/configure.zcml +117 -0
- collective/workspace/events.py +27 -0
- collective/workspace/i18n.sh +79 -0
- collective/workspace/interfaces.py +16 -0
- collective/workspace/locales/collective.workspace.pot +95 -0
- collective/workspace/locales/de/LC_MESSAGES/collective.workspace.po +92 -0
- collective/workspace/locales/de/LC_MESSAGES/plone.po +63 -0
- collective/workspace/locales/fi/LC_MESSAGES/collective.workspace.po +92 -0
- collective/workspace/locales/fi/LC_MESSAGES/plone.po +63 -0
- collective/workspace/locales/manual-collective.workspace.pot +14 -0
- collective/workspace/locales/manual-plone.pot +5 -0
- collective/workspace/locales/plone.pot +66 -0
- collective/workspace/membership.py +221 -0
- collective/workspace/pas.py +112 -0
- collective/workspace/profiles/default/actions.xml +28 -0
- collective/workspace/profiles/default/catalog.xml +10 -0
- collective/workspace/profiles/default/collective.workspace.txt +1 -0
- collective/workspace/profiles/default/metadata.xml +7 -0
- collective/workspace/profiles/default/registry.xml +29 -0
- collective/workspace/profiles/default/rolemap.xml +9 -0
- collective/workspace/setuphandlers.py +21 -0
- collective/workspace/templates/WorkspaceGroupManagerForm.zpt +85 -0
- collective/workspace/templates/team_roster.pt +108 -0
- collective/workspace/templates/team_roster_row.pt +34 -0
- collective/workspace/testing.py +66 -0
- collective/workspace/tests/__init__.py +0 -0
- collective/workspace/tests/test_example.py +22 -0
- collective/workspace/tests/test_robot.py +18 -0
- collective/workspace/tests/test_workspace.py +242 -0
- collective/workspace/tests/workspace.robot +68 -0
- collective/workspace/vocabs.py +30 -0
- collective/workspace/workspace.py +211 -0
- collective.workspace-4.0.0-py3.14-nspkg.pth +1 -0
- collective_workspace-4.0.0.dist-info/METADATA +263 -0
- collective_workspace-4.0.0.dist-info/RECORD +43 -0
- collective_workspace-4.0.0.dist-info/WHEEL +5 -0
- collective_workspace-4.0.0.dist-info/entry_points.txt +2 -0
- collective_workspace-4.0.0.dist-info/namespace_packages.txt +1 -0
- collective_workspace-4.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from AccessControl.Permissions import add_user_folders
|
|
2
|
+
from collective.workspace import pas
|
|
3
|
+
from Products.PluggableAuthService import registerMultiPlugin
|
|
4
|
+
from zope.i18nmessageid import MessageFactory
|
|
5
|
+
|
|
6
|
+
workspaceMessageFactory = MessageFactory("collective.workspace")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
registerMultiPlugin(pas.WorkspaceGroupManager.meta_type)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def initialize(context):
|
|
13
|
+
|
|
14
|
+
context.registerClass(
|
|
15
|
+
pas.WorkspaceGroupManager,
|
|
16
|
+
permission=add_user_folders,
|
|
17
|
+
constructors=(
|
|
18
|
+
pas.manage_addWorkspaceGroupManagerForm,
|
|
19
|
+
pas.addWorkspaceGroupManager,
|
|
20
|
+
),
|
|
21
|
+
visibility=None,
|
|
22
|
+
)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from collective.workspace.interfaces import IHasWorkspace
|
|
2
|
+
from plone import api
|
|
3
|
+
from plone.app.dexterity.permissions import DXFieldPermissionChecker
|
|
4
|
+
from zope.component import adapter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@adapter(IHasWorkspace)
|
|
8
|
+
class WorkspaceFieldPermissionChecker(DXFieldPermissionChecker):
|
|
9
|
+
def validate(self, field_name, vocabulary_name=None):
|
|
10
|
+
"""Override the permission checker to allow querying the users
|
|
11
|
+
vocabulary even if there is no user field in this context
|
|
12
|
+
"""
|
|
13
|
+
if (
|
|
14
|
+
field_name == "user"
|
|
15
|
+
and vocabulary_name == "plone.app.vocabularies.Users"
|
|
16
|
+
and api.user.has_permission(
|
|
17
|
+
"collective.workspace: Manage roster", obj=self.context
|
|
18
|
+
)
|
|
19
|
+
):
|
|
20
|
+
return True
|
|
21
|
+
return super().validate(field_name, vocabulary_name)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from AccessControl import getSecurityManager
|
|
2
|
+
from collections import namedtuple
|
|
3
|
+
from collective.workspace import workspaceMessageFactory as _
|
|
4
|
+
from collective.workspace.interfaces import IRosterView
|
|
5
|
+
from collective.workspace.interfaces import IWorkspace
|
|
6
|
+
from plone.autoform.base import AutoFields
|
|
7
|
+
from plone.autoform.form import AutoExtensibleForm
|
|
8
|
+
from plone.z3cform import z2
|
|
9
|
+
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|
10
|
+
from Products.statusmessages.interfaces import IStatusMessage
|
|
11
|
+
from z3c.form import button
|
|
12
|
+
from z3c.form.form import DisplayForm
|
|
13
|
+
from z3c.form.form import EditForm
|
|
14
|
+
from z3c.form.interfaces import ActionExecutionError
|
|
15
|
+
from zope.cachedescriptors.property import Lazy as lazy_property
|
|
16
|
+
from zope.interface import implementer
|
|
17
|
+
from zope.publisher.interfaces.browser import IPublishTraverse
|
|
18
|
+
|
|
19
|
+
import transaction
|
|
20
|
+
|
|
21
|
+
Action = namedtuple("Action", "label view_name permission")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@implementer(IRosterView)
|
|
25
|
+
class TeamRosterView(AutoFields, DisplayForm):
|
|
26
|
+
"""Display the roster as a table."""
|
|
27
|
+
|
|
28
|
+
row_template = ViewPageTemplateFile("templates/team_roster_row.pt")
|
|
29
|
+
|
|
30
|
+
row_actions = (
|
|
31
|
+
Action("Edit", "edit-roster", "collective.workspace: Manage roster"),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
table_actions = ()
|
|
35
|
+
|
|
36
|
+
def __init__(self, context, request):
|
|
37
|
+
self.context = context
|
|
38
|
+
self.request = request
|
|
39
|
+
self.workspace = IWorkspace(self.context)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def label(self):
|
|
43
|
+
return _("Roster: ${title}", mapping={"title": self.context.Title()})
|
|
44
|
+
|
|
45
|
+
@lazy_property
|
|
46
|
+
def schema(self):
|
|
47
|
+
return self.workspace.membership_schema
|
|
48
|
+
|
|
49
|
+
ignoreContext = True
|
|
50
|
+
|
|
51
|
+
def getContent(self):
|
|
52
|
+
return self.context
|
|
53
|
+
|
|
54
|
+
def row_views(self):
|
|
55
|
+
for membership in self.workspace:
|
|
56
|
+
for widget in self.widgets.values():
|
|
57
|
+
widget.ignoreContext = False
|
|
58
|
+
widget.context = membership
|
|
59
|
+
widget.update()
|
|
60
|
+
yield self.row_template(membership=membership)
|
|
61
|
+
|
|
62
|
+
@lazy_property
|
|
63
|
+
def can_edit_roster(self):
|
|
64
|
+
return getSecurityManager().checkPermission(
|
|
65
|
+
"collective.workspace: Manage roster", self.context
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def update(self):
|
|
69
|
+
z2.switch_on(self)
|
|
70
|
+
self.updateFieldsFromSchemata()
|
|
71
|
+
self.updateWidgets()
|
|
72
|
+
|
|
73
|
+
def render(self):
|
|
74
|
+
return self.index()
|
|
75
|
+
|
|
76
|
+
def __call__(self):
|
|
77
|
+
self.update()
|
|
78
|
+
return self.render()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@implementer(IPublishTraverse)
|
|
82
|
+
class TeamMemberEditForm(AutoExtensibleForm, EditForm):
|
|
83
|
+
def __init__(self, context, request):
|
|
84
|
+
self.context = context
|
|
85
|
+
self.request = request
|
|
86
|
+
self.workspace = IWorkspace(self.context)
|
|
87
|
+
|
|
88
|
+
key = None
|
|
89
|
+
|
|
90
|
+
def publishTraverse(self, request, name):
|
|
91
|
+
self.key = name
|
|
92
|
+
return self
|
|
93
|
+
|
|
94
|
+
@lazy_property
|
|
95
|
+
def schema(self):
|
|
96
|
+
return self.workspace.membership_schema
|
|
97
|
+
|
|
98
|
+
def updateFields(self):
|
|
99
|
+
super().updateFields()
|
|
100
|
+
# don't show the user field if we are editing
|
|
101
|
+
if self.key:
|
|
102
|
+
del self.fields["user"]
|
|
103
|
+
|
|
104
|
+
@lazy_property
|
|
105
|
+
def ignoreContext(self):
|
|
106
|
+
return not bool(self.key)
|
|
107
|
+
|
|
108
|
+
@lazy_property
|
|
109
|
+
def label(self):
|
|
110
|
+
if self.key:
|
|
111
|
+
return self.getContent()._title
|
|
112
|
+
else:
|
|
113
|
+
return _("Add Person to Roster")
|
|
114
|
+
|
|
115
|
+
@lazy_property
|
|
116
|
+
def _content(self):
|
|
117
|
+
if not self.key:
|
|
118
|
+
return self.context
|
|
119
|
+
workspace = self.workspace
|
|
120
|
+
memberdata = workspace.members[self.key]
|
|
121
|
+
return workspace.membership_factory(workspace, memberdata)
|
|
122
|
+
|
|
123
|
+
def getContent(self):
|
|
124
|
+
return self._content
|
|
125
|
+
|
|
126
|
+
def validateInvariants(self, membership):
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
@button.buttonAndHandler(_("Save"))
|
|
130
|
+
def handleSave(self, action):
|
|
131
|
+
data, errors = self.extractData()
|
|
132
|
+
if errors:
|
|
133
|
+
self.status = self.formErrorsMessage
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
status = _("Changes saved")
|
|
137
|
+
|
|
138
|
+
if self.key:
|
|
139
|
+
membership = self.getContent()
|
|
140
|
+
membership.update(data)
|
|
141
|
+
else:
|
|
142
|
+
# Add new roster member
|
|
143
|
+
membership = self.workspace.add_to_team(**data)
|
|
144
|
+
status = _("User added")
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
self.validateInvariants(membership)
|
|
148
|
+
except ActionExecutionError:
|
|
149
|
+
# make sure above changes won't be persisted
|
|
150
|
+
transaction.abort()
|
|
151
|
+
raise
|
|
152
|
+
|
|
153
|
+
self._finished = True
|
|
154
|
+
IStatusMessage(self.request).addStatusMessage(status, "info")
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def can_remove(self):
|
|
158
|
+
return self.key
|
|
159
|
+
|
|
160
|
+
@button.buttonAndHandler(_("Remove"), condition=lambda self: self.can_remove)
|
|
161
|
+
def handleRemove(self, action):
|
|
162
|
+
membership = self.getContent()
|
|
163
|
+
membership.remove_from_team()
|
|
164
|
+
self._finished = True
|
|
165
|
+
IStatusMessage(self.request).addStatusMessage(_("User removed"), "info")
|
|
166
|
+
|
|
167
|
+
_finished = False
|
|
168
|
+
|
|
169
|
+
def render(self):
|
|
170
|
+
if self._finished:
|
|
171
|
+
return " "
|
|
172
|
+
return super().render()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .interfaces import IHasWorkspace
|
|
2
|
+
from .interfaces import IWorkspace
|
|
3
|
+
from plone.indexer import indexer
|
|
4
|
+
from zope.interface import Interface
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@indexer(IHasWorkspace)
|
|
8
|
+
def workspace_members(self):
|
|
9
|
+
workspace = IWorkspace(self)
|
|
10
|
+
return set(workspace.members or [])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@indexer(Interface)
|
|
14
|
+
def null_indexer(self):
|
|
15
|
+
raise AttributeError
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<configure
|
|
2
|
+
xmlns="http://namespaces.zope.org/zope"
|
|
3
|
+
xmlns:browser="http://namespaces.zope.org/browser"
|
|
4
|
+
xmlns:five="http://namespaces.zope.org/five"
|
|
5
|
+
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
|
6
|
+
xmlns:i18n="http://namespaces.zope.org/i18n"
|
|
7
|
+
xmlns:plone="http://namespaces.plone.org/plone"
|
|
8
|
+
i18n_domain="collective.workspace"
|
|
9
|
+
>
|
|
10
|
+
|
|
11
|
+
<five:registerPackage
|
|
12
|
+
package="."
|
|
13
|
+
initialize=".initialize"
|
|
14
|
+
/>
|
|
15
|
+
<i18n:registerTranslations directory="locales" />
|
|
16
|
+
|
|
17
|
+
<include package="plone.app.dexterity" />
|
|
18
|
+
|
|
19
|
+
<permission
|
|
20
|
+
id="collective.workspace.ViewRoster"
|
|
21
|
+
title="collective.workspace: View roster"
|
|
22
|
+
>
|
|
23
|
+
<role name="TeamMember" />
|
|
24
|
+
<role name="TeamGuest" />
|
|
25
|
+
<role name="TeamManager" />
|
|
26
|
+
<role name="Site Administrator" />
|
|
27
|
+
<role name="Manager" />
|
|
28
|
+
<role name="Owner" />
|
|
29
|
+
</permission>
|
|
30
|
+
|
|
31
|
+
<permission
|
|
32
|
+
id="collective.workspace.ManageRoster"
|
|
33
|
+
title="collective.workspace: Manage roster"
|
|
34
|
+
>
|
|
35
|
+
<role name="TeamManager" />
|
|
36
|
+
<role name="Site Administrator" />
|
|
37
|
+
<role name="Manager" />
|
|
38
|
+
<role name="Owner" />
|
|
39
|
+
</permission>
|
|
40
|
+
|
|
41
|
+
<genericsetup:registerProfile
|
|
42
|
+
name="default"
|
|
43
|
+
title="collective.workspace"
|
|
44
|
+
description="Installs the collective.workspace package"
|
|
45
|
+
provides="Products.GenericSetup.interfaces.EXTENSION"
|
|
46
|
+
directory="profiles/default"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
<genericsetup:importStep
|
|
50
|
+
name="collective.workspace_various"
|
|
51
|
+
title="collective.workspace various"
|
|
52
|
+
description=""
|
|
53
|
+
handler=".setuphandlers.setup_pas"
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<plone:behavior
|
|
57
|
+
name="collective.workspace.team_workspace"
|
|
58
|
+
title="Team workspace"
|
|
59
|
+
description="This item is a team workspace."
|
|
60
|
+
factory=".workspace.Workspace"
|
|
61
|
+
provides=".interfaces.IWorkspace"
|
|
62
|
+
for="plone.dexterity.interfaces.IDexterityContent"
|
|
63
|
+
marker=".interfaces.IHasWorkspace"
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
<browser:page
|
|
67
|
+
name="team-roster"
|
|
68
|
+
for=".interfaces.IHasWorkspace"
|
|
69
|
+
class=".browser.TeamRosterView"
|
|
70
|
+
template="templates/team_roster.pt"
|
|
71
|
+
permission="collective.workspace.ViewRoster"
|
|
72
|
+
/>
|
|
73
|
+
|
|
74
|
+
<browser:page
|
|
75
|
+
name="edit-roster"
|
|
76
|
+
for=".interfaces.IHasWorkspace"
|
|
77
|
+
class=".browser.TeamMemberEditForm"
|
|
78
|
+
permission="collective.workspace.ManageRoster"
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<utility
|
|
82
|
+
name="collective.workspace.groups"
|
|
83
|
+
component=".vocabs.TeamGroupsVocabulary"
|
|
84
|
+
/>
|
|
85
|
+
|
|
86
|
+
<adapter factory=".adapters.WorkspaceFieldPermissionChecker" />
|
|
87
|
+
|
|
88
|
+
<adapter
|
|
89
|
+
factory=".pas.WorkspaceRoles"
|
|
90
|
+
for=".interfaces.IHasWorkspace"
|
|
91
|
+
name="collective.workspace"
|
|
92
|
+
/>
|
|
93
|
+
|
|
94
|
+
<adapter factory=".membership.workspace_from_membership" />
|
|
95
|
+
|
|
96
|
+
<utility
|
|
97
|
+
factory=".pas.TeamManagerRoleDelegation"
|
|
98
|
+
provides="plone.app.workflow.interfaces.ISharingPageRole"
|
|
99
|
+
name="TeamManager"
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<adapter
|
|
103
|
+
factory=".catalog.workspace_members"
|
|
104
|
+
name="workspace_members"
|
|
105
|
+
/>
|
|
106
|
+
<adapter
|
|
107
|
+
factory=".catalog.null_indexer"
|
|
108
|
+
name="workspace_members"
|
|
109
|
+
/>
|
|
110
|
+
|
|
111
|
+
<subscriber handler=".workspace.handle_workspace_added" />
|
|
112
|
+
<subscriber handler=".workspace.handle_workspace_modified" />
|
|
113
|
+
<subscriber handler=".workspace.handle_workspace_removed" />
|
|
114
|
+
<subscriber handler=".workspace.handle_workspace_copied" />
|
|
115
|
+
<subscriber handler=".workspace.handle_principal_deleted" />
|
|
116
|
+
|
|
117
|
+
</configure>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from zope.interface.interfaces import ObjectEvent
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TeamMemberEvent(ObjectEvent):
|
|
5
|
+
"""Base for team member events.
|
|
6
|
+
|
|
7
|
+
This is used instead of normal Zope object lifecycle
|
|
8
|
+
events so it can be dispatched based on the workspace
|
|
9
|
+
rather than based on the modified object (which is
|
|
10
|
+
just a dictionary in this case).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, object, membership):
|
|
14
|
+
self.object = object
|
|
15
|
+
self.membership = membership
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TeamMemberAddedEvent(TeamMemberEvent):
|
|
19
|
+
"""Event for when a member is added."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TeamMemberRemovedEvent(TeamMemberEvent):
|
|
23
|
+
"""Event for when a member is removed."""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TeamMemberModifiedEvent(TeamMemberEvent):
|
|
27
|
+
"""Event for when a member is modified."""
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# Shell script to manage .po files.
|
|
4
|
+
#
|
|
5
|
+
# Run this file in the folder main __init__.py of product
|
|
6
|
+
#
|
|
7
|
+
# E.g. if your product is yourproduct.name
|
|
8
|
+
# you run this file in yourproduct.name/yourproduct/name
|
|
9
|
+
#
|
|
10
|
+
#
|
|
11
|
+
# Copyright 2010 mFabrik http://mfabrik.com
|
|
12
|
+
#
|
|
13
|
+
# http://plone.org/documentation/manual/plone-community-developer-documentation/i18n/localization
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
# Assume the product name is the current folder name
|
|
17
|
+
CURRENT_PATH=`pwd`
|
|
18
|
+
CATALOGNAMES="collective.workspace plone"
|
|
19
|
+
|
|
20
|
+
# List of languages
|
|
21
|
+
LANGUAGES="de"
|
|
22
|
+
|
|
23
|
+
# Create locales folder structure for languages
|
|
24
|
+
install -d locales
|
|
25
|
+
for lang in $LANGUAGES; do
|
|
26
|
+
install -d locales/$lang/LC_MESSAGES
|
|
27
|
+
done
|
|
28
|
+
|
|
29
|
+
I18NDUDE=~/Plone/zinstance/bin/i18ndude
|
|
30
|
+
|
|
31
|
+
if test ! -e $I18NDUDE; then
|
|
32
|
+
echo "You must install i18ndude with buildout"
|
|
33
|
+
echo "See https://github.com/collective/collective.developermanual/blob/master/source/i18n/localization.txt"
|
|
34
|
+
exit
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Do we need to merge manual PO entries from a file called manual.pot.
|
|
39
|
+
# this option is later passed to i18ndude
|
|
40
|
+
#
|
|
41
|
+
|
|
42
|
+
for catalogname in $CATALOGNAMES; do
|
|
43
|
+
echo "Catalog: ${catalogname}"
|
|
44
|
+
if test -e locales/manual-${catalogname}.pot; then
|
|
45
|
+
echo "Manual PO entries detected"
|
|
46
|
+
MERGE="--merge locales/manual-${catalogname}.pot"
|
|
47
|
+
else
|
|
48
|
+
echo "No manual PO entries detected"
|
|
49
|
+
MERGE=""
|
|
50
|
+
fi
|
|
51
|
+
$I18NDUDE rebuild-pot --pot locales/$catalogname.pot $MERGE --create $catalogname .
|
|
52
|
+
echo ""
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# Rebuild .pot
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Compile po files
|
|
59
|
+
for lang in $(find locales -mindepth 1 -maxdepth 1 -type d); do
|
|
60
|
+
|
|
61
|
+
if test -d $lang/LC_MESSAGES; then
|
|
62
|
+
|
|
63
|
+
for catalogname in $CATALOGNAMES; do
|
|
64
|
+
|
|
65
|
+
PO=$lang/LC_MESSAGES/${catalogname}.po
|
|
66
|
+
|
|
67
|
+
# Create po file if not exists
|
|
68
|
+
touch $PO
|
|
69
|
+
|
|
70
|
+
# Sync po file
|
|
71
|
+
echo "Syncing $PO"
|
|
72
|
+
$I18NDUDE sync --pot locales/$catalogname.pot $PO
|
|
73
|
+
echo ""
|
|
74
|
+
|
|
75
|
+
done
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
done
|
|
79
|
+
#!/bin/sh
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from zope.i18nmessageid import MessageFactory
|
|
2
|
+
from zope.interface import Interface
|
|
3
|
+
|
|
4
|
+
_ = MessageFactory("collective.workspace")
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class IHasWorkspace(Interface):
|
|
8
|
+
"""Marker for team workspaces."""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IWorkspace(Interface):
|
|
12
|
+
"""Interface for interacting with an item's workspace features."""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class IRosterView(Interface):
|
|
16
|
+
"""Marker for display view of a roster."""
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# --- PLEASE EDIT THE LINES BELOW CORRECTLY ---
|
|
2
|
+
# SOME DESCRIPTIVE TITLE.
|
|
3
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
4
|
+
msgid ""
|
|
5
|
+
msgstr ""
|
|
6
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
7
|
+
"POT-Creation-Date: 2017-06-14 09:07+0000\n"
|
|
8
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
|
|
9
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
10
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
11
|
+
"MIME-Version: 1.0\n"
|
|
12
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
13
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
14
|
+
"Plural-Forms: nplurals=1; plural=0\n"
|
|
15
|
+
"Language-Code: en\n"
|
|
16
|
+
"Language-Name: English\n"
|
|
17
|
+
"Preferred-Encodings: utf-8 latin1\n"
|
|
18
|
+
"Domain: DOMAIN\n"
|
|
19
|
+
|
|
20
|
+
#: collective/workspace/templates/team_roster.pt:15
|
|
21
|
+
msgid "+ Add person to roster"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#: collective/workspace/browser.py:119
|
|
25
|
+
msgid "Add Person to Roster"
|
|
26
|
+
msgstr ""
|
|
27
|
+
|
|
28
|
+
msgid "Admins"
|
|
29
|
+
msgstr ""
|
|
30
|
+
|
|
31
|
+
#: collective/workspace/pas.py:333
|
|
32
|
+
msgid "Can edit roster"
|
|
33
|
+
msgstr ""
|
|
34
|
+
|
|
35
|
+
#: collective/workspace/browser.py:141
|
|
36
|
+
msgid "Changes saved"
|
|
37
|
+
msgstr ""
|
|
38
|
+
|
|
39
|
+
msgid "Edit"
|
|
40
|
+
msgstr ""
|
|
41
|
+
|
|
42
|
+
#: collective/workspace/membership.py:37
|
|
43
|
+
msgid "Groups"
|
|
44
|
+
msgstr ""
|
|
45
|
+
|
|
46
|
+
msgid "Guests"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#: collective/workspace/configure.zcml:42
|
|
50
|
+
msgid "Installs the collective.workspace package"
|
|
51
|
+
msgstr ""
|
|
52
|
+
|
|
53
|
+
#: collective/workspace/membership.py:31
|
|
54
|
+
msgid "Position"
|
|
55
|
+
msgstr ""
|
|
56
|
+
|
|
57
|
+
#: collective/workspace/browser.py:166
|
|
58
|
+
msgid "Remove"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#: collective/workspace/browser.py:44
|
|
62
|
+
msgid "Roster: ${title}"
|
|
63
|
+
msgstr ""
|
|
64
|
+
|
|
65
|
+
#: collective/workspace/browser.py:135
|
|
66
|
+
msgid "Save"
|
|
67
|
+
msgstr ""
|
|
68
|
+
|
|
69
|
+
#: collective/workspace/templates/team_roster.pt:46
|
|
70
|
+
msgid "Selected people:"
|
|
71
|
+
msgstr ""
|
|
72
|
+
|
|
73
|
+
#: collective/workspace/configure.zcml:57
|
|
74
|
+
msgid "Team workspace"
|
|
75
|
+
msgstr ""
|
|
76
|
+
|
|
77
|
+
#: collective/workspace/configure.zcml:57
|
|
78
|
+
msgid "This item is a team workspace."
|
|
79
|
+
msgstr ""
|
|
80
|
+
|
|
81
|
+
#: collective/workspace/membership.py:26
|
|
82
|
+
msgid "User"
|
|
83
|
+
msgstr ""
|
|
84
|
+
|
|
85
|
+
#: collective/workspace/browser.py:149
|
|
86
|
+
msgid "User added"
|
|
87
|
+
msgstr ""
|
|
88
|
+
|
|
89
|
+
#: collective/workspace/browser.py:172
|
|
90
|
+
msgid "User removed"
|
|
91
|
+
msgstr ""
|
|
92
|
+
|
|
93
|
+
#: collective/workspace/configure.zcml:42
|
|
94
|
+
msgid "collective.workspace"
|
|
95
|
+
msgstr ""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
4
|
+
"POT-Creation-Date: 2017-06-14 09:07+0000\n"
|
|
5
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
|
|
6
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
7
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
8
|
+
"MIME-Version: 1.0\n"
|
|
9
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
10
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
11
|
+
"Plural-Forms: nplurals=1; plural=0\n"
|
|
12
|
+
"Language-Code: en\n"
|
|
13
|
+
"Language-Name: English\n"
|
|
14
|
+
"Preferred-Encodings: utf-8 latin1\n"
|
|
15
|
+
"Domain: DOMAIN\n"
|
|
16
|
+
|
|
17
|
+
#: collective/workspace/templates/team_roster.pt:15
|
|
18
|
+
msgid "+ Add person to roster"
|
|
19
|
+
msgstr "+ Person zum Team hinzufügen"
|
|
20
|
+
|
|
21
|
+
#: collective/workspace/browser.py:119
|
|
22
|
+
msgid "Add Person to Roster"
|
|
23
|
+
msgstr "Eine Person zum Team hinzufügen"
|
|
24
|
+
|
|
25
|
+
msgid "Admins"
|
|
26
|
+
msgstr ""
|
|
27
|
+
|
|
28
|
+
#: collective/workspace/pas.py:333
|
|
29
|
+
msgid "Can edit roster"
|
|
30
|
+
msgstr "Kann Team bearbeiten"
|
|
31
|
+
|
|
32
|
+
#: collective/workspace/browser.py:141
|
|
33
|
+
msgid "Changes saved"
|
|
34
|
+
msgstr "Änderungen gespeichert"
|
|
35
|
+
|
|
36
|
+
msgid "Edit"
|
|
37
|
+
msgstr "Bearbeiten"
|
|
38
|
+
|
|
39
|
+
#: collective/workspace/membership.py:37
|
|
40
|
+
msgid "Groups"
|
|
41
|
+
msgstr "Gruppen"
|
|
42
|
+
|
|
43
|
+
msgid "Guests"
|
|
44
|
+
msgstr ""
|
|
45
|
+
|
|
46
|
+
#: collective/workspace/configure.zcml:42
|
|
47
|
+
msgid "Installs the collective.workspace package"
|
|
48
|
+
msgstr ""
|
|
49
|
+
|
|
50
|
+
#: collective/workspace/membership.py:31
|
|
51
|
+
msgid "Position"
|
|
52
|
+
msgstr "Position"
|
|
53
|
+
|
|
54
|
+
#: collective/workspace/browser.py:166
|
|
55
|
+
msgid "Remove"
|
|
56
|
+
msgstr "Entfernen"
|
|
57
|
+
|
|
58
|
+
#: collective/workspace/browser.py:44
|
|
59
|
+
msgid "Roster: ${title}"
|
|
60
|
+
msgstr "Teamverwaltung: ${title}"
|
|
61
|
+
|
|
62
|
+
#: collective/workspace/browser.py:135
|
|
63
|
+
msgid "Save"
|
|
64
|
+
msgstr "Speichern"
|
|
65
|
+
|
|
66
|
+
#: collective/workspace/templates/team_roster.pt:46
|
|
67
|
+
msgid "Selected people:"
|
|
68
|
+
msgstr "Ausgewählte Personen"
|
|
69
|
+
|
|
70
|
+
#: collective/workspace/configure.zcml:57
|
|
71
|
+
msgid "Team workspace"
|
|
72
|
+
msgstr ""
|
|
73
|
+
|
|
74
|
+
#: collective/workspace/configure.zcml:57
|
|
75
|
+
msgid "This item is a team workspace."
|
|
76
|
+
msgstr ""
|
|
77
|
+
|
|
78
|
+
#: collective/workspace/membership.py:26
|
|
79
|
+
msgid "User"
|
|
80
|
+
msgstr "Benutzer"
|
|
81
|
+
|
|
82
|
+
#: collective/workspace/browser.py:149
|
|
83
|
+
msgid "User added"
|
|
84
|
+
msgstr ""
|
|
85
|
+
|
|
86
|
+
#: collective/workspace/browser.py:172
|
|
87
|
+
msgid "User removed"
|
|
88
|
+
msgstr "Benutzer entfernt"
|
|
89
|
+
|
|
90
|
+
#: collective/workspace/configure.zcml:42
|
|
91
|
+
msgid "collective.workspace"
|
|
92
|
+
msgstr ""
|