ExecutionButton.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <div
  3. :id="`execution-${trackingId}`"
  4. class="execution-button"
  5. >
  6. <button
  7. :title="`${ellapsed}s`"
  8. @click="show"
  9. >
  10. {{ buttonText }}
  11. </button>
  12. </div>
  13. </template>
  14. <script>
  15. // import { ExecutionFeedbackButton } from '../js/ExecutionFeedbackButton.js'
  16. export default {
  17. name: 'ExecutionButton',
  18. // mixins: [ExecutionFeedbackButton],
  19. props: {
  20. executionTrackingId: {
  21. type: String,
  22. required: true
  23. }
  24. },
  25. emits: ['show'],
  26. data () {
  27. return {
  28. trackingId: '',
  29. ellapsed: 0,
  30. isWaiting: true
  31. }
  32. },
  33. computed: {
  34. buttonText () {
  35. if (this.isWaiting) {
  36. return 'Executing...'
  37. } else {
  38. return `${this.ellapsed}s`
  39. }
  40. }
  41. },
  42. mounted () {
  43. this.trackingId = this.executionTrackingId
  44. this.constructFromJson(this.executionTrackingId)
  45. },
  46. methods: {
  47. constructFromJson (json) {
  48. this.trackingId = json
  49. this.ellapsed = 0
  50. this.isWaiting = true
  51. },
  52. async show () {
  53. this.$emit('show')
  54. if (window.executionDialog) {
  55. await window.executionDialog.reset()
  56. window.executionDialog.show()
  57. window.executionDialog.fetchExecutionResult(this.trackingId)
  58. }
  59. },
  60. onExecStatusChanged () {
  61. this.isWaiting = false
  62. this.domTitle = this.ellapsed + 's'
  63. },
  64. // Override from ExecutionFeedbackButton
  65. onExecutionFinished (logEntry) {
  66. if (logEntry.timedOut) {
  67. this.renderExecutionResult('action-timeout', 'Timed out')
  68. } else if (logEntry.blocked) {
  69. this.renderExecutionResult('action-blocked', 'Blocked!')
  70. } else if (logEntry.exitCode !== 0) {
  71. this.renderExecutionResult('action-nonzero-exit', 'Exit code ' + logEntry.exitCode)
  72. } else {
  73. this.ellapsed = Math.ceil(new Date(logEntry.datetimeFinished) - new Date(logEntry.datetimeStarted)) / 1000
  74. this.renderExecutionResult('action-success', 'Success!')
  75. }
  76. },
  77. renderExecutionResult (resultCssClass, temporaryStatusMessage) {
  78. this.updateDom(resultCssClass, '[' + temporaryStatusMessage + ']')
  79. this.onExecStatusChanged()
  80. },
  81. updateDom (resultCssClass, title) {
  82. // For execution button, we don't need to update classes as much
  83. // since it's a simpler component
  84. if (resultCssClass) {
  85. const button = this.$el.querySelector('button')
  86. if (button) {
  87. button.classList.add(resultCssClass)
  88. }
  89. }
  90. }
  91. }
  92. }
  93. </script>
  94. <style scoped>
  95. .execution-button {
  96. display: inline-block;
  97. }
  98. .execution-button button {
  99. padding: 0.25em 0.5em;
  100. border: 1px solid #ccc;
  101. border-radius: 3px;
  102. background: #fff;
  103. cursor: pointer;
  104. font-size: 0.9em;
  105. transition: all 0.2s ease;
  106. }
  107. .execution-button button:hover {
  108. background: #f5f5f5;
  109. border-color: #999;
  110. }
  111. /* Animation classes */
  112. .execution-button button.action-timeout {
  113. background: #fff3cd;
  114. border-color: #ffeaa7;
  115. color: #856404;
  116. }
  117. .execution-button button.action-blocked {
  118. background: #f8d7da;
  119. border-color: #f5c6cb;
  120. color: #721c24;
  121. }
  122. .execution-button button.action-nonzero-exit {
  123. background: #f8d7da;
  124. border-color: #f5c6cb;
  125. color: #721c24;
  126. }
  127. .execution-button button.action-success {
  128. background: #d4edda;
  129. border-color: #c3e6cb;
  130. color: #155724;
  131. }
  132. </style>