ArgumentForm.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. class ArgumentForm extends window.HTMLElement {
  2. setup (json, callback) {
  3. this.setAttribute('class', 'actionArguments')
  4. this.constructTemplate()
  5. this.domTitle.innerText = json.title
  6. this.domIcon.innerHTML = json.icon
  7. this.createDomFormArguments(json.arguments)
  8. this.domBtnStart.onclick = () => {
  9. for (const arg of this.argInputs) {
  10. if (!arg.validity.valid) {
  11. return
  12. }
  13. }
  14. const argvs = this.getArgumentValues()
  15. callback(argvs)
  16. this.remove()
  17. }
  18. this.domBtnCancel.onclick = () => {
  19. this.remove()
  20. }
  21. }
  22. getArgumentValues () {
  23. const ret = []
  24. for (const arg of this.argInputs) {
  25. ret.push({
  26. name: arg.name,
  27. value: arg.value
  28. })
  29. }
  30. return ret
  31. }
  32. constructTemplate () {
  33. const tpl = document.getElementById('tplArgumentForm')
  34. const content = tpl.content.cloneNode(true)
  35. this.appendChild(content)
  36. this.domTitle = this.querySelector('h2')
  37. this.domIcon = this.querySelector('span.icon')
  38. this.domWrapper = this.querySelector('.wrapper')
  39. this.domArgs = this.querySelector('.arguments')
  40. this.domBtnStart = this.querySelector('[name=start]')
  41. this.domBtnCancel = this.querySelector('[name=cancel]')
  42. }
  43. createDomFormArguments (args) {
  44. this.argInputs = []
  45. for (const arg of args) {
  46. const domFieldWrapper = document.createElement('p')
  47. domFieldWrapper.appendChild(this.createDomLabel(arg))
  48. domFieldWrapper.appendChild(this.createDomInput(arg))
  49. this.domArgs.appendChild(domFieldWrapper)
  50. }
  51. }
  52. createDomLabel (arg) {
  53. const domLbl = document.createElement('label')
  54. domLbl.innerText = arg.title + ':'
  55. domLbl.setAttribute('for', arg.name)
  56. return domLbl
  57. }
  58. createDomInput (arg) {
  59. let domEl = null
  60. if (arg.choices.length > 0) {
  61. domEl = document.createElement('select')
  62. // select/choice elements don't get an onchange/validation because theoretically
  63. // the user should only select from a dropdown of valid options. The choices are
  64. // riggeriously checked on StartAction anyway. ValidateArgumentType is only
  65. // meant for showing simple warnings in the UI before running.
  66. for (const choice of arg.choices) {
  67. domEl.appendChild(this.createSelectOption(choice))
  68. }
  69. } else {
  70. domEl = document.createElement('input')
  71. domEl.onchange = () => {
  72. const validateArgumentTypeArgs = {
  73. value: domEl.value,
  74. type: arg.type
  75. }
  76. window.fetch(window.restBaseUrl + 'ValidateArgumentType', {
  77. method: 'POST',
  78. headers: {
  79. 'Content-Type': 'application/json'
  80. },
  81. body: JSON.stringify(validateArgumentTypeArgs)
  82. }).then((res) => {
  83. if (res.ok) {
  84. return res.json()
  85. } else {
  86. throw new Error(res.statusText)
  87. }
  88. }).then((json) => {
  89. console.log(json.valid)
  90. if (json.valid) {
  91. domEl.setCustomValidity('')
  92. } else {
  93. domEl.setCustomValidity(json.description)
  94. }
  95. })
  96. }
  97. }
  98. domEl.name = arg.name
  99. domEl.value = arg.defaultValue
  100. this.argInputs.push(domEl)
  101. return domEl
  102. }
  103. createSelectOption (choice) {
  104. const domEl = document.createElement('option')
  105. domEl.setAttribute('value', choice.value)
  106. domEl.innerText = choice.title
  107. return domEl
  108. }
  109. }
  110. window.customElements.define('argument-form', ArgumentForm)