Bläddra i källkod

Disable sorting if query contains and there is no default sorting

- Also fixed caret not showing up when sorting occurs by default for
  a default sorting state coming from :query-sort-by and
  :query-sort-desc
- Also cleaned up sort state. Rum local state doesn't seem necessary
Gabriel Horner 3 år sedan
förälder
incheckning
60067cb817
2 ändrade filer med 69 tillägg och 43 borttagningar
  1. 65 43
      src/main/frontend/components/query_table.cljs
  2. 4 0
      src/main/frontend/db/query_dsl.cljs

+ 65 - 43
src/main/frontend/components/query_table.cljs

@@ -2,6 +2,7 @@
   (:require [frontend.components.svg :as svg]
             [frontend.date :as date]
             [frontend.db :as db]
+            [frontend.db.query-dsl :as query-dsl]
             [frontend.handler.common :as common-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.state :as state]
@@ -13,38 +14,9 @@
             [rum.core :as rum]
             [frontend.modules.outliner.tree :as tree]))
 
-;; TODO: extract to table utils
-(defn- sort-result-by
-  [by-item desc? result]
-  (let [comp (if desc? > <)]
-    (sort-by by-item comp result)))
-
-(rum/defc sortable-title
-  [title key by-item desc? block-id]
-  [:th.whitespace-nowrap
-   [:a {:on-click (fn []
-                    (reset! by-item key)
-                    (swap! desc? not)
-                    (when block-id
-                      (when key
-                        (editor-handler/set-block-property! block-id :query-sort-by (name key)))
-                      (editor-handler/set-block-property! block-id :query-sort-desc @desc?)))}
-    [:div.flex.items-center
-     [:span.mr-1 title]
-     (when (= @by-item key)
-       [:span
-        (if @desc? (svg/caret-down) (svg/caret-up))])]]])
-
-(defn get-keys
-  [result page?]
-  (let [keys (->> (distinct (mapcat keys (map :block/properties result)))
-                  (remove (property/built-in-properties))
-                  (remove #{:template}))
-        keys (if page? (cons :page keys) (cons :block keys))
-        keys (if page? (distinct (concat keys [:created-at :updated-at])) keys)]
-    keys))
-
-(defn attach-clock-property
+;; Util fns
+;; ================
+(defn- attach-clock-property
   [result]
   (let [ks [:block/properties :clock-time]
         result (map (fn [b]
@@ -77,6 +49,64 @@
     :else
     true))
 
+(defn- get-sort-state
+  "Return current sort direction and column (item) being sorted, respectively
+  :sort-desc? and :sort-by-item. :sort-by-item is nil if no sorting is to be
+  done"
+  [state current-block]
+  (let [*sort-by-item (get state ::sort-by-item)
+        *desc? (get state ::desc?)
+        p-desc? (get-in current-block [:block/properties :query-sort-desc])
+        desc? (desc? *desc? p-desc?)
+        p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
+        sort-by-item (or @*sort-by-item
+                         (some-> p-sort-by keyword)
+                         (if (query-dsl/query-contains-filter? (:block/content current-block) "sort-by")
+                           nil
+                           :updated-at))]
+    {:sort-desc? desc?
+     :sort-by-item sort-by-item}))
+
+(defn- sort-result [result {:keys [sort-by-item sort-desc?]}]
+  (if (some? sort-by-item)
+    (let [comp (if sort-desc? > <)]
+      (sort-by (fn [item]
+                 (block/normalize-block (sort-by-fn sort-by-item item)))
+               comp
+               result))
+    result))
+
+;; Components and public fns
+;; =========================
+(rum/defc sortable-title
+  [title key state {:keys [sort-by-item sort-desc?]} block-id]
+  (let [*sort-by-item (get state ::sort-by-item)
+        *desc? (get state ::desc?)]
+    [:th.whitespace-nowrap
+     [:a {:on-click (fn []
+                      ;; The two local state atom changes have no effect on
+                      ;; preserving state. Consider deleting?
+                      (reset! *sort-by-item key)
+                      (swap! *desc? not)
+                      (editor-handler/set-block-property! block-id :query-sort-by (name key))
+                      (editor-handler/set-block-property! block-id :query-sort-desc (not sort-desc?)))}
+     [:div.flex.items-center
+      [:span.mr-1 title]
+      (when (= sort-by-item key)
+        [:span
+         (if sort-desc? (svg/caret-down) (svg/caret-up))])]]]))
+
+(defn get-keys
+  [result page?]
+  (let [keys (->> (distinct (mapcat keys (map :block/properties result)))
+                  (remove (property/built-in-properties))
+                  (remove #{:template}))
+        keys (if page? (cons :page keys) (cons :block keys))
+        keys (if page? (distinct (concat keys [:created-at :updated-at])) keys)]
+    keys))
+
+;; We refer to rows and columns in a table as keys and items.
+;; TODO: Rename key(s) naming as it conflict with core fns
 (rum/defcs result-table < rum/reactive
   (rum/local nil ::sort-by-item)
   (rum/local nil ::desc?)
@@ -84,12 +114,8 @@
   [state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
   (when current-block
     (let [result (tree/filter-top-level-blocks result)
-          p-sort-by (keyword (get-in current-block [:block/properties :query-sort-by]))
-          p-desc? (get-in current-block [:block/properties :query-sort-desc])
           select? (get state ::select?)
-          *sort-by-item (get state ::sort-by-item)
-          *desc? (get state ::desc?)
-          sort-by-item (or @*sort-by-item (some-> p-sort-by keyword) :updated-at)
+          sort-state (get-sort-state state current-block)
           ;; remove templates
           result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
           result (if page? result (attach-clock-property result))
@@ -108,11 +134,7 @@
                           (filter included-keys keys)
                           included-keys)
                   keys))
-          desc? (desc? *desc? p-desc?)
-          result (sort-result-by (fn [item]
-                                   (block/normalize-block (sort-by-fn sort-by-item item)))
-                                 desc?
-                                 result)]
+          result (sort-result result sort-state)]
       [:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
                              :style {:width "100%"}
                              :class (when-not page? "query-table")}
@@ -124,7 +146,7 @@
                              (util/format "clock-time(total: %s)" (clock/minutes->days:hours:minutes
                                                                    clock-time-total))
                              (name key))]
-              (sortable-title key-name key *sort-by-item *desc? (:block/uuid current-block))))]]
+              (sortable-title key-name key state sort-state (:block/uuid current-block))))]]
         [:tbody
          (for [item result]
            (let [format (:block/format item)]

+ 4 - 0
src/main/frontend/db/query_dsl.cljs

@@ -577,6 +577,10 @@ Some bindings in this fn:
                             (when sort-by
                               {:transform-fn sort-by})))))))
 
+(defn query-contains-filter?
+  [query filter-name]
+  (string/includes? query (str "(" filter-name)))
+
 (comment
   ;; {{query (and (page-property foo bar) [[hello]])}}