|
229 | 229 | </div> |
230 | 230 |
|
231 | 231 | <div class="form-group"> |
232 | | - <label for="service">Service (optional)</label> |
233 | | - <input |
| 232 | + <label for="service"> |
| 233 | + Service |
| 234 | + <i v-if="loadingServices" class="pi pi-spin pi-spinner" style="margin-left: 4px" /> |
| 235 | + </label> |
| 236 | + <select |
234 | 237 | id="service" |
235 | 238 | v-model="form.service" |
236 | | - type="text" |
237 | | - placeholder="web, app, worker..." |
238 | | - :disabled="saving" |
239 | | - /> |
240 | | - <span class="hint">Leave empty to use deployment name as container</span> |
| 239 | + :disabled="saving || loadingServices || !form.deployment_name" |
| 240 | + > |
| 241 | + <option value="">Default ({{ form.deployment_name || "select deployment" }})</option> |
| 242 | + <option v-for="svc in deploymentServices" :key="svc.name" :value="svc.name"> |
| 243 | + {{ svc.name }} |
| 244 | + </option> |
| 245 | + </select> |
| 246 | + <span class="hint">Target service container for the command</span> |
241 | 247 | </div> |
242 | 248 |
|
243 | 249 | <div class="form-group"> |
|
374 | 380 | import { ref, computed, onMounted, watch } from "vue"; |
375 | 381 | import { schedulerApi, deploymentsApi } from "@/services/api"; |
376 | 382 | import type { ScheduledTask, TaskExecution } from "@/services/api"; |
377 | | -import type { Deployment } from "@/types"; |
| 383 | +import type { Deployment, Service } from "@/types"; |
378 | 384 | import { useNotificationsStore } from "@/stores/notifications"; |
379 | 385 | import { useAuthStore } from "@/stores/auth"; |
380 | 386 | import ConfirmModal from "@/components/ConfirmModal.vue"; |
@@ -512,6 +518,34 @@ const defaultForm = (): CronJobForm => ({ |
512 | 518 | }); |
513 | 519 |
|
514 | 520 | const form = ref<CronJobForm>(defaultForm()); |
| 521 | +const deploymentServices = ref<Service[]>([]); |
| 522 | +const loadingServices = ref(false); |
| 523 | +
|
| 524 | +const fetchDeploymentServices = async (deploymentName: string) => { |
| 525 | + if (!deploymentName) { |
| 526 | + deploymentServices.value = []; |
| 527 | + return; |
| 528 | + } |
| 529 | + loadingServices.value = true; |
| 530 | + try { |
| 531 | + const response = await deploymentsApi.getServices(deploymentName); |
| 532 | + deploymentServices.value = response.data.services || []; |
| 533 | + } catch { |
| 534 | + deploymentServices.value = []; |
| 535 | + } finally { |
| 536 | + loadingServices.value = false; |
| 537 | + } |
| 538 | +}; |
| 539 | +
|
| 540 | +watch( |
| 541 | + () => form.value.deployment_name, |
| 542 | + (name, oldName) => { |
| 543 | + if (oldName) { |
| 544 | + form.value.service = ""; |
| 545 | + } |
| 546 | + fetchDeploymentServices(name); |
| 547 | + }, |
| 548 | +); |
515 | 549 |
|
516 | 550 | const isFormValid = computed(() => { |
517 | 551 | return Boolean( |
|
0 commit comments