|
1 | 1 | <script lang="ts">
|
2 | 2 | import { onMount } from 'svelte';
|
| 3 | + import { fade } from 'svelte/transition'; |
3 | 4 |
|
4 | 5 | import {
|
5 | 6 | InfoCircleSolid, PlaySolid, StopSolid, TrashBinSolid, EditSolid, FileCloneSolid, BookOpenSolid,
|
|
16 | 17 | import { classModalLabel } from '../Style.js';
|
17 | 18 | import { tq } from '../../util/translate.js';
|
18 | 19 | import { apiEdit, apiGet } from '../../util/api.js';
|
| 20 | + import { choicesFromArray } from '../../util/form.js'; |
19 | 21 | import { type executionPromptsType } from './Config.js';
|
20 | 22 | import {
|
21 | 23 | classModalBackdrop, classModalBtns, classPopover, classPopoverTitle, classPopoverColumn1,
|
|
86 | 88 | let jobList: jobInfos[] = $state([]);
|
87 | 89 | let jobActions = $state({});
|
88 | 90 | let apiError = $state('');
|
| 91 | + let apiSuccess = $state(''); |
89 | 92 |
|
90 | 93 | interface executionPromptsFieldValues {
|
91 | 94 | tags: string,
|
|
149 | 152 | if (a) {
|
150 | 153 | a.scrollIntoView({behavior: "smooth", block: "end", inline: "end"});
|
151 | 154 | }
|
| 155 | + } else { |
| 156 | + apiSuccess = t('common.success'); |
| 157 | + setTimeout(() => {apiSuccess = ''}, 6000); |
152 | 158 | }
|
153 | 159 | }
|
154 | 160 |
|
|
170 | 176 | if (!jobId) {
|
171 | 177 | return;
|
172 | 178 | }
|
173 |
| - // todo: add execution prompt values |
174 |
| - apiEdit('post', `job/${jobId}`, undefined, showAPIErrors); |
| 179 | + let promptData = {}; |
| 180 | +
|
| 181 | + for (let f of executionPrompts.config.fields) { |
| 182 | + promptData[f] = executionPrompts.field_values[f]; |
| 183 | + } |
| 184 | +
|
| 185 | + if (executionPrompts.config.vars.length) { |
| 186 | + let c: string[] = []; |
| 187 | +
|
| 188 | + for (let [k, v] of Object.entries(executionPrompts.var_values)) { |
| 189 | + if (v && v.trim()) { |
| 190 | + c.push(`-e "${k}=${v}"`) |
| 191 | + } |
| 192 | + } |
| 193 | +
|
| 194 | + if (c.length) { |
| 195 | + if (!executionPrompts.config.fields.includes('cmd_args')) { |
| 196 | + promptData['cmd_args'] = ''; |
| 197 | + } |
| 198 | + promptData['cmd_args'] += ` ${c.join(' ')}` |
| 199 | + } |
| 200 | + } |
| 201 | +
|
| 202 | + apiEdit('post', `job/${jobId}`, promptData, showAPIErrors); |
| 203 | + jobActions[jobId].exec = false; |
175 | 204 | }
|
176 | 205 |
|
177 | 206 | function updateExecutionPrompts(encodedPrompts: string|null) {
|
|
207 | 236 |
|
208 | 237 | <div id={apiErrorAlert} class="h-0"></div>
|
209 | 238 | {#if apiError}
|
210 |
| - <Alert border color="red" class="text-wrap"> |
211 |
| - <CloseCircleSolid slot="icon" class="w-5 h-5" /> {apiError} |
212 |
| - </Alert> |
| 239 | + <div transition:fade> |
| 240 | + <Alert border color="red" class="text-wrap"> |
| 241 | + <CloseCircleSolid slot="icon" class="w-5 h-5" /> {apiError} |
| 242 | + </Alert> |
| 243 | + </div> |
| 244 | +{/if} |
| 245 | +{#if apiSuccess} |
| 246 | + <div transition:fade> |
| 247 | + <Alert border color="green" class="text-wrap"> |
| 248 | + <InfoCircleSolid slot="icon" class="w-5 h-5" /> {apiSuccess} |
| 249 | + </Alert> |
| 250 | + </div> |
213 | 251 | {/if}
|
214 | 252 | <div>
|
215 | 253 | <Table striped={true}>
|
|
230 | 268 | {job.name}
|
231 | 269 | <button id="job-name-{job.id}" class="ml-1">
|
232 | 270 | <InfoCircleSolid size="sm"/>
|
233 |
| - <span class="sr-only">Show Job Information</span> |
| 271 | + <span class="sr-only">{t('jobs.info')}</span> |
234 | 272 | </button>
|
235 | 273 | </TableBodyCell>
|
236 | 274 | <TableBodyCell class="max-lg:hidden">{job.inventory_file ? job.inventory_file : '-'}</TableBodyCell>
|
|
239 | 277 | {job.next_run ? job.next_run : '-'}
|
240 | 278 | <button id="job-schedule-{job.id}" class="ml-1">
|
241 | 279 | <InfoCircleSolid size="sm"/>
|
242 |
| - <span class="sr-only">Show Execution Information</span> |
| 280 | + <span class="sr-only">{t('jobs.info.execution')}</span> |
243 | 281 | </button>
|
244 | 282 | </TableBodyCell>
|
245 | 283 | <TableBodyCell>
|
|
284 | 322 | <div id="job-infos-{job.id}">
|
285 | 323 | <Popover triggeredBy="#job-name-{job.id}" class={classPopover} placement="bottom-start">
|
286 | 324 | <div class="p-3 space-y-2">
|
287 |
| - <h3 class={classPopoverTitle}>Job Information</h3> |
| 325 | + <h3 class={classPopoverTitle}>{t('jobs.info')}</h3> |
288 | 326 | </div>
|
289 | 327 | <table>
|
290 | 328 | <tbody>
|
|
355 | 393 | </Popover>
|
356 | 394 | <Popover triggeredBy="#job-schedule-{job.id}" class={classPopover} placement="bottom-start">
|
357 | 395 | <div class="p-3 space-y-2">
|
358 |
| - <h3 class={classPopoverTitle}>Execution Information</h3> |
| 396 | + <h3 class={classPopoverTitle}>{t('jobs.info.execution')}</h3> |
359 | 397 | <table>
|
360 | 398 | <tbody>
|
361 | 399 | <tr>
|
362 | 400 | <td class={classPopoverColumn1}>
|
363 |
| - Schedule Enabled: |
| 401 | + {t('jobs.form.enabled')}: |
364 | 402 | </td>
|
365 | 403 | <td class={classPopoverColumn2Div}>
|
366 | 404 | <button class="cursor-default">
|
|
370 | 408 | </tr>
|
371 | 409 | <tr>
|
372 | 410 | <td class={classPopoverColumn1}>
|
373 |
| - Schedule Cron: |
| 411 | + {t('jobs.form.schedule')}: |
374 | 412 | </td>
|
375 | 413 | <td class={classPopoverColumn2Text}>
|
376 | 414 | {job.schedule ? job.schedule : '-'}
|
377 | 415 | </td>
|
378 | 416 | </tr>
|
379 | 417 | <tr>
|
380 | 418 | <td class={classPopoverColumn1}>
|
381 |
| - Next Run: |
| 419 | + {t('jobs.info.next_run')}: |
382 | 420 | </td>
|
383 | 421 | <td class={classPopoverColumn2Text}>
|
384 | 422 | {job.next_run ? job.next_run : '-'}
|
|
387 | 425 | {#if job.executions.length}
|
388 | 426 | <tr>
|
389 | 427 | <td class={classPopoverColumn1}>
|
390 |
| - Last Run: |
| 428 | + {t('jobs.info.last_run')}: |
391 | 429 | </td>
|
392 | 430 | <td class={classPopoverColumn2Text}>
|
393 | 431 | {job.executions[0].time_start}
|
394 | 432 | </td>
|
395 | 433 | </tr>
|
396 | 434 | <tr>
|
397 | 435 | <td class={classPopoverColumn1}>
|
398 |
| - Status: |
| 436 | + {t('common.status')}: |
399 | 437 | </td>
|
400 | 438 | <td class={classPopoverColumn2Text}>
|
401 | 439 | {job.executions[0].status_name}
|
402 | 440 | </td>
|
403 | 441 | </tr>
|
404 | 442 | <tr>
|
405 | 443 | <td class={classPopoverColumn1}>
|
406 |
| - Duration: |
| 444 | + {t('jobs.info.duration')}: |
407 | 445 | </td>
|
408 | 446 | <td class={classPopoverColumn2Text}>
|
409 | 447 | {job.executions[0].time_duration}
|
410 | 448 | </td>
|
411 | 449 | </tr>
|
412 | 450 | <tr>
|
413 | 451 | <td class={classPopoverColumn1}>
|
414 |
| - Failed: |
| 452 | + {t('jobs.info.failed')}: |
415 | 453 | </td>
|
416 | 454 | <td class={classPopoverColumn2Div}>
|
417 | 455 | <button class="cursor-default">
|
|
422 | 460 | {#if job.executions[0].failed}
|
423 | 461 | <tr>
|
424 | 462 | <td class={classPopoverColumn1}>
|
425 |
| - Error: |
| 463 | + {t('common.error')}: |
426 | 464 | </td>
|
427 | 465 | <td class={classPopoverColumn2Div}>
|
428 | 466 | <Alert color="red" border>{job.executions[0].error_s}</Alert>
|
|
435 | 473 | </div>
|
436 | 474 | </Popover>
|
437 | 475 | <Modal bind:open={jobActions[job.id].exec} size="sm" autoclose={true} placement="top-center" backdropClass={classModalBackdrop}>
|
438 |
| - <Heading tag="h2">Execute Job</Heading> |
| 476 | + <Heading tag="h2">{t('jobs.execute')}</Heading> |
439 | 477 |
|
440 | 478 | {#if executionPrompts.config.fields.includes('limit')}
|
441 | 479 | <Label for="job_prompt_{job.id}_limit" class={classModalLabel}>{t('jobs.form.limit')}</Label>
|
442 | 480 | <Input id="job_prompt_{job.id}_limit" bind:value={executionPrompts.field_values.limit} />
|
443 | 481 | {/if}
|
444 |
| - {#if executionPrompts.config.fields.includes('mode_check')} |
445 |
| - <Label for="job_prompt_{job.id}_mode_check" class={classModalLabel}>{t('jobs.form.mode_check')}</Label> |
446 |
| - <div class={classCenterChildDiv}> |
447 |
| - <Toggle id="job_prompt_{job.id}_mode_check" bind:checked={executionPrompts.field_values.mode_check} /> |
448 |
| - </div> |
449 |
| - {/if} |
450 |
| - {#if executionPrompts.config.fields.includes('mode_diff')} |
451 |
| - <Label for="job_prompt_{job.id}_mode_diff" class={classModalLabel}>{t('jobs.form.mode_diff')}</Label> |
452 |
| - <div class={classCenterChildDiv}> |
453 |
| - <Toggle id="job_prompt_{job.id}_mode_diff" bind:checked={executionPrompts.field_values.mode_diff} /> |
454 |
| - </div> |
455 |
| - {/if} |
| 482 | + <div> |
| 483 | + {#if executionPrompts.config.fields.includes('mode_check')} |
| 484 | + <Label for="job_prompt_{job.id}_mode_check" class={classModalLabel}>{t('jobs.form.mode_check')}</Label> |
| 485 | + <div class={classCenterChildDiv}> |
| 486 | + <Toggle id="job_prompt_{job.id}_mode_check" bind:checked={executionPrompts.field_values.mode_check} /> |
| 487 | + </div> |
| 488 | + {/if} |
| 489 | + {#if executionPrompts.config.fields.includes('mode_diff')} |
| 490 | + <Label for="job_prompt_{job.id}_mode_diff" class={classModalLabel}>{t('jobs.form.mode_diff')}</Label> |
| 491 | + <div class={classCenterChildDiv}> |
| 492 | + <Toggle id="job_prompt_{job.id}_mode_diff" bind:checked={executionPrompts.field_values.mode_diff} /> |
| 493 | + </div> |
| 494 | + {/if} |
| 495 | + </div> |
456 | 496 | {#if executionPrompts.config.fields.includes('tags')}
|
457 | 497 | <Label for="job_prompt_{job.id}_tags" class={classModalLabel}>{t('jobs.form.tags')}</Label>
|
458 | 498 | <Input id="job_prompt_{job.id}_tags" bind:value={executionPrompts.field_values.tags} />
|
|
474 | 514 | <Select id="job_prompt_{job.id}_creds" items={usableCredentialChoices}
|
475 | 515 | bind:value={executionPrompts.field_values.credentials} />
|
476 | 516 | {/if}
|
| 517 | + {#each executionPrompts.config.vars as v, i (v.name)} |
| 518 | + {#if v.kind == 'text'} |
| 519 | + <Label for="job_prompt_{job.id}_var_{i}" class={classModalLabel}>{v.name}</Label> |
| 520 | + <Input id="job_prompt_{job.id}_var_{i}" bind:value={executionPrompts.var_values[v.varName]} /> |
| 521 | + <!-- todo: regex validation --> |
| 522 | + {:else} |
| 523 | + <Label for="job_prompt_{job.id}_var_{i}" class={classModalLabel}>{v.name}</Label> |
| 524 | + <Select id="job_prompt_{job.id}_var_{i}" items={choicesFromArray(v.choices)} |
| 525 | + bind:value={executionPrompts.var_values[v.varName]} /> |
| 526 | + {/if} |
| 527 | + {/each} |
477 | 528 |
|
478 | 529 | <div class={classModalBtns}>
|
479 | 530 | <!--
|
|
0 commit comments