Skip to content
Snippets Groups Projects
Commit 6fdefbc8 authored by Alexis POYEN's avatar Alexis POYEN
Browse files

Resolve "Handle Capturers affectation"

parent 8a70d0e8
No related branches found
No related tags found
No related merge requests found
......@@ -82,7 +82,6 @@ func (d *DataHandler) getCapturerCapturer(w http.ResponseWriter, r *http.Request
http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
return
}
// fmt.Println(o)
if o.UserID != user.UserID {
http.Error(w, ErrorCannotAccessRessource, http.StatusForbidden)
return
......
package models
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"forge.grandlyon.com/apoyen/elections/internal/auth"
)
type capturerDeskRound struct {
CapturerID uint
DeskRoundID uint
}
// handleCapturer handle API calls on Capturer
func (d *DataHandler) handleCapturerDeskRound(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/CapturerDeskRound/"))
switch method := r.Method; method {
case "POST":
switch auth.GetLoggedUserTechnical(w, r).Role {
case "ADMIN":
d.postCapturerDeskRound(w, r)
case "CAPTURER", "VISUALIZER":
http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
default:
http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
}
case "DELETE":
switch auth.GetLoggedUserTechnical(w, r).Role {
case "ADMIN":
d.deleteCapturerDeskRound(w, r, id)
case "CAPTURER", "VISUALIZER":
http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
default:
http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
}
default:
http.Error(w, "method not allowed", 400)
}
}
func (d *DataHandler) postCapturerDeskRound(w http.ResponseWriter, r *http.Request) {
var o capturerDeskRound
err := json.NewDecoder(r.Body).Decode(&o)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var capturer Capturer
if err := d.db.First(&capturer, o.CapturerID).Error; err != nil {
http.Error(w, ErrorIDDoesNotExist, http.StatusNotFound)
return
}
var deskRound DeskRound
if err := d.db.First(&deskRound, o.DeskRoundID).Error; err != nil {
http.Error(w, ErrorIDDoesNotExist, http.StatusNotFound)
return
}
d.db.Model(&capturer).Association("DeskRounds").Append(&deskRound)
d.db.Preload("DeskRounds").First(&capturer)
json.NewEncoder(w).Encode(capturer)
}
func (d *DataHandler) deleteCapturerDeskRound(w http.ResponseWriter, r *http.Request, id int) {
var o capturerDeskRound
err := json.NewDecoder(r.Body).Decode(&o)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var capturer Capturer
if err := d.db.First(&capturer, o.CapturerID).Error; err != nil {
http.Error(w, ErrorIDDoesNotExist, http.StatusNotFound)
return
}
var deskRound DeskRound
if err := d.db.First(&deskRound, o.DeskRoundID).Error; err != nil {
http.Error(w, ErrorIDDoesNotExist, http.StatusNotFound)
return
}
d.db.Model(&capturer).Association("DeskRounds").Delete(&deskRound)
json.NewEncoder(w).Encode(capturer)
}
......@@ -232,6 +232,8 @@ func (d *DataHandler) ProcessAPI(w http.ResponseWriter, r *http.Request) {
d.handleRound(w, r)
case "DeskRound":
d.handleDeskRound(w, r)
case "CapturerDeskRound":
d.handleCapturerDeskRound(w, r)
}
}
......
......@@ -87,6 +87,11 @@ func AdminTests(t *testing.T) {
// Delete a DeskRound should fail with 400
do("DELETE", "/api/DeskRound/1", xsrfHeader, ``, 400, `method not allowed`)
// Add deskround to capturer
do("POST", "/api/CapturerDeskRound", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 200, `{"ID":1,"UserID":2,"Name":"capturer","DeskRounds":[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":null,"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":null}]}`)
// Remove DeskRound to capturer
do("DELETE", "/api/CapturerDeskRound/1", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 200, ``)
// Update a DeskRound should be done after desk completion by capturing votes
// do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"Validated":true}`, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":true,"Votes":[]}`)
......
......@@ -99,6 +99,11 @@ func CapturerTests(t *testing.T) {
// Delete a DeskRound should fail with 400
do("DELETE", "/api/DeskRound/1", xsrfHeader, ``, 400, `method not allowed`)
// Add deskround to capturer should fail with 405
do("POST", "/api/CapturerDeskRound", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
// Remove DeskRound to capturer
do("DELETE", "/api/CapturerDeskRound/1", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
}
// Do a in memory login with an known admin
do("POST", "/Login", noH, `{"login": "capturer","password": "password"}`, 200, "")
......
......@@ -61,10 +61,10 @@ func TestAll(t *testing.T) {
removeRoundRemoveDeskRoundsTest(t)
resetData(t)
AdminTests(t)
// resetDataWithData(t)
// CapturerTests(t)
// resetDataWithData(t)
// VisualizerTests(t)
resetDataWithData(t)
CapturerTests(t)
resetDataWithData(t)
VisualizerTests(t)
os.RemoveAll("./data")
}
......
......@@ -86,6 +86,11 @@ func VisualizerTests(t *testing.T) {
// Delete a DeskRound should fail with 400
do("DELETE", "/api/DeskRound/1", xsrfHeader, ``, 400, `method not allowed`)
// Add deskround to capturer should fail with 405
do("POST", "/api/CapturerDeskRound", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
// Remove DeskRound to capturer
do("DELETE", "/api/CapturerDeskRound/1", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
}
// Do a in memory login with an known admin
do("POST", "/Login", noH, `{"login": "visualizer","password": "password"}`, 200, "")
......
// Imports
import * as Auth from "/services/auth/auth.js";
import * as Common from "/services/common/common.js";
import * as Getters from "/services/common/getters.js";
import * as Messages from "/services/messages/messages.js";
......@@ -43,6 +44,61 @@ class RoundDesk {
</div>
`;
current_user = await Auth.GetUser();
this.mountModal("capturers-modal");
this.handleDom();
}
handleDom() {
let roundHandler = this;
document.getElementById(`round-new`).addEventListener("click", function () {
roundHandler.newRound();
});
document
.getElementById(`capturers-modal-close`)
.addEventListener("click", function () {
Common.toggleModal("capturers-modal", "capturers-modal-card");
});
}
mountModal(where) {
const mountpoint = where;
document.getElementById(mountpoint).innerHTML = /* HTML */ `
<div class="modal-background"></div>
<div class="modal-card" id="capturers-modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Ajout/supression de saisisseurs</p>
<button
class="delete"
aria-label="close"
id="capturers-modal-close"
></button>
</header>
<section class="modal-card-body">
<div class="columns">
<div class="column">
<header class="card-header card-header-success">
<p class="card-header-title">
Saisisseurs actifs
</p>
</header>
<div id="active-capturers">
Liste des saisisseurs actif
</div>
</div>
<div class="column">
<header class="card-header card-header-danger">
<p class="card-header-title">
Saisisseurs disponibles
</p>
</header>
<div id="available-capturers""> Liste des saisseurs disponibles
</div>
</div>
</section>
</div>
`;
}
deskRoundTemplate(deskRound) {
......@@ -54,7 +110,17 @@ class RoundDesk {
id="deskrounds-deskround-desc-${deskRound.ID}"
class="level-left"
></div>
<div class="level-right"></div>
<div class="level-right">
<a
id="deskrounds-deskround-capturers-${deskRound.ID}"
class="button is-link is-small"
title="Saisisseurs"
>
<span class="icon is-small">
<i class="fas fa-user"></i>
</span>
</a>
</div>
</nav>
</div>
</div>
......@@ -85,7 +151,10 @@ class RoundDesk {
</div>
<div class="field">
<div class="control">
<label class="checkbox" ${!this.deskRound.Completed ? 'disabled="true"' : ""}>
<label
class="checkbox"
${!this.deskRound.Completed ? 'disabled="true"' : ""}
>
<input
class="input"
type="checkbox"
......@@ -109,6 +178,19 @@ class RoundDesk {
</div>`;
}
capturersTemplate(capturer) {
return /* HTML */ `<div class="card card-list">
<div id="capturers-capturer-${capturer.ID}" class="card-content">
<div class="content">
<nav class="level">
<div class="level-left">${capturer.Name}</div>
<div class="level-right"></div>
</nav>
</div>
</div>
</div>`;
}
async displayDesks() {
let deskRounds = await this.updateDeskRounds();
const markup = deskRounds
......@@ -128,7 +210,12 @@ class RoundDesk {
deskRoundHandler.activateDeskRound(deskRound);
deskRoundHandler.deskRound = deskRound;
deskRoundHandler.displayDeskRoundsDetails();
// TODO open capturers affected
});
document
.getElementById(`deskrounds-deskround-capturers-${deskRound.ID}`)
.addEventListener("click", function () {
Common.toggleModal("capturers-modal", "capturers-modal-card");
deskRoundHandler.refreshCapturers();
});
});
}
......@@ -182,7 +269,6 @@ class RoundDesk {
}
async saveDeskRound() {
let round;
try {
const response = await fetch("/api/DeskRound/" + this.deskRound.ID, {
method: "PUT",
......@@ -208,4 +294,117 @@ class RoundDesk {
Messages.Show("is-success", "Bureau de vote mis à jour");
this.displayDesks();
}
async refreshCapturers() {
let deskRoundHandler = this;
let capturersAvailable;
let capturersActive;
try {
const response = await fetch("/api/Capturer/", {
method: "GET",
headers: new Headers({
"XSRF-Token": current_user.xsrftoken,
}),
});
if (response.status !== 200) {
throw new Error(
`Capturers could not be fetched (status ${response.status})`
);
}
let capturers = await response.json();
capturersAvailable = capturers.filter(function (capturer) {
let flag = true;
capturer.DeskRounds.forEach((deskRound) => {
if (deskRound.ID === deskRoundHandler.deskRound.ID) flag = false;
});
return flag;
});
capturersActive = capturers.filter(function (capturer) {
let flag = false;
capturer.DeskRounds.forEach((deskRound) => {
if (deskRound.ID === deskRoundHandler.deskRound.ID) flag = true;
});
return flag;
});
} catch (e) {
Messages.Show("is-warning", e.message);
console.error(e);
}
let markup = capturersAvailable
.map((capturer) => this.capturersTemplate(capturer))
.join("");
document.getElementById("available-capturers").innerHTML = markup;
markup = capturersActive
.map((capturer) => this.capturersTemplate(capturer))
.join("");
document.getElementById("active-capturers").innerHTML = markup;
capturersAvailable.map(async (capturer) => {
document
.getElementById(`capturers-capturer-${capturer.ID}`)
.addEventListener("click", async function () {
await deskRoundHandler.addCapturerToDesk(capturer);
await deskRoundHandler.refreshCapturers();
});
});
capturersActive.map(async (capturer) => {
document
.getElementById(`capturers-capturer-${capturer.ID}`)
.addEventListener("click", async function () {
await deskRoundHandler.removeCapturerFromDesk(capturer);
await deskRoundHandler.refreshCapturers();
});
});
}
async addCapturerToDesk(capturer) {
try {
const response = await fetch("/api/CapturerDeskRound/", {
method: "POST",
headers: new Headers({
"XSRF-Token": current_user.xsrftoken,
}),
body: JSON.stringify({
CapturerID: capturer.ID,
DeskRoundID: this.deskRound.ID,
}),
});
if (response.status !== 200) {
throw new Error(
`DeskRound could not be added to capturer (status ${response.status})`
);
}
await response.json();
} catch (e) {
Messages.Show("is-warning", e.message);
console.error(e);
return;
}
}
async removeCapturerFromDesk(capturer) {
try {
const response = await fetch("/api/CapturerDeskRound/", {
method: "delete",
headers: new Headers({
"XSRF-Token": current_user.xsrftoken,
}),
body: JSON.stringify({
CapturerID: capturer.ID,
DeskRoundID: this.deskRound.ID,
}),
});
if (response.status !== 200) {
throw new Error(
`DeskRound could not be removed from capturer (status ${response.status})`
);
}
} catch (e) {
Messages.Show("is-warning", e.message);
console.error(e);
}
}
}
......@@ -37,6 +37,7 @@ class Round {
</div>
<div class="modal" id="round-modal"></div>
<div class="modal" id="capturers-modal"></div>
`;
current_user = await Auth.GetUser();
this.roundsHandler = await RoundsCard.mount("rounds-list", this)
......
......@@ -121,3 +121,11 @@ select {
#round-desks .columns {
max-height: 90%;
}
.card-header-success{
background-color: rgba(127,186,0,.95);
}
.card-header-danger{
background-color: rgba(242,80,34,.95);
}
\ No newline at end of file
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