qa: Refactor work attribution

This commit is contained in:
nemunaire 2024-09-18 16:45:08 +02:00
parent 8c6db30c52
commit 0f9d56fcbf
2 changed files with 97 additions and 19 deletions

View File

@ -243,6 +243,8 @@ func deleteQATodo(c *gin.Context) {
type QAAssignWork struct { type QAAssignWork struct {
Turns int `json:"turns"` Turns int `json:"turns"`
Start int `json:"start"` Start int `json:"start"`
TeamPrefix string `json:"team_prefix"`
TeamAssistants string `json:"team_assistants"`
} }
func assignWork(c *gin.Context) { func assignWork(c *gin.Context) {
@ -254,6 +256,12 @@ func assignWork(c *gin.Context) {
if uaw.Turns == 0 { if uaw.Turns == 0 {
uaw.Turns = 1 uaw.Turns = 1
} }
if uaw.TeamPrefix == "" {
uaw.TeamPrefix = "FIC Groupe "
}
if uaw.TeamAssistants == "" {
uaw.TeamAssistants = "assistants"
}
teams, err := fic.GetTeams() teams, err := fic.GetTeams()
if err != nil { if err != nil {
@ -265,7 +273,7 @@ func assignWork(c *gin.Context) {
// Remove assistant team // Remove assistant team
for tid := len(teams) - 1; tid >= 0; tid-- { for tid := len(teams) - 1; tid >= 0; tid-- {
team := teams[tid] team := teams[tid]
if strings.Contains(strings.ToLower(team.Name), "assistants") { if strings.Contains(strings.ToLower(team.Name), uaw.TeamAssistants) {
teams = append(teams[:tid], teams[tid+1:]...) teams = append(teams[:tid], teams[tid+1:]...)
} }
} }
@ -277,10 +285,27 @@ func assignWork(c *gin.Context) {
return return
} }
// Struct to store reported team (due to owned exercice)
var teamIdStack []int64
for i := 0; i < uaw.Turns; i++ { for i := 0; i < uaw.Turns; i++ {
for eid, ex := range exercices { for eid, ex := range exercices {
team := teams[(uaw.Start+eid+uaw.Turns*i)%len(teams)] team := teams[(uaw.Start+eid+uaw.Turns*i)%len(teams)]
if len(teamIdStack) > 0 {
teamIdStack = append(teamIdStack, team.Id)
team, _ = fic.GetTeam(teamIdStack[0])
teamIdStack = append([]int64{}, teamIdStack[1:]...)
}
j := 0
// Find a team not responsible for this exercice
for (strings.Contains(ex.Path, "grp") && strings.Contains(ex.Path, "-grp"+strings.TrimPrefix(team.Name, uaw.TeamPrefix)+"-")) || (!strings.Contains(ex.Path, "grp") && strings.HasPrefix(ex.Path, strings.TrimPrefix(team.Name, uaw.TeamPrefix)+"-")) {
j += 1
teamIdStack = append(teamIdStack, team.Id)
team = teams[(uaw.Start+eid+uaw.Turns*i+j)%len(teams)]
}
_, err := team.NewQATodo(ex.Id) _, err := team.NewQATodo(ex.Id)
if err != nil { if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})

View File

@ -6,7 +6,10 @@
import { import {
Button, Button,
Container, Container,
FormGroup,
Input, Input,
Label,
Spinner,
Table, Table,
} from '@sveltestrap/sveltestrap'; } from '@sveltestrap/sveltestrap';
@ -21,16 +24,35 @@
let start = 0; let start = 0;
let turns = 3; let turns = 3;
let team_prefix = "";
let team_assistants = "";
let assignInProgress = false;
async function assignExercices() { async function assignExercices() {
assignInProgress = true;
const res = await fetch(`api/qa_assign_work`, { const res = await fetch(`api/qa_assign_work`, {
method: 'POST', method: 'POST',
headers: {'Accept': 'application/json'}, headers: {'Accept': 'application/json'},
body: JSON.stringify({ body: JSON.stringify({
start, start,
turns, turns,
team_prefix,
team_assistants,
}), }),
}) })
if (res.status == 200) {
teams.refresh();
assignInProgress = false;
} else {
assignInProgress = false;
throw new Error((await res.json()).errmsg);
}
}
async function deleteAssignation() {
const res = await fetch(`api/qa_assign_work`, {
method: 'DELETE',
});
if (res.status == 200) { if (res.status == 200) {
teams.refresh(); teams.refresh();
} else { } else {
@ -40,22 +62,9 @@
</script> </script>
<Container class="mt-2 mb-5"> <Container class="mt-2 mb-5">
<div class="d-flex justify-content-between">
<h2> <h2>
Équipes Équipes
</h2> </h2>
<div class="input-group">
<Input type="number" bind:value={start} />
<Input type="number" bind:value={turns} />
<Button
color="light"
size="sm"
on:click={assignExercices}
>
Assigner des exercices
</Button>
</div>
</div>
<p> <p>
<input type="search" class="form-control" placeholder="Filtrer" bind:value={query} autofocus> <input type="search" class="form-control" placeholder="Filtrer" bind:value={query} autofocus>
@ -93,4 +102,48 @@
{/each} {/each}
</tbody> </tbody>
</Table> </Table>
<hr>
<h2>
Assigner des exercices aux équipes
</h2>
<form on:submit|preventDefault={assignExercices}>
<FormGroup>
<Label for="ae-start">Compteur de départ</Label>
<Input type="number" id="ae-start" bind:value={start} />
<p class="form-text">
Incrémenter de 1 pour chaque nouveau challenge blanc, cela décale l'attribution des exercices.
</p>
</FormGroup>
<FormGroup>
<Label for="ae-turns">Nombre d'itérations</Label>
<Input type="number" id="ae-turns" bind:value={turns} />
</FormGroup>
<FormGroup>
<Label for="ae-prefix">Préfixe des noms d'équipes</Label>
<Input id="ae-prefix" bind:value={team_prefix} placeholder="FIC Groupe" />
</FormGroup>
<FormGroup>
<Label for="ae-assistants">Nom de l'équipe assistants</Label>
<Input id="ae-assistants" bind:value={team_assistants} placeholder="Assistants" />
</FormGroup>
<Button
type="submit"
disabled={assignInProgress}
color="primary"
>
{#if assignInProgress}
<Spinner size="sm" />
{/if}
Assigner des exercices
</Button>
<Button
type="button"
color="danger"
on:click={deleteAssignation}
>
Supprimer toute assignation
</Button>
</form>
</Container> </Container>