0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 18:48:37 -05:00

Page ordering

This commit is contained in:
Jesús Espino 2016-12-21 19:17:16 +01:00
parent 2e04fe60f4
commit 960f2e7e7a
6 changed files with 280 additions and 43 deletions

View file

@ -54,10 +54,8 @@
li {
align-items: center;
border-bottom: 1px solid $soft-ui-border;
display: flex;
flex-direction: row;
padding: $small;
width: 100%;
.page-icon {
@ -147,6 +145,143 @@
}
.element-list-body {
align-items: center;
border-bottom: 1px solid $soft-ui-border;
display: flex;
padding: $small;
transition: none;
width: 100%;
svg {
fill: $soft-ui-icons;
height: 13px;
margin-right: 8px;
width: 13px;
}
.element-actions {
align-items: center;
display: flex;
flex-shrink: 0;
width: 62px;
}
.element-icon {
svg {
fill: $medium-ui-icons;
}
}
.toggle-content {
margin-left: auto;
width: 12px;
svg {
fill: $intense-ui-icons;
transform: rotate(90deg);
width: 10px;
}
&.inverse {
svg { transform: rotate(270deg); }
}
&:hover {
svg {
fill: $medium-ui-icons;
}
}
}
&.group {
&.open {
.toggle-content {
flex-shrink: 0;
svg {
transform: rotate(270deg);
}
}
}
}
span.element-name {
min-width: 40px;
min-height: 16px;
display: block;
color: $medium-ui-text;
font-size: $fs13;
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.selected {
.element-icon {
svg {
fill: $main-ui-color;
}
}
span {
color: $main-ui-color;
}
}
.selected {
svg {
fill: $intense-ui-icons;
}
}
&:hover {
border-color: $main-ui-color;
.element-icon {
svg {
fill: $intense-ui-icons;
}
}
span {
color: $intense-ui-text;
}
}
&.drag-top {
border-top: 40px solid $color-gray-lighter !important;
}
&.drag-bottom {
border-bottom: 40px solid $color-gray-lighter !important;
}
&.drag-inside {
border: 2px solid $main-ui-color !important;
}
}
}
}

View file

@ -41,6 +41,7 @@
::grid-x-axis
::grid-color
::grid-alignment
::order
::background
::background-opacity
::layout]))
@ -156,7 +157,8 @@
:data {}
:metadata {:width width
:height height
:layout layout}}]
:layout layout
:order 0}}]
(->> (rp/req :create/page params)
(rx/map :payload)
(rx/map page-created)))))
@ -246,6 +248,22 @@
{:pre [(uuid? id)]}
(PersistMetadata. id))
(deftype PersistPages []
ptk/WatchEvent
(watch [_ state stream]
(letfn [(resolve-pages [state]
(let [project (get-in state [:workspace :project])]
(->> (vals (:pages state))
(filter #(= project (:project %)))
(sort-by #(get-in % [:metadata :order])))))]
(->> (rx/from-coll (resolve-pages state))
(rx/map :id)
(rx/map persist-metadata)))))
(defn persist-pages
[]
(PersistPages.))
;; --- Update Page Options
(deftype UpdateMetadata [id metadata]
@ -259,6 +277,34 @@
{:pre [(uuid? id) (us/valid? ::metadata metadata)]}
(UpdateMetadata. id metadata))
(deftype UpdateOrder [id order]
IMetadataUpdate
ptk/UpdateEvent
(update [this state]
(assoc-in state [:pages id :metadata :order] order)))
(defn update-order
[id order]
{:pre [(uuid? id)]}
(UpdateOrder. id order))
(deftype ReorderPages []
IMetadataUpdate
ptk/UpdateEvent
(update [this state]
(letfn [(resolve-pages []
(let [project (get-in state [:workspace :project])]
(->> (vals (:pages state))
(filter #(= project (:project %)))
(sort-by #(get-in % [:metadata :order])))))
(ordered-pages [[state idx] page]
[(assoc-in state [:pages (:id page) :metadata :order] (* 10 idx)) (inc idx)])]
(first (reduce ordered-pages [state, 1] (resolve-pages))))))
(defn reorder-pages
[]
(ReorderPages.))
;; --- Update Page
(deftype UpdatePage [id name width height layout]

View file

@ -86,21 +86,6 @@
:text i/text
:group i/folder))
(defn- get-hover-position
[event group?]
(let [target (.-currentTarget event)
brect (.getBoundingClientRect target)
width (.-offsetHeight target)
y (- (.-clientY event) (.-top brect))
part (/ (* 30 width) 100)]
(if group?
(cond
(> part y) :top
(< (- width part) y) :bottom
:else :middle)
(if (>= y (/ width 2))
:bottom
:top))))
;; --- Shape Name (Component)
@ -173,7 +158,7 @@
(on-drag-over [event]
(dom/prevent-default event)
(dnd/set-drop-effect! event "move")
(let [over (get-hover-position event false)]
(let [over (dnd/get-hover-position event false)]
(swap! local assoc :over over)))
(on-drag-enter [event]
(swap! local assoc :over true))
@ -254,7 +239,7 @@
(on-drag-over [event]
(dom/prevent-default event)
(dnd/set-drop-effect! event "move")
(let [over (get-hover-position event true)]
(let [over (dnd/get-hover-position event true)]
(swap! local assoc :over over)))
(on-drag-enter [event]
(swap! local assoc :over true))

View file

@ -10,6 +10,7 @@
[cuerdas.core :as str]
[uxbox.util.i18n :refer (tr)]
[uxbox.util.router :as r]
[uxbox.util.data :refer (classnames)]
[potok.core :as ptk]
[uxbox.store :as st]
[uxbox.main.data.projects :as dp]
@ -21,6 +22,7 @@
[uxbox.main.ui.icons :as i]
[uxbox.util.mixins :as mx :include-macros true]
[uxbox.main.ui.lightbox :as lbx]
[uxbox.util.dom.dnd :as dnd]
[uxbox.util.dom :as dom]))
;; --- Refs
@ -30,7 +32,7 @@
(let [project (get-in state [:workspace :project])]
(->> (vals (:pages state))
(filter #(= project (:project %)))
(sort-by :created-at))))
(sort-by #(get-in % [:metadata :order])))))
(def pages-ref
(-> (l/lens resolve-pages)
@ -38,31 +40,84 @@
;; --- Component
(mx/defc page-item
(mx/defcs page-item
{:mixins [(mx/local) mx/static mx/reactive]}
[page total active?]
(letfn [(on-edit [event]
(udl/open! :page-form {:page page}))
[own page total active?]
(let [local (:rum/local own)
classes (classnames
:selected active?
:drag-active (:dragging @local)
:drag-top (= :top (:over @local))
:drag-bottom (= :bottom (:over @local))
:drag-inside (= :middle (:over @local)))]
(letfn [(on-edit [event]
(udl/open! :page-form {:page page}))
(on-navigate [event]
(st/emit! (dp/go-to (:project page) (:id page))))
(on-navigate [event]
(st/emit! (dp/go-to (:project page) (:id page))))
(delete []
(let [next #(st/emit! (dp/go-to (:project page)))]
(st/emit! (udp/delete-page (:id page) next))))
(delete []
(let [next #(st/emit! (dp/go-to (:project page)))]
(st/emit! (udp/delete-page (:id page) next))))
(on-delete [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(udl/open! :confirm {:on-accept delete}))]
[:li {:class (when active? "selected")
:on-click on-navigate}
[:div.page-icon i/page]
[:span (:name page)]
[:div.page-actions
[:a {:on-click on-edit} i/pencil]
(if (> total 1)
[:a {:on-click on-delete} i/trash])]]))
(on-delete [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(udl/open! :confirm {:on-accept delete}))
(on-drag-start [event]
(let [target (dom/event->target event)]
(dnd/set-allowed-effect! event "move")
(dnd/set-data! event (:id page))
(dnd/set-image! event target 50 10)
(swap! local assoc :dragging true)))
(on-drag-end [event]
(swap! local assoc :dragging false :over nil))
(on-drop [event]
(dom/stop-propagation event)
(let [id (dnd/get-data event)
over (:over @local)]
(case (:over @local)
:top (let [new-order (dec (get-in page [:metadata :order]))]
(st/emit! (udp/update-order id new-order))
(st/emit! (udp/reorder-pages))
(st/emit! (udp/persist-pages)))
:bottom (let [new-order (inc (get-in page [:metadata :order]))]
(st/emit! (udp/update-order id new-order))
(st/emit! (udp/reorder-pages))
(st/emit! (udp/persist-pages))))
(swap! local assoc :dragging false :over nil)))
(on-drag-over [event]
(dom/prevent-default event)
(dnd/set-drop-effect! event "move")
(let [over (dnd/get-hover-position event false)]
(swap! local assoc :over over)))
(on-drag-enter [event]
(swap! local assoc :over true))
(on-drag-leave [event]
(swap! local assoc :over false))]
[:li {:class (when active? "selected")}
[:div.element-list-body
{:class classes
:style {:opacity (if (:dragging @local)
"0.5"
"1")}
:on-click on-navigate
:on-double-click #(dom/stop-propagation %)
:on-drag-start on-drag-start
:on-drag-enter on-drag-enter
:on-drag-leave on-drag-leave
:on-drag-over on-drag-over
:on-drag-end on-drag-end
:on-drop on-drop
:draggable true}
[:div.page-icon i/page]
[:span (:name page)]
[:div.page-actions
[:a {:on-click on-edit} i/pencil]
(if (> total 1)
[:a {:on-click on-delete} i/trash])]]])))
(mx/defc sitemap-toolbox
{:mixins [mx/static mx/reactive]}

View file

@ -59,7 +59,7 @@
{:mixins [mx/static mx/reactive]}
[{:keys [metadata id] :as page}]
(let [data (merge +page-defaults+
(select-keys page [:name :id])
(select-keys page [:name :id :project])
(select-keys metadata [:width :height :layout])
(mx/react form-data))
valid? (forms/valid? data +page-form+)]

View file

@ -46,3 +46,19 @@
([e key]
(let [dt (.-dataTransfer e)]
(read-string (.getData dt (str key))))))
(defn get-hover-position
[event group?]
(let [target (.-currentTarget event)
brect (.getBoundingClientRect target)
width (.-offsetHeight target)
y (- (.-clientY event) (.-top brect))
part (/ (* 30 width) 100)]
(if group?
(cond
(> part y) :top
(< (- width part) y) :bottom
:else :middle)
(if (>= y (/ width 2))
:bottom
:top))))