RunJobDropdown.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <script setup lang="ts">
  2. import { defineAsyncComponent, PropType, ref } from "vue";
  3. import { useWebsocketsStore } from "@/stores/websockets";
  4. import { useLongJobsStore } from "@/stores/longJobs";
  5. const QuickConfirm = defineAsyncComponent(
  6. () => import("@/components/QuickConfirm.vue")
  7. );
  8. defineProps({
  9. jobs: { type: Array as PropType<any[]>, default: () => [] }
  10. });
  11. const showJobDropdown = ref(false);
  12. const { socket } = useWebsocketsStore();
  13. const { setJob } = useLongJobsStore();
  14. const runJob = job => {
  15. let id;
  16. let title;
  17. socket.dispatch(job.socket, {
  18. cb: () => {},
  19. onProgress: res => {
  20. if (res.status === "started") {
  21. id = res.id;
  22. title = res.title;
  23. }
  24. if (id)
  25. setJob({
  26. id,
  27. name: title,
  28. ...res
  29. });
  30. }
  31. });
  32. };
  33. </script>
  34. <template>
  35. <tippy
  36. v-if="jobs.length > 0"
  37. class="runJobDropdown"
  38. :touch="true"
  39. :interactive="true"
  40. placement="bottom-end"
  41. theme="dropdown"
  42. ref="dropdown"
  43. trigger="click"
  44. append-to="parent"
  45. @show="
  46. () => {
  47. showJobDropdown = true;
  48. }
  49. "
  50. @hide="
  51. () => {
  52. showJobDropdown = false;
  53. }
  54. "
  55. >
  56. <div class="control has-addons" ref="trigger">
  57. <button class="button is-primary">Run Job</button>
  58. <button class="button dropdown-toggle">
  59. <i class="material-icons">
  60. {{ showJobDropdown ? "expand_more" : "expand_less" }}
  61. </i>
  62. </button>
  63. </div>
  64. <template #content>
  65. <div class="nav-dropdown-items" v-if="jobs.length > 0">
  66. <quick-confirm
  67. v-for="(job, index) in jobs"
  68. :key="`job-${index}-${job.name}-${job.id}`"
  69. placement="top"
  70. @confirm="runJob(job)"
  71. >
  72. <button class="nav-item button" :title="job.name">
  73. <i
  74. class="material-icons icon-with-button"
  75. content="Run Job"
  76. v-tippy
  77. >play_arrow</i
  78. >
  79. <p>{{ job.name }}</p>
  80. </button>
  81. </quick-confirm>
  82. </div>
  83. <p v-else class="no-jobs">No jobs available.</p>
  84. </template>
  85. </tippy>
  86. </template>
  87. <style lang="less" scoped>
  88. .nav-dropdown-items {
  89. & > span:not(:last-child) .nav-item.button {
  90. margin-bottom: 10px !important;
  91. }
  92. .nav-item.button .icon-with-button {
  93. font-size: 22px;
  94. color: var(--primary-color);
  95. }
  96. }
  97. .no-jobs {
  98. text-align: center;
  99. margin: 10px 0;
  100. }
  101. </style>