The frontend/UI server, written in JS using the MarkoJS library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.3 KiB

  1. module.exports = class {
  2. onCreate() {
  3. this.mounted = false
  4. }
  5. closeModal() {
  6. this.emit("close")
  7. if (this.mounted) {
  8. window.removeEventListener("keydown", this.onPress)
  9. }
  10. }
  11. onInput(input) {
  12. if (!this.mounted) {
  13. return
  14. }
  15. if (input) {
  16. if (input.enabled && (!this.input || !this.input.enabled)) {
  17. this.emit("open")
  18. }
  19. if (input.closable) {
  20. if (input.enabled && (!this.input || !this.input.enabled)) {
  21. window.addEventListener("keydown", this.onPress)
  22. } else if (!input.enabled && (this.input && this.input.enabled)) {
  23. window.removeEventListener("keydown", this.onPress)
  24. }
  25. }
  26. }
  27. }
  28. onMount() {
  29. this.onPress = this.onPress.bind(this)
  30. this.mounted = true
  31. if (this.input.enabled && this.input.closable) {
  32. window.addEventListener("keydown", this.onPress)
  33. }
  34. }
  35. onUnmount() {
  36. if (this.input.enabled) {
  37. window.removeEventListener("keydown", this.onPress)
  38. }
  39. }
  40. /**
  41. *
  42. * @param {KeyboardEvent} ev
  43. */
  44. onPress(ev) {
  45. if (ev.key === "Escape" && ev.ctrlKey ) {
  46. this.closeModal()
  47. }
  48. }
  49. getValues() {
  50. /** @type {HTMLElement[]} */
  51. const elems = this.findInputs()
  52. const map = {}
  53. for (const component of this.getComponents()) {
  54. if (component.getFormData != null) {
  55. Object.assign(map, component.getFormData() || {})
  56. }
  57. }
  58. return elems.reduce((map, elem) => {
  59. let path = elem.getAttribute("name").split(".")
  60. let node = map
  61. for (const part of path.slice(0, -1)) {
  62. if (node[part] == null) {
  63. node[part] = {}
  64. }
  65. node = node[part]
  66. }
  67. node[path[path.length - 1]] = elem.value;
  68. return map
  69. }, map)
  70. }
  71. /**
  72. * @param {HTMLElement} elem
  73. */
  74. findInputs(elem = this.getEl()) {
  75. let results = []
  76. if (elem.childNodes.length === 0) {
  77. return []
  78. }
  79. for (let i = 0; i < elem.children.length; ++i) {
  80. const child = elem.children.item(i)
  81. if (child.dataset.formboundary != null) {
  82. continue
  83. }
  84. if (child.nodeName === "INPUT" || child.nodeName === "TEXTAREA") {
  85. results.push(child)
  86. } else {
  87. results = results.concat(this.findInputs(child))
  88. }
  89. }
  90. return results
  91. }
  92. }