2021-08-30 10:46:18 +00:00
|
|
|
<script context="module">
|
|
|
|
import { get_store_value } from 'svelte/internal';
|
|
|
|
|
|
|
|
import { exercices_idx } from '../stores/themes.js';
|
|
|
|
|
2022-02-02 14:29:46 +00:00
|
|
|
export async function load({ url, stuff }) {
|
2021-08-30 10:46:18 +00:00
|
|
|
const eidx = get_store_value(exercices_idx);
|
|
|
|
|
2022-02-02 14:29:46 +00:00
|
|
|
const exercice = eidx[url.searchParams.get("eid")]?eidx[url.searchParams.get("eid")]:null;
|
2021-08-30 10:46:18 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
props: {
|
2021-10-22 08:14:39 +00:00
|
|
|
refresh_issues: stuff.refresh_issues,
|
2021-08-30 10:46:18 +00:00
|
|
|
exercice: exercice,
|
2022-02-02 14:29:46 +00:00
|
|
|
fillIssue: exercice !== null || url.searchParams.get("fill-issue") !== null,
|
2021-08-30 10:46:18 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import {
|
|
|
|
Alert,
|
|
|
|
Button,
|
|
|
|
Card,
|
|
|
|
CardBody,
|
|
|
|
CardHeader,
|
|
|
|
Container,
|
|
|
|
Icon,
|
|
|
|
Table,
|
|
|
|
} from 'sveltestrap';
|
|
|
|
|
2021-09-01 00:21:49 +00:00
|
|
|
import DateFormat from '../components/DateFormat.svelte';
|
|
|
|
|
2021-08-30 10:46:18 +00:00
|
|
|
import { issues, issues_nb_responses, issues_known_responses } from '../stores/issues.js';
|
|
|
|
import { settings } from '../stores/settings.js';
|
|
|
|
|
|
|
|
import FormIssue from '../components/FormIssue.svelte';
|
|
|
|
|
2021-09-02 15:11:53 +00:00
|
|
|
export let refresh_issues = null;
|
2021-08-30 10:46:18 +00:00
|
|
|
export let exercice = null;
|
|
|
|
export let fillIssue = false;
|
|
|
|
let issue = {};
|
|
|
|
|
|
|
|
issues_known_responses.set($issues_nb_responses);
|
|
|
|
|
|
|
|
function newIssue() {
|
|
|
|
fillIssue = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
let sberr = "";
|
|
|
|
let message = "";
|
|
|
|
let messageClass = "success";
|
|
|
|
|
2021-09-02 15:11:53 +00:00
|
|
|
function waitDiff(curissues, i) {
|
|
|
|
refresh_issues((issues) => {
|
|
|
|
if (i > 0 && (!issues || issues.length <= curissues)) {
|
|
|
|
setTimeout(waitDiff, 850, curissues, i-1);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-08-30 10:46:18 +00:00
|
|
|
function respondTo(_issue) {
|
|
|
|
exercice = null;
|
|
|
|
issue = {id: _issue.id, description: ''};
|
|
|
|
fillIssue = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function submit_issue(event) {
|
|
|
|
sberr = "";
|
|
|
|
if (!issue.id && issue.subject.length < 3) {
|
|
|
|
messageClass = "warning";
|
|
|
|
sberr = "L'objet de votre rapport d'anomalie est trop court !";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-01 09:20:41 +00:00
|
|
|
const response = await fetch('issue', {
|
2021-08-30 10:46:18 +00:00
|
|
|
method: "POST",
|
2021-09-06 11:46:24 +00:00
|
|
|
headers: {'Accept': 'application/json'},
|
2021-08-30 10:46:18 +00:00
|
|
|
body: JSON.stringify(issue),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (response.status < 300) {
|
|
|
|
const data = await response.json();
|
|
|
|
messageClass = 'success';
|
|
|
|
message = data.errmsg;
|
|
|
|
issue = { };
|
|
|
|
exercice = null;
|
2021-09-02 14:40:52 +00:00
|
|
|
fillIssue = false;
|
2021-09-02 15:11:53 +00:00
|
|
|
|
|
|
|
const currentissues = get_store_value(issues);
|
|
|
|
waitDiff(currentissues.length, 7);
|
2021-08-30 10:46:18 +00:00
|
|
|
} else {
|
|
|
|
messageClass = 'danger';
|
|
|
|
|
|
|
|
let data = "";
|
|
|
|
try {
|
|
|
|
data = await response.json();
|
|
|
|
} catch(e) {
|
|
|
|
data = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data && data.errmsg)
|
|
|
|
message = data.errmsg;
|
|
|
|
if (response.statys != 402)
|
|
|
|
sberr = "Une erreur est survenue lors de l'envoi. Veuillez réessayer dans quelques instants.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<Container fluid class="my-3">
|
|
|
|
{#if message || sberr}
|
|
|
|
<Alert color={messageClass} fade={false}>
|
|
|
|
{#if !sberr}
|
|
|
|
<strong>Votre rapport a bien été envoyé !</strong>
|
|
|
|
{:else}
|
|
|
|
<strong>{sberr}</strong>
|
|
|
|
{/if}
|
|
|
|
{message}
|
|
|
|
</Alert>
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
{#if fillIssue}
|
|
|
|
<Card class="border-warning mt-3 mb-5">
|
|
|
|
<CardHeader class="bg-warning text-light">
|
|
|
|
<Icon name="file-earmark-plus" />
|
|
|
|
{#if issue.id}
|
|
|
|
Répondre à un message
|
|
|
|
{:else}
|
|
|
|
Rapporter une anomalie sur un défi
|
|
|
|
{/if}
|
|
|
|
</CardHeader>
|
|
|
|
<CardBody>
|
|
|
|
{#if !$settings.acceptNewIssue}
|
|
|
|
<p class="card-text">Rapprochez-vous d'un membre de l'équipe afin d'obtenir de l'aide.</p>
|
|
|
|
{:else}
|
|
|
|
<FormIssue
|
|
|
|
{exercice}
|
|
|
|
bind:issue={issue}
|
|
|
|
on:submit={submit_issue}
|
|
|
|
/>
|
|
|
|
{/if}
|
|
|
|
</CardBody>
|
|
|
|
</Card>
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
<Card>
|
|
|
|
<Table hover striped>
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>Objet</th>
|
|
|
|
<th>État / Priorité</th>
|
|
|
|
<th>Géré par</th>
|
|
|
|
<th>Messages</th>
|
|
|
|
<th>
|
|
|
|
{#if !fillIssue}
|
|
|
|
<Button sm color="warning" on:click={newIssue}>
|
|
|
|
<Icon name="file-earmark-plus" />
|
|
|
|
</Button>
|
|
|
|
{/if}
|
|
|
|
</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{#each $issues as issue (issue.id)}
|
|
|
|
<tr>
|
|
|
|
<td>
|
|
|
|
{issue.subject}
|
2021-09-01 09:20:41 +00:00
|
|
|
{#if issue.exercice} (défi <a href="{issue.url}">{issue.exercice}</a>){/if}
|
2021-08-30 10:46:18 +00:00
|
|
|
</td>
|
|
|
|
<td>{issue.state} / {issue.priority}</td>
|
|
|
|
<td>{#if issue.assignee}{issue.assignee}{:else}En attente d'attribution{/if}</td>
|
|
|
|
<td>
|
|
|
|
{#each issue.texts as text, index}
|
|
|
|
<p style="margin-left: 15px; text-indent: -15px">
|
|
|
|
{#if !text.assignee || text.assignee == '$team'}Vous{:else}{text.assignee}{/if}
|
2021-09-01 00:21:49 +00:00
|
|
|
le <DateFormat date={text.date} /> :
|
2021-08-30 10:46:18 +00:00
|
|
|
<span style="white-space: pre-line">{text.cnt}</span>
|
|
|
|
</p>
|
|
|
|
{/each}
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<Button
|
|
|
|
sm
|
|
|
|
color={issue.state == 'need-info'?'danger':'light'}
|
|
|
|
on:click={respondTo(issue)}
|
|
|
|
>
|
|
|
|
<Icon name={issue.state == 'need-info'?'envelope-fill':'envelope-open-fill'} />
|
|
|
|
</Button>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{:else}
|
|
|
|
<tr>
|
|
|
|
<td colspan="5" class="text-center py-2">
|
|
|
|
Aucune anomalie remontée pour l'instant.<br>
|
2021-09-02 09:36:44 +00:00
|
|
|
Vous souhaitez nous faire <a href="issues?fill-issue">remonter un problème</a> ?
|
2021-08-30 10:46:18 +00:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{/each}
|
|
|
|
</tbody>
|
|
|
|
</Table>
|
|
|
|
</Card>
|
|
|
|
</Container>
|