From c609d2dec6174c8704d59be39b577959663fcad5 Mon Sep 17 00:00:00 2001
From: "alonso.torres" <alonso.torres@kaleidos.net>
Date: Tue, 5 Dec 2023 16:42:48 +0100
Subject: [PATCH] :sparkles: Select on track row/column selects cells

---
 common/src/app/common/types/shape/layout.cljc | 18 +++++++---
 .../data/workspace/grid_layout/editor.cljs    | 16 +++++++++
 .../options/menus/layout_container.cljs       | 35 ++++++++++++++-----
 .../options/menus/layout_container.scss       |  5 ++-
 4 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc
index 2259a12e6..5427519bc 100644
--- a/common/src/app/common/types/shape/layout.cljc
+++ b/common/src/app/common/types/shape/layout.cljc
@@ -1146,22 +1146,30 @@
 
     (assoc parent :shapes (into [] (reverse new-shapes)))))
 
-(defn shapes-by-row
+(defn cells-by-row
   [parent index]
   (->> (:layout-grid-cells parent)
        (filter (fn [[_ {:keys [row row-span]}]]
                  (and (>= (inc index) row)
                       (< (inc index) (+ row row-span)))))
-       (map second)
-       (mapcat :shapes)))
+       (map second)))
 
-(defn shapes-by-column
+(defn cells-by-column
   [parent index]
   (->> (:layout-grid-cells parent)
        (filter (fn [[_ {:keys [column column-span]}]]
                  (and (>= (inc index) column)
                       (< (inc index) (+ column column-span)))))
-       (map second)
+       (map second)))
+
+(defn shapes-by-row
+  [parent index]
+  (->> (cells-by-row parent index)
+       (mapcat :shapes)))
+
+(defn shapes-by-column
+  [parent index]
+  (->> (cells-by-column parent index)
        (mapcat :shapes)))
 
 (defn cells-coordinates
diff --git a/frontend/src/app/main/data/workspace/grid_layout/editor.cljs b/frontend/src/app/main/data/workspace/grid_layout/editor.cljs
index 82621a7c4..5512447b5 100644
--- a/frontend/src/app/main/data/workspace/grid_layout/editor.cljs
+++ b/frontend/src/app/main/data/workspace/grid_layout/editor.cljs
@@ -7,6 +7,7 @@
 (ns app.main.data.workspace.grid-layout.editor
   (:require
    [app.common.geom.rect :as grc]
+   [app.common.types.shape.layout :as ctl]
    [app.main.data.workspace.state-helpers :as wsh]
    [potok.core :as ptk]))
 
@@ -84,3 +85,18 @@
                         (-> local
                             (update :vbox merge (select-keys srect [:x :y :x1 :x2 :y1 :y2])))))))))))
 
+(defn select-track-cells
+  [grid-id type index]
+  (ptk/reify ::select-track-cells
+    ptk/UpdateEvent
+    (update [_ state]
+      (let [objects (wsh/lookup-page-objects state)
+            parent  (get objects grid-id)
+
+            cells
+            (if (= type :column)
+              (ctl/cells-by-column parent index)
+              (ctl/cells-by-row parent index))
+
+            selected (into #{} (map :id) cells)]
+        (assoc-in state [:workspace-grid-edition grid-id :selected] selected)))))
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
index c0adcfe32..4c080c873 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.cljs
@@ -957,7 +957,7 @@
     value))
 
 (mf/defc grid-track-info
-  [{:keys [is-col? type index column set-column-value set-column-type remove-element reorder-track hover-track]}]
+  [{:keys [is-col? type index column set-column-value set-column-type remove-element reorder-track hover-track on-select-track]}]
   (let [new-css-system (mf/use-ctx ctx/new-css-system)
 
         drop-track
@@ -978,6 +978,13 @@
          (fn []
            (hover-track type index false)))
 
+        handle-select-track
+        (mf/use-fn
+         (mf/deps on-select-track type index)
+         (fn []
+           (when on-select-track
+             (on-select-track type index))))
+
         [dprops dref]
         (h/use-sortable
          :data-type "penpot/grid-track"
@@ -998,7 +1005,8 @@
              :on-pointer-leave pointer-leave}
 
        [:div {:class (stl/css :track-info-container)}
-        [:div {:class (stl/css :track-info-dir-icon)}
+        [:div {:class (stl/css :track-info-dir-icon)
+               :on-click handle-select-track}
          (if is-col? i/flex-vertical-refactor i/flex-horizontal-refactor)]
 
         [:div {:class (stl/css :track-info-value)}
@@ -1057,7 +1065,8 @@
         i/minus]])))
 
 (mf/defc grid-columns-row
-  [{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element reorder-track hover-track] :as props}]
+  [{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type
+           remove-element reorder-track hover-track on-select-track] :as props}]
   (let [new-css-system (mf/use-ctx ctx/new-css-system)
 
         column-num (count column-values)
@@ -1098,7 +1107,8 @@
                                   :set-column-type set-column-type
                                   :remove-element remove-element
                                   :reorder-track reorder-track
-                                  :hover-track hover-track}])]])]
+                                  :hover-track hover-track
+                                  :on-select-track on-select-track}])]])]
 
       [:div.grid-columns
        [:div.grid-columns-header
@@ -1119,7 +1129,8 @@
                                   :set-column-type set-column-type
                                   :remove-element remove-element
                                   :reorder-track reorder-track
-                                  :hover-track hover-track}])]])])))
+                                  :hover-track hover-track
+                                  :on-select-track on-select-track}])]])])))
 
 ;; LAYOUT COMPONENT
 
@@ -1695,6 +1706,12 @@
          (fn [type index hover?]
            (st/emit! (dwsl/hover-layout-track ids type index hover?))))
 
+        handle-select-track
+        (mf/use-fn
+         (mf/deps ids)
+         (fn [type index]
+           (st/emit! (dwge/select-track-cells (first ids) type index))))
+
         set-column-value
         (mf/use-fn
          (mf/deps ids)
@@ -1720,7 +1737,7 @@
         handle-locate-grid
         (mf/use-callback
          (fn []
-           (st/emit! (dwge/locate-board (first ids)))))        ]
+           (st/emit! (dwge/locate-board (first ids)))))]
 
     (if new-css-system
       [:div {:class (stl/css :grid-layout-menu)}
@@ -1767,7 +1784,8 @@
                               :set-column-type set-column-type
                               :remove-element remove-element
                               :reorder-track reorder-track
-                              :hover-track hover-track}]
+                              :hover-track hover-track
+                              :on-select-track handle-select-track}]
 
         [:& grid-columns-row {:is-col? false
                               :expanded? @grid-rows-open?
@@ -1778,7 +1796,8 @@
                               :set-column-type set-column-type
                               :remove-element remove-element
                               :reorder-track reorder-track
-                              :hover-track hover-track}]]
+                              :hover-track hover-track
+                              :on-select-track handle-select-track}]]
        [:div {:class (stl/css :row)}
         [:& gap-section {:gap-selected? gap-selected?
                          :on-change set-gap
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
index 94a8f9790..97fe318b2 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/layout_container.scss
@@ -222,15 +222,18 @@
   }
 
   .track-info-dir-icon {
+    cursor: pointer;
     border-radius: $br-8 0 0 $br-8;
     background-color: var(--input-background-color);
     padding: 0 $s-8;
-
     svg {
       @extend .button-icon;
       stroke: var(--icon-foreground);
       height: 100%;
     }
+    &:hover svg {
+      stroke: var(--icon-foreground-hover);
+    }
   }
 
   .track-info-value {