mirror of
https://github.com/penpot/penpot.git
synced 2025-03-19 11:11:21 -05:00
🎉 Component swap
This commit is contained in:
parent
917e6425d1
commit
fac72a5874
26 changed files with 837 additions and 348 deletions
|
@ -463,20 +463,22 @@
|
|||
(d/update-in-when data [:components component-id :objects] reg-objects))))
|
||||
|
||||
(defmethod process-change :mov-objects
|
||||
[data {:keys [parent-id shapes index page-id component-id ignore-touched after-shape]}]
|
||||
[data {:keys [parent-id shapes index page-id component-id ignore-touched after-shape component-swap]}]
|
||||
(letfn [(calculate-invalid-targets [objects shape-id]
|
||||
(let [reduce-fn #(into %1 (calculate-invalid-targets objects %2))]
|
||||
(->> (get-in objects [shape-id :shapes])
|
||||
(reduce reduce-fn #{shape-id}))))
|
||||
|
||||
;; Avoid placing a shape as a direct or indirect child of itself,
|
||||
;; or inside its main component if it's in a copy.
|
||||
;; or inside its main component if it's in a copy,
|
||||
;; or inside a copy
|
||||
(is-valid-move? [objects shape-id]
|
||||
(let [invalid-targets (calculate-invalid-targets objects shape-id)]
|
||||
(and (contains? objects shape-id)
|
||||
(not (invalid-targets parent-id))
|
||||
(not (cph/components-nesting-loop? objects shape-id parent-id))
|
||||
#_(cph/valid-frame-target? objects parent-id shape-id))))
|
||||
(or component-swap
|
||||
(not (ctk/in-component-copy? (get objects parent-id))))))) ;; We don't want to change the structure of component copies
|
||||
|
||||
(insert-items [prev-shapes index shapes]
|
||||
(let [prev-shapes (or prev-shapes [])]
|
||||
|
|
|
@ -308,9 +308,12 @@
|
|||
|
||||
(defn change-parent
|
||||
([changes parent-id shapes]
|
||||
(change-parent changes parent-id shapes nil))
|
||||
(change-parent changes parent-id shapes nil {}))
|
||||
|
||||
([changes parent-id shapes index]
|
||||
(change-parent changes parent-id shapes index {}))
|
||||
|
||||
([changes parent-id shapes index options]
|
||||
(assert-page-id! changes)
|
||||
(assert-objects! changes)
|
||||
(let [objects (lookup-objects changes)
|
||||
|
@ -323,7 +326,9 @@
|
|||
:shapes (->> shapes reverse (mapv :id))}
|
||||
|
||||
(some? index)
|
||||
(assoc :index index))
|
||||
(assoc :index index)
|
||||
(:component-swap options)
|
||||
(assoc :component-swap true))
|
||||
|
||||
mk-undo-change
|
||||
(fn [undo-changes shape]
|
||||
|
|
|
@ -531,6 +531,14 @@
|
|||
(merge-path other-path item))))
|
||||
[other-path last-item false]))))
|
||||
|
||||
(defn prev-path
|
||||
"Remove the last item of the path."
|
||||
[path]
|
||||
(let [split (split-path path)]
|
||||
(if (= 1 (count split))
|
||||
""
|
||||
(join-path (butlast split)))))
|
||||
|
||||
(defn compact-name
|
||||
"Append the first item of the path and the name."
|
||||
[path name]
|
||||
|
|
|
@ -134,12 +134,19 @@
|
|||
[shape]
|
||||
(some? (:shape-ref shape)))
|
||||
|
||||
(defn in-component-copy-not-head?
|
||||
"Check if the shape is inside a component non-main instance and
|
||||
is not the head of a subinstance."
|
||||
[shape]
|
||||
(and (some? (:shape-ref shape))
|
||||
(nil? (:component-id shape))))
|
||||
|
||||
(defn in-component-copy-not-root?
|
||||
"Check if the shape is inside a component non-main instance and
|
||||
is not the root shape."
|
||||
[shape]
|
||||
(and (some? (:shape-ref shape))
|
||||
(nil? (:component-id shape))))
|
||||
(nil? (:component-root shape))))
|
||||
|
||||
(defn main-instance-of?
|
||||
"Check if this shape is the root of the main instance of the given component."
|
||||
|
|
|
@ -344,3 +344,22 @@
|
|||
(if (= parent-id uuid/zero)
|
||||
current-top
|
||||
(get-top-instance objects parent current-top))))
|
||||
|
||||
|
||||
(defn get-first-not-copy-parent
|
||||
"Go trough the parents until we find a shape that is not a copy of a component."
|
||||
[objects id]
|
||||
(let [shape (get objects id)]
|
||||
(if (ctk/in-component-copy? shape)
|
||||
(get-first-not-copy-parent objects (:parent-id shape))
|
||||
shape)))
|
||||
|
||||
(defn has-any-copy-parent?
|
||||
"Check if the shape has any parent that is a copy of a component."
|
||||
[objects shape]
|
||||
(let [parent (get objects (:parent-id shape))]
|
||||
(if (nil? parent)
|
||||
false
|
||||
(if (ctk/in-component-copy? parent)
|
||||
true
|
||||
(has-any-copy-parent? objects (:parent-id shape))))))
|
||||
|
|
|
@ -73,6 +73,18 @@
|
|||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
svg {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
fill: $color-gray-20;
|
||||
margin-right: 1rem;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
&.back {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,6 +597,26 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.copy {
|
||||
flex-wrap: wrap;
|
||||
border-radius: 8px;
|
||||
border: 1px solid $color-gray-60;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
|
||||
.component-name {
|
||||
width: 80%;
|
||||
color: $color-white;
|
||||
}
|
||||
.component-parent-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
padding-left: calc(0.5rem + 16px);
|
||||
color: $color-gray-40;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-option .custom-select {
|
||||
|
@ -2554,3 +2586,125 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-swap {
|
||||
.search-block {
|
||||
margin: 0.7rem 0.5rem 0.2rem 0.2rem;
|
||||
height: 2.1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
height: 0.7rem;
|
||||
width: 0.7rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search-block {
|
||||
border: 1px solid $color-gray-30;
|
||||
margin: 0.6rem 0.5rem 0.2rem 0.2rem;
|
||||
padding: $size-1 $size-2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
border-color: $color-gray-20;
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-color: $color-primary;
|
||||
}
|
||||
|
||||
& .search-input {
|
||||
background-color: $color-gray-50;
|
||||
border: none;
|
||||
color: $color-gray-10;
|
||||
font-size: $fs12;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
flex-grow: 1;
|
||||
|
||||
&:focus {
|
||||
color: lighten($color-gray-10, 8%);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
& .search-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
fill: $color-gray-30;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
&.close {
|
||||
transform: rotate(45deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-path {
|
||||
display: flex;
|
||||
margin: 0.4rem 0 0 0.4rem;
|
||||
cursor: pointer;
|
||||
svg {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
margin-right: 0.5rem;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.component-list {
|
||||
margin: 0.7rem 0.5rem 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.component-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
cursor: pointer;
|
||||
svg {
|
||||
background-color: $color-canvas;
|
||||
border-radius: $br4;
|
||||
border: 2px solid transparent;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: $size-2;
|
||||
}
|
||||
|
||||
.selected {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: auto;
|
||||
color: $color-gray-30;
|
||||
}
|
||||
}
|
||||
|
||||
.component-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
height: 24px;
|
||||
svg {
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
}
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -921,7 +921,7 @@
|
|||
component-shape (ctn/get-component-shape objects shape)
|
||||
component-shape-parent (ctn/get-component-shape objects parent)
|
||||
|
||||
detach? (and (ctk/in-component-copy-not-root? shape)
|
||||
detach? (and (ctk/in-component-copy-not-head? shape)
|
||||
(not= (:id component-shape)
|
||||
(:id component-shape-parent)))
|
||||
deroot? (and (ctk/instance-root? shape)
|
||||
|
@ -1834,6 +1834,11 @@
|
|||
;; Calculate position for the pasted elements
|
||||
[frame-id parent-id delta index] (calculate-paste-position state mouse-pos in-viewport?)
|
||||
|
||||
;; We don't want to change the structure of component copies
|
||||
;; If the parent-id or the frame-id are component-copies, we need to get the first not copy parent
|
||||
parent-id (:id (ctn/get-first-not-copy-parent page-objects parent-id))
|
||||
frame-id (:id (ctn/get-first-not-copy-parent page-objects frame-id))
|
||||
|
||||
process-shape
|
||||
(fn [_ shape]
|
||||
(let [parent (get page-objects parent-id)
|
||||
|
@ -1841,7 +1846,7 @@
|
|||
component-shape-parent (ctn/get-component-shape page-objects parent)
|
||||
;; if foreign instance, or a shape belonging to another component, detach the shape
|
||||
detach? (or (foreign-instance? shape paste-objects state)
|
||||
(and (ctk/in-component-copy-not-root? shape)
|
||||
(and (ctk/in-component-copy-not-head? shape)
|
||||
(not= (:id component-shape)
|
||||
(:id component-shape-parent))))
|
||||
assign-shapes? (and (or (cph/group-shape? shape)
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
|
||||
;; Shapes that are in a component, but are not root, must be detached,
|
||||
;; because they will be now children of a non instance group.
|
||||
shapes-to-detach (filter ctk/in-component-copy-not-root? shapes)
|
||||
shapes-to-detach (filter ctk/in-component-copy-not-head? shapes)
|
||||
|
||||
;; Look at the `get-empty-groups-after-group-creation`
|
||||
;; docstring to understand the real purpose of this code
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
[app.main.data.workspace.notifications :as-alias dwn]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.specialized-panel :as dwsp]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.main.data.workspace.thumbnails :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
|
@ -744,6 +745,57 @@
|
|||
(rx/map #(update-component-sync (:id %) file-id (uuid/next)) (rx/from shapes))
|
||||
(rx/of (dwu/commit-undo-transaction undo-id)))))))
|
||||
|
||||
(defn- find-shape-index
|
||||
[objects id shape-id]
|
||||
(let [object (get objects id)]
|
||||
(when object
|
||||
(let [shapes (:shapes object)]
|
||||
(or (->> shapes
|
||||
(map-indexed (fn [index shape] [shape index]))
|
||||
(filter #(= shape-id (first %)))
|
||||
first
|
||||
second)
|
||||
0)))))
|
||||
|
||||
(defn component-swap
|
||||
"Swaps a component with another one"
|
||||
[shape file-id id-new-component]
|
||||
(dm/assert! (uuid? id-new-component))
|
||||
(dm/assert! (uuid? file-id))
|
||||
(ptk/reify ::component-swap
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [page (wsh/lookup-page state)
|
||||
libraries (wsh/get-libraries state)
|
||||
|
||||
objects (:objects page)
|
||||
index (find-shape-index objects (:parent-id shape) (:id shape))
|
||||
position (gpt/point (:x shape) (:y shape))
|
||||
changes (-> (pcb/empty-changes it (:id page))
|
||||
(pcb/with-objects objects))
|
||||
|
||||
[new-shape changes]
|
||||
(dwlh/generate-instantiate-component changes
|
||||
objects
|
||||
file-id
|
||||
id-new-component
|
||||
position
|
||||
page
|
||||
libraries)
|
||||
changes (pcb/change-parent changes (:parent-id shape) [new-shape] index {:component-swap true})
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(ptk/data-event :layout/update [(:id new-shape)])
|
||||
(dws/select-shapes (d/ordered-set (:id new-shape)))
|
||||
(dwsh/delete-shapes nil (d/ordered-set (:id shape)) {:component-swap true})
|
||||
(dwu/commit-undo-transaction undo-id)
|
||||
(dwsp/open-specialized-panel :component-swap [(assoc new-shape :parent-id (:parent-id shape))]))))))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(def valid-asset-types
|
||||
#{:colors :components :typographies})
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@
|
|||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:workspace-local :selected] d/toggle-selection id toggle?)
|
||||
(assoc-in [:workspace-local :last-selected] id)))
|
||||
(assoc-in [:workspace-local :last-selected] id)
|
||||
(dissoc :specialized-panel)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
|
@ -188,7 +189,8 @@
|
|||
(update [_ state]
|
||||
(-> state
|
||||
(update-in [:workspace-local :selected] disj id)
|
||||
(update :workspace-local dissoc :last-selected)))))
|
||||
(update :workspace-local dissoc :last-selected)
|
||||
(dissoc :specialized-panel)))))
|
||||
|
||||
(defn shift-select-shapes
|
||||
([id]
|
||||
|
@ -206,7 +208,8 @@
|
|||
(-> state
|
||||
(assoc-in [:workspace-local :selected]
|
||||
(set/union selection append-to-selection))
|
||||
(update :workspace-local assoc :last-selected id)))))))
|
||||
(update :workspace-local assoc :last-selected id)
|
||||
(dissoc :specialized-panel)))))))
|
||||
|
||||
(defn select-shapes
|
||||
[ids]
|
||||
|
@ -223,7 +226,9 @@
|
|||
ids (if (d/not-empty? focus)
|
||||
(cpf/filter-not-focus objects focus ids)
|
||||
ids)]
|
||||
(assoc-in state [:workspace-local :selected] ids)))
|
||||
(-> state
|
||||
(assoc-in [:workspace-local :selected] ids)
|
||||
(dissoc :specialized-panel))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
|
@ -277,7 +282,9 @@
|
|||
(update :workspace-local
|
||||
#(-> %
|
||||
(assoc :selected (d/ordered-set))
|
||||
(dissoc :selected-frame))))))))
|
||||
(dissoc :selected-frame)))
|
||||
:allways
|
||||
(dissoc :specialized-panel))))))
|
||||
|
||||
;; --- Select Shapes (By selrect)
|
||||
|
||||
|
@ -631,7 +638,11 @@
|
|||
(when (or (not move-delta?) (nil? (get-in state [:workspace-local :transform])))
|
||||
(let [page (wsh/lookup-page state)
|
||||
objects (:objects page)
|
||||
selected (wsh/lookup-selected state)]
|
||||
selected (->> (wsh/lookup-selected state)
|
||||
(map #(get objects %))
|
||||
(remove #(ctk/in-component-copy-not-root? %)) ;; We don't want to change the structure of component copies
|
||||
(map :id)
|
||||
set)]
|
||||
(when (seq selected)
|
||||
(let [obj (get objects (first selected))
|
||||
delta (if move-delta?
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.shape :as cts]
|
||||
|
@ -133,8 +132,9 @@
|
|||
(declare update-shape-flags)
|
||||
|
||||
(defn delete-shapes
|
||||
([ids] (delete-shapes nil ids))
|
||||
([page-id ids]
|
||||
([ids] (delete-shapes nil ids {}))
|
||||
([page-id ids] (delete-shapes page-id ids {}))
|
||||
([page-id ids options]
|
||||
(dm/assert! (sm/set-of-uuid? ids))
|
||||
(ptk/reify ::delete-shapes
|
||||
ptk/WatchEvent
|
||||
|
@ -154,11 +154,11 @@
|
|||
;; Look for shapes that are inside a component copy, but are
|
||||
;; not the root. In this case, they must not be deleted,
|
||||
;; but hidden (to be able to recover them more easily).
|
||||
(let [shape (get objects shape-id)
|
||||
component-shape (ctn/get-component-shape objects shape)]
|
||||
(and (ctk/in-component-copy? shape)
|
||||
(not= shape component-shape)
|
||||
(not (ctk/main-instance? component-shape)))))
|
||||
;; Unless we are doing a component swap, in which case we want
|
||||
;; to delete the old shape
|
||||
(let [shape (get objects shape-id)]
|
||||
(and (ctn/has-any-copy-parent? objects shape)
|
||||
(not (:component-swap options)))))
|
||||
|
||||
[ids-to-delete ids-to-hide]
|
||||
(if components-v2
|
||||
|
@ -347,6 +347,11 @@
|
|||
frame-id
|
||||
(:parent-id base))
|
||||
|
||||
;; If the parent-id or the frame-id are component-copies, we need to get the first not copy parent
|
||||
parent-id (:id (ctn/get-first-not-copy-parent objects parent-id)) ;; We don't want to change the structure of component copies
|
||||
frame-id (:id (ctn/get-first-not-copy-parent objects frame-id))
|
||||
|
||||
|
||||
shape (cts/setup-shape
|
||||
(-> attrs
|
||||
(assoc :type type)
|
||||
|
|
|
@ -68,8 +68,9 @@
|
|||
:cut {:tooltip (ds/meta "X")
|
||||
:command (ds/c-mod "x")
|
||||
:subsections [:edit]
|
||||
:fn #(emit-when-no-readonly (dw/copy-selected)
|
||||
(dw/delete-selected))}
|
||||
:fn #(emit-when-no-readonly
|
||||
(dw/copy-selected)
|
||||
(dw/delete-selected))}
|
||||
|
||||
:paste {:tooltip (ds/meta "V")
|
||||
:disabled true
|
||||
|
|
31
frontend/src/app/main/data/workspace/specialized_panel.cljs
Normal file
31
frontend/src/app/main/data/workspace/specialized_panel.cljs
Normal file
|
@ -0,0 +1,31 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.data.workspace.specialized-panel
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(defn interrupt? [e] (= e :interrupt))
|
||||
|
||||
(def clear-specialized-panel
|
||||
(ptk/reify ::clear-specialized-panel
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(dissoc state :specialized-panel))))
|
||||
|
||||
(defn open-specialized-panel
|
||||
[type shapes]
|
||||
(ptk/reify ::open-specialized-panel
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state :specialized-panel {:type type :shapes shapes}))
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(->> stream
|
||||
(rx/filter interrupt?)
|
||||
(rx/take 1)
|
||||
(rx/map (constantly clear-specialized-panel))))))
|
|
@ -513,10 +513,11 @@
|
|||
:else
|
||||
[move-vector nil])
|
||||
|
||||
nesting-loop? (some #(cph/components-nesting-loop? objects (:id %) target-frame) shapes)]
|
||||
nesting-loop? (some #(cph/components-nesting-loop? objects (:id %) target-frame) shapes)
|
||||
is-component-copy? (ctk/in-component-copy? (get objects target-frame))]
|
||||
|
||||
(cond-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector))
|
||||
(not nesting-loop?)
|
||||
(and (not nesting-loop?) (not is-component-copy?))
|
||||
(dwm/build-change-frame-modifiers objects selected target-frame drop-index cell-data)
|
||||
:always
|
||||
(dwm/set-modifiers false false {:snap-ignore-axis snap-ignore-axis}))))))
|
||||
|
@ -820,7 +821,7 @@
|
|||
|
||||
shape-ids-to-detach
|
||||
(reduce (fn [result shape]
|
||||
(if (and (some? shape) (ctk/in-component-copy-not-root? shape))
|
||||
(if (and (some? shape) (ctk/in-component-copy-not-head? shape))
|
||||
(let [shape-component (ctn/get-component-shape objects shape)]
|
||||
(if (= (:id frame-component) (:id shape-component))
|
||||
result
|
||||
|
|
|
@ -573,3 +573,6 @@
|
|||
|
||||
(defn workspace-preview-blend-by-id [id]
|
||||
(l/derived (l/key id) workspace-preview-blend =))
|
||||
|
||||
(def specialized-panel
|
||||
(l/derived :specialized-panel st/state))
|
||||
|
|
|
@ -118,7 +118,9 @@
|
|||
on-drag-start
|
||||
(fn [event]
|
||||
(if (or disabled (not draggable?))
|
||||
(dom/prevent-default event)
|
||||
(do
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event))
|
||||
(do
|
||||
(dom/stop-propagation event)
|
||||
(dnd/set-data! event data-type data)
|
||||
|
@ -178,7 +180,8 @@
|
|||
on-mount
|
||||
(fn []
|
||||
(let [dom (mf/ref-val ref)]
|
||||
(.setAttribute dom "draggable" draggable?)
|
||||
(.setAttribute dom "draggable" true) ;; In firefox it needs to be draggable for problems with event handling.
|
||||
;; It will stop the drag operation in on-drag-start
|
||||
|
||||
;; Register all events in the (default) bubble mode, so that they
|
||||
;; are captured by the most leaf item. The handler will stop
|
||||
|
|
|
@ -444,7 +444,7 @@
|
|||
|
||||
has-component? (some true? (map #(ctk/instance-head? %) shapes))
|
||||
is-component? (and single? (-> shapes first :component-id some?))
|
||||
in-copy-not-root? (some true? (map #(ctk/in-component-copy-not-root? %) shapes))
|
||||
in-copy-not-root? (some true? (map #(ctk/in-component-copy-not-head? %) shapes))
|
||||
|
||||
objects (deref refs/workspace-page-objects)
|
||||
touched? (and single? (cph/component-touched? objects (:id (first shapes))))
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -145,10 +147,15 @@
|
|||
(mf/use-fn
|
||||
(mf/deps id index objects)
|
||||
(fn [side _data]
|
||||
(if (= side :center)
|
||||
(st/emit! (dw/relocate-selected-shapes id 0))
|
||||
(let [to-index (if (= side :top) (inc index) index)
|
||||
parent-id (cph/get-parent-id objects id)]
|
||||
(let [to-index (cond
|
||||
(= side :center) 0
|
||||
(= side :top) (inc index)
|
||||
:else index)
|
||||
parent-id (if (= side :center)
|
||||
id
|
||||
(cph/get-parent-id objects id))
|
||||
parent (get objects parent-id)]
|
||||
(when-not (ctk/in-component-copy? parent) ;; We don't want to change the structure of component copies
|
||||
(st/emit! (dw/relocate-selected-shapes parent-id to-index))))))
|
||||
|
||||
on-hold
|
||||
|
@ -176,7 +183,10 @@
|
|||
:data {:id (:id item)
|
||||
:index index
|
||||
:name (:name item)}
|
||||
:draggable? (and sortable? (not read-only?)))
|
||||
:draggable? (and
|
||||
sortable?
|
||||
(not read-only?)
|
||||
(not (ctn/has-any-copy-parent? objects item)))) ;; We don't want to change the structure of component copies
|
||||
|
||||
ref (mf/use-ref)
|
||||
depth (+ depth 1)
|
||||
|
@ -372,7 +382,7 @@
|
|||
[:div.toggle-element {:class (when ^boolean hidden? "selected")
|
||||
:title (if (:hidden item)
|
||||
(tr "workspace.shape.menu.show")
|
||||
(tr "workspace.shape.menu.hide"))
|
||||
(tr "workspace.shape.menu.hide"))
|
||||
:on-click toggle-visibility}
|
||||
(if ^boolean hidden? i/eye-closed i/eye)]
|
||||
[:div.block-element {:class (when ^boolean blocked? "selected")
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
[app.main.ui.viewer.inspect.right-sidebar :as hrs]
|
||||
[app.main.ui.workspace.sidebar.options.menus.align :refer [align-options]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.bool :refer [bool-options]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.exports :refer [exports-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
|
||||
[app.main.ui.workspace.sidebar.options.menus.interactions :refer [interactions-menu]]
|
||||
|
@ -67,6 +68,13 @@
|
|||
:page-id page-id
|
||||
:file-id file-id}]]))
|
||||
|
||||
(mf/defc specialized-panel
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [panel]}]
|
||||
(when (= (:type panel) :component-swap)
|
||||
[:& component-menu {:shape (first (:shapes panel)) :swap-opened? true}]))
|
||||
|
||||
|
||||
(mf/defc options-content
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [selected section shapes shapes-with-children page-id file-id on-change-section on-expand]}]
|
||||
|
@ -76,6 +84,7 @@
|
|||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
edition (mf/deref refs/selected-edition)
|
||||
grid-edition (mf/deref refs/workspace-grid-edition)
|
||||
sp-panel (mf/deref refs/specialized-panel)
|
||||
|
||||
selected-shapes (into [] (keep (d/getf objects)) selected)
|
||||
first-selected-shape (first selected-shapes)
|
||||
|
@ -116,6 +125,9 @@
|
|||
{:ids [edition]
|
||||
:values (get objects edition)}]
|
||||
|
||||
(not (nil? sp-panel))
|
||||
[:& specialized-panel {:panel sp-panel}]
|
||||
|
||||
(d/not-empty? drawing)
|
||||
[:& shape-options
|
||||
{:shape (:object drawing)
|
||||
|
@ -177,6 +189,10 @@
|
|||
{:ids [edition]
|
||||
:values (get objects edition)}]
|
||||
|
||||
sp-panel
|
||||
[:& specialized-panel {:panel sp-panel}]
|
||||
|
||||
|
||||
(d/not-empty? drawing)
|
||||
[:& shape-options
|
||||
{:shape (:object drawing)
|
||||
|
|
|
@ -11,10 +11,13 @@
|
|||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.specialized-panel :as dwsp]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.render :refer [component-svg]]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
|
@ -23,6 +26,7 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -144,9 +148,153 @@
|
|||
(when (or @editing? creating?)
|
||||
[:div.counter (str @size "/300")])]])))
|
||||
|
||||
(mf/defc component-swap
|
||||
[{:keys [shapes] :as props}]
|
||||
(let [shape (first shapes)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
workspace-file (deref refs/workspace-file)
|
||||
workspace-data (deref refs/workspace-data)
|
||||
workspace-libraries (deref refs/workspace-libraries)
|
||||
objects (deref refs/workspace-page-objects)
|
||||
libraries (assoc workspace-libraries current-file-id (assoc workspace-file :data workspace-data))
|
||||
filters* (mf/use-state
|
||||
{:term ""
|
||||
:file-id (:component-file shape)
|
||||
:path (cph/prev-path (:name shape))})
|
||||
filters (deref filters*)
|
||||
|
||||
components (-> (get-in libraries [(:file-id filters) :data :components])
|
||||
vals)
|
||||
|
||||
components (if (str/empty? (:term filters))
|
||||
components
|
||||
(filter #(str/includes? (str/lower (:name %)) (str/lower (:term filters))) components))
|
||||
|
||||
groups (->> (map :path components)
|
||||
(filter #(= (cph/prev-path (:path %)) (:path filters)))
|
||||
(remove str/empty?)
|
||||
distinct
|
||||
(map #(hash-map :name %)))
|
||||
|
||||
components (filter #(= (:path %) (:path filters)) components)
|
||||
|
||||
items (->> (concat groups components)
|
||||
(sort-by :name))
|
||||
|
||||
;; Get the ids of the components and its root-shapes that are parents of the current shape, to avoid loops
|
||||
get-comps-ids (fn get-comps-ids [shape ids]
|
||||
(if (uuid/zero? (:id shape))
|
||||
ids
|
||||
(let [ids (if (ctk/instance-head? shape)
|
||||
(conj ids (:id shape) (:component-id shape))
|
||||
ids)]
|
||||
(get-comps-ids (get objects (:parent-id shape)) ids))))
|
||||
|
||||
parent-components (set (get-comps-ids (get objects (:parent-id shape)) []))
|
||||
|
||||
on-library-change
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [value (or (-> (dom/get-target event)
|
||||
(dom/get-value))
|
||||
(as-> (dom/get-current-target event) $
|
||||
(dom/get-attribute $ "data-test")))
|
||||
value (uuid/uuid value)]
|
||||
(swap! filters* assoc :file-id value :term "" :path ""))))
|
||||
|
||||
on-search-term-change
|
||||
(mf/use-fn
|
||||
(mf/deps new-css-system)
|
||||
(fn [event]
|
||||
;; NOTE: When old-css-system is removed this function will recibe value and event
|
||||
;; Let won't be necessary any more
|
||||
(let [value (if ^boolean new-css-system
|
||||
event
|
||||
(dom/get-target-val event))]
|
||||
(swap! filters* assoc :term value))))
|
||||
|
||||
|
||||
on-search-clear-click
|
||||
(mf/use-fn #(swap! filters* assoc :term ""))
|
||||
|
||||
on-go-back
|
||||
(mf/use-fn
|
||||
(mf/deps (:path filters))
|
||||
#(swap! filters* assoc :path (cph/prev-path (:path filters))))
|
||||
|
||||
on-enter-group
|
||||
(mf/use-fn #(swap! filters* assoc :path %))
|
||||
|
||||
handle-key-down
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [enter? (kbd/enter? event)
|
||||
esc? (kbd/esc? event)
|
||||
node (dom/event->target event)]
|
||||
|
||||
(when ^boolean enter? (dom/blur! node))
|
||||
(when ^boolean esc? (dom/blur! node)))))]
|
||||
|
||||
[:div.component-swap
|
||||
[:div.element-set-title
|
||||
[:span (tr "workspace.options.component.swap")]]
|
||||
[:div.component-swap-content
|
||||
[:div.search-block
|
||||
[:input.search-input
|
||||
{:placeholder (str (tr "labels.search") " " (get-in libraries [(:file-id filters) :name]))
|
||||
:type "text"
|
||||
:value (:term filters)
|
||||
:on-change on-search-term-change
|
||||
:on-key-down handle-key-down}]
|
||||
|
||||
(if ^boolean (str/empty? (:term filters))
|
||||
[:div.search-icon
|
||||
i/search]
|
||||
[:div.search-icon.close
|
||||
{:on-click on-search-clear-click}
|
||||
i/close])]
|
||||
|
||||
[:select.input-select {:value (:file-id filters)
|
||||
:data-mousetrap-dont-stop true
|
||||
:on-change on-library-change}
|
||||
(for [library (vals libraries)]
|
||||
[:option {:key (:id library) :value (:id library)} (:name library)])]
|
||||
|
||||
(when-not (str/empty? (:path filters))
|
||||
[:div.component-path {:on-click on-go-back}
|
||||
[:span i/arrow-slide]
|
||||
[:span (-> (cph/split-path (:path filters))
|
||||
last)]])
|
||||
[:div.component-list
|
||||
(for [item items]
|
||||
(if (:id item)
|
||||
(let [data (get-in libraries [(:file-id filters) :data])
|
||||
container (ctf/get-component-page data item)
|
||||
root-shape (ctf/get-component-root data item)
|
||||
loop? (or (contains? parent-components (:main-instance-id item))
|
||||
(contains? parent-components (:id item)))]
|
||||
[:div.component-item
|
||||
{:class (stl/css-case :disabled loop?)
|
||||
:key (:id item)
|
||||
:on-click #(when-not loop?
|
||||
(st/emit!
|
||||
(dwl/component-swap shape (:file-id filters) (:id item))))}
|
||||
[:& component-svg {:root-shape root-shape
|
||||
:objects (:objects container)}]
|
||||
[:span.component-name
|
||||
{:class (stl/css-case :selected (= (:id item) (:component-id shape)))}
|
||||
(:name item)]])
|
||||
[:div.component-group {:key (uuid/next) :on-click #(on-enter-group (:name item))}
|
||||
[:span (:name item)]
|
||||
[:span i/arrow-slide]]))]]]))
|
||||
|
||||
|
||||
|
||||
(mf/defc component-menu
|
||||
[{:keys [ids values shape] :as props}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
[{:keys [shape swap-opened?] :as props}]
|
||||
(let [[ids values] [[(:id shape)] (select-keys shape component-attrs)]
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
|
||||
|
@ -171,6 +319,7 @@
|
|||
main-instance? (if components-v2
|
||||
(ctk/main-instance? values)
|
||||
true)
|
||||
can-swap? (and components-v2 (not main-instance?))
|
||||
main-component? (:main-instance values)
|
||||
lacks-annotation? (nil? (:annotation values))
|
||||
|
||||
|
@ -342,13 +491,20 @@
|
|||
[:& component-annotation {:id id :values values :shape shape :component component}])])]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (tr "workspace.options.component")]
|
||||
[:div.element-set-title {:class (stl/css-case :back swap-opened?)
|
||||
:on-click #(when swap-opened? (st/emit! :interrupt))}
|
||||
[:div
|
||||
(when swap-opened?
|
||||
[:span
|
||||
i/arrow-slide])
|
||||
[:span (tr "workspace.options.component")]]
|
||||
[:span (if main-instance?
|
||||
(tr "workspace.options.component.main")
|
||||
(tr "workspace.options.component.copy"))]]
|
||||
[:div.element-set-content
|
||||
[:div.row-flex.component-row
|
||||
{:class (stl/css-case :copy can-swap?)
|
||||
:on-click #(when can-swap? (st/emit! (dwsp/open-specialized-panel :component-swap [shape])))}
|
||||
(if main-instance?
|
||||
i/component
|
||||
i/component-copy)
|
||||
|
@ -391,7 +547,14 @@
|
|||
[(tr "workspace.shape.menu.reset-overrides") do-reset-component])
|
||||
(when can-update-main?
|
||||
[(tr "workspace.shape.menu.update-main") do-update-remote-component])
|
||||
[(tr "workspace.shape.menu.go-main") do-navigate-component-file]])))}]]]
|
||||
[(tr "workspace.shape.menu.go-main") do-navigate-component-file]])))}]]
|
||||
|
||||
(when components-v2
|
||||
(when can-swap?
|
||||
[:div.component-parent-name
|
||||
(cph/merge-path-item (:path component) (:name component))])]
|
||||
|
||||
(when swap-opened?
|
||||
[:& component-swap {:shapes [shape]}])
|
||||
|
||||
(when (and (not swap-opened?) components-v2)
|
||||
[:& component-annotation {:id id :values values :shape shape :component component}])]]))))
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs-shape fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
|
||||
|
@ -36,7 +36,6 @@
|
|||
constraint-values (select-keys shape constraint-attrs)
|
||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||
layout-item-values (select-keys shape layout-item-attrs)
|
||||
[comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)]
|
||||
|
||||
ids (hooks/use-equal-memo ids)
|
||||
|
||||
|
@ -63,9 +62,7 @@
|
|||
:values measure-values
|
||||
:type type
|
||||
:shape shape}]
|
||||
[:& component-menu {:ids comp-ids
|
||||
:values comp-values
|
||||
:shape shape}]
|
||||
[:& component-menu {:shape shape}]
|
||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
||||
[:& constraints-menu {:ids ids
|
||||
:values constraint-values}])
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraints-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.grid-cell :as grid-cell]
|
||||
|
@ -66,7 +66,6 @@
|
|||
[stroke-ids stroke-values] (get-attrs [shape] objects :stroke)
|
||||
[text-ids text-values] (get-attrs [shape] objects :text)
|
||||
[svg-ids svg-values] [[(:id shape)] (select-keys shape [:svg-attrs])]
|
||||
[comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)]
|
||||
[layout-item-ids layout-item-values] (get-attrs [shape] objects :layout-item)]
|
||||
|
||||
|
||||
|
@ -74,7 +73,7 @@
|
|||
:options true)}
|
||||
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
|
||||
[:& measures-menu {:type type :ids measure-ids :values measure-values :shape shape}]
|
||||
[:& component-menu {:ids comp-ids :values comp-values :shape shape}] ;;remove this in components-v2
|
||||
[:& component-menu {:shape shape}] ;;remove this in components-v2
|
||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||
|
||||
(when (and (= (count ids) 1) is-layout-child? is-grid-parent?)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.data.workspace.path :as dwdp]
|
||||
[app.main.data.workspace.specialized-panel :as dwsp]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
|
@ -84,7 +85,8 @@
|
|||
|
||||
left-click?
|
||||
(do
|
||||
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?))
|
||||
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?)
|
||||
dwsp/clear-specialized-panel)
|
||||
|
||||
(when (and (not= edition id) (or text-editing? grid-editing?))
|
||||
(st/emit! dw/clear-edition-mode))
|
||||
|
|
|
@ -90,63 +90,58 @@
|
|||
|
||||
(t/deftest test-touched-children-add
|
||||
(t/async done
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"
|
||||
:fill-color clr/white
|
||||
:fill-opacity 1})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/sample-shape :shape2 :circle
|
||||
{:name "Circle 1"}))
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"
|
||||
:fill-color clr/white
|
||||
:fill-opacity 1})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/sample-shape :shape2 :circle
|
||||
{:name "Circle 1"}))
|
||||
|
||||
instance1 (thp/get-shape state :instance1)
|
||||
shape2 (thp/get-shape state :shape2)
|
||||
instance1 (thp/get-shape state :instance1)
|
||||
shape2 (thp/get-shape state :shape2)
|
||||
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
;; Expected shape tree:
|
||||
;;
|
||||
;; [Page]
|
||||
;; Root Frame
|
||||
;; Rect 1
|
||||
;; Rect 1
|
||||
;; Rect 1* #--> Rect 1
|
||||
;; #{:shapes-group}
|
||||
;; [Page: Page 1]
|
||||
;; Root Frame
|
||||
;; {Rect 1}
|
||||
;; Rect1
|
||||
;; Rect 1 #--> Rect 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Circle 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;;
|
||||
;; [Rect 1]
|
||||
;; page1 / Rect 1
|
||||
;;
|
||||
(let [[[group shape1 shape2] [c-group c-shape1] _component]
|
||||
(thl/resolve-instance-and-main-allow-dangling
|
||||
new-state
|
||||
(thp/id :instance1))]
|
||||
;; [Component: Rect 1] core.cljs:200:23
|
||||
;; --> [Page 1] Rect 1
|
||||
|
||||
(t/is (= (:name group) "Rect 1"))
|
||||
(t/is (= (:touched group) #{:shapes-group}))
|
||||
(t/is (= (:name shape1) "Circle 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (not= (:shape-ref shape2) nil))
|
||||
(let [[[group shape1] [c-group c-shape1] _component]
|
||||
(thl/resolve-instance-and-main-allow-dangling
|
||||
new-state
|
||||
(thp/id :instance1))]
|
||||
|
||||
(t/is (= (:name c-group) "Rect 1"))
|
||||
(t/is (= (:touched c-group) nil))
|
||||
(t/is (= (:shape-ref c-group) nil))
|
||||
(t/is (= (:name c-shape1) "Rect 1"))
|
||||
(t/is (= (:touched c-shape1) nil))
|
||||
(t/is (= (:shape-ref c-shape1) nil)))))]
|
||||
(t/is (= (:name group) "Rect 1"))
|
||||
(t/is (nil? (:touched group)))
|
||||
(t/is (= (:name shape1) "Rect 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (not= (:shape-ref shape1) nil))
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape2)} (:id instance1) 0)
|
||||
:the/end))))
|
||||
(t/is (= (:name c-group) "Rect 1"))
|
||||
(t/is (= (:touched c-group) nil))
|
||||
(t/is (= (:shape-ref c-group) nil))
|
||||
(t/is (= (:name c-shape1) "Rect 1"))
|
||||
(t/is (= (:touched c-shape1) nil))
|
||||
(t/is (= (:shape-ref c-shape1) nil)))))]
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape2)} (:id instance1) 0) ;; We cant't change the structure of component copies, so this operation will do nothing
|
||||
:the/end))))
|
||||
|
||||
(t/deftest test-touched-children-delete
|
||||
(t/async done
|
||||
|
@ -215,78 +210,78 @@
|
|||
|
||||
(t/deftest test-touched-children-move
|
||||
(t/async done
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"})
|
||||
(thp/sample-shape :shape2 :rect
|
||||
{:name "Rect 2"})
|
||||
(thp/sample-shape :shape3 :rect
|
||||
{:name "Rect 3"})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)
|
||||
(thp/id :shape2)
|
||||
(thp/id :shape3)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1)))
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"})
|
||||
(thp/sample-shape :shape2 :rect
|
||||
{:name "Rect 2"})
|
||||
(thp/sample-shape :shape3 :rect
|
||||
{:name "Rect 3"})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)
|
||||
(thp/id :shape2)
|
||||
(thp/id :shape3)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1)))
|
||||
|
||||
[group1' shape1']
|
||||
(thl/resolve-instance state (thp/id :instance1))
|
||||
[group1' shape1']
|
||||
(thl/resolve-instance state (thp/id :instance1))
|
||||
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
;; Expected shape tree:
|
||||
;;
|
||||
;; [Page]
|
||||
;; Root Frame
|
||||
;; Component 1
|
||||
;; Rect 1
|
||||
;; Rect 2
|
||||
;; Rect 3
|
||||
;; Component 1* #--> Component 1
|
||||
;; #{:shapes-group}
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 3 ---> Rect 3
|
||||
;;
|
||||
;; [Component 1]
|
||||
;; page1 / Component 1
|
||||
;;
|
||||
(let [[[group shape1 shape2 shape3]
|
||||
[c-group c-shape1 c-shape2 c-shape3] _component]
|
||||
(thl/resolve-instance-and-main-allow-dangling
|
||||
new-state
|
||||
(thp/id :instance1))]
|
||||
;; [Page: Page 1]
|
||||
;; Root Frame
|
||||
;; {Component 1} #
|
||||
;; Rect 1
|
||||
;; Rect 2
|
||||
;; Rect 3
|
||||
;; Component 1 #--> Component 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 3 ---> Rect 3
|
||||
;;
|
||||
;; ========= Local library
|
||||
;;
|
||||
;; [Component: Component 1]
|
||||
;; --> [Page 1] Component 1
|
||||
|
||||
(t/is (= (:name group) "Component 1"))
|
||||
(t/is (= (:touched group) #{:shapes-group}))
|
||||
(t/is (= (:name shape1) "Rect 2"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (not= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (not= (:shape-ref shape2) nil))
|
||||
(t/is (= (:name shape3) "Rect 3"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (not= (:shape-ref shape3) nil))
|
||||
(let [[[group shape1 shape2 shape3]
|
||||
[c-group c-shape1 c-shape2 c-shape3] _component]
|
||||
(thl/resolve-instance-and-main-allow-dangling
|
||||
new-state
|
||||
(thp/id :instance1))]
|
||||
|
||||
(t/is (= (:name c-group) "Component 1"))
|
||||
(t/is (= (:touched c-group) nil))
|
||||
(t/is (= (:shape-ref c-group) nil))
|
||||
(t/is (= (:name c-shape1) "Rect 1"))
|
||||
(t/is (= (:touched c-shape1) nil))
|
||||
(t/is (= (:shape-ref c-shape1) nil))
|
||||
(t/is (= (:name c-shape2) "Rect 2"))
|
||||
(t/is (= (:touched c-shape2) nil))
|
||||
(t/is (= (:shape-ref c-shape2) nil))
|
||||
(t/is (= (:name c-shape3) "Rect 3"))
|
||||
(t/is (= (:touched c-shape3) nil))
|
||||
(t/is (= (:shape-ref c-shape3) nil)))))]
|
||||
(t/is (= (:name group) "Component 1"))
|
||||
(t/is (nil? (:touched group)))
|
||||
(t/is (= (:name shape1) "Rect 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (not= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 2"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (not= (:shape-ref shape2) nil))
|
||||
(t/is (= (:name shape3) "Rect 3"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (not= (:shape-ref shape3) nil))
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape1')} (:id group1') 2)
|
||||
:the/end))))
|
||||
(t/is (= (:name c-group) "Component 1"))
|
||||
(t/is (= (:touched c-group) nil))
|
||||
(t/is (= (:shape-ref c-group) nil))
|
||||
(t/is (= (:name c-shape1) "Rect 1"))
|
||||
(t/is (= (:touched c-shape1) nil))
|
||||
(t/is (= (:shape-ref c-shape1) nil))
|
||||
(t/is (= (:name c-shape2) "Rect 2"))
|
||||
(t/is (= (:touched c-shape2) nil))
|
||||
(t/is (= (:shape-ref c-shape2) nil))
|
||||
(t/is (= (:name c-shape3) "Rect 3"))
|
||||
(t/is (= (:touched c-shape3) nil))
|
||||
(t/is (= (:shape-ref c-shape3) nil)))))]
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape1')} (:id group1') 2) ;; We cant't change the structure of component copies, so this operation will do nothing
|
||||
:the/end))))
|
||||
|
||||
(t/deftest test-touched-from-lib
|
||||
(t/async
|
||||
|
@ -1507,109 +1502,97 @@
|
|||
|
||||
(t/deftest test-update-children-add
|
||||
(t/async done
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"
|
||||
:fill-color clr/white
|
||||
:fill-opacity 1})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/instantiate-component :instance2
|
||||
(thp/id :component1))
|
||||
(thp/sample-shape :shape2 :circle
|
||||
{:name "Circle 1"}))
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"
|
||||
:fill-color clr/white
|
||||
:fill-opacity 1})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/instantiate-component :instance2
|
||||
(thp/id :component1))
|
||||
(thp/sample-shape :shape2 :circle
|
||||
{:name "Circle 1"}))
|
||||
|
||||
file (wsh/get-local-file state)
|
||||
file (wsh/get-local-file state)
|
||||
|
||||
instance1 (thp/get-shape state :instance1)
|
||||
shape2 (thp/get-shape state :shape2)
|
||||
instance1 (thp/get-shape state :instance1)
|
||||
shape2 (thp/get-shape state :shape2)
|
||||
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
;; Expected shape tree:
|
||||
;;
|
||||
;; [Page]
|
||||
;; Root Frame
|
||||
;; Rect 1
|
||||
;; [Page: Page 1]
|
||||
;; Root Frame
|
||||
;; {Rect 1} #
|
||||
;; Rect 1
|
||||
;; Rect 1 #--> Rect 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 1 #--> Rect 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Circle 1
|
||||
;; Rect 1
|
||||
;; Rect 1 #--> Rect 1
|
||||
;; Circle 1 ---> Circle 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 1 #--> Rect 1
|
||||
;; Circle 1 ---> Circle 1
|
||||
;; Rect 1 ---> Rect 1
|
||||
;;
|
||||
;; [Rect 1]
|
||||
;; page1 / Rect 1
|
||||
;; ========= Local library
|
||||
;;
|
||||
(let [[[main1 shape1 shape2]
|
||||
[c-main1 c-shape1 c-shape2] component1]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :main1))
|
||||
;; [Component: Rect 1]
|
||||
;; --> [Page 1] Rect 1
|
||||
;;
|
||||
(let [[[main1 shape1]
|
||||
[c-main1 c-shape1] component1]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :main1))
|
||||
|
||||
[[instance1 shape3 shape4]
|
||||
[c-instance1 c-shape3 c-shape4] component2]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance1))
|
||||
[[instance1 shape2]
|
||||
[c-instance1 c-shape2] component2]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance1))
|
||||
|
||||
[[instance2 shape5 shape6]
|
||||
[c-instance2 c-shape5 c-shape6] component3]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance2))]
|
||||
[[instance2 shape3]
|
||||
[c-instance2 c-shape3] component3]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance2))]
|
||||
|
||||
(t/is (= (:name main1) "Rect 1"))
|
||||
(t/is (= (:touched main1) nil))
|
||||
(t/is (= (:shape-ref main1) nil))
|
||||
(t/is (= (:name shape1) "Circle 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (= (:shape-ref shape2) nil))
|
||||
(t/is (= (:name main1) "Rect 1"))
|
||||
(t/is (= (:touched main1) nil))
|
||||
(t/is (= (:shape-ref main1) nil))
|
||||
(t/is (= (:name shape1) "Rect 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (= (:shape-ref shape1) nil))
|
||||
|
||||
(t/is (= (:name instance1) "Rect 1"))
|
||||
(t/is (= (:touched instance1) nil))
|
||||
(t/is (= (:shape-ref instance1) (:id c-main1)))
|
||||
(t/is (= (:name shape3) "Circle 1"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (= (:shape-ref shape3) (:id c-shape1)))
|
||||
(t/is (= (:name shape4) "Rect 1"))
|
||||
(t/is (= (:touched shape4) nil))
|
||||
(t/is (= (:shape-ref shape4) (:id c-shape2)))
|
||||
(t/is (= (:name instance1) "Rect 1"))
|
||||
(t/is (= (:touched instance1) nil))
|
||||
(t/is (= (:shape-ref instance1) (:id c-main1)))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (= (:shape-ref shape2) (:id c-shape1)))
|
||||
|
||||
(t/is (= (:name instance2) "Rect 1"))
|
||||
(t/is (= (:touched instance2) nil))
|
||||
(t/is (= (:shape-ref instance2) (:id c-main1)))
|
||||
(t/is (= (:name shape5) "Circle 1"))
|
||||
(t/is (= (:touched shape5) nil))
|
||||
(t/is (= (:shape-ref shape5) (:id c-shape1)))
|
||||
(t/is (= (:name shape6) "Rect 1"))
|
||||
(t/is (= (:touched shape6) nil))
|
||||
(t/is (= (:shape-ref shape4) (:id c-shape2)))
|
||||
(t/is (= (:name instance2) "Rect 1"))
|
||||
(t/is (= (:touched instance2) nil))
|
||||
(t/is (= (:shape-ref instance2) (:id c-main1)))
|
||||
(t/is (= (:name shape3) "Rect 1"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (= (:shape-ref shape2) (:id c-shape1)))
|
||||
|
||||
(t/is (= component1 component2 component3))
|
||||
(t/is (= c-main1 main1))
|
||||
(t/is (= c-shape1 shape1))
|
||||
(t/is (= c-shape2 shape2))
|
||||
(t/is (= c-instance1 c-main1))
|
||||
(t/is (= c-shape3 c-shape1))
|
||||
(t/is (= c-shape4 c-shape2))
|
||||
(t/is (= c-instance2 c-main1))
|
||||
(t/is (= c-shape5 c-shape1))
|
||||
(t/is (= c-shape6 c-shape2)))))]
|
||||
(t/is (= component1 component2 component3))
|
||||
(t/is (= c-main1 main1))
|
||||
(t/is (= c-shape1 shape1))
|
||||
(t/is (= c-instance1 c-main1))
|
||||
(t/is (= c-shape2 c-shape1))
|
||||
(t/is (= c-instance2 c-main1))
|
||||
(t/is (= c-shape3 c-shape1)))))]
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape2)} (:id instance1) 0)
|
||||
(dwl/update-component-sync (:id instance1) (:id file))
|
||||
:the/end))))
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape2)} (:id instance1) 0) ;; We cant't change the structure of component copies, so this operation will do nothing
|
||||
(dwl/update-component-sync (:id instance1) (:id file))
|
||||
:the/end))))
|
||||
|
||||
(t/deftest test-update-children-delete
|
||||
(t/async done
|
||||
|
@ -1724,126 +1707,126 @@
|
|||
|
||||
(t/deftest test-update-children-move
|
||||
(t/async done
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"})
|
||||
(thp/sample-shape :shape2 :rect
|
||||
{:name "Rect 2"})
|
||||
(thp/sample-shape :shape3 :rect
|
||||
{:name "Rect 3"})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)
|
||||
(thp/id :shape2)
|
||||
(thp/id :shape3)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/instantiate-component :instance2
|
||||
(thp/id :component1)))
|
||||
(let [state (-> thp/initial-state
|
||||
(thp/sample-page)
|
||||
(thp/sample-shape :shape1 :rect
|
||||
{:name "Rect 1"})
|
||||
(thp/sample-shape :shape2 :rect
|
||||
{:name "Rect 2"})
|
||||
(thp/sample-shape :shape3 :rect
|
||||
{:name "Rect 3"})
|
||||
(thp/make-component :main1 :component1
|
||||
[(thp/id :shape1)
|
||||
(thp/id :shape2)
|
||||
(thp/id :shape3)])
|
||||
(thp/instantiate-component :instance1
|
||||
(thp/id :component1))
|
||||
(thp/instantiate-component :instance2
|
||||
(thp/id :component1)))
|
||||
|
||||
file (wsh/get-local-file state)
|
||||
file (wsh/get-local-file state)
|
||||
|
||||
[instance1 shape1' _shape2' _shape3']
|
||||
(thl/resolve-instance state (thp/id :instance1))
|
||||
[instance1 shape1' _shape2' _shape3']
|
||||
(thl/resolve-instance state (thp/id :instance1))
|
||||
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
store (the/prepare-store state done
|
||||
(fn [new-state]
|
||||
;; Expected shape tree:
|
||||
;;
|
||||
;; [Page]
|
||||
;; Root Frame
|
||||
;; Component 1
|
||||
;; Rect 2
|
||||
;; Rect 1
|
||||
;; Rect 2
|
||||
;; Rect 3
|
||||
;; Component 1 #--> Component 1
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 3 ---> Rect 3
|
||||
;; Component 1 #--> Component 1
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 1 ---> Rect 1
|
||||
;; Rect 2 ---> Rect 2
|
||||
;; Rect 3 ---> Rect 3
|
||||
;;
|
||||
;; [Component 1]
|
||||
;; page1 / Component 1
|
||||
;;
|
||||
(let [[[main1 shape1 shape2 shape3]
|
||||
[c-main1 c-shape1 c-shape2 c-shape3] component1]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :main1))
|
||||
(let [[[main1 shape1 shape2 shape3]
|
||||
[c-main1 c-shape1 c-shape2 c-shape3] component1]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :main1))
|
||||
|
||||
[[instance1 shape4 shape5 shape6]
|
||||
[c-instance1 c-shape4 c-shape5 c-shape6] component2]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance1))
|
||||
[[instance1 shape4 shape5 shape6]
|
||||
[c-instance1 c-shape4 c-shape5 c-shape6] component2]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance1))
|
||||
|
||||
[[instance2 shape7 shape8 shape9]
|
||||
[c-instance2 c-shape7 c-shape8 c-shape9] component3]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance2))]
|
||||
[[instance2 shape7 shape8 shape9]
|
||||
[c-instance2 c-shape7 c-shape8 c-shape9] component3]
|
||||
(thl/resolve-instance-and-main
|
||||
new-state
|
||||
(thp/id :instance2))]
|
||||
|
||||
(t/is (= (:name main1) "Component 1"))
|
||||
(t/is (= (:touched main1) nil))
|
||||
(t/is (= (:shape-ref main1) nil))
|
||||
(t/is (= (:name shape1) "Rect 2"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 1"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (= (:shape-ref shape2) nil))
|
||||
(t/is (= (:name shape3) "Rect 3"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (= (:shape-ref shape3) nil))
|
||||
(t/is (= (:name main1) "Component 1"))
|
||||
(t/is (= (:touched main1) nil))
|
||||
(t/is (= (:shape-ref main1) nil))
|
||||
(t/is (= (:name shape1) "Rect 1"))
|
||||
(t/is (= (:touched shape1) nil))
|
||||
(t/is (= (:shape-ref shape1) nil))
|
||||
(t/is (= (:name shape2) "Rect 2"))
|
||||
(t/is (= (:touched shape2) nil))
|
||||
(t/is (= (:shape-ref shape2) nil))
|
||||
(t/is (= (:name shape3) "Rect 3"))
|
||||
(t/is (= (:touched shape3) nil))
|
||||
(t/is (= (:shape-ref shape3) nil))
|
||||
|
||||
(t/is (= (:name instance1) "Component 1"))
|
||||
(t/is (= (:touched instance1) nil))
|
||||
(t/is (= (:shape-ref instance1) (:id c-main1)))
|
||||
(t/is (= (:name shape4) "Rect 2"))
|
||||
(t/is (= (:touched shape4) nil))
|
||||
(t/is (= (:shape-ref shape4) (:id c-shape1)))
|
||||
(t/is (= (:name shape5) "Rect 1"))
|
||||
(t/is (= (:touched shape5) nil))
|
||||
(t/is (= (:shape-ref shape5) (:id c-shape2)))
|
||||
(t/is (= (:name shape6) "Rect 3"))
|
||||
(t/is (= (:touched shape6) nil))
|
||||
(t/is (= (:shape-ref shape6) (:id c-shape3)))
|
||||
(t/is (= (:name instance1) "Component 1"))
|
||||
(t/is (= (:touched instance1) nil))
|
||||
(t/is (= (:shape-ref instance1) (:id c-main1)))
|
||||
(t/is (= (:name shape4) "Rect 1"))
|
||||
(t/is (= (:touched shape4) nil))
|
||||
(t/is (= (:shape-ref shape4) (:id c-shape1)))
|
||||
(t/is (= (:name shape5) "Rect 2"))
|
||||
(t/is (= (:touched shape5) nil))
|
||||
(t/is (= (:shape-ref shape5) (:id c-shape2)))
|
||||
(t/is (= (:name shape6) "Rect 3"))
|
||||
(t/is (= (:touched shape6) nil))
|
||||
(t/is (= (:shape-ref shape6) (:id c-shape3)))
|
||||
|
||||
(t/is (= (:name instance2) "Component 1"))
|
||||
(t/is (= (:touched instance2) nil))
|
||||
(t/is (= (:shape-ref instance2) (:id c-main1)))
|
||||
(t/is (= (:name shape7) "Rect 2"))
|
||||
(t/is (= (:touched shape7) nil))
|
||||
(t/is (= (:shape-ref shape7) (:id c-shape1)))
|
||||
(t/is (= (:name shape8) "Rect 1"))
|
||||
(t/is (= (:touched shape8) nil))
|
||||
(t/is (= (:shape-ref shape8) (:id c-shape2)))
|
||||
(t/is (= (:name shape9) "Rect 3"))
|
||||
(t/is (= (:touched shape9) nil))
|
||||
(t/is (= (:shape-ref shape9) (:id c-shape3)))
|
||||
(t/is (= (:name instance2) "Component 1"))
|
||||
(t/is (= (:touched instance2) nil))
|
||||
(t/is (= (:shape-ref instance2) (:id c-main1)))
|
||||
(t/is (= (:name shape7) "Rect 1"))
|
||||
(t/is (= (:touched shape7) nil))
|
||||
(t/is (= (:shape-ref shape7) (:id c-shape1)))
|
||||
(t/is (= (:name shape8) "Rect 2"))
|
||||
(t/is (= (:touched shape8) nil))
|
||||
(t/is (= (:shape-ref shape8) (:id c-shape2)))
|
||||
(t/is (= (:name shape9) "Rect 3"))
|
||||
(t/is (= (:touched shape9) nil))
|
||||
(t/is (= (:shape-ref shape9) (:id c-shape3)))
|
||||
|
||||
(t/is (= component1 component2 component3))
|
||||
(t/is (= c-main1 main1))
|
||||
(t/is (= c-shape1 shape1))
|
||||
(t/is (= c-shape2 shape2))
|
||||
(t/is (= c-shape3 shape3))
|
||||
(t/is (= c-instance1 c-main1))
|
||||
(t/is (= c-shape4 c-shape4))
|
||||
(t/is (= c-shape5 c-shape5))
|
||||
(t/is (= c-shape6 c-shape6))
|
||||
(t/is (= c-instance2 c-main1))
|
||||
(t/is (= c-shape7 c-shape7))
|
||||
(t/is (= c-shape8 c-shape8))
|
||||
(t/is (= c-shape9 c-shape9)))))]
|
||||
(t/is (= component1 component2 component3))
|
||||
(t/is (= c-main1 main1))
|
||||
(t/is (= c-shape1 shape1))
|
||||
(t/is (= c-shape2 shape2))
|
||||
(t/is (= c-shape3 shape3))
|
||||
(t/is (= c-instance1 c-main1))
|
||||
(t/is (= c-shape4 c-shape4))
|
||||
(t/is (= c-shape5 c-shape5))
|
||||
(t/is (= c-shape6 c-shape6))
|
||||
(t/is (= c-instance2 c-main1))
|
||||
(t/is (= c-shape7 c-shape7))
|
||||
(t/is (= c-shape8 c-shape8))
|
||||
(t/is (= c-shape9 c-shape9)))))]
|
||||
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape1')} (:id instance1) 2)
|
||||
(dwl/update-component-sync (:id instance1) (:id file))
|
||||
:the/end))))
|
||||
(ptk/emit!
|
||||
store
|
||||
(dw/relocate-shapes #{(:id shape1')} (:id instance1) 2)
|
||||
(dwl/update-component-sync (:id instance1) (:id file))
|
||||
:the/end))))
|
||||
|
||||
(t/deftest test-update-from-lib
|
||||
(t/async done
|
||||
|
|
|
@ -1673,6 +1673,9 @@ msgstr "(you)"
|
|||
msgid "labels.your-account"
|
||||
msgstr "Your account"
|
||||
|
||||
msgid "labels.search"
|
||||
msgstr "Search"
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "media.loading"
|
||||
msgstr "Loading image…"
|
||||
|
@ -3590,6 +3593,9 @@ msgstr "Edit an annotation"
|
|||
msgid "workspace.options.component.main"
|
||||
msgstr "Main"
|
||||
|
||||
|
||||
msgid "workspace.options.component.swap"
|
||||
msgstr "Swap component"
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
|
||||
msgid "workspace.options.constraints"
|
||||
msgstr "Constraints"
|
||||
|
|
|
@ -1725,6 +1725,9 @@ msgstr "(tú)"
|
|||
msgid "labels.your-account"
|
||||
msgstr "Tu cuenta"
|
||||
|
||||
msgid "labels.search"
|
||||
msgstr "Buscar"
|
||||
|
||||
#: src/app/main/data/workspace/persistence.cljs, src/app/main/data/media.cljs
|
||||
msgid "media.loading"
|
||||
msgstr "Cargando imagen…"
|
||||
|
@ -3666,6 +3669,9 @@ msgstr "Editar una nota"
|
|||
msgid "workspace.options.component.main"
|
||||
msgstr "Principal"
|
||||
|
||||
|
||||
msgid "workspace.options.component.swap"
|
||||
msgstr "Intercambiar componente"
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
|
||||
msgid "workspace.options.constraints"
|
||||
msgstr "Restricciones"
|
||||
|
|
Loading…
Add table
Reference in a new issue