views.cljs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. :value (if (= (get datum :view nil) :value)
  13. (get datum :value "")
  14. (get datum :error (get datum :display (get datum :value ""))));TODO: add "highlight" display mode (possibly just a css class)
  15. :on-change #(re-frame/dispatch [::events/edit-cell-value c r (.. % -target -value)])
  16. :on-focus #(re-frame/dispatch [::events/movement-enter-cell c r])
  17. :on-blur #(re-frame/dispatch [::events/movement-leave-cell c r])
  18. :on-keyPress #(when (= (.. % -which) 13)
  19. (re-frame/dispatch [::events/press-enter-in-cell c r]))}]]))
  20. (defn row [r cols data]
  21. ^{:key (str "row-" r)} [:tr
  22. (cons
  23. ^{:key (str "row-head-" r)} [:th (str r)]
  24. (map #(cell % r data) cols))])
  25. (defn header-row [cols]
  26. ^{:key "header"} [:tr
  27. (cons
  28. ^{:key "corner"} [:th]
  29. (map (fn [c] ^{:key (str "col-head-" c)} [:th c]) cols))])
  30. (defn sheet [data]
  31. [:table
  32. {:id "main-table"}
  33. [:tbody
  34. ;TODO: figure out appropriate starting values for maxrow and maxcol (maybe keep them intentionally small)
  35. ;TODO: figure out movement (maybe allow scroll overflow)
  36. (let [maxrow 50;(utils/highest-row data)
  37. maxcol "L";(utils/highest-col data)
  38. cols (take-while (partial not= (utils/next-letter maxcol)) utils/col-letters)]
  39. (cons
  40. (header-row cols)
  41. (map #(row % cols data) (range 1 (inc maxrow)))))]])
  42. (defn controls []
  43. [:div
  44. [:button "one"]
  45. ;extend range (number field, then shrink/left/up and expand/right/down buttons on either side)
  46. ;fill range (single tap, single column/row fill? number field and button?)
  47. ;move range (designate new "top-left corner" cell for range, figure out overwriting destination cells)
  48. ;empty range (delete contents, re-evaluate)
  49. ;delete range (figure out how to move cells over)
  50. ;copy range (figure out clipboard)
  51. [:button "two"]])
  52. (defn controls-group [state]
  53. [:div
  54. {:id "controls"}
  55. [:div
  56. ;TODO: link left controls with position of the whole table
  57. {:id "controls-left"
  58. :class (if (= state :left) "open" "")}
  59. [controls]]
  60. [:div
  61. {:id "controls-bottom"
  62. :class (if (= state :bottom) "open" "")}
  63. [controls]]
  64. ;←↑→↓
  65. [:button
  66. {:id "left-controls-button"
  67. :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :left) nil :left)])}
  68. (if (= state :left) "←" "→")]
  69. [:button
  70. {:id "bottom-controls-button"
  71. :on-click #(re-frame/dispatch [::events/set-controls-state (if (= state :bottom) nil :bottom)])}
  72. (if (= state :bottom) "↓" "↑")]
  73. [:div
  74. {:id "main-logo"
  75. :title "Microtables"}
  76. [:img {:src "logo.svg"}]]])
  77. (defn main-panel []
  78. (let [data (re-frame/subscribe [::subs/table-data])
  79. controls-state (re-frame/subscribe [::subs/controls-state])]
  80. [:div
  81. [sheet @data]
  82. [controls-group @controls-state]]))