qa: Improve work assignation
Some checks are pending
continuous-integration/drone/push Build is running

This commit is contained in:
nemunaire 2025-01-14 10:42:11 +01:00
parent fb5147fac3
commit e71dc24a27
2 changed files with 88 additions and 24 deletions

View File

@ -246,6 +246,9 @@ type QAAssignWork struct {
Start int `json:"start"` Start int `json:"start"`
TeamPrefix string `json:"team_prefix"` TeamPrefix string `json:"team_prefix"`
TeamAssistants string `json:"team_assistants"` TeamAssistants string `json:"team_assistants"`
OnlyExercices bool `json:"only_exercices"`
WithoutStandaloneExercices bool `json:"without_standalone_exercices"`
WithoutThemes bool `json:"without_themes"`
} }
func assignWork(c *gin.Context) { func assignWork(c *gin.Context) {
@ -279,19 +282,80 @@ func assignWork(c *gin.Context) {
} }
} }
exercices, err := fic.GetExercices() var themes []*fic.Theme
if !uaw.OnlyExercices && !uaw.WithoutThemes {
themes, err = fic.GetThemes()
if err != nil {
log.Println("Unable to GetThemes: ", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list themes: %s", err.Error())})
return
}
}
var exercices []*fic.Exercice
if uaw.OnlyExercices {
exercices, err = fic.GetExercices()
if err != nil { if err != nil {
log.Println("Unable to GetExercices: ", err.Error()) log.Println("Unable to GetExercices: ", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list exercices: %s", err.Error())}) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list exercices: %s", err.Error())})
return return
} }
if uaw.WithoutStandaloneExercices || uaw.WithoutThemes {
for i := len(exercices) - 1; i >= 0; i-- {
if (exercices[i].IdTheme == nil && uaw.WithoutStandaloneExercices) || (exercices[i].IdTheme != nil && uaw.WithoutThemes) {
exercices = append(exercices[:i], exercices[i+1:]...)
}
}
}
} else if !uaw.WithoutStandaloneExercices {
exercices, err = (&fic.Theme{URLId: "_", Path: "exercices"}).GetExercices()
if err != nil {
log.Println("Unable to GetStandaloneExercices: ", err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to list exercices: %s", err.Error())})
return
}
}
// Struct to store reported team (due to owned exercice) // Struct to store reported team (due to owned exercice)
var teamIdStack []int64 var teamIdStack []int64
for i := 0; i < uaw.Turns; i++ { for i := 0; i < uaw.Turns; i++ {
lasttid := 0
for tid, theme := range themes {
lasttid = tid
team := teams[(uaw.Start+tid+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(theme.Path, "grp") && strings.Contains(theme.Path, "-grp"+strings.TrimPrefix(team.Name, uaw.TeamPrefix)+"-")) || (!strings.Contains(theme.Path, "grp") && strings.HasPrefix(theme.Path, strings.TrimPrefix(team.Name, uaw.TeamPrefix)+"-")) {
j += 1
teamIdStack = append(teamIdStack, team.Id)
team = teams[(uaw.Start+tid+uaw.Turns*i+j)%len(teams)]
}
exercices, err := theme.GetExercices()
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
for _, ex := range exercices {
_, err := team.NewQATodo(ex.Id)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
return
}
}
}
for eid, ex := range exercices { for eid, ex := range exercices {
team := teams[(uaw.Start+eid+uaw.Turns*i)%len(teams)] team := teams[(uaw.Start+lasttid+eid+uaw.Turns*i)%len(teams)]
if len(teamIdStack) > 0 { if len(teamIdStack) > 0 {
teamIdStack = append(teamIdStack, team.Id) teamIdStack = append(teamIdStack, team.Id)

View File

@ -22,10 +22,12 @@
goto("teams/" + id) goto("teams/" + id)
} }
let start = 0; let assignForm = {
let turns = 3; start: 0,
let team_prefix = ""; turns: 3,
let team_assistants = ""; team_prefix: "",
team_assistants: "",
}
let assignInProgress = false; let assignInProgress = false;
async function assignExercices() { async function assignExercices() {
@ -33,12 +35,7 @@
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(assignForm),
start,
turns,
team_prefix,
team_assistants,
}),
}) })
if (res.status == 200) { if (res.status == 200) {
teams.refresh(); teams.refresh();
@ -111,23 +108,26 @@
<form on:submit|preventDefault={assignExercices}> <form on:submit|preventDefault={assignExercices}>
<FormGroup> <FormGroup>
<Label for="ae-start">Compteur de départ</Label> <Label for="ae-start">Compteur de départ</Label>
<Input type="number" id="ae-start" bind:value={start} /> <Input type="number" id="ae-start" bind:value={assignForm.start} />
<p class="form-text"> <p class="form-text">
Incrémenter de 1 pour chaque nouveau challenge blanc, cela décale l'attribution des exercices. Incrémenter de 1 pour chaque nouveau challenge blanc, cela décale l'attribution des exercices.
</p> </p>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<Label for="ae-turns">Nombre d'itérations</Label> <Label for="ae-turns">Nombre d'itérations</Label>
<Input type="number" id="ae-turns" bind:value={turns} /> <Input type="number" id="ae-turns" bind:value={assignForm.turns} />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<Label for="ae-prefix">Préfixe des noms d'équipes</Label> <Label for="ae-prefix">Préfixe des noms d'équipes</Label>
<Input id="ae-prefix" bind:value={team_prefix} placeholder="FIC Groupe" /> <Input id="ae-prefix" bind:value={assignForm.team_prefix} placeholder="FIC Groupe" />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<Label for="ae-assistants">Nom de l'équipe assistants</Label> <Label for="ae-assistants">Nom de l'équipe assistants</Label>
<Input id="ae-assistants" bind:value={team_assistants} placeholder="Assistants" /> <Input id="ae-assistants" bind:value={assignForm.team_assistants} placeholder="Assistants" />
</FormGroup> </FormGroup>
<Input class="mb-3" type="switch" label="Ne pas répartir les exercices indépendants" bind:checked={assignForm.without_standalone_exercices} />
<Input class="mb-3" type="switch" label="Ne pas répartir les scénarios" bind:checked={assignForm.without_themes} />
<Input class="mb-3" type="switch" label="Répartir tous les exercices existant sans considération des scénarios dans lesquels ils se trouvent" bind:checked={assignForm.only_exercices} />
<Button <Button
type="submit" type="submit"
disabled={assignInProgress} disabled={assignInProgress}