Skip to content
Snippets Groups Projects
Commit 4ee3e4d3 authored by Simen's avatar Simen
Browse files

Added functionality for editing groups, and added groups to navbar

parent 0acaaa83
Branches feat/29-createGroup
No related tags found
1 merge request!1Fix/permissions
Pipeline #158207 passed
...@@ -8,7 +8,7 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer): ...@@ -8,7 +8,7 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = Group model = Group
fields = ["owner", "name", "description"] fields = ["id", "owner", "name", "description"]
class MembershipSerializer(serializers.ModelSerializer): class MembershipSerializer(serializers.ModelSerializer):
...@@ -16,4 +16,4 @@ class MembershipSerializer(serializers.ModelSerializer): ...@@ -16,4 +16,4 @@ class MembershipSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Membership model = Membership
fields = ["member", "group"] fields = ["id", "member", "group"]
from django.urls import path from django.urls import path
from .views import GroupView, MembershipView from .views import GroupView, MembershipView, getGroup
urlpatterns = [ urlpatterns = [
path("api/groups/", GroupView.as_view(), name="group-view"), path("api/groups/", GroupView.as_view(), name="group-view"),
path("api/members/", MembershipView.as_view(), name="membership-view"), path("api/members/", MembershipView.as_view(), name="membership-view"),
path("api/groups/<int:pk>/", getGroup.as_view(), name="updateGroup-view"),
] ]
...@@ -9,7 +9,7 @@ from rest_framework.filters import OrderingFilter ...@@ -9,7 +9,7 @@ from rest_framework.filters import OrderingFilter
class GroupView( class GroupView(
mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, generics.GenericAPIView,
): ):
queryset = Group.objects.all() queryset = Group.objects.all()
serializer_class = GroupSerializer serializer_class = GroupSerializer
...@@ -26,21 +26,34 @@ class GroupView( ...@@ -26,21 +26,34 @@ class GroupView(
serializer.save(owner=self.request.user) serializer.save(owner=self.request.user)
class MembershipView( class getGroup(
mixins.RetrieveModelMixin, mixins.RetrieveModelMixin,
mixins.UpdateModelMixin, mixins.UpdateModelMixin,
mixins.DestroyModelMixin, mixins.DestroyModelMixin,
mixins.ListModelMixin, mixins.ListModelMixin,
generics.GenericAPIView, generics.GenericAPIView,
): ):
queryset = Membership.objects.all() queryset = Group.objects.all()
serializer_class = MembershipSerializer serializer_class = GroupSerializer
# permission_classes = [permissions.IsAuthenticated] # permission_classes = [permissions.IsAuthenticated]
"""
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs) return self.retrieve(request, *args, **kwargs)
"""
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
class MembershipView(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
generics.GenericAPIView,
):
queryset = Membership.objects.all()
serializer_class = MembershipSerializer
# permission_classes = [permissions.IsAuthenticated]
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs) return self.list(request, *args, **kwargs)
......
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
</div> </div>
<div class="col-lg-6"></div> <div class="col-lg-6"></div>
<div class="col-lg-6"> <div class="col-lg-6">
<input type="button" class="btn btn-primary" id="btn-ok-group" value=" OK "> <input type="button" class="btn btn-primary hide" id="btn-ok-group" value=" OK ">
<input type="button" class="btn btn-secondary" id="btn-cancel-group" value="Cancel"> <input type="button" class="btn btn-secondary hide" id="btn-cancel-group" value="Cancel">
<input type="button" class="btn btn-primary" id="btn-edit-group" value=" Edit ">
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
......
let cancelButton; let cancelButton;
let okButton; let okButton;
let editButton;
let oldFormData; let oldFormData;
function handleCancelButtonDuringCreate() { function handleCancelButtonDuringCreate() {
window.location.replace("groups.html"); window.location.replace("groups.html");
} }
async function createExercise() { function handleCancelButtonDuringEdit() {
setReadOnly(true, "#form-group");
okButton.className += " hide";
cancelButton.className += " hide";
editButton.className = editButton.className.replace(" hide", "");
cancelButton.removeEventListener("click", handleCancelButtonDuringEdit);
let form = document.querySelector("#form-group");
if (oldFormData.has("name")) form.name.value = oldFormData.get("name");
if (oldFormData.has("description")) form.description.value = oldFormData.get("description");
oldFormData.delete("name");
oldFormData.delete("description");
}
async function createGroup() {
let form = document.querySelector("#form-group"); let form = document.querySelector("#form-group");
let formData = new FormData(form); let formData = new FormData(form);
let body = {"name": formData.get("name"), let body = {"name": formData.get("name"),
...@@ -24,16 +41,95 @@ async function createExercise() { ...@@ -24,16 +41,95 @@ async function createExercise() {
} }
} }
function handleEditGroupButtonClick() {
setReadOnly(false, "#form-group");
editButton.className += " hide";
okButton.className = okButton.className.replace(" hide", "");
cancelButton.className = cancelButton.className.replace(" hide", "");
cancelButton.addEventListener("click", handleCancelButtonDuringEdit);
let form = document.querySelector("#form-group");
oldFormData = new FormData(form);
}
async function retrieveGroup(id) {
let response = await sendRequest("GET", `${HOST}/api/groups/${id}/`);
console.log(response.ok)
if (!response.ok) {
let data = await response.json();
let alert = createAlert("Could not retrieve group data!", data);
document.body.prepend(alert);
} else {
let groupData = await response.json();
let form = document.querySelector("#form-group");
let formData = new FormData(form);
for (let key of formData.keys()) {
let selector
selector = `input[name="${key}"], textarea[name="${key}"]`;
let input = form.querySelector(selector);
let newVal = groupData[key];
input.value = newVal;
}
}
}
async function updateGroup(id) {
let form = document.querySelector("#form-group");
let formData = new FormData(form);
let body = {"name": formData.get("name"),
"description": formData.get("description"),
};
let response = await sendRequest("PUT", `${HOST}/api/groups/${id}/`, body);
if (!response.ok) {
let data = await response.json();
let alert = createAlert(`Could not update group ${id}`, data);
document.body.prepend(alert);
} else {
setReadOnly(true, "#form-group");
okButton.className += " hide";
cancelButton.className += " hide";
editButton.className = editButton.className.replace(" hide", "");
cancelButton.removeEventListener("click", handleCancelButtonDuringEdit);
oldFormData.delete("name");
oldFormData.delete("description");
}
}
window.addEventListener("DOMContentLoaded", async () => { window.addEventListener("DOMContentLoaded", async () => {
cancelButton = document.querySelector("#btn-cancel-group"); cancelButton = document.querySelector("#btn-cancel-group");
okButton = document.querySelector("#btn-ok-group"); okButton = document.querySelector("#btn-ok-group");
editButton = document.querySelector("#btn-edit-group");
oldFormData = null; oldFormData = null;
setReadOnly(false, "#form-group"); const urlParams = new URLSearchParams(window.location.search);
okButton.className = okButton.className.replace(" hide", ""); // view/edit
cancelButton.className = cancelButton.className.replace(" hide", ""); if (urlParams.has('id')) {
const groupId = urlParams.get('id');
await retrieveGroup(groupId);
editButton.addEventListener("click", handleEditGroupButtonClick);
okButton.addEventListener("click", (async (id) => await updateGroup(id)).bind(undefined, groupId));
}
//create
else {
setReadOnly(false, "#form-group");
okButton.addEventListener("click", async () => await createExercise()); editButton.className += " hide";
cancelButton.addEventListener("click", handleCancelButtonDuringCreate); okButton.className = okButton.className.replace(" hide", "");
cancelButton.className = cancelButton.className.replace(" hide", "");
okButton.addEventListener("click", async () => await createGroup());
cancelButton.addEventListener("click", handleCancelButtonDuringCreate);
}
}); });
\ No newline at end of file
...@@ -9,7 +9,7 @@ async function fetchGroups(request) { ...@@ -9,7 +9,7 @@ async function fetchGroups(request) {
let exerciseTemplate = document.querySelector("#template-group"); let exerciseTemplate = document.querySelector("#template-group");
groups.forEach(group => { groups.forEach(group => {
const exerciseAnchor = exerciseTemplate.content.firstElementChild.cloneNode(true); const exerciseAnchor = exerciseTemplate.content.firstElementChild.cloneNode(true);
exerciseAnchor.href = `exercise.html?id=${group.id}`; exerciseAnchor.href = `group.html?id=${group.id}`;
const h5 = exerciseAnchor.querySelector("h5"); const h5 = exerciseAnchor.querySelector("h5");
h5.textContent = group.name; h5.textContent = group.name;
......
...@@ -19,6 +19,7 @@ class NavBar extends HTMLElement { ...@@ -19,6 +19,7 @@ class NavBar extends HTMLElement {
<a class="nav-link hide" id="nav-mycoach" href="mycoach.html">Coach</a> <a class="nav-link hide" id="nav-mycoach" href="mycoach.html">Coach</a>
<a class="nav-link hide" id="nav-myathletes" href="myathletes.html">Athletes</a> <a class="nav-link hide" id="nav-myathletes" href="myathletes.html">Athletes</a>
<a class="nav-link hide" id="nav-meals" href="meals.html">Meal registration</a> <a class="nav-link hide" id="nav-meals" href="meals.html">Meal registration</a>
<a class="nav-link hide" id="nav-groups" href="groups.html">Groups</a>
<hr> <hr>
</div> </div>
<div class="my-2 my-lg-0 me-5"> <div class="my-2 my-lg-0 me-5">
......
...@@ -24,6 +24,8 @@ function updateNavBar() { ...@@ -24,6 +24,8 @@ function updateNavBar() {
makeNavLinkActive("nav-myathletes"); makeNavLinkActive("nav-myathletes");
} else if (window.location.pathname == "/meals.html") { } else if (window.location.pathname == "/meals.html") {
makeNavLinkActive("nav-myathletes"); makeNavLinkActive("nav-myathletes");
} else if (window.location.pathname == "/groups.html") {
makeNavLinkActive("nav-groups");
} }
if (isUserAuthenticated()) { if (isUserAuthenticated()) {
...@@ -35,6 +37,7 @@ function updateNavBar() { ...@@ -35,6 +37,7 @@ function updateNavBar() {
document.querySelector('a[href="exercises.html"').classList.remove("hide"); document.querySelector('a[href="exercises.html"').classList.remove("hide");
document.querySelector('a[href="myathletes.html"').classList.remove("hide"); document.querySelector('a[href="myathletes.html"').classList.remove("hide");
document.querySelector('a[href="meals.html"').classList.remove("hide"); document.querySelector('a[href="meals.html"').classList.remove("hide");
document.querySelector('a[href="groups.html"').classList.remove("hide");
} else { } else {
document.getElementById("btn-login-nav").classList.remove("hide"); document.getElementById("btn-login-nav").classList.remove("hide");
document.getElementById("btn-register").classList.remove("hide"); document.getElementById("btn-register").classList.remove("hide");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment