qa: Managers can view team and manage theirs todo list
This commit is contained in:
parent
b94beb363b
commit
cd64fc90bf
13 changed files with 526 additions and 24 deletions
53
qa/ui/src/routes/teams/+page.svelte
Normal file
53
qa/ui/src/routes/teams/+page.svelte
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import { teams } from '$lib/stores/teams';
|
||||
|
||||
import {
|
||||
Container,
|
||||
Table,
|
||||
} from 'sveltestrap';
|
||||
|
||||
teams.refresh();
|
||||
|
||||
let query = "";
|
||||
const fields = ["name", "color", "active", "external_id"];
|
||||
|
||||
function show(id) {
|
||||
goto("teams/" + id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<Container class="mt-2 mb-5">
|
||||
<h2>
|
||||
Équipes
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
<input type="search" class="form-control" placeholder="Filtrer" bind:value={query} autofocus>
|
||||
</p>
|
||||
<Table class="table-hover table-bordered table-striped">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
{#each fields as field}
|
||||
<th>
|
||||
{field}
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $teams as team (team.id)}
|
||||
{#if team.name.indexOf(query) >= 0}
|
||||
<tr on:click={() => show(team.id)}>
|
||||
{#each fields as field}
|
||||
<td class:text-end={field == "image"}>
|
||||
{team[field]}
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/if}
|
||||
{/each}
|
||||
</tbody>
|
||||
</Table>
|
||||
</Container>
|
||||
197
qa/ui/src/routes/teams/[tid]/+page.svelte
Normal file
197
qa/ui/src/routes/teams/[tid]/+page.svelte
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
Container,
|
||||
Row,
|
||||
Spinner,
|
||||
} from 'sveltestrap';
|
||||
|
||||
import MyExercices from '$lib/components/MyExercices.svelte';
|
||||
import MyTodo from '$lib/components/MyTodo.svelte';
|
||||
import { exercices, exercicesByTheme, exercicesIdx } from '$lib/stores/exercices'
|
||||
import { themes, themesIdx } from '$lib/stores/themes'
|
||||
|
||||
import { getTeam } from '$lib/teams';
|
||||
|
||||
exercices.refresh();
|
||||
themes.refresh();
|
||||
|
||||
let teamtodos = null;
|
||||
let teamP = getTeam($page.params.tid);
|
||||
let todosP = null;
|
||||
teamP.then((team) => {
|
||||
teamtodos = team.todos;
|
||||
todosP = team.todos.refresh();
|
||||
});
|
||||
|
||||
let newTodo = 0;
|
||||
async function submitNewTodo(team) {
|
||||
const res = await fetch(`api/qa_work.json`, {
|
||||
method: 'POST',
|
||||
headers: {'Accept': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
id_team: team.id,
|
||||
id_exercice: newTodo,
|
||||
}),
|
||||
})
|
||||
if (res.status == 200) {
|
||||
newTodo = 0;
|
||||
todosP = team.todos.refresh();
|
||||
return await res.json();
|
||||
} else {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
let newThemeTodo = 0;
|
||||
async function submitNewThemeTodo(team) {
|
||||
for(const e of $exercicesByTheme[newThemeTodo]) {
|
||||
await fetch(`api/qa_work.json`, {
|
||||
method: 'POST',
|
||||
headers: {'Accept': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
id_team: team.id,
|
||||
id_exercice: e.id,
|
||||
}),
|
||||
})
|
||||
}
|
||||
newThemeTodo = 0;
|
||||
todosP = team.todos.refresh();
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await teamP}
|
||||
<Container class="mt-2 mb-5">
|
||||
<div class="d-flex justify-content-center">
|
||||
<Spinner size="lg" />
|
||||
</div>
|
||||
</Container>
|
||||
{:then team}
|
||||
<Container class="mt-2 mb-5">
|
||||
<h2 class="d-flex align-items-center">
|
||||
<div
|
||||
style={"width: 1em; height: 1em; background-color: " + team.toHexColor()}
|
||||
class="me-2 rounded"
|
||||
/>
|
||||
{team.name}
|
||||
</h2>
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<h3>Tâches de l'équipe</h3>
|
||||
{#await todosP}
|
||||
<div class="text-center">
|
||||
<Spinner size="lg" />
|
||||
</div>
|
||||
{:then}
|
||||
<table class="table table-stripped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Scénario</th>
|
||||
<th>Défi</th>
|
||||
<th>Act</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each $teamtodos as todo (todo.id)}
|
||||
<tr>
|
||||
<td>
|
||||
{#if $exercicesIdx.length == 0 && $themesIdx.length == 0}
|
||||
<Spinner size="sm" />
|
||||
{:else}
|
||||
<a href="themes/{$exercicesIdx[todo.id_exercice].id_theme}">
|
||||
{$themesIdx[$exercicesIdx[todo.id_exercice].id_theme].name}
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
{#if $exercicesIdx.length == 0}
|
||||
<Spinner size="sm" />
|
||||
{:else}
|
||||
{$exercicesIdx[todo.id_exercice].title}
|
||||
{/if}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<Button
|
||||
color="danger"
|
||||
size="sm"
|
||||
on:click={todo.delete(team).then(() => { todosP = team.todos.refresh(); })}
|
||||
>
|
||||
🗑
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<form
|
||||
on:submit={() => submitNewTodo(team)}
|
||||
>
|
||||
<div class="input-group">
|
||||
<label class="input-group-text" for="exerciceTodo">Exercice</label>
|
||||
<select
|
||||
class="form-select"
|
||||
id="exercice"
|
||||
bind:value={newTodo}
|
||||
>
|
||||
{#each Object.keys($exercicesByTheme) as thid}
|
||||
<optgroup label={$themesIdx[thid].name}>
|
||||
{#each $exercicesByTheme[thid] as exercice (exercice.id)}
|
||||
<option value={exercice.id}>{exercice.title}</option>
|
||||
{/each}
|
||||
</optgroup>
|
||||
{/each}
|
||||
</select>
|
||||
<Button
|
||||
color="success"
|
||||
type="submit"
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<form
|
||||
on:submit={() => submitNewThemeTodo(team)}
|
||||
>
|
||||
<div class="input-group">
|
||||
<label class="input-group-text" for="themeTodo">Thème</label>
|
||||
<select
|
||||
class="form-select"
|
||||
id="themeTodo"
|
||||
bind:value={newThemeTodo}
|
||||
>
|
||||
{#each Object.keys($exercicesByTheme) as thid}
|
||||
<option value={$themesIdx[thid].id}>{$themesIdx[thid].name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<Button
|
||||
color="success"
|
||||
type="submit"
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{/await}
|
||||
</Col>
|
||||
<Col>
|
||||
<MyExercices {team} />
|
||||
<MyTodo {team} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
{/await}
|
||||
Reference in a new issue