mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-23 01:32:25 +02:00
Merge conflict
This commit is contained in:
parent
20c0813f78
commit
908e06c8eb
7 changed files with 20 additions and 21 deletions
|
@ -36,7 +36,6 @@
|
|||
</form>
|
||||
</section>
|
||||
</div>
|
||||
{% if member_count and member_count > 0 %}
|
||||
<div class="section-outlined__utility-button mobile-lg:padding-right-105 {% if portfolio %} mobile:grid-col-12 desktop:grid-col-6 desktop:padding-left-3{% endif %}">
|
||||
<section aria-label="Domains report component" class="margin-top-205">
|
||||
<a href="{% url 'export_members_portfolio' %}" class="usa-button usa-button--unstyled usa-button--with-icon usa-button--justify-right" role="button">
|
||||
|
@ -46,7 +45,6 @@
|
|||
</a>
|
||||
</section>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- ---------- MAIN TABLE ---------- -->
|
||||
|
|
|
@ -812,7 +812,7 @@ class MemberExportTest(MockDbForIndividualTests, MockEppLib):
|
|||
@override_flag("organization_members", active=True)
|
||||
@less_console_noise_decorator
|
||||
def test_member_export(self):
|
||||
"""Tests the member export report"""
|
||||
"""Tests the member export report by comparing the csv output."""
|
||||
content_type = ContentType.objects.get_for_model(PortfolioInvitation)
|
||||
LogEntry.objects.create(
|
||||
user=self.lebowski_user,
|
||||
|
|
|
@ -175,7 +175,7 @@ class MemberExport(BaseExport):
|
|||
"additional_permissions_display",
|
||||
"member_display",
|
||||
"domain_info",
|
||||
"source",
|
||||
"type",
|
||||
"invitation_date",
|
||||
"invited_by",
|
||||
]
|
||||
|
|
|
@ -280,10 +280,12 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation):
|
|||
F("user__last_login"), Value("YYYY-MM-DD"), function="to_char", output_field=TextField()
|
||||
)
|
||||
else:
|
||||
# an array of domains, with id and name, colon separated
|
||||
domain_query = Concat(
|
||||
F("user__permissions__domain_id"),
|
||||
Value(":"),
|
||||
F("user__permissions__domain__name"),
|
||||
# specify the output_field to ensure union has same column types
|
||||
output_field=CharField(),
|
||||
)
|
||||
last_active_query = Cast(F("user__last_login"), output_field=TextField())
|
||||
|
@ -299,7 +301,9 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation):
|
|||
),
|
||||
"additional_permissions_display": F("additional_permissions"),
|
||||
"member_display": Case(
|
||||
# If email is present and not blank, use email
|
||||
When(Q(user__email__isnull=False) & ~Q(user__email=""), then=F("user__email")),
|
||||
# If first name or last name is present, use concatenation of first_name + " " + last_name
|
||||
When(
|
||||
Q(user__first_name__isnull=False) | Q(user__last_name__isnull=False),
|
||||
then=Concat(
|
||||
|
@ -308,16 +312,18 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation):
|
|||
Coalesce(F("user__last_name"), Value("")),
|
||||
),
|
||||
),
|
||||
# If neither, use an empty string
|
||||
default=Value(""),
|
||||
output_field=CharField(),
|
||||
),
|
||||
"domain_info": ArrayAgg(
|
||||
domain_query,
|
||||
distinct=True,
|
||||
# only include domains in portfolio
|
||||
filter=Q(user__permissions__domain__isnull=False)
|
||||
& Q(user__permissions__domain__domain_info__portfolio=portfolio),
|
||||
),
|
||||
"source": Value("permission", output_field=CharField()),
|
||||
"type": Value("member", output_field=CharField()),
|
||||
"invitation_date": PortfolioInvitationModelAnnotation.get_invitation_date_query(
|
||||
object_id_query=cls.get_portfolio_invitation_id_query()
|
||||
),
|
||||
|
@ -452,13 +458,14 @@ class PortfolioInvitationModelAnnotation(BaseModelAnnotation):
|
|||
"last_active": Value("Invited", output_field=TextField()),
|
||||
"additional_permissions_display": F("additional_permissions"),
|
||||
"member_display": F("email"),
|
||||
# Use ArrayRemove to return an empty list when no domain invitations are found
|
||||
"domain_info": ArrayRemoveNull(
|
||||
ArrayAgg(
|
||||
Subquery(domain_invitations.values("domain_info")),
|
||||
distinct=True,
|
||||
)
|
||||
),
|
||||
"source": Value("invitation", output_field=CharField()),
|
||||
"type": Value("invitedmember", output_field=CharField()),
|
||||
"invitation_date": cls.get_invitation_date_query(
|
||||
object_id_query=Cast(OuterRef("id"), output_field=TextField())
|
||||
),
|
||||
|
|
|
@ -66,7 +66,7 @@ class PortfolioMembersJson(PortfolioMembersPermission, View):
|
|||
"additional_permissions_display",
|
||||
"member_display",
|
||||
"domain_info",
|
||||
"source",
|
||||
"type",
|
||||
)
|
||||
|
||||
def initial_invitations_search(self, portfolio):
|
||||
|
@ -83,7 +83,7 @@ class PortfolioMembersJson(PortfolioMembersPermission, View):
|
|||
"additional_permissions_display",
|
||||
"member_display",
|
||||
"domain_info",
|
||||
"source",
|
||||
"type",
|
||||
)
|
||||
|
||||
def apply_search_term(self, queryset, request):
|
||||
|
@ -119,12 +119,12 @@ class PortfolioMembersJson(PortfolioMembersPermission, View):
|
|||
view_only = not user.has_edit_members_portfolio_permission(portfolio) or not user_can_edit_other_users
|
||||
|
||||
is_admin = UserPortfolioRoleChoices.ORGANIZATION_ADMIN in (item.get("roles") or [])
|
||||
action_url = reverse("member" if item["source"] == "permission" else "invitedmember", kwargs={"pk": item["id"]})
|
||||
action_url = reverse(item["type"], kwargs={"pk": item["id"]})
|
||||
|
||||
# Serialize member data
|
||||
member_json = {
|
||||
"id": item.get("id", ""),
|
||||
"source": item.get("source", ""),
|
||||
"id": item.get("id", ""), # id is id of UserPortfolioPermission or PortfolioInvitation
|
||||
"type": item.get("type", ""), # source is member or invitedmember
|
||||
"name": " ".join(filter(None, [item.get("first_name", ""), item.get("last_name", "")])),
|
||||
"email": item.get("email_display", ""),
|
||||
"member_display": item.get("member_display", ""),
|
||||
|
|
|
@ -461,14 +461,7 @@ class PortfolioMembersView(PortfolioMembersPermissionView, View):
|
|||
|
||||
def get(self, request):
|
||||
"""Add additional context data to the template."""
|
||||
# Get portfolio from session
|
||||
portfolio = request.session.get("portfolio")
|
||||
context = {}
|
||||
if portfolio:
|
||||
user_count = portfolio.portfolio_users.count()
|
||||
invitation_count = PortfolioInvitation.objects.filter(portfolio=portfolio).count()
|
||||
context.update({"member_count": user_count + invitation_count})
|
||||
return render(request, "portfolio_members.html", context=context)
|
||||
return render(request, "portfolio_members.html")
|
||||
|
||||
|
||||
class NewMemberView(PortfolioMembersPermissionView, FormMixin):
|
||||
|
|
|
@ -175,9 +175,10 @@ class ExportMembersPortfolio(View):
|
|||
def get(self, request, *args, **kwargs):
|
||||
"""Returns the members report"""
|
||||
|
||||
portfolio_display = "portfolio"
|
||||
# Swap the spaces for dashes to make the formatted name look prettier
|
||||
portfolio_display = "organization"
|
||||
if request.session.get("portfolio"):
|
||||
portfolio_display = str(request.session.get("portfolio")).replace(" ", "-")
|
||||
portfolio_display = str(request.session.get("portfolio")).lower().replace(" ", "-")
|
||||
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = f'attachment; filename="members-for-{portfolio_display}.csv"'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue