ActionButton.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. class ActionButton extends window.HTMLButtonElement {
  2. constructFromJson (json) {
  3. this.title = json.title
  4. this.states = []
  5. this.stateLabels = []
  6. this.temporaryStatusMessage = null
  7. this.currentState = 0
  8. this.isWaiting = false
  9. this.actionCallUrl = window.restBaseUrl + 'StartAction?actionName=' + this.title
  10. if (json.icon === '') {
  11. this.unicodeIcon = '&#x1f4a9'
  12. } else {
  13. this.unicodeIcon = unescape(json.icon)
  14. }
  15. this.onclick = () => { this.startAction() }
  16. this.constructTemplate()
  17. this.updateHtml()
  18. }
  19. startAction () {
  20. this.disabled = true
  21. this.isWaiting = true
  22. this.updateHtml()
  23. this.classList = [] // Removes old animation classes
  24. window.fetch(this.actionCallUrl).then(res => res.json()
  25. ).then((json) => {
  26. if (json.timedOut) {
  27. this.onActionResult('actionTimeout', 'Timed out')
  28. } else if (json.exitCode !== 0) {
  29. this.onActionResult('actionNonZeroExit', 'Exit code ' + json.exitCode)
  30. } else {
  31. this.onActionResult('actionSuccess', 'Success!')
  32. }
  33. }).catch(err => {
  34. this.onActionError(err)
  35. })
  36. }
  37. onActionResult (cssClass, temporaryStatusMessage) {
  38. this.temporaryStatusMessage = '[ ' + temporaryStatusMessage + ' ]'
  39. this.updateHtml()
  40. this.classList.add(cssClass)
  41. }
  42. onActionError (err) {
  43. console.log('callback error', err)
  44. this.disabled = false
  45. this.isWaiting = false
  46. this.updateHtml()
  47. this.classList.add('actionFailed')
  48. }
  49. constructTemplate () {
  50. const tpl = document.getElementById('tplActionButton')
  51. const content = tpl.content.cloneNode(true)
  52. /*
  53. * FIXME: Should probably be using a shadowdom here, but seem to
  54. * get an error when combined with custom elements.
  55. */
  56. this.appendChild(content)
  57. this.domTitle = this.querySelector('.title')
  58. this.domIcon = this.querySelector('.icon')
  59. }
  60. updateHtml () {
  61. if (this.temporaryStatusMessage != null) {
  62. this.domTitle.innerText = this.temporaryStatusMessage
  63. this.domTitle.classList.add('temporaryStatusMessage')
  64. this.isWaiting = false
  65. this.disabled = false
  66. setTimeout(() => {
  67. this.temporaryStatusMessage = null
  68. this.domTitle.classList.remove('temporaryStatusMessage')
  69. this.updateHtml()
  70. }, 2000)
  71. } else if (this.isWaiting) {
  72. this.domTitle.innerText = 'Waiting...'
  73. } else {
  74. this.domTitle.innerText = this.title
  75. }
  76. this.domIcon.innerHTML = this.unicodeIcon
  77. }
  78. getCurrentStateLabel (useLabels = true) {
  79. if (useLabels) {
  80. return this.stateLabels[this.currentState]
  81. } else {
  82. return this.states[this.currentState]
  83. }
  84. }
  85. getNextStateLabel () {
  86. return this.stateLabels[this.currentState + 1]
  87. }
  88. }
  89. window.customElements.define('action-button', ActionButton, { extends: 'button' })