feat(politics): implement reconcilePoliticalVacancies endpoint and UI integration for managing political vacancies
This commit is contained in:
@@ -348,7 +348,13 @@
|
||||
"nextRun": "Pinakataas nga sunod nga dagan",
|
||||
"remaining": "Nahibilin",
|
||||
"noTasks": "Walay tasks para ani nga worker.",
|
||||
"missingUserId": "Walay user ID nga anaa (kulang ang setUserId)."
|
||||
"missingUserId": "Walay user ID nga anaa (kulang ang setUserId).",
|
||||
"politicsReconcile": "Idugang ang kulang nga politikal nga mga bakante",
|
||||
"politicsReconcileLoading": "Gidugang ang politikal nga mga bakante …",
|
||||
"politicsReconcileConfirm": "Idugang karon ang kulang nga politikal nga mga bakante?",
|
||||
"politicsReconcileSuccess": "Naghimo og {count} ka bakante. Petsa sa eleksiyon: {date}",
|
||||
"politicsReconcileNone": "Walay kulang nga politikal nga mga bakante nga nakit-an.",
|
||||
"politicsReconcileError": "Dili madugang ang politikal nga mga bakante."
|
||||
}
|
||||
},
|
||||
"chatrooms": {
|
||||
|
||||
@@ -383,7 +383,13 @@
|
||||
"cadence": "Intervall",
|
||||
"nextRun": "Spätester nächster Lauf",
|
||||
"remaining": "Verbleibend",
|
||||
"noTasks": "Keine Tasks für diesen Worker."
|
||||
"noTasks": "Keine Tasks für diesen Worker.",
|
||||
"politicsReconcile": "Fehlende politische Ausschreibungen ergänzen",
|
||||
"politicsReconcileLoading": "Politische Ausschreibungen werden ergänzt …",
|
||||
"politicsReconcileConfirm": "Fehlende politische Ausschreibungen jetzt ergänzen?",
|
||||
"politicsReconcileSuccess": "{count} Ausschreibung(en) angelegt. Wahltermin: {date}",
|
||||
"politicsReconcileNone": "Keine fehlenden politischen Ausschreibungen gefunden.",
|
||||
"politicsReconcileError": "Politische Ausschreibungen konnten nicht ergänzt werden."
|
||||
}
|
||||
},
|
||||
"chatrooms": {
|
||||
|
||||
@@ -438,7 +438,13 @@
|
||||
"nextRun": "Latest next run",
|
||||
"remaining": "Remaining",
|
||||
"noTasks": "No tasks for this worker.",
|
||||
"missingUserId": "No user ID available (setUserId missing)."
|
||||
"missingUserId": "No user ID available (setUserId missing).",
|
||||
"politicsReconcile": "Add missing political vacancies",
|
||||
"politicsReconcileLoading": "Adding political vacancies …",
|
||||
"politicsReconcileConfirm": "Add the missing political vacancies now?",
|
||||
"politicsReconcileSuccess": "Created {count} vacancy/vacancies. Election date: {date}",
|
||||
"politicsReconcileNone": "No missing political vacancies found.",
|
||||
"politicsReconcileError": "Political vacancies could not be added."
|
||||
}
|
||||
},
|
||||
"chatrooms": {
|
||||
|
||||
@@ -321,7 +321,13 @@
|
||||
"nextRun": "Próxima ejecución máxima",
|
||||
"remaining": "Restante",
|
||||
"noTasks": "No hay tareas para este worker.",
|
||||
"missingUserId": "No hay ID de usuario disponible (falta setUserId)."
|
||||
"missingUserId": "No hay ID de usuario disponible (falta setUserId).",
|
||||
"politicsReconcile": "Añadir vacantes políticas pendientes",
|
||||
"politicsReconcileLoading": "Añadiendo vacantes políticas …",
|
||||
"politicsReconcileConfirm": "¿Añadir ahora las vacantes políticas pendientes?",
|
||||
"politicsReconcileSuccess": "Se han creado {count} vacante(s). Fecha de elección: {date}",
|
||||
"politicsReconcileNone": "No se encontraron vacantes políticas pendientes.",
|
||||
"politicsReconcileError": "No se pudieron añadir las vacantes políticas."
|
||||
}
|
||||
},
|
||||
"chatrooms": {
|
||||
|
||||
@@ -321,7 +321,13 @@
|
||||
"nextRun": "Prochaine exécution au plus tard",
|
||||
"remaining": "Restant",
|
||||
"noTasks": "Aucune tâche pour ce worker.",
|
||||
"missingUserId": "Aucun ID utilisateur disponible (setUserId manquant)."
|
||||
"missingUserId": "Aucun ID utilisateur disponible (setUserId manquant).",
|
||||
"politicsReconcile": "Ajouter les postes politiques vacants",
|
||||
"politicsReconcileLoading": "Ajout des postes politiques vacants …",
|
||||
"politicsReconcileConfirm": "Ajouter maintenant les postes politiques vacants ?",
|
||||
"politicsReconcileSuccess": "{count} poste(s) vacant(s) créé(s). Date de l'élection : {date}",
|
||||
"politicsReconcileNone": "Aucun poste politique vacant manquant n'a été trouvé.",
|
||||
"politicsReconcileError": "Les postes politiques vacants n'ont pas pu être ajoutés."
|
||||
}
|
||||
},
|
||||
"chatrooms": {
|
||||
|
||||
@@ -22,8 +22,15 @@
|
||||
<button type="button" @click="requestSchedules">
|
||||
{{ $t('admin.falukant.workerSchedules.refresh') }}
|
||||
</button>
|
||||
<button type="button" :disabled="reconcilingPolitics" @click="reconcilePoliticalVacancies">
|
||||
{{ $t(reconcilingPolitics
|
||||
? 'admin.falukant.workerSchedules.politicsReconcileLoading'
|
||||
: 'admin.falukant.workerSchedules.politicsReconcile') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p v-if="politicsResult" class="politics-result">{{ politicsResult }}</p>
|
||||
|
||||
<p v-if="generatedAt" class="generated-at">
|
||||
{{ $t('admin.falukant.workerSchedules.generatedAt') }}: {{ formatTs(generatedAt) }}
|
||||
</p>
|
||||
@@ -79,6 +86,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import apiClient from '@/utils/axios.js';
|
||||
|
||||
export default {
|
||||
name: 'AdminFalukantWorkerSchedulesView',
|
||||
@@ -91,6 +99,8 @@ export default {
|
||||
loading: false,
|
||||
error: null,
|
||||
timer: null,
|
||||
reconcilingPolitics: false,
|
||||
politicsResult: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -177,6 +187,26 @@ export default {
|
||||
this.error = this.$t('admin.falukant.workerSchedules.sendError');
|
||||
}
|
||||
},
|
||||
async reconcilePoliticalVacancies() {
|
||||
if (!window.confirm(this.$t('admin.falukant.workerSchedules.politicsReconcileConfirm'))) return;
|
||||
this.reconcilingPolitics = true;
|
||||
this.politicsResult = null;
|
||||
try {
|
||||
const { data } = await apiClient.post('/api/admin/falukant/politics/reconcile-vacancies');
|
||||
const count = Number(data?.createdCount || 0);
|
||||
this.politicsResult = count
|
||||
? this.$t('admin.falukant.workerSchedules.politicsReconcileSuccess', {
|
||||
count,
|
||||
date: new Date(data.electionDate).toLocaleString()
|
||||
})
|
||||
: this.$t('admin.falukant.workerSchedules.politicsReconcileNone');
|
||||
} catch (err) {
|
||||
this.politicsResult = err?.response?.data?.error
|
||||
|| this.$t('admin.falukant.workerSchedules.politicsReconcileError');
|
||||
} finally {
|
||||
this.reconcilingPolitics = false;
|
||||
}
|
||||
},
|
||||
handleDaemonMessage(evt) {
|
||||
try {
|
||||
const payload = JSON.parse(evt.data);
|
||||
@@ -214,6 +244,7 @@ export default {
|
||||
.toolbar { display: flex; gap: 12px; align-items: center; margin: 12px 0; flex-wrap: wrap; }
|
||||
.toggle { display: inline-flex; gap: 6px; align-items: center; }
|
||||
.generated-at { color: #666; margin-bottom: 8px; }
|
||||
.politics-result { margin: 8px 0; color: #216b2f; }
|
||||
.workers { display: grid; gap: 12px; }
|
||||
.worker-card { border: 1px solid #ddd; border-radius: 8px; padding: 12px; background: #fff; }
|
||||
.worker-card__header { display: flex; justify-content: space-between; gap: 12px; align-items: center; flex-wrap: wrap; }
|
||||
|
||||
Reference in New Issue
Block a user