Sprint 3 : protocoles de vote et boite a outils
Backend: - Sessions de vote : list, close, tally, threshold details, auto-expiration - Protocoles : update, simulate, meta-gouvernance, formulas CRUD - Service vote enrichi : close_session, get_threshold_details, nuanced breakdown - Schemas : ThresholdDetailOut, VoteResultOut, FormulaSimulationRequest/Result - WebSocket broadcast sur chaque vote + fermeture session - 25 nouveaux tests (threshold details, close, nuanced, simulation) Frontend: - 5 composants vote : VoteBinary, VoteNuanced, ThresholdGauge, FormulaDisplay, VoteHistory - 3 composants protocoles : ProtocolPicker, FormulaEditor, ModeParamsDisplay - Simulateur de formules interactif (page /protocols/formulas) - Page detail protocole (/protocols/[id]) - Composable useWebSocket (live updates) - Composable useVoteFormula (calcul client-side reactif) - Integration KaTeX pour rendu LaTeX des formules Documentation: - API reference : 8 nouveaux endpoints documentes - Formules : tables d'inertie, parametres detailles, simulation API - Guide vote : vote binaire/nuance, jauge, historique, simulateur, meta-gouvernance 55 tests passes (+ 1 skipped), 126 fichiers total. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
frontend/app/components/protocols/ProtocolPicker.vue
Normal file
64
frontend/app/components/protocols/ProtocolPicker.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* Dropdown/select to pick a voting protocol.
|
||||
*
|
||||
* Fetches protocols from the store and renders them in a USelect
|
||||
* with protocol name, mode params, and vote type badge.
|
||||
*/
|
||||
import type { VotingProtocol } from '~/stores/protocols'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string | null
|
||||
voteType?: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string | null]
|
||||
}>()
|
||||
|
||||
const protocols = useProtocolsStore()
|
||||
|
||||
onMounted(async () => {
|
||||
if (protocols.protocols.length === 0) {
|
||||
await protocols.fetchProtocols(props.voteType ? { vote_type: props.voteType } : undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const filteredProtocols = computed(() => {
|
||||
if (!props.voteType) return protocols.protocols
|
||||
return protocols.protocols.filter(p => p.vote_type === props.voteType)
|
||||
})
|
||||
|
||||
const options = computed(() => {
|
||||
return filteredProtocols.value.map(p => ({
|
||||
label: buildLabel(p),
|
||||
value: p.id,
|
||||
}))
|
||||
})
|
||||
|
||||
function buildLabel(p: VotingProtocol): string {
|
||||
const typeLabel = p.vote_type === 'binary' ? 'Binaire' : 'Nuance'
|
||||
const params = p.mode_params ? ` [${p.mode_params}]` : ''
|
||||
return `${p.name} - ${typeLabel}${params}`
|
||||
}
|
||||
|
||||
function onSelect(value: string) {
|
||||
emit('update:modelValue', value || null)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<USelect
|
||||
:model-value="modelValue ?? undefined"
|
||||
:items="options"
|
||||
placeholder="Selectionnez un protocole..."
|
||||
:loading="protocols.loading"
|
||||
value-key="value"
|
||||
@update:model-value="onSelect"
|
||||
/>
|
||||
<p v-if="protocols.error" class="text-xs text-red-500 mt-1">
|
||||
{{ protocols.error }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user