server/frontend/ui/src/components/FlagKey.svelte

209 lines
6.7 KiB
Svelte

<script>
import {
Button,
Icon,
Spinner,
} from 'sveltestrap';
import { settings } from '../stores/settings.js';
export let refresh_my = null;
export let exercice_id = 0;
export let flag = { };
export let value = "";
let values = [""];
function waitChoices(i) {
refresh_my((my) => {
let haveChoices = false;
if (my && my.exercices[exercice_id].flags) {
my.exercices[exercice_id].flags.forEach((f) => {
if (f.id == flag.id && f.choices) {
haveChoices = true;
}
})
}
if (haveChoices) {
wcsubmitted = false;
} else if (i > 0) {
setTimeout(waitChoices, 450, i-1);
}
})
}
let wcsubmitted = false;
async function wantchoices() {
wcsubmitted = true;
const response = await fetch(
"wantchoices/" + exercice_id,
{
method: "POST",
headers: {'Accept': 'application/json'},
body: JSON.stringify({ id: Number(flag.id) }),
}
)
if (response.status < 300) {
waitChoices(15);
} else {
wcsubmitted = false;
}
}
function addItem() {
values.push("");
values = values;
}
$: {
let v = values.slice();
// Remove empty cells
if (!flag.nb_lines) {
for (let i = v.length - 1; i > 0; i--) {
if (!v[i].length) {
v.splice(i, 1);
}
}
}
// Sort cells
if (flag.ignore_order) {
v = v.sort();
}
value = v.join(flag.separator ? flag.separator : ',');
if (flag.separator) {
value += flag.separator;
}
}
$: {
if (flag.nb_lines) {
while (values.length != flag.nb_lines) {
if (values.length > flag.nb_lines) {
values.pop();
} else {
values.push("");
}
}
}
}
</script>
<div class="form-group mb-3">
<label for="sol_{flag.type}{flag.id}_0">{flag.label}&nbsp;:</label>
{#if flag.found && flag.value}
<span>{flag.value}</span>
{/if}
{#if !flag.found}
{#each values as v, index}
{#if !flag.choices}
<div class="input-group" class:mt-1={index != 0}>
{#if flag.type == 'number'}
<input
type="number"
class="form-control flag"
id="sol_{flag.type}{flag.id}_{index}"
autocomplete="off"
bind:value={values[index]}
placeholder={flag.placeholder}
title={flag.placeholder}
min={flag.min}
max={flag.max}
step={flag.step}
>
{:else if !flag.multiline}
<input
type="text"
class="form-control flag"
id="sol_{flag.type}{flag.id}_{index}"
autocomplete="off"
bind:value={values[index]}
placeholder={flag.placeholder}
title={flag.placeholder}
>
{:else}
<textarea
class="form-control flag"
id="sol_{flag.type}{flag.id}_{index}"
autocomplete="off"
bind:value={values[index]}
placeholder="{flag.placeholder}"
title="{flag.placeholder}"
></textarea>
{/if}
{#if flag.unit}
<span class="input-group-text">{flag.unit}</span>
{/if}
{#if flag.choices_cost > 0}
<Button
color="success"
type="button"
on:click={wantchoices}
disabled={wcsubmitted}
title="Cliquez pour échanger ce champ de texte par une liste de choix. L'opération vous coûtera {flag.choices_cost * $settings.wchoiceCurrentCoefficient} points."
>
{#if wcsubmitted}
<Spinner size="sm" class="me-2" />
{/if}
<Icon name="tasks" />
Liste de propositions ({flag.choices_cost * $settings.wchoiceCurrentCoefficient} {flag.choices_cost * $settings.wchoiceCurrentCoefficient===1?"point":"points"})
</Button>
{:else if flag.separator && !flag.nb_lines && index == values.length - 1}
<Button
color="success"
type="button"
title="Ajouter un élément."
on:click={addItem}
>
<Icon name="plus" />
</Button>
{/if}
</div>
{:else if flag.type == 'radio'}
{#each Object.keys(flag.choices) as l, i}
<div class="form-check">
<input
id="sol_{flag.type}{flag.id}_{index}_{i}"
type="radio"
value={l}
bind:group={values[index]}
class="form-check-input"
>
<label
class="form-check-label"
for="sol_{flag.type}{flag.id}_{index}_{i}"
>
{flag.choices[l]}
</label>
</div>
{/each}
{:else}
<select
class="form-select"
id="sol_{flag.type}{flag.id}_{index}"
bind:value={values[index]}
>
{#each Object.keys(flag.choices) as l}
<option value={l}>{flag.choices[l]}</option>
{/each}
</select>
{/if}
{/each}
{#if flag.help}
<small class="form-text text-muted">{@html flag.help}</small>
{/if}
{:else}
<Icon
name="check"
class="form-control-feedback text-success"
aria-hidden="true"
title="Flag trouvé à {flag.found}"
/>
{/if}
</div>