Allow creating, listing and leaving groups

This commit is contained in:
Gabriel Augendre 2019-03-03 18:45:47 +01:00
parent 81fa2ad19d
commit 9103545a23
11 changed files with 187 additions and 5 deletions

View file

@ -1,7 +1,8 @@
from django.contrib import admin
from django.contrib.admin import register
from django.contrib.auth.admin import UserAdmin
from .models import Friend, FriendLocation
from .models import Friend, FriendLocation, LocationSharingGroup
admin.site.register(Friend, UserAdmin)
@ -13,3 +14,10 @@ class FriendLocationAdmin(admin.ModelAdmin):
('Place', {'fields': ('latitude', 'longitude')}),
('Dates', {'fields': ('start_date', 'end_date')}),
]
@register(LocationSharingGroup)
class LocationSharingGroupAdmin(admin.ModelAdmin):
list_display = [
'name',
]

View file

@ -0,0 +1,22 @@
# Generated by Django 2.1.7 on 2019-03-03 16:57
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0006_auto_20190303_1308'),
]
operations = [
migrations.CreateModel(
name='LocationSharingGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=250)),
('friends', models.ManyToManyField(related_name='location_sharing_groups', to=settings.AUTH_USER_MODEL)),
],
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.1.7 on 2019-03-03 17:34
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0007_locationsharinggroup'),
]
operations = [
migrations.AlterField(
model_name='locationsharinggroup',
name='friends',
field=models.ManyToManyField(blank=True, related_name='location_sharing_groups', to=settings.AUTH_USER_MODEL),
),
]

View file

@ -53,3 +53,8 @@ class FriendLocation(BaseModel):
html += f' until {self.end_date}'
return html
class LocationSharingGroup(models.Model):
name = models.CharField(max_length=250)
friends = models.ManyToManyField(Friend, related_name='location_sharing_groups', blank=True)

View file

@ -6,3 +6,7 @@
.messages-container {
margin-top: 1em;
}
#quick-actions {
margin-bottom: 1em;
}

View file

@ -45,7 +45,7 @@
</div>
{% block quick_actions %}
{% if quick_actions %}
<div class="row">
<div class="row" id="quick-actions">
<div class="col-12 d-none d-md-block"> {# Visible only on large screens #}
{% for qa in quick_actions %}
<a href="{{ qa.url }}" class="btn btn-{{ qa.category }}">

View file

@ -0,0 +1,19 @@
{% extends 'map/base.html' %}
{% load crispy_forms_filters %}
{% block title %}Create a group{% endblock %}
{% block h1 %}Create a group{% endblock %}
{% block content %}
<div class="alert alert-info">
<h4 class="alert-heading">Notice</h4>
<div>
All members in this group can see your location.
</div>
</div>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Create</button>
</form>
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends 'map/base.html' %}
{% load crispy_forms_filters %}
{% block title %}Leave a group{% endblock %}
{% block h1 %}Leave a group{% endblock %}
{% block content %}
<div class="alert alert-warning">
<h4 class="alert-heading">Are you sure?</h4>
<div>
If you leave this group you will not be able to see the location of people in the group.
If you're the last member of the group, it will be deleted.
</div>
</div>
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-warning">Yes, I'm sure</button>
<a href="{% url 'manage-groups' %}" class="btn btn-secondary">No, cancel</a>
</form>
{% endblock %}

View file

@ -0,0 +1,27 @@
{% extends 'map/base.html' %}
{% load crispy_forms_filters %}
{% block title %}Manage your groups{% endblock %}
{% block h1 %}Manage your groups{% endblock %}
{% block content %}
<div class="alert alert-info">
<h4 class="alert-heading">Notice</h4>
<div>
Here you can list and manage groups you belong to. All members in these groups can see your location.
</div>
</div>
<ul class="list-group">
{% for group in groups %}
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ group.name }}
<span>
<span class="badge badge-secondary badge-pill">{{ group.friends.count }}</span>
<a href="{% url 'leave-group' group.pk %}" class="btn btn-sm btn-secondary">Leave</a>
</span>
</li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -7,6 +7,9 @@ urlpatterns = [
path('change-location', views.EditLocationView.as_view(), name='change-location'),
path('add-location', views.AddLocationView.as_view(), name='add-location'),
path('delete-location', views.DeleteLocationView.as_view(), name='delete-location'),
path('manage-groups', views.ManageGroupsView.as_view(), name='manage-groups'),
path('add-group', views.CreateGroupView.as_view(), name='add-group'),
path('leave-group/<int:pk>', views.LeaveGroupView.as_view(), name='leave-group'),
path('accounts/profile', views.UpdateProfileView.as_view(), name='change-profile'),
path('accounts/profile/delete', views.DeleteProfileView.as_view(), name='delete-profile'),
]

View file

@ -15,7 +15,7 @@ class MapView(LoginRequiredMixin, QuickActionsMixin, generic.ListView):
def get_quick_actions(self):
if hasattr(self.request.user, 'location'):
return [{
actions = [{
'url': reverse_lazy('change-location'),
'category': 'primary',
'display': f'Change your location'
@ -25,12 +25,20 @@ class MapView(LoginRequiredMixin, QuickActionsMixin, generic.ListView):
'display': f'Delete your location'
}]
else:
return [{
actions = [{
'url': reverse_lazy('add-location'),
'category': 'primary',
'display': f'Add your location'
}]
actions.append({
'url': reverse_lazy('manage-groups'),
'category': 'secondary',
'display': f'Manage your groups'
})
return actions
class EditLocationView(LoginRequiredMixin, generic.UpdateView):
model = models.FriendLocation
@ -121,3 +129,50 @@ class DeleteProfileView(LoginRequiredMixin, generic.DeleteView):
def get_success_url(self):
messages.success(self.request, 'Your profile has been successfully and permanently deleted')
return super().get_success_url()
class ManageGroupsView(LoginRequiredMixin, QuickActionsMixin, generic.ListView):
model = models.LocationSharingGroup
context_object_name = 'groups'
template_name = 'map/list_groups.html'
def get_queryset(self):
return self.request.user.location_sharing_groups.all()
def get_quick_actions(self):
return [{
'url': reverse_lazy('add-group'),
'category': 'primary',
'display': 'Create a group'
}]
class CreateGroupView(LoginRequiredMixin, QuickActionsMixin, generic.CreateView):
model = models.LocationSharingGroup
context_object_name = 'group'
template_name = 'map/change_group.html'
success_url = reverse_lazy('manage-groups')
fields = [
'name'
]
def get_success_url(self):
self.object.friends.add(self.request.user)
messages.success(self.request, 'The group has been successfully created')
return super().get_success_url()
class LeaveGroupView(LoginRequiredMixin, generic.UpdateView):
model = models.LocationSharingGroup
context_object_name = 'group'
template_name = 'map/leave_group.html'
fields = []
success_url = reverse_lazy('manage-groups')
def get_success_url(self):
self.object.friends.remove(self.request.user)
if self.object.friends.count() == 0:
self.object.delete()
messages.success(self.request, 'You successfully left the group')
return super().get_success_url()