RunJobDropdown.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. class="runJobDropdown"
  37. :touch="true"
  38. :interactive="true"
  39. placement="bottom-end"
  40. theme="dropdown"
  41. ref="dropdown"
  42. trigger="click"
  43. append-to="parent"
  44. @show="
  45. () => {
  46. showJobDropdown = true;
  47. }
  48. "
  49. @hide="
  50. () => {
  51. showJobDropdown = false;
  52. }
  53. "
  54. >
  55. <div class="control has-addons" ref="trigger">
  56. <button class="button is-primary">Run Job</button>
  57. <button class="button dropdown-toggle">
  58. <i class="material-icons">
  59. {{ showJobDropdown ? "expand_more" : "expand_less" }}
  60. </i>
  61. </button>
  62. </div>
  63. <template #content>
  64. <div class="nav-dropdown-items" v-if="jobs.length > 0">
  65. <quick-confirm
  66. v-for="(job, index) in jobs"
  67. :key="`job-${index}`"
  68. placement="top"
  69. @confirm="runJob(job)"
  70. >
  71. <button class="nav-item button" :title="job.name">
  72. <i
  73. class="material-icons icon-with-button"
  74. content="Run Job"
  75. v-tippy
  76. >play_arrow</i
  77. >
  78. <p>{{ job.name }}</p>
  79. </button>
  80. </quick-confirm>
  81. </div>
  82. <p v-else class="no-jobs">No jobs available.</p>
  83. </template>
  84. </tippy>
  85. </template>
  86. <style lang="less" scoped>
  87. .nav-dropdown-items {
  88. & > span:not(:last-child) .nav-item.button {
  89. margin-bottom: 10px !important;
  90. }
  91. .nav-item.button .icon-with-button {
  92. font-size: 22px;
  93. color: var(--primary-color);
  94. }
  95. }
  96. .no-jobs {
  97. text-align: center;
  98. margin: 10px 0;
  99. }
  100. </style>