Skip to content

Commit

Permalink
feat: query tables support both sort and custom properties
Browse files Browse the repository at this point in the history
  • Loading branch information
tiensonqin committed Jul 19, 2021
1 parent 5dcb128 commit fa17476
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 96 deletions.
32 changes: 21 additions & 11 deletions src/main/frontend/components/block.cljs
Expand Up @@ -2138,16 +2138,26 @@
(ui/foldable
[:div.custom-query-title
title
(when (and current-block (not page-list?))
(when current-block
[:div.flex.flex-row.align-items.mt-2 {:on-mouse-down (fn [e] (util/stop e))}
[:span.mr-2.ml-2.text-sm "Table view"]
[:div {:style {:margin-top 3}}
(ui/toggle table?
(fn []
(editor-handler/set-block-property! current-block-uuid
"query-table"
(not table?)))
true)]])]
(when-not page-list?
[:div.flex.flex-row
[:div.mx-2 [:span.text-sm "Table view"]]
[:div {:style {:margin-top 5}}
(ui/toggle table?
(fn []
(editor-handler/set-block-property! current-block-uuid
"query-table"
(not table?)))
true)]])

[:a.mx-2.opacity-60.hover:opacity-100.block
{:on-click (fn []
(let [all-keys (query-table/get-keys result page-list?)]
(state/pub-event! [:modal/set-query-properties current-block all-keys])))}
[:span.table-query-properties
[:span.text-sm.mr-1 "Set properties"]
svg/settings-sm]]])]
(cond
(and (seq result) view-f)
(let [result (try
Expand All @@ -2160,10 +2170,10 @@
(util/hiccup-keywordize result))

page-list?
(query-table/result-table config result {:page? true} map-inline page-cp ->elem inline-text)
(query-table/result-table config current-block result {:page? true} map-inline page-cp ->elem inline-text)

table?
(query-table/result-table config result {:page? false} map-inline page-cp ->elem inline-text)
(query-table/result-table config current-block result {:page? false} map-inline page-cp ->elem inline-text)

(and (seq result) (or only-blocks? blocks-grouped-by-page?))
(->hiccup result (cond-> (assoc config
Expand Down
4 changes: 4 additions & 0 deletions src/main/frontend/components/block.css
Expand Up @@ -427,3 +427,7 @@ a:hover > .bullet-container .bullet {
a.filter svg {
transform: scale(0.9);
}

.table-query-properties svg {
display: inline;
}
159 changes: 85 additions & 74 deletions src/main/frontend/components/query_table.cljs
Expand Up @@ -7,7 +7,8 @@
[frontend.date :as date]
[frontend.state :as state]
[clojure.string :as string]
[frontend.components.svg :as svg]))
[frontend.components.svg :as svg]
[frontend.handler.common :as common-handler]))

;; TODO: extract to table utils
(defn- sort-result-by
Expand All @@ -30,85 +31,95 @@
[: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 (concat keys [:created-at :updated-at])]
keys))

(rum/defcs result-table < rum/reactive
(rum/local :updated-at ::sort-by-item)
(rum/local true ::desc?)
(rum/local false ::select?)
[state config result {:keys [select-keys page?]} map-inline page-cp ->elem inline-text]
(let [select? (get state ::select?)
*sort-by-item (get state ::sort-by-item)
*desc? (get state ::desc?)
editor-box (get config :editor-box)
;; remove templates
result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
all-keys (->> (distinct (mapcat keys (map :block/properties result)))
(remove property/built-in-properties))
keys (if (seq select-keys) select-keys all-keys)
keys (if page? (cons :page keys) (cons :block keys))
keys (concat keys [:created-at :updated-at])
sort-by-fn (fn [item]
(let [key @*sort-by-item]
(case key
:created-at
(:block/created-at item)
:updated-at
(:block/updated-at item)
:block
(:block/content item)
:page
(:block/name item)
(get-in item [:block/properties key]))))
result (sort-result-by sort-by-fn @*desc? result)]
[:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
:style {:width "100%"}}
[:table.table-auto
(for [key keys]
(sortable-title (name key) key *sort-by-item *desc?))
(for [item result]
(let [format (:block/format item)
edit-input-id (str "edit-block-" (:id config) "-" (:block/uuid item))
heading-level (:block/heading-level item)]
[:tr.cursor
(for [key keys]
(let [value (case key
[state config current-block result {:keys [page?]} map-inline page-cp ->elem inline-text]
(when current-block
(let [select? (get state ::select?)
*sort-by-item (get state ::sort-by-item)
*desc? (get state ::desc?)
editor-box (get config :editor-box)
;; remove templates
result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)
query-properties (some-> (get-in current-block [:block/properties :query-properties] "")
(common-handler/safe-read-string "Parsing query properties failed"))
keys (if (seq query-properties)
query-properties
(get-keys result page?))
sort-by-fn (fn [item]
(let [key @*sort-by-item]
(case key
:created-at
(:block/created-at item)
:updated-at
(:block/updated-at item)
:block
(:block/content item)
:page
[:string (or (:block/original-name item)
(:block/name item))]
(:block/name item)
(get-in item [:block/properties key]))))
result (sort-result-by sort-by-fn @*desc? result)]
[:div.overflow-x-auto {:on-mouse-down (fn [e] (.stopPropagation e))
:style {:width "100%"}}
[:table.table-auto
(for [key keys]
(sortable-title (name key) key *sort-by-item *desc?))
(for [item result]
(let [format (:block/format item)
edit-input-id (str "edit-block-" (:id config) "-" (:block/uuid item))
heading-level (:block/heading-level item)]
[:tr.cursor
(for [key keys]
(let [value (case key
:page
[:string (or (:block/original-name item)
(:block/name item))]

:block ; block title
(let [title (:block/title item)]
(if (seq title)
[:element (->elem :div (map-inline config title))]
[:string (:block/content item)]))
:block ; block title
(let [title (:block/title item)]
(if (seq title)
[:element (->elem :div (map-inline config title))]
[:string (:block/content item)]))

:created-at
[:string (when-let [created-at (:block/created-at item)]
(date/int->local-time-2 created-at))]
:created-at
[:string (when-let [created-at (:block/created-at item)]
(date/int->local-time-2 created-at))]

:updated-at
[:string (when-let [updated-at (:block/updated-at item)]
(date/int->local-time-2 updated-at))]
:updated-at
[:string (when-let [updated-at (:block/updated-at item)]
(date/int->local-time-2 updated-at))]

[:string (get-in item [:block/properties key])])]
[:td.whitespace-nowrap {:on-mouse-down (fn [] (reset! select? false))
:on-mouse-move (fn [] (reset! select? true))
:on-mouse-up (fn []
(when-not @select?
(state/sidebar-add-block!
(state/get-current-repo)
(:db/id item)
:block-ref
{:block item})))}
(when value
(if (= :element (first value))
(second value)
(let [value (second value)]
(if (coll? value)
(let [vals (for [item value]
(page-cp {} {:block/name item}))]
(interpose [:span ", "] vals))
(if (not (string? value))
value
(if-let [page (db/entity [:block/name (string/lower-case value)])]
(page-cp {} page)
(inline-text format value)))))))]))]))]]))
[:string (get-in item [:block/properties key])])]
[:td.whitespace-nowrap {:on-mouse-down (fn [] (reset! select? false))
:on-mouse-move (fn [] (reset! select? true))
:on-mouse-up (fn []
(when-not @select?
(state/sidebar-add-block!
(state/get-current-repo)
(:db/id item)
:block-ref
{:block item})))}
(when value
(if (= :element (first value))
(second value)
(let [value (second value)]
(if (coll? value)
(let [vals (for [item value]
(page-cp {} {:block/name item}))]
(interpose [:span ", "] vals))
(if (not (string? value))
value
(if-let [page (db/entity [:block/name (string/lower-case value)])]
(page-cp {} page)
(inline-text format value)))))))]))]))]])))
16 changes: 16 additions & 0 deletions src/main/frontend/handler/editor.cljs
Expand Up @@ -923,6 +923,22 @@
(let [key (keyword key)]
(block-property-aux! block-id key value)))

(defn set-block-query-properties!
[block-id all-properties key add?]
(when-let [block (db/entity [:block/uuid block-id])]
(let [query-properties (-> (get-in block [:block/properties :query-properties] "")
(common-handler/safe-read-string "Failed to parse query properties"))
query-properties (if (seq query-properties)
query-properties
all-properties)
query-properties (if add?
(distinct (conj query-properties key))
(remove #{key} query-properties))
query-properties (vec query-properties)]
(if (seq query-properties)
(set-block-property! block-id :query-properties (str query-properties))
(remove-block-property! block-id :query-properties)))))

(defn set-block-timestamp!
[block-id key value]
(let [key (string/lower-case key)
Expand Down
61 changes: 52 additions & 9 deletions src/main/frontend/handler/events.cljs
Expand Up @@ -7,14 +7,18 @@
[frontend.util :as util :refer [profile]]
[frontend.config :as config]
[frontend.handler.notification :as notification]
[frontend.handler.common :as common-handler]
[frontend.handler.editor :as editor-handler]
[frontend.components.encryption :as encryption]
[frontend.fs.nfs :as nfs]
[frontend.db.conn :as conn]
[frontend.handler.migrate :as migrate]
[frontend.db-schema :as db-schema]
[frontend.db :as db]
[datascript.core :as d]
["semver" :as semver]))
["semver" :as semver]
[clojure.set :as set]
[rum.core :as rum]))

;; TODO: should we move all events here?

Expand All @@ -30,8 +34,8 @@
"Please make sure that you've installed the logseq app for the repo %s on GitHub. "
repo-url)
(ui/button
"Install Logseq on GitHub"
:href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]]
"Install Logseq on GitHub"
:href (str "https://github.com/apps/" config/github-app-name "/installations/new"))]]
:error
false))

Expand Down Expand Up @@ -86,17 +90,56 @@
"Grant native filesystem permission for directory: "
[:b (config/get-local-dir repo)]]
(ui/button
"Grant"
:class "ui__modal-enter"
:on-click (fn []
(nfs/check-directory-permission! repo)
(close-fn)))])))
"Grant"
:class "ui__modal-enter"
:on-click (fn []
(nfs/check-directory-permission! repo)
(close-fn)))])))

(defmethod handle :modal/nfs-ask-permission []
(when-let [repo (get-local-repo)]
(state/set-modal! (ask-permission repo))))


(defonce *query-properties (atom {}))
(rum/defc query-properties-settings-inner < rum/reactive
{:will-unmount (fn [state]
(reset! *query-properties {})
state)}
[block shown-properties all-properties close-fn]
(let [query-properties (rum/react *query-properties)]
[:div.p-4
[:div.font-bold "Properties settings for this query:"]
(for [property all-properties]
(let [property-value (get query-properties property)
shown? (if (nil? property-value)
(contains? shown-properties property)
property-value)]
[:div.flex.flex-row.m-2.justify-between.align-items
[:div (name property)]
[:div.mt-1 (ui/toggle shown?
(fn []
(let [value (not shown?)]
(swap! *query-properties assoc property value)
(editor-handler/set-block-query-properties!
(:block/uuid block)
all-properties
property
value)))
true)]]))]))

(defn query-properties-settings
[block shown-properties all-properties]
(fn [close-fn]
(query-properties-settings-inner block shown-properties all-properties close-fn)))

(defmethod handle :modal/set-query-properties [[_ block all-properties]]
(let [block-properties (some-> (get-in block [:block/properties :query-properties])
(common-handler/safe-read-string "Parsing query properties failed"))
shown-properties (if (seq block-properties)
(set block-properties)
(set all-properties))
shown-properties (set/intersection (set all-properties) shown-properties)]
(state/set-modal! (query-properties-settings block shown-properties all-properties))))

(defmethod handle :after-db-restore [[_ repos]]
(mapv (fn [{url :url} repo]
Expand Down
2 changes: 1 addition & 1 deletion src/main/frontend/ui.cljs
Expand Up @@ -446,7 +446,7 @@
"exiting" "ease-in duration-200 opacity-100 translate-y-0 sm:scale-100"
"exited" "ease-in duration-200 opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95")}
[:div.absolute.top-0.right-0.pt-2.pr-2
[:button.ui__modal-close
[:a.ui__modal-close.opacity-60.hover:opacity-100
{:aria-label "Close"
:type "button"
:on-click close-fn}
Expand Down
2 changes: 1 addition & 1 deletion src/main/frontend/util/property.cljs
Expand Up @@ -14,7 +14,7 @@

(def built-in-properties
(set/union
#{:id :custom-id :background-color :heading :collapsed :created-at :updated-at :last-modified-at :created_at :last_modified_at :query-table}
#{:id :custom-id :background-color :heading :collapsed :created-at :updated-at :last-modified-at :created_at :last_modified_at :query-table :query-properties}
(set (map keyword config/markers))))

(defn properties-built-in?
Expand Down

0 comments on commit fa17476

Please sign in to comment.