Skip to content

Commit

Permalink
Merge pull request 2i2c-org#195 from jnywong/submission-level-access
Browse files Browse the repository at this point in the history
Remove Teams and add submission collaborators
  • Loading branch information
jnywong authored Nov 22, 2024
2 parents 8521870 + 06a0312 commit 764c2b7
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 210 deletions.
23 changes: 5 additions & 18 deletions frx_challenges/web/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,17 @@ def __init__(self, id=None, *args, **kwargs):
self.fields["file"].label = False


class TeamForm(forms.Form):
"""Form to create a new team"""
class AddCollaboratorForm(forms.Form):
"""Form to add a collaborator to a submission"""

def __init__(self, team_id=None, *args, **kwargs):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.helper = FormHelper()
self.helper.form_method = "post"
self.fields["name"] = forms.CharField(label="Team Name")
self.helper.add_input(
Submit("submit", "Submit", css_class="form-control btn btn-secondary")
)


class AddMemberForm(forms.Form):
"""Form to add a member to a team"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.helper = FormHelper()
self.helper.form_method = "post"
self.fields["username"] = forms.CharField(label="GitHub username")
self.fields["is_admin"] = forms.BooleanField(required=False)
self.helper.add_input(
Submit("submit", "Add Member", css_class="form-control btn btn-secondary")
)
self.fields["username"] = forms.CharField()
self.fields["username"].label = "GitHub username"
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Generated by Django 5.1.2 on 2024-11-22 17:20

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("web", "0030_evaluation_evaluator_logs"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.RemoveField(
model_name="submission",
name="team",
),
migrations.RemoveField(
model_name="evaluation",
name="evaluator_logs",
),
migrations.CreateModel(
name="Collaborators",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("is_owner", models.BooleanField()),
(
"submission",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="web.submission"
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"unique_together": {("user", "submission")},
},
),
migrations.DeleteModel(
name="Team",
),
migrations.DeleteModel(
name="TeamMembership",
),
]
33 changes: 10 additions & 23 deletions frx_challenges/web/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@
# Create your models here.


class Team(models.Model):
name = models.CharField(max_length=1024)
members = models.ManyToManyField(
User, through="TeamMembership", related_name="teams"
)


class Submission(models.Model):
"""
A submission can be a collection of versions.
Expand All @@ -25,16 +18,6 @@ class Submission(models.Model):
name = models.CharField(max_length=1024, default="My model name")
description = models.CharField(max_length=2048, default="My model description")
date_created = models.DateTimeField(auto_now=True)
# FIXME: A default for the team had to be provided
# but because there was no default team, it was set to None
team = models.ForeignKey(
Team,
on_delete=models.CASCADE,
null=True,
blank=True,
default=None,
related_name="projects",
)
metadata = JSONField(
blank=True, null=True, schema=settings.SITE_SUBMISSION_FORM_SCHEMA
)
Expand Down Expand Up @@ -161,14 +144,18 @@ def __str__(self):
return f"({self.status}) {self.result} {self.version.data_uri}"


class TeamMembership(models.Model):
is_admin = models.BooleanField()
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="memberships")
team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name="memberships")
class Collaborators(models.Model):
"""
The owner of a submission can add/remove collaborators.
"""

is_owner = models.BooleanField()
submission = models.ForeignKey(Submission, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)

class Meta:
# A user can be added to a team only once
unique_together = ("user", "team")
# A user can be added as a collaborator only once
unique_together = ("user", "submission")


class Page(models.Model):
Expand Down
18 changes: 18 additions & 0 deletions frx_challenges/web/templates/collaborators/add.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% extends "page.html" %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container py-2">
<div class="row py-2">
<div class="col py-2">
<h1>Add collaborator to submission</h1>
</div>
<div class="col">
<a href="{% url 'submissions-detail' id %}"
class="btn btn-primary m-2 float-end">Back to submission</a>
</div>
</div>
<div class="row py-2">
<div class="col py-2">{% crispy form %}</div>
</div>
</div>
{% endblock body %}
68 changes: 68 additions & 0 deletions frx_challenges/web/templates/collaborators/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{% extends "page.html" %}
{% block body %}
<div class="container py-2">
<div class="row py-2">
<div class="col py-2">
<div class="row py-2">
<div class="col-6">
<h1>{{ submission.name }}</h1>
{% if submission.description %}<p>{{ submission.description }}</p>{% endif %}
</div>
{% if is_submission_owner %}
<div class="col-6">
<div class=" col">
<a href="{% url 'collaborators-add' submission.id %}"
class="btn btn-secondary m-2 float-end">Add collaborator</a>
</div>
<div class=" col">
<a href="{% url 'submissions-detail' submission.id %}"
class="btn btn-primary m-2 float-end">Back to submission</a>
</div>
</div>
{% endif %}
</div>
</div>
</div>
<div class="container py-2">
{% if collaborators %}
<div class="row py-2">
<div class="col-12">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col">Collaborators</th>
<th></th>
</tr>
</thead>
<tbody>
{% for c in collaborators %}
<tr>
<td>
<p>
{{ c.user.username }}
{% if c.is_owner %}<span>(submission owner)</span>{% endif %}
</p>
</td>
<td>
{% if is_submission_owner %}
{% if not c.is_owner %}
<a href={% url 'collaborators-delete' submission.id c.id %}>Remove</a>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% else %}
<div class="row py-2">
<div class="col">
<a href="" class="btn btn-secondary mt-2">Add collaborator</a>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock body %}
4 changes: 0 additions & 4 deletions frx_challenges/web/templates/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@
<li class="nav-item">
<a class="btn btn-primary" href="{% url 'submissions-list' %}">Submissions</a>
</li>
<li class="nav-item">
<a class="nav-link {% if request.resolver_match.url_name == 'teams-list' %}active{% endif %}"
href="{% url 'teams-list' %}">My Teams</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link" href="{% url 'account_logout' %}">Logout</a>
Expand Down
24 changes: 16 additions & 8 deletions frx_challenges/web/templates/submission/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@
<div class="row py-2">
<div class="col py-2">
<div class="row py-2">
<div class="col-8">
<div class="col-6">
<h1>{{ submission.name }}</h1>
{% if submission.description %}<p>{{ submission.description }}</p>{% endif %}
</div>
{% if is_owner %}
<div class="col-4 text-end">
<a href="{% url 'submissions-edit' submission.id %}"
class="btn btn-secondary mt-2 float-end">Edit submission</a>
<div class="col-6">
<div class=" col">
<a href="{% url 'collaborators-list' submission.id %}"
class="btn btn-secondary m-2 float-end">Manage collaborators</a>
</div>
<div class="col">
<a href="{% url 'submissions-edit' submission.id %}"
class="btn btn-primary m-2 float-end">Edit submission</a>
</div>
</div>
{% endif %}
</div>
Expand All @@ -44,10 +50,12 @@ <h1>{{ submission.name }}</h1>
</div>
</div>
<div class="row py-2 border-top">
<div class="col">
<a href="{% url 'upload' submission.id %}"
class="btn btn-primary mt-2 float-end">Upload</a>
</div>
{% if is_collaborator %}
<div class="col">
<a href="{% url 'upload' submission.id %}"
class="btn btn-primary mt-2 float-end">Upload</a>
</div>
{% endif %}
</div>
<div class="row py-2">
{% if versions %}
Expand Down
4 changes: 3 additions & 1 deletion frx_challenges/web/templates/submission/edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
<div class="container py-2">
<div class="row py-2">
<div class="col py-2">
<h1>Edit a submission</h1>
<h1>
Edit <a href={% url 'submissions-detail' submission.id %}>{{ submission.name }}</a>
</h1>
<br>
{{ html_content|safe }}
</div>
Expand Down
26 changes: 16 additions & 10 deletions frx_challenges/web/urls.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
from django.urls import path

from .views import default, pages, submissions, teams, versions
from .views import collaborators, default, pages, submissions, versions # teams

urlpatterns = [
path("upload/<int:id>", versions.upload, name="upload"),
path("teams/list", teams.list, name="teams-list"),
path("teams/create", teams.create, name="teams-create"),
path("teams/<int:id>", teams.view, name="teams-view"),
path("teams/<int:id>/add-member", teams.add_member, name="teams-add-member"),
path(
"teams/<int:team_id>/remove-member/<int:user_id>",
teams.remove_member,
name="teams-remove-member",
),
path("page/<slug:slug>", pages.view, name="page-view"),
path("file/<slug:slug>", pages.content_file, name="content-file"),
path("leaderboard", default.leaderboard, name="leaderboard"),
path("submissions/", submissions.list, name="submissions-list"),
path("submissions/create", submissions.create, name="submissions-create"),
path("submissions/<int:id>", submissions.detail, name="submissions-detail"),
path("submissions/<int:id>/edit", submissions.edit, name="submissions-edit"),
path(
"submissions/<int:id>/collaborators",
collaborators.list,
name="collaborators-list",
),
path(
"submissions/<int:id>/collaborators/add",
collaborators.add,
name="collaborators-add",
),
path(
"submissions/<int:id>/collaborators/delete/<int:collab_id>",
collaborators.delete,
name="collaborators-delete",
),
path("versions/<int:id>", versions.view, name="versions-view"),
path(
"evaluation/<int:id>", submissions.detail_evaluation, name="evaluation-detail"
Expand Down
Loading

0 comments on commit 764c2b7

Please sign in to comment.