views.cljs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. (ns microtables-frontend.views
  2. (:require
  3. [re-frame.core :as re-frame]
  4. [microtables-frontend.subs :as subs]
  5. [microtables-frontend.events :as events]
  6. [microtables-frontend.utils :as utils]))
  7. ;; TABLE COMPONENTS
  8. (defn cell [c r data]
  9. (let [datum (get-in data [c r])]
  10. ^{:key (str c r)} [:td
  11. [:input {:id (str c r)
  12. :class (if (= (:view datum) :highlighted) "highlighted" "")
  13. :value (if (= (get datum :view nil) :value)
  14. (get datum :value "")
  15. (get datum :error (get datum :display (get datum :value ""))));TODO: add "highlight" display mode (possibly just a css class)
  16. :on-change #(re-frame/dispatch [::events/edit-cell-value c r (.. % -target -value)])
  17. :on-focus #(re-frame/dispatch [::events/movement-enter-cell c r])
  18. :on-blur #(re-frame/dispatch [::events/movement-leave-cell c r])
  19. :on-keyPress #(when (= (.. % -which) 13)
  20. (re-frame/dispatch [::events/press-enter-in-cell c r]))}]]))
  21. (defn row [r cols data]
  22. ^{:key (str "row-" r)} [:tr
  23. (cons
  24. ^{:key (str "row-head-" r)} [:th (str r)]
  25. (map #(cell % r data) cols))])
  26. (defn header-row [cols]
  27. ^{:key "header"} [:tr
  28. (cons
  29. ^{:key "corner"} [:th]
  30. (map (fn [c] ^{:key (str "col-head-" c)} [:th c]) cols))])
  31. (defn sheet [data]
  32. [:table
  33. {:id "main-table"}
  34. [:tbody
  35. ;TODO: figure out appropriate starting values for maxrow and maxcol (maybe keep them intentionally small)
  36. ;TODO: figure out movement (maybe allow scroll overflow)
  37. (let [maxrow 50;(utils/highest-row data)
  38. maxcol "Z";(utils/highest-col data)
  39. cols (take-while (partial not= (utils/next-letter maxcol)) utils/col-letters)]
  40. (cons
  41. (header-row cols)
  42. (map #(row % cols data) (range 1 (inc maxrow)))))]])
  43. (defn extend-range
  44. []
  45. [:div {:class "control-group"}
  46. [:div {:class "control-label"}
  47. "Extend Range"]
  48. [:button "-cols"]
  49. [:input]
  50. [:button]])
  51. (defn controls []
  52. [:div
  53. ;[extend-range]
  54. ;extend range (number field, then shrink/left/up and expand/right/down buttons on either side)
  55. ;fill range (single tap, single column/row fill? number field and button?)
  56. ;move range (designate new "top-left corner" cell for range, figure out overwriting destination cells)
  57. ;empty range (delete contents, re-evaluate)
  58. ;delete range (figure out how to move cells over)
  59. ;copy range (figure out clipboard)
  60. [:div
  61. {:class "control-group"}
  62. #_[:a ;TODO: consider making the "About" info an overlay rather than a link
  63. {:href "/about.html"
  64. :target "_blank"}
  65. "About"]
  66. "This is a demo version only, and still in development. Nothing gets saved for the moment."
  67. [:br]
  68. "Try adding values (plain numbers) or formulae (ex: \"=B2 + sum(A1:A6)\") into the cells."
  69. [:br]
  70. "Created by "
  71. [:a
  72. {:href "https://betweentwocommits.com/about"
  73. :target "_blank"}
  74. "Brandon Wong"]]])
  75. (defn control-panel [state]
  76. [:div
  77. {:id "controls"}
  78. [:div
  79. ;TODO: link left controls with position of the whole table
  80. {:id "controls-left"
  81. :class (if (= state :left) "open" "")}
  82. [controls]]
  83. [:div
  84. {:id "controls-bottom"
  85. :class (if (= state :bottom) "open" "")}
  86. [controls]]
  87. ;←↑→↓
  88. [:div
  89. {:id "left-controls-button"
  90. :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :left) nil :left)])}
  91. (if (= state :left) "←" "→")]
  92. [:div
  93. {:id "bottom-controls-button"
  94. :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :bottom) nil :bottom)])}
  95. (if (= state :bottom) "↓" "↑")]
  96. [:div
  97. {:id "main-logo"
  98. :title "Microtables"}
  99. [:img {:src "logo.svg"}]]])
  100. (defn main-panel []
  101. (let [data (re-frame/subscribe [::subs/table-data])
  102. controls-state (re-frame/subscribe [::subs/controls-state])]
  103. [:div
  104. [sheet @data]
  105. [control-panel @controls-state]]))