Give org owners a screen to manage and contact their member teams. Fixes #106
This commit is contained in:
parent
15011e9ffd
commit
96cad889c6
7 changed files with 247 additions and 2 deletions
|
@ -456,6 +456,10 @@ class OrganizationForm(forms.ModelForm):
|
|||
'cover_img',
|
||||
]
|
||||
|
||||
class OrgContactForm(forms.Form):
|
||||
to = forms.ChoiceField(label=_(""))
|
||||
body = forms.CharField(label=_(""), widget=forms.widgets.Textarea)
|
||||
|
||||
class RequestToJoinOrgForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = OrgTeamRequest
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{% extends "get_together/emails/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h3>Message from {{org.name|striptags}}</h3>
|
||||
|
||||
<p><strong>Sender</strong>: {{ sender|striptags }}<br></p>
|
||||
<p><strong>To team</strong>: {{ team.name|striptags }}<br></p>
|
||||
|
||||
<p>{{body|striptags}}</p>
|
||||
|
||||
<br>
|
||||
<a href="https://{{site.domain}}{% url 'show-org' org.slug %}" title="{{ org.name|striptags }} page.">Go to the organization's page.</a>
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,12 @@
|
|||
{% extends 'get_together/emails/base.txt' %}
|
||||
{% block content %}
|
||||
== Message from {{org.name}} ==
|
||||
|
||||
Sender: {{ sender }}
|
||||
To team: {{ team.name }}
|
||||
|
||||
{{ body|striptags }}
|
||||
|
||||
Organization page: https://{{site.domain}}{% url 'show-org' org.slug %}
|
||||
|
||||
{% endblock %}
|
133
get_together/templates/get_together/orgs/manage_teams.html
Normal file
133
get_together/templates/get_together/orgs/manage_teams.html
Normal file
|
@ -0,0 +1,133 @@
|
|||
{% extends "get_together/base.html" %}
|
||||
{% load markup tz %}
|
||||
|
||||
{% block add_to_title %} | {{org.name}}{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if requests %}
|
||||
<div class="alerts">
|
||||
<div class="alert alert-success">You have <a href="#requests">{{ requests.count }} request{{requests.count|pluralize}}</a> to join your Org!</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="fluid-container">
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<h2><a href="{% url 'show-org' org.slug %}">{{ org.name }}</a> Teams</h2>
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th colspan="2">Team</th>
|
||||
<th>Contact</th>
|
||||
<th>Location</th>
|
||||
<th>Members</th>
|
||||
</tr>
|
||||
{% for team in teams %}
|
||||
<tr>
|
||||
<td><img class="rounded" src="{{team.card_img_url}}" height="64px"></td>
|
||||
<td><a href="{% url 'show-team-by-slug' team.slug %}">{{team.name}}</a></td>
|
||||
<td>
|
||||
<a href="javascript:contact_team({{team.id}});" class="fa fa-envelope" title="Contact"></a>
|
||||
</td>
|
||||
<td>
|
||||
{{team.city.short_name}}
|
||||
</td>
|
||||
<td>
|
||||
{{team.members.count}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if requests %}
|
||||
<h3 id="requests">Requests to join</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th colspan="2">Team</th>
|
||||
<th>Location</th>
|
||||
<th>Owner</th>
|
||||
<th>Requested</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for req in requests %}
|
||||
<tr>
|
||||
<td><img class="rounded" src="{{req.team.card_img_url}}" height="64px"></td>
|
||||
<td><a href="{% url 'show-team-by-slug' req.team.slug %}">{{req.team.name}}</a></td>
|
||||
<td>
|
||||
{{req.team.city.short_name}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'show-profile' req.team.owner_profile.id %}">{{req.team.owner_profile}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{req.requested_date|date}}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-success" href="{% url 'confirm-request-to-join-org' req.request_key %}">Confirm</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if invites %}
|
||||
<h3>Pending invitations</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th colspan="2">Team</th>
|
||||
<th>Location</th>
|
||||
<th>Owner</th>
|
||||
<th>Invited</th>
|
||||
</tr>
|
||||
{% for req in invites %}
|
||||
<tr>
|
||||
<td><img class="rounded" src="{{req.team.card_img_url}}" height="64px"></td>
|
||||
<td><a href="{% url 'show-team-by-slug' req.team.slug %}">{{req.team.name}}</a></td>
|
||||
<td>
|
||||
{{req.team.city.short_name}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'show-profile' req.team.owner_profile.id %}">{{req.team.owner_profile}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{req.requested_date|date}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<div class="container">
|
||||
<h4>Contact</h4><hr/>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<form action="{% url 'manage-teams' org.slug %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ contact_form.as_p }}
|
||||
<button type="submit" class="btn btn-primary btn-sm">Send</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$("#id_to").selectmenu();
|
||||
});
|
||||
|
||||
function contact_team(team_id) {
|
||||
$("#id_to").val(team_id);
|
||||
$("#id_to").selectmenu("refresh");
|
||||
$("#id_body").focus();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -24,7 +24,7 @@
|
|||
{% if can_edit_org %}
|
||||
<div id="admin_buttons" class="mb-2">
|
||||
<a href="{% url 'edit-org' org.slug %}" class="btn btn-secondary btn-sm"><i class="fa fa-pencil"></i> Edit Org</a>
|
||||
<a href="#" class="btn btn-secondary btn-sm disabled"><i class="fa fa-users"></i> Manage Teams</a>
|
||||
<a href="{% url 'manage-teams' org.slug %}" class="btn btn-secondary btn-sm"><i class="fa fa-users"></i> Manage Teams</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if org.banner_img %}
|
||||
|
|
|
@ -112,6 +112,7 @@ urlpatterns = [
|
|||
path('team/<int:team_id>/+invite_to_join_org/', views.invite_to_join_org, name='invite-to-join-org'),
|
||||
path('org/<str:org_slug>/+request_to_join_org/', views.request_to_join_org, name='request-to-join-org'),
|
||||
path('org/+confirm_request/<str:request_key>/', views.confirm_request_to_join_org, name='confirm-request-to-join-org'),
|
||||
path('org/<str:org_slug>/+manage_teams/', views.manage_org_teams, name='manage-teams'),
|
||||
path('org/<str:org_slug>/+create-event/', views.create_common_event, name='create-common-event'),
|
||||
path('common/<int:event_id>/+create-event/', views.create_common_event_team_select, name='create-common-event-team-select'),
|
||||
path('common/<int:event_id>/+edit/', views.edit_common_event, name='edit-common-event'),
|
||||
|
|
|
@ -13,7 +13,7 @@ from django.conf import settings
|
|||
|
||||
from events.models.profiles import Organization, Team, UserProfile, Member, OrgTeamRequest
|
||||
from events.models.events import Event, CommonEvent, Place, Attendee
|
||||
from events.forms import OrganizationForm, CommonEventForm, RequestToJoinOrgForm, InviteToJoinOrgForm, AcceptRequestToJoinOrgForm, AcceptInviteToJoinOrgForm
|
||||
from events.forms import OrganizationForm, CommonEventForm, RequestToJoinOrgForm, InviteToJoinOrgForm, AcceptRequestToJoinOrgForm, AcceptInviteToJoinOrgForm, OrgContactForm
|
||||
from events import location
|
||||
from events.utils import slugify
|
||||
|
||||
|
@ -290,6 +290,87 @@ def accept_invite_to_join_org(request, req):
|
|||
return redirect('home')
|
||||
|
||||
|
||||
@login_required
|
||||
def manage_org_teams(request, org_slug):
|
||||
org = get_object_or_404(Organization, slug=org_slug)
|
||||
if not request.user.profile.can_edit_org(org):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not manage this organization\'s members.'))
|
||||
return redirect('show-org', org.slug)
|
||||
|
||||
teams = Team.objects.filter(organization=org)
|
||||
team_choices = [(team.id, team.name) for team in teams]
|
||||
default_choices = [('all', 'All Teams (%s)' % len(team_choices))]
|
||||
if request.method == 'POST':
|
||||
contact_form = OrgContactForm(request.POST)
|
||||
contact_form.fields['to'].choices = default_choices + team_choices
|
||||
if contact_form.is_valid():
|
||||
to = contact_form.cleaned_data['to']
|
||||
body = contact_form.cleaned_data['body']
|
||||
if to == 'all':
|
||||
count = 0
|
||||
for team in teams:
|
||||
contact_team(team, org, body, request.user.profile)
|
||||
count += 1
|
||||
messages.add_message(request, messages.SUCCESS, message=_('Emailed %s teams' % count))
|
||||
else:
|
||||
try:
|
||||
team = Team.objects.get(id=to)
|
||||
contact_team(team, org, body, request.user.profile)
|
||||
messages.add_message(request, messages.SUCCESS, message=_('Emailed %s' % team.name))
|
||||
except Team.DoesNotExist:
|
||||
messages.add_message(request, messages.ERROR, message=_('Error sending message: Unknown team (%s)'%to))
|
||||
pass
|
||||
return redirect('manage-teams', org.slug)
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, message=_('Error sending message: %s' % contact_form.errors))
|
||||
else:
|
||||
contact_form = OrgContactForm()
|
||||
contact_form.fields['to'].choices = default_choices + team_choices
|
||||
|
||||
pending = OrgTeamRequest.objects.filter(organization=org, joined_date__isnull=True).exclude(team__in=teams)
|
||||
context = {
|
||||
'org': org,
|
||||
'teams': teams,
|
||||
'requests': pending.filter(request_origin=OrgTeamRequest.TEAM),
|
||||
'invites': pending.filter(request_origin=OrgTeamRequest.ORG),
|
||||
'contact_form': contact_form,
|
||||
'can_edit_org': request.user.profile.can_edit_org(org),
|
||||
}
|
||||
return render(request, 'get_together/orgs/manage_teams.html', context)
|
||||
|
||||
|
||||
def contact_team(team, org, body, sender):
|
||||
context = {
|
||||
'sender': sender,
|
||||
'team': team,
|
||||
'org': org,
|
||||
'body': body,
|
||||
'site': Site.objects.get(id=1),
|
||||
}
|
||||
email_subject = 'A message from: %s' % org.name
|
||||
email_body_text = render_to_string('get_together/emails/orgs/team_contact.txt', context)
|
||||
email_body_html = render_to_string('get_together/emails/orgs/team_contact.html', context)
|
||||
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
|
||||
|
||||
for member in Member.objects.filter(team=team, role=Member.ADMIN):
|
||||
email_recipients = [member.user.user.email]
|
||||
success = send_mail(
|
||||
from_email=email_from,
|
||||
html_message=email_body_html,
|
||||
message=email_body_text,
|
||||
recipient_list=email_recipients,
|
||||
subject=email_subject,
|
||||
fail_silently=True,
|
||||
)
|
||||
EmailRecord.objects.create(
|
||||
sender=sender.user,
|
||||
recipient=member.user.user,
|
||||
email=member.user.user.email,
|
||||
subject=email_subject,
|
||||
body=email_body_text,
|
||||
ok=success
|
||||
)
|
||||
|
||||
def show_common_event(request, event_id, event_slug):
|
||||
event = get_object_or_404(CommonEvent, id=event_id)
|
||||
context = {
|
||||
|
|
Loading…
Reference in a new issue