mirror of https://github.com/logseq/logseq
refactor(ui): use pagination component for All pages
parent
8b8fe908c0
commit
f5789bd4f9
|
@ -818,6 +818,36 @@
|
|||
(notification/show! (str (t :tips/all-done) "!") :success)
|
||||
(js/setTimeout #(refresh-fn) 200)))]]))
|
||||
|
||||
(rum/defc pagination
|
||||
"Pagination component, like `<< <Prev 1/10 Next> >>`.
|
||||
|
||||
- current: current page number
|
||||
- total: total number of items
|
||||
- per-page: number of items per page
|
||||
- on-change: callback function when page number changes"
|
||||
[& {:keys [current total per-page on-change]
|
||||
:or {current 1 per-page 40}}]
|
||||
(let [total-pages (int (Math/ceil (/ total per-page)))
|
||||
has-prev? (> current 1)
|
||||
has-next? (< current total-pages)
|
||||
prev-page (if (= 1 current) 1 (dec current))
|
||||
next-page (if (= total-pages current) total-pages (inc current))]
|
||||
[:div.flex.items-center.noselect
|
||||
(when has-prev?
|
||||
[[:a.fade-link.flex
|
||||
{:on-click #(on-change 1)}
|
||||
(ui/icon "chevrons-left")]
|
||||
[:a.fade-link.flex.items-center {:on-click #(on-change prev-page)}
|
||||
(ui/icon "caret-left") (t :paginates/prev)]])
|
||||
[:div.px-2
|
||||
[:span (str current "/" total-pages)]]
|
||||
(when has-next?
|
||||
[[:a.fade-link.flex.items-center {:on-click #(on-change next-page)}
|
||||
(t :paginates/next) (ui/icon "caret-right")]
|
||||
[:a.fade-link.flex
|
||||
{:on-click #(on-change total-pages)}
|
||||
(ui/icon "chevrons-right")]])]))
|
||||
|
||||
(rum/defcs ^:large-vars/cleanup-todo all-pages < rum/reactive
|
||||
(rum/local nil ::pages)
|
||||
(rum/local nil ::search-key)
|
||||
|
@ -847,15 +877,17 @@
|
|||
*search-input (rum/create-ref)
|
||||
|
||||
*indeterminate (rum/derived-atom
|
||||
[*checks] ::indeterminate
|
||||
(fn [checks]
|
||||
(when-let [checks (vals checks)]
|
||||
(if (every? true? checks)
|
||||
1 (if (some true? checks) -1 0)))))
|
||||
[*checks] ::indeterminate
|
||||
(fn [checks]
|
||||
(when-let [checks (vals checks)]
|
||||
(if (every? true? checks)
|
||||
1 (if (some true? checks) -1 0)))))
|
||||
|
||||
mobile? (util/mobile?)
|
||||
total-items (count @*results-all)
|
||||
;; FIXME: "pages" is ambiguous here, it can be either "Logseq pages" or "result pages"
|
||||
total-pages (if-not @*results-all 0
|
||||
(js/Math.ceil (/ (count @*results-all) per-page-num)))
|
||||
(js/Math.ceil (/ total-items per-page-num)))
|
||||
to-page (fn [page]
|
||||
(when (> total-pages 1)
|
||||
(if (and (> page 0)
|
||||
|
@ -878,7 +910,7 @@
|
|||
[:div.flex-1.cp__all_pages
|
||||
[:h1.title (t :all-pages)]
|
||||
|
||||
[:div.text-sm.ml-1.opacity-70.mb-4 (t :paginates/pages (count @*results-all))]
|
||||
[:div.text-sm.ml-1.opacity-70.mb-4 (t :paginates/pages total-items)]
|
||||
|
||||
(when current-repo
|
||||
|
||||
|
@ -918,168 +950,151 @@
|
|||
[idx (boolean (get @*checks idx))])))
|
||||
(reset! *results pages)))
|
||||
|
||||
(let [has-prev? (> @*current-page 1)
|
||||
has-next? (not= @*current-page total-pages)]
|
||||
[:div
|
||||
[:div.actions
|
||||
{:class (util/classnames [{:has-selected (or (nil? @*indeterminate)
|
||||
(not= 0 @*indeterminate))}])}
|
||||
[:div.l.flex.items-center
|
||||
[:div.actions-wrap
|
||||
(ui/button
|
||||
[(ui/icon "trash" {:style {:font-size 15}}) (t :delete)]
|
||||
:on-click (fn []
|
||||
(let [selected (filter (fn [[_ v]] v) @*checks)
|
||||
selected (and (seq selected)
|
||||
(into #{} (for [[k _] selected] k)))]
|
||||
(when-let [pages (and selected (filter #(contains? selected (:block/idx %)) @*results))]
|
||||
(state/set-modal! (batch-delete-dialog pages false #(do
|
||||
(reset! *checks nil)
|
||||
(refresh-pages)))))))
|
||||
:class "fade-link"
|
||||
:small? true)]
|
||||
[:div
|
||||
[:div.actions
|
||||
{:class (util/classnames [{:has-selected (or (nil? @*indeterminate)
|
||||
(not= 0 @*indeterminate))}])}
|
||||
[:div.l.flex.items-center
|
||||
[:div.actions-wrap
|
||||
(ui/button
|
||||
[(ui/icon "trash" {:style {:font-size 15}}) (t :delete)]
|
||||
:on-click (fn []
|
||||
(let [selected (filter (fn [[_ v]] v) @*checks)
|
||||
selected (and (seq selected)
|
||||
(into #{} (for [[k _] selected] k)))]
|
||||
(when-let [pages (and selected (filter #(contains? selected (:block/idx %)) @*results))]
|
||||
(state/set-modal! (batch-delete-dialog pages false #(do
|
||||
(reset! *checks nil)
|
||||
(refresh-pages)))))))
|
||||
:class "fade-link"
|
||||
:small? true)]
|
||||
|
||||
[:div.search-wrap.flex.items-center.pl-2
|
||||
(let [search-fn (fn []
|
||||
(let [^js input (rum/deref *search-input)]
|
||||
(search-key (.-value input))
|
||||
(reset! *current-page 1)))
|
||||
reset-fn (fn []
|
||||
[:div.search-wrap.flex.items-center.pl-2
|
||||
(let [search-fn (fn []
|
||||
(let [^js input (rum/deref *search-input)]
|
||||
(set! (.-value input) "")
|
||||
(reset! *search-key nil)))]
|
||||
(search-key (.-value input))
|
||||
(reset! *current-page 1)))
|
||||
reset-fn (fn []
|
||||
(let [^js input (rum/deref *search-input)]
|
||||
(set! (.-value input) "")
|
||||
(reset! *search-key nil)))]
|
||||
|
||||
[(ui/button (ui/icon "search")
|
||||
:on-click search-fn
|
||||
:small? true)
|
||||
[:input.form-input {:placeholder (t :search/page-names)
|
||||
:on-key-up (fn [^js e]
|
||||
(let [^js target (.-target e)]
|
||||
(if (string/blank? (.-value target))
|
||||
(reset! *search-key nil)
|
||||
(cond
|
||||
(= 13 (.-keyCode e)) (search-fn)
|
||||
(= 27 (.-keyCode e)) (reset-fn)))))
|
||||
:ref *search-input
|
||||
:default-value ""}]
|
||||
[(ui/button (ui/icon "search")
|
||||
:on-click search-fn
|
||||
:small? true)
|
||||
[:input.form-input {:placeholder (t :search/page-names)
|
||||
:on-key-up (fn [^js e]
|
||||
(let [^js target (.-target e)]
|
||||
(if (string/blank? (.-value target))
|
||||
(reset! *search-key nil)
|
||||
(cond
|
||||
(= 13 (.-keyCode e)) (search-fn)
|
||||
(= 27 (.-keyCode e)) (reset-fn)))))
|
||||
:ref *search-input
|
||||
:default-value ""}]
|
||||
|
||||
(when (not (string/blank? @*search-key))
|
||||
[:a.cancel {:on-click reset-fn}
|
||||
(ui/icon "x")])])]]
|
||||
(when (not (string/blank? @*search-key))
|
||||
[:a.cancel {:on-click reset-fn}
|
||||
(ui/icon "x")])])]]
|
||||
|
||||
[:div.r.flex.items-center.justify-between
|
||||
[:div
|
||||
(ui/tippy
|
||||
{:html [:small (str (t :page/show-whiteboards) " ?")]
|
||||
:arrow true}
|
||||
[:a.button.whiteboard
|
||||
{:class (util/classnames [{:active (boolean @*whiteboard?)}])
|
||||
:on-click #(reset! *whiteboard? (not @*whiteboard?))}
|
||||
(ui/icon "whiteboard" {:extension? true :style {:fontSize ui/icon-size}})])]
|
||||
[:div
|
||||
(ui/tippy
|
||||
{:html [:small (str (t :page/show-journals) " ?")]
|
||||
:arrow true}
|
||||
[:a.button.journal
|
||||
{:class (util/classnames [{:active (boolean @*journal?)}])
|
||||
:on-click #(reset! *journal? (not @*journal?))}
|
||||
(ui/icon "calendar" {:size ui/icon-size})])]
|
||||
[:div.r.flex.items-center.justify-between
|
||||
[:div
|
||||
(ui/tippy
|
||||
{:html [:small (str (t :page/show-whiteboards) " ?")]
|
||||
:arrow true}
|
||||
[:a.button.whiteboard
|
||||
{:class (util/classnames [{:active (boolean @*whiteboard?)}])
|
||||
:on-click #(reset! *whiteboard? (not @*whiteboard?))}
|
||||
(ui/icon "whiteboard" {:extension? true :style {:fontSize ui/icon-size}})])]
|
||||
[:div
|
||||
(ui/tippy
|
||||
{:html [:small (str (t :page/show-journals) " ?")]
|
||||
:arrow true}
|
||||
[:a.button.journal
|
||||
{:class (util/classnames [{:active (boolean @*journal?)}])
|
||||
:on-click #(reset! *journal? (not @*journal?))}
|
||||
(ui/icon "calendar" {:size ui/icon-size})])]
|
||||
|
||||
[:div.paginates
|
||||
[:span.flex.items-center
|
||||
{:class (util/classnames [{:is-first (= 1 @*current-page)
|
||||
:is-last (= @*current-page total-pages)}])}
|
||||
(when has-prev?
|
||||
[:a.py-4.pr-2.fade-link.flex.items-center
|
||||
{:on-click #(to-page (dec @*current-page))}
|
||||
(ui/icon "caret-left") (str " " (t :paginates/prev))])
|
||||
[:span.opacity-60 (str @*current-page "/" total-pages)]
|
||||
(when has-next?
|
||||
[:a.py-4.pl-2.fade-link.flex.items-center
|
||||
{:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ")
|
||||
(ui/icon "caret-right")])]]
|
||||
[:div.paginates
|
||||
(pagination :current @*current-page
|
||||
:total total-items
|
||||
:per-page per-page-num
|
||||
:on-change #(to-page %))]
|
||||
|
||||
(ui/dropdown-with-links
|
||||
(fn [{:keys [toggle-fn]}]
|
||||
[:a.button.fade-link
|
||||
{:on-click toggle-fn}
|
||||
(ui/icon "dots" {:size ui/icon-size})])
|
||||
[{:title (t :remove-orphaned-pages)
|
||||
:options {:on-click (fn []
|
||||
(let [orphaned-pages (model/get-orphaned-pages {})
|
||||
orphaned-pages? (seq orphaned-pages)]
|
||||
(if orphaned-pages?
|
||||
(state/set-modal!
|
||||
(batch-delete-dialog
|
||||
orphaned-pages true
|
||||
#(do
|
||||
(reset! *checks nil)
|
||||
(refresh-pages))))
|
||||
(notification/show! "Congratulations, no orphaned pages in your graph!" :success))))}
|
||||
:icon (ui/icon "file-x")}
|
||||
{:title (t :all-files)
|
||||
:options {:href (rfe/href :all-files)}
|
||||
:icon (ui/icon "files")}]
|
||||
{})]]
|
||||
(ui/dropdown-with-links
|
||||
(fn [{:keys [toggle-fn]}]
|
||||
[:a.button.fade-link
|
||||
{:on-click toggle-fn}
|
||||
(ui/icon "dots" {:size ui/icon-size})])
|
||||
[{:title (t :remove-orphaned-pages)
|
||||
:options {:on-click (fn []
|
||||
(let [orphaned-pages (model/get-orphaned-pages {})
|
||||
orphaned-pages? (seq orphaned-pages)]
|
||||
(if orphaned-pages?
|
||||
(state/set-modal!
|
||||
(batch-delete-dialog
|
||||
orphaned-pages true
|
||||
#(do
|
||||
(reset! *checks nil)
|
||||
(refresh-pages))))
|
||||
(notification/show! "Congratulations, no orphaned pages in your graph!" :success))))}
|
||||
:icon (ui/icon "file-x")}
|
||||
{:title (t :all-files)
|
||||
:options {:href (rfe/href :all-files)}
|
||||
:icon (ui/icon "files")}]
|
||||
{})]]
|
||||
|
||||
[:table.table-auto.cp__all_pages_table
|
||||
[:thead
|
||||
[:tr
|
||||
[:th.selector
|
||||
(checkbox-opt "all-pages-select-all"
|
||||
(= 1 @*indeterminate)
|
||||
{:on-change (fn []
|
||||
(let [indeterminate? (= -1 @*indeterminate)
|
||||
all? (= 1 @*indeterminate)]
|
||||
(doseq [{:block/keys [idx]} @*results]
|
||||
(swap! *checks assoc idx (or indeterminate? (not all?))))))
|
||||
:indeterminate (= -1 @*indeterminate)})]
|
||||
[:table.table-auto.cp__all_pages_table
|
||||
[:thead
|
||||
[:tr
|
||||
[:th.selector
|
||||
(checkbox-opt "all-pages-select-all"
|
||||
(= 1 @*indeterminate)
|
||||
{:on-change (fn []
|
||||
(let [indeterminate? (= -1 @*indeterminate)
|
||||
all? (= 1 @*indeterminate)]
|
||||
(doseq [{:block/keys [idx]} @*results]
|
||||
(swap! *checks assoc idx (or indeterminate? (not all?))))))
|
||||
:indeterminate (= -1 @*indeterminate)})]
|
||||
|
||||
(sortable-title (t :block/name) :block/name *sort-by-item *desc?)
|
||||
(when-not mobile?
|
||||
[(sortable-title (t :page/backlinks) :block/backlinks *sort-by-item *desc?)
|
||||
(sortable-title (t :page/created-at) :block/created-at *sort-by-item *desc?)
|
||||
(sortable-title (t :page/updated-at) :block/updated-at *sort-by-item *desc?)])]]
|
||||
(sortable-title (t :block/name) :block/name *sort-by-item *desc?)
|
||||
(when-not mobile?
|
||||
[(sortable-title (t :page/backlinks) :block/backlinks *sort-by-item *desc?)
|
||||
(sortable-title (t :page/created-at) :block/created-at *sort-by-item *desc?)
|
||||
(sortable-title (t :page/updated-at) :block/updated-at *sort-by-item *desc?)])]]
|
||||
|
||||
[:tbody
|
||||
(for [{:block/keys [idx name created-at updated-at backlinks] :as page} @*results]
|
||||
(when-not (string/blank? name)
|
||||
[:tr {:key name}
|
||||
[:td.selector
|
||||
(checkbox-opt (str "label-" idx)
|
||||
(get @*checks idx)
|
||||
{:on-change (fn []
|
||||
(swap! *checks update idx not))})]
|
||||
[:tbody
|
||||
(for [{:block/keys [idx name created-at updated-at backlinks] :as page} @*results]
|
||||
(when-not (string/blank? name)
|
||||
[:tr {:key name}
|
||||
[:td.selector
|
||||
(checkbox-opt (str "label-" idx)
|
||||
(get @*checks idx)
|
||||
{:on-change (fn []
|
||||
(swap! *checks update idx not))})]
|
||||
|
||||
[:td.name [:a {:on-click (fn [e]
|
||||
[:td.name [:a {:on-click (fn [e]
|
||||
(.preventDefault e)
|
||||
(let [repo (state/get-current-repo)]
|
||||
(when (gobj/get e "shiftKey")
|
||||
(state/sidebar-add-block!
|
||||
repo
|
||||
(:db/id page)
|
||||
:page))))
|
||||
:href (rfe/href :page {:name (:block/name page)})}
|
||||
(component-block/page-cp {} page)]]
|
||||
(let [repo (state/get-current-repo)]
|
||||
(when (gobj/get e "shiftKey")
|
||||
(state/sidebar-add-block!
|
||||
repo
|
||||
(:db/id page)
|
||||
:page))))
|
||||
:href (rfe/href :page {:name (:block/name page)})}
|
||||
(component-block/page-cp {} page)]]
|
||||
|
||||
(when-not mobile?
|
||||
[:td.backlinks [:span backlinks]])
|
||||
|
||||
(when-not mobile?
|
||||
(when-not mobile?
|
||||
[[:td.backlinks [:span backlinks]]
|
||||
[:td.created-at [:span (if created-at
|
||||
(date/int->local-time-2 created-at)
|
||||
"Unknown")]])
|
||||
(when-not mobile?
|
||||
"Unknown")]]
|
||||
[:td.updated-at [:span (if updated-at
|
||||
(date/int->local-time-2 updated-at)
|
||||
"Unknown")]])]))]]
|
||||
"Unknown")]]])]))]]
|
||||
|
||||
[:div.paginates
|
||||
[:span]
|
||||
[:span.flex.items-center
|
||||
(when has-prev?
|
||||
[:a.py-4.text-sm.fade-link.flex.items-center {:on-click #(to-page (dec @*current-page))}
|
||||
(ui/icon "caret-left") (str " " (t :paginates/prev))])
|
||||
(when has-next?
|
||||
[:a.py-4.pl-2.text-sm.fade-link.flex.items-center {:on-click #(to-page (inc @*current-page))} (str (t :paginates/next) " ")
|
||||
(ui/icon "caret-right")])]]]))]))
|
||||
[:div.flex.justify-end.py-4
|
||||
(pagination :current @*current-page
|
||||
:total total-items
|
||||
:per-page per-page-num
|
||||
:on-change #(to-page %))]])]))
|
||||
|
|
|
@ -195,27 +195,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.paginates {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 4px;
|
||||
|
||||
> span {
|
||||
color: var(--ls-primary-text-color);
|
||||
|
||||
&:last-child {
|
||||
a {
|
||||
user-select: none;
|
||||
|
||||
&:active {
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cp__vertical-menu-button {
|
||||
|
|
Loading…
Reference in New Issue