Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
485 changes: 484 additions & 1 deletion tests/test_contributors_views.py

Large diffs are not rendered by default.

25 changes: 18 additions & 7 deletions website/profile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def get_profile_image_url(user, size=settings.PROFILE_IMAGE_MEDIUM):
use_ssl=True,
size=size)

def serialize_user(user, node=None, admin=False, full=False, is_profile=False, include_node_counts=False):
def serialize_user(user, node=None, admin=False, full=False, is_profile=False, include_node_counts=False, invite_date=None, include_email=False):
"""
Return a dictionary representation of a registered user.

Expand All @@ -34,6 +34,11 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
contrib = user
user = contrib.user
fullname = user.display_full_name(node=node)
institution = None
prefetch_cache = getattr(user, '_prefetched_objects_cache', {})
if 'affiliated_institutions' in prefetch_cache:
affiliated = list(user.affiliated_institutions.all())
institution = sorted(affiliated, key=lambda i: i.pk)[0] if affiliated else None
idp_attrs = user.get_idp_attr()

# @R2022-48
Expand Down Expand Up @@ -92,8 +97,11 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
'mfa_url': mfa_url, # @R-2023-55
'is_mfa': is_mfa, # @R-2023-55
'have_email': user.have_email,
'idp_email': idp_attrs.get('email'),
'affiliation': institution.name if institution else '',
'invite_date': invite_date,
}
if include_email:
ret['email'] = user.username if user.have_email else ''
if node is not None:
if admin:
flags = {
Expand Down Expand Up @@ -123,6 +131,7 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
if full:
# Add emails
if is_profile:
ret['idp_email'] = idp_attrs.get('email')
ret['emails'] = [
{
'address': each,
Expand Down Expand Up @@ -202,11 +211,13 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
return ret


def serialize_contributors(contribs, node, **kwargs):
return [
serialize_user(contrib, node, **kwargs)
for contrib in contribs.iterator()
]
def serialize_contributors(contribs, node, invite_dates=None, **kwargs):
result = []
for contrib in contribs:
user_obj = contrib.user if isinstance(contrib, Contributor) else contrib
date = invite_dates.get(user_obj._id) if invite_dates else None
result.append(serialize_user(contrib, node, invite_date=date, **kwargs))
return result


def serialize_visible_contributors(node):
Expand Down
55 changes: 51 additions & 4 deletions website/project/views/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,17 +522,64 @@ def node_choose_addons(auth, node, **kwargs):
node.config_addons(request.json, auth)


def _get_contributor_invite_dates(node, contributor_guids):
invite_dates = {}

# Include admin_contributor_added to cover proxy-registration additions (代理登録)
for log in NodeLog.objects.filter(
node=node,
action__in=[NodeLog.CONTRIB_ADDED, NodeLog.ADMIN_CONTRIB_ADDED],
).order_by('date').values('date', 'params'):
for user_guid in log['params'].get('contributors', []):
if isinstance(user_guid, str):
invite_dates[user_guid] = log['date'].strftime('%Y-%m-%d')

node_created = node.created.strftime('%Y-%m-%d')

# Fallback for contributors with no log entry (e.g. project creator, contributors inherited
# from a parent when creating a component). Uses the node creation date as the invite date.
for guid in contributor_guids:
if guid not in invite_dates:
invite_dates[guid] = node_created

return invite_dates


@must_be_valid_project
@must_not_be_retracted_registration
@must_have_permission(READ)
@ember_flag_is_active(features.EMBER_PROJECT_CONTRIBUTORS)
def node_contributors(auth, node, **kwargs):
ret = _view_project(node, auth, primary=True)
contribs = node.contributor_set.include('user__groups', 'user__guids', 'user__ext')
ret['contributors'] = utils.serialize_contributors(contribs, node)
is_admin = node.has_permission(auth.user, ADMIN)

contrib_includes = ['user__groups', 'user__guids', 'user__ext']
admin_includes = ['groups', 'guids', 'ext']
if is_admin:
contrib_includes.append('user__affiliated_institutions')
admin_includes.append('affiliated_institutions')

contribs = node.contributor_set.include(*contrib_includes)
admin_contribs = node.parent_admin_contributors.include(*admin_includes)

invite_dates = None
admin_invite_dates = None
if is_admin:
contribs = list(contribs)
admin_contribs = list(admin_contribs)
invite_dates = _get_contributor_invite_dates(node, [c.user._id for c in contribs])
node_created = node.created.strftime('%Y-%m-%d')
admin_invite_dates = {u._id: node_created for u in admin_contribs}

ret['contributors'] = utils.serialize_contributors(
contribs, node, invite_dates=invite_dates, include_email=is_admin
)
ret['access_requests'] = utils.serialize_access_requests(node)
admin_contribs = node.parent_admin_contributors.include('groups', 'guids', 'ext')
ret['adminContributors'] = utils.serialize_contributors(admin_contribs, node, admin=True)
ret['adminContributors'] = utils.serialize_contributors(
admin_contribs, node, admin=True,
invite_dates=admin_invite_dates, include_email=is_admin
)

return ret

@must_be_valid_project
Expand Down
12 changes: 11 additions & 1 deletion website/templates/project/contributors.mako
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@
data-bind="css: {sortable: ($data === 'contrib' && $root.isSortable())}" style="min-width: 100px;white-space: nowrap;">${_("Name")}
</th>
<th style="min-width: 140px;width: 200px;white-space: nowrap;"></th>
% if permissions.ADMIN in user['permissions']:
<th style="min-width: 180px;width: 220px;white-space: nowrap;">${_("E-mail")}</th>
<th style="min-width: 180px;width: 220px;white-space: nowrap;">${_("Affiliated Institutions")}</th>
<th style="min-width: 90px;width: 100px;white-space: nowrap;">${_("Invite Date")}</th>
% endif
<th style="min-width: 150px;width: 160px;white-space: nowrap;">
${_("Permissions")}
<i class="fa fa-question-circle permission-info"
Expand All @@ -192,7 +197,7 @@
data-html="true"
></i>
</th>
<th class="biblio-contrib" style="min-width:144px;white-space: nowrap;">
<th class="biblio-contrib" style="min-width:100px;width:110px;white-space: nowrap;">
${_("Bibliographic Contributor")}
<i class="fa fa-question-circle visibility-info"
data-toggle="popover"
Expand Down Expand Up @@ -290,6 +295,11 @@
<a class="name-search" data-bind="text: contributor.shortname, attr:{href: profileUrl}"></a>
</span>
</td>
% if permissions.ADMIN in user['permissions']:
<td class="table-only" data-bind="text: contributor.email || '-'"></td>
<td class="table-only" data-bind="text: contributor.affiliation || '-'"></td>
<td class="table-only" data-bind="text: contributor.invite_date || '-'"></td>
% endif
<td class="permissions">
<div class="header" data-bind="visible: contributor.expanded() && $root.collapsed()"></div>
<div class="td-content" data-bind="visible: !$root.collapsed() || contributor.expanded()">
Expand Down
8 changes: 8 additions & 0 deletions website/translations/en/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -2871,6 +2871,14 @@ msgstr ""
msgid "Non-Bibliographic"
msgstr ""

#: website/templates/project/contributors.mako:187
msgid "Affiliated Institutions"
msgstr ""

#: website/templates/project/contributors.mako:188
msgid "Invite Date"
msgstr ""

#: website/templates/project/contributors.mako:63
msgid "Drag and drop contributors to change listing order."
msgstr ""
Expand Down
10 changes: 9 additions & 1 deletion website/translations/ja/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -3315,7 +3315,7 @@ msgstr "読込み"
#: website/templates/project/contributors.mako:243
#: website/templates/project/modal_add_contributor.mako:218
msgid "Bibliographic Contributor"
msgstr "目録表示メンバー"
msgstr "目録表示"

#: website/templates/project/contributors.mako:36
#: website/templates/project/contributors.mako:199
Expand All @@ -3332,6 +3332,14 @@ msgstr "目録で表示"
msgid "Non-Bibliographic"
msgstr "目録で非表示"

#: website/templates/project/contributors.mako:187
msgid "Affiliated Institutions"
msgstr "所属機関"

#: website/templates/project/contributors.mako:188
msgid "Invite Date"
msgstr "招待日"

#: website/templates/project/contributors.mako:63
msgid "Drag and drop contributors to change listing order."
msgstr "メンバーをドラッグ&ドロップして、リストの順序を変更します。"
Expand Down
8 changes: 8 additions & 0 deletions website/translations/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -3240,6 +3240,14 @@ msgstr ""
msgid "Non-Bibliographic"
msgstr ""

#: website/templates/project/contributors.mako:187
msgid "Affiliated Institutions"
msgstr ""

#: website/templates/project/contributors.mako:188
msgid "Invite Date"
msgstr ""

#: website/templates/project/contributors.mako:63
msgid "Drag and drop contributors to change listing order."
msgstr ""
Expand Down
Loading