mirror of
https://github.com/penpot/penpot.git
synced 2025-04-04 19:11:20 -05:00
🎉 Absorb colors and typographies
This commit is contained in:
parent
7da159d52a
commit
43e0b5cfa5
18 changed files with 644 additions and 223 deletions
|
@ -17,10 +17,12 @@
|
|||
[app.common.spec :as us]
|
||||
[app.common.pages.changes-spec :as pcs]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.colors-list :as ctcl]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]))
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typographies-list :as ctyl]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Specific helpers
|
||||
|
@ -309,7 +311,7 @@
|
|||
|
||||
(defmethod process-change :add-color
|
||||
[data {:keys [color]}]
|
||||
(update data :colors assoc (:id color) color))
|
||||
(ctcl/add-color data color))
|
||||
|
||||
(defmethod process-change :mod-color
|
||||
[data {:keys [color]}]
|
||||
|
@ -375,7 +377,7 @@
|
|||
|
||||
(defmethod process-change :add-typography
|
||||
[data {:keys [typography]}]
|
||||
(update data :typographies assoc (:id typography) typography))
|
||||
(ctyl/add-typography data typography))
|
||||
|
||||
(defmethod process-change :mod-typography
|
||||
[data {:keys [typography]}]
|
||||
|
|
|
@ -205,21 +205,6 @@
|
|||
([libraries library-id component-id]
|
||||
(get-in libraries [library-id :data :components component-id])))
|
||||
|
||||
(defn is-main-of?
|
||||
[shape-main shape-inst]
|
||||
(and (:shape-ref shape-inst)
|
||||
(or (= (:shape-ref shape-inst) (:id shape-main))
|
||||
(= (:shape-ref shape-inst) (:shape-ref shape-main)))))
|
||||
|
||||
(defn is-main-instance?
|
||||
[shape-id page-id component]
|
||||
(and (= shape-id (:main-instance-id component))
|
||||
(= page-id (:main-instance-page component))))
|
||||
|
||||
(defn get-component-root
|
||||
[component]
|
||||
(get-in component [:objects (:id component)]))
|
||||
|
||||
(defn get-component-shape
|
||||
"Get the parent shape linked to a component for this shape, if any"
|
||||
[objects shape]
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
|
@ -485,7 +486,7 @@
|
|||
add-instance-grid
|
||||
(fn [data components]
|
||||
(let [position-seq (ctst/generate-shape-grid
|
||||
(map cph/get-component-root components)
|
||||
(map ctk/get-component-root components)
|
||||
start-pos
|
||||
grid-gap)]
|
||||
(loop [data data
|
||||
|
|
|
@ -102,6 +102,12 @@
|
|||
:fill-opacity opacity
|
||||
:fill-color-gradient gradient)))))
|
||||
|
||||
(defn attach-fill-color
|
||||
[shape position ref-id ref-file]
|
||||
(-> shape
|
||||
(assoc-in [:fills position :fill-color-ref-id] ref-id)
|
||||
(assoc-in [:fills position :fill-color-ref-file] ref-file)))
|
||||
|
||||
(defn detach-fill-color
|
||||
[shape position]
|
||||
(-> shape
|
||||
|
@ -127,6 +133,12 @@
|
|||
:stroke-opacity opacity
|
||||
:stroke-color-gradient gradient)))))
|
||||
|
||||
(defn attach-stroke-color
|
||||
[shape position ref-id ref-file]
|
||||
(-> shape
|
||||
(assoc-in [:strokes position :stroke-color-ref-id] ref-id)
|
||||
(assoc-in [:strokes position :stroke-color-ref-file] ref-file)))
|
||||
|
||||
(defn detach-stroke-color
|
||||
[shape position]
|
||||
(-> shape
|
||||
|
@ -152,6 +164,12 @@
|
|||
:opacity opacity
|
||||
:gradient gradient)))))
|
||||
|
||||
(defn attach-shadow-color
|
||||
[shape position ref-id ref-file]
|
||||
(-> shape
|
||||
(assoc-in [:shadow position :color :id] ref-id)
|
||||
(assoc-in [:shadow position :color :file-id] ref-file)))
|
||||
|
||||
(defn detach-shadow-color
|
||||
[shape position]
|
||||
(-> shape
|
||||
|
@ -176,6 +194,11 @@
|
|||
:color color
|
||||
:opacity opacity
|
||||
:gradient gradient)))))
|
||||
(defn attach-grid-color
|
||||
[shape position ref-id ref-file]
|
||||
(-> shape
|
||||
(assoc-in [:grids position :params :color :id] ref-id)
|
||||
(assoc-in [:grids position :params :color :file-id] ref-file)))
|
||||
|
||||
(defn detach-grid-color
|
||||
[shape position]
|
||||
|
@ -213,11 +236,87 @@
|
|||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn uses-library-color?
|
||||
"Check if the shape uses the given library color."
|
||||
[shape library-id color]
|
||||
(let [all-colors (get-all-colors shape)]
|
||||
(some #(and (= (:ref-id %) (:id color))
|
||||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn- process-shape-colors
|
||||
"Execute an update function on all colors of a shape."
|
||||
[shape func]
|
||||
(let [process-fill (fn [shape [position fill]]
|
||||
(func shape
|
||||
position
|
||||
(fill->shape-color fill)
|
||||
set-fill-color
|
||||
attach-fill-color
|
||||
detach-fill-color))
|
||||
|
||||
process-stroke (fn [shape [position stroke]]
|
||||
(func shape
|
||||
position
|
||||
(stroke->shape-color stroke)
|
||||
set-stroke-color
|
||||
attach-stroke-color
|
||||
detach-stroke-color))
|
||||
|
||||
process-shadow (fn [shape [position shadow]]
|
||||
(func shape
|
||||
position
|
||||
(shadow->shape-color shadow)
|
||||
set-shadow-color
|
||||
attach-shadow-color
|
||||
detach-shadow-color))
|
||||
|
||||
process-grid (fn [shape [position grid]]
|
||||
(func shape
|
||||
position
|
||||
(grid->shape-color grid)
|
||||
set-grid-color
|
||||
attach-grid-color
|
||||
detach-grid-color))
|
||||
|
||||
process-text-node (fn [node]
|
||||
(as-> node $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))))
|
||||
|
||||
process-text (fn [shape]
|
||||
(let [content (:content shape)
|
||||
new-content (txt/transform-nodes process-text-node content)]
|
||||
(if (not= content new-content)
|
||||
(assoc shape :content new-content)
|
||||
shape)))]
|
||||
|
||||
(as-> shape $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))
|
||||
(reduce process-shadow $ (d/enumerate (:shadow $)))
|
||||
(reduce process-grid $ (d/enumerate (:grids $)))
|
||||
(process-text $))))
|
||||
|
||||
(defn remap-colors
|
||||
"Change the shape so that any use of the given color now points to
|
||||
the given library."
|
||||
[shape library-id color]
|
||||
(let [remap-color (fn [shape position shape-color _ attach-fn _]
|
||||
(if (= (:ref-id shape-color) (:id color))
|
||||
(attach-fn shape
|
||||
position
|
||||
(:id color)
|
||||
library-id)
|
||||
shape))]
|
||||
|
||||
(process-shape-colors shape remap-color)))
|
||||
|
||||
(defn sync-shape-colors
|
||||
"Look for usage of any color of the given library inside the shape,
|
||||
and, in this case, copy the library color into the shape."
|
||||
[shape library-id library-colors]
|
||||
(let [sync-color (fn [shape position shape-color set-fn detach-fn]
|
||||
(let [sync-color (fn [shape position shape-color set-fn _ detach-fn]
|
||||
(if (= (:ref-file shape-color) library-id)
|
||||
(let [library-color (get library-colors (:ref-id shape-color))]
|
||||
(if (some? library-color)
|
||||
|
@ -227,51 +326,7 @@
|
|||
(:opacity library-color)
|
||||
(:gradient library-color))
|
||||
(detach-fn shape position)))
|
||||
shape))
|
||||
shape))]
|
||||
|
||||
sync-fill (fn [shape [position fill]]
|
||||
(sync-color shape
|
||||
position
|
||||
(fill->shape-color fill)
|
||||
set-fill-color
|
||||
detach-fill-color))
|
||||
(process-shape-colors shape sync-color)))
|
||||
|
||||
sync-stroke (fn [shape [position stroke]]
|
||||
(sync-color shape
|
||||
position
|
||||
(stroke->shape-color stroke)
|
||||
set-stroke-color
|
||||
detach-stroke-color))
|
||||
|
||||
sync-shadow (fn [shape [position shadow]]
|
||||
(sync-color shape
|
||||
position
|
||||
(shadow->shape-color shadow)
|
||||
set-shadow-color
|
||||
detach-shadow-color))
|
||||
|
||||
sync-grid (fn [shape [position grid]]
|
||||
(sync-color shape
|
||||
position
|
||||
(grid->shape-color grid)
|
||||
set-grid-color
|
||||
detach-grid-color))
|
||||
|
||||
sync-text-node (fn [node]
|
||||
(as-> node $
|
||||
(reduce sync-fill $ (d/enumerate (:fills $)))
|
||||
(reduce sync-stroke $ (d/enumerate (:strokes $)))))
|
||||
|
||||
sync-text (fn [shape]
|
||||
(let [content (:content shape)
|
||||
new-content (txt/transform-nodes sync-text-node content)]
|
||||
(if (not= content new-content)
|
||||
(assoc shape :content new-content)
|
||||
shape)))]
|
||||
|
||||
(as-> shape $
|
||||
(reduce sync-fill $ (d/enumerate (:fills $)))
|
||||
(reduce sync-stroke $ (d/enumerate (:strokes $)))
|
||||
(reduce sync-shadow $ (d/enumerate (:shadow $)))
|
||||
(reduce sync-grid $ (d/enumerate (:grids $)))
|
||||
(sync-text $))))
|
||||
|
|
26
common/src/app/common/types/colors_list.cljc
Normal file
26
common/src/app/common/types/colors_list.cljc
Normal file
|
@ -0,0 +1,26 @@
|
|||
;; 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) UXBOX Labs SL
|
||||
|
||||
(ns app.common.types.colors-list
|
||||
(:require
|
||||
[app.common.data :as d]))
|
||||
|
||||
(defn colors-seq
|
||||
[file-data]
|
||||
(vals (:colors file-data)))
|
||||
|
||||
(defn add-color
|
||||
[file-data color]
|
||||
(update file-data :colors assoc (:id color) color))
|
||||
|
||||
(defn get-color
|
||||
[file-data color-id]
|
||||
(get-in file-data [:colors color-id]))
|
||||
|
||||
(defn update-color
|
||||
[file-data color-id f]
|
||||
(update-in file-data [:colors color-id] f))
|
||||
|
|
@ -7,7 +7,24 @@
|
|||
(ns app.common.types.component)
|
||||
|
||||
(defn instance-of?
|
||||
[shape component]
|
||||
[shape file-id component]
|
||||
(and (some? (:component-id shape))
|
||||
(= (:component-id shape) (:id component))))
|
||||
(some? (:component-file shape))
|
||||
(= (:component-id shape) (:id component))
|
||||
(= (:component-file shape) file-id)))
|
||||
|
||||
(defn is-main-of?
|
||||
[shape-main shape-inst]
|
||||
(and (:shape-ref shape-inst)
|
||||
(or (= (:shape-ref shape-inst) (:id shape-main))
|
||||
(= (:shape-ref shape-inst) (:shape-ref shape-main)))))
|
||||
|
||||
(defn is-main-instance?
|
||||
[shape-id page-id component]
|
||||
(and (= shape-id (:main-instance-id component))
|
||||
(= page-id (:main-instance-page component))))
|
||||
|
||||
(defn get-component-root
|
||||
[component]
|
||||
(get-in component [:objects (:id component)]))
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
(s/def ::path (s/nilable string?))
|
||||
|
||||
(s/def ::container
|
||||
(s/keys :req-un [::id ::name ::ctst/objects]
|
||||
;; (s/keys :req-un [::id ::name ::ctst/objects]
|
||||
(s/keys :req-un [::id ::name]
|
||||
:opt-un [::type ::path]))
|
||||
|
||||
(defn make-container
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.colors-list :as ctcl]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typography :as cty]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]))
|
||||
|
@ -91,6 +94,10 @@
|
|||
|
||||
;; Helpers
|
||||
|
||||
(defn file-data
|
||||
[file]
|
||||
(:data file))
|
||||
|
||||
(defn update-file-data
|
||||
[file f]
|
||||
(update file :data f))
|
||||
|
@ -108,19 +115,51 @@
|
|||
(ctpl/update-page file-data (:id container) f)
|
||||
(ctkl/update-component file-data (:id container) f)))
|
||||
|
||||
(defn find-instances
|
||||
"Find all uses of a component in a file (may be in pages or in the components
|
||||
of the local library).
|
||||
|
||||
Returns a vector [[container shapes] [container shapes]...]"
|
||||
[file-data component]
|
||||
(let [find-instances-in-container
|
||||
(fn [container component]
|
||||
(let [instances (filter #(ctk/instance-of? % component) (ctn/shapes-seq container))]
|
||||
(when (d/not-empty? instances)
|
||||
[[container instances]])))]
|
||||
;; Asset helpers
|
||||
|
||||
(mapcat #(find-instances-in-container % component) (containers-seq file-data))))
|
||||
(defmulti uses-asset?
|
||||
"Checks if a shape uses the given asset."
|
||||
(fn [asset-type _ _ _] asset-type))
|
||||
|
||||
(defmethod uses-asset? :component
|
||||
[_ shape library-id component]
|
||||
(ctk/instance-of? shape library-id component))
|
||||
|
||||
(defmethod uses-asset? :color
|
||||
[_ shape library-id color]
|
||||
(ctc/uses-library-color? shape library-id color))
|
||||
|
||||
(defmethod uses-asset? :typography
|
||||
[_ shape library-id typography]
|
||||
(cty/uses-library-typography? shape library-id typography))
|
||||
|
||||
(defn find-asset-type-usages
|
||||
"Find all usages of an asset in a file (may be in pages or in the components
|
||||
of the local library).
|
||||
|
||||
Returns a list ((asset ((container shapes) (container shapes)...))...)"
|
||||
[file-data library-data asset-type]
|
||||
(let [assets-seq (case asset-type
|
||||
:component (ctkl/components-seq library-data)
|
||||
:color (ctcl/colors-seq library-data)
|
||||
:typography (ctyl/typographies-seq library-data))
|
||||
|
||||
find-usages-in-container
|
||||
(fn [container asset]
|
||||
(let [instances (filter #(uses-asset? asset-type % (:id library-data) asset)
|
||||
(ctn/shapes-seq container))]
|
||||
(when (d/not-empty? instances)
|
||||
[[container instances]])))
|
||||
|
||||
find-asset-usages
|
||||
(fn [file-data library-id asset-type asset]
|
||||
(mapcat #(find-usages-in-container % asset) (containers-seq file-data)))]
|
||||
|
||||
(mapcat (fn [asset]
|
||||
(let [instances (find-asset-usages file-data (:id library-data) asset-type asset)]
|
||||
(when (d/not-empty? instances)
|
||||
[[asset instances]])))
|
||||
assets-seq)))
|
||||
|
||||
(defn get-or-add-library-page
|
||||
[file-data grid-gap]
|
||||
|
@ -276,95 +315,20 @@
|
|||
"Find all assets of a library that are used in the file, and
|
||||
move them to the file local library."
|
||||
[file-data library-data]
|
||||
(let [; Build a list of all components in the library used in the file
|
||||
; The list is in the form [[component [[container shapes] [container shapes]...]]...]
|
||||
used-components ; A vector of pair [component instances], where instances is non-empty
|
||||
(mapcat (fn [component]
|
||||
(let [instances (find-instances file-data component)]
|
||||
(when (d/not-empty? instances)
|
||||
[[component instances]])))
|
||||
(ctkl/components-seq library-data))]
|
||||
(let [used-components (find-asset-type-usages file-data library-data :component)
|
||||
used-colors (find-asset-type-usages file-data library-data :color)
|
||||
used-typographies (find-asset-type-usages file-data library-data :typography)]
|
||||
|
||||
(if (empty? used-components)
|
||||
file-data
|
||||
(let [; Search for the library page. If not exists, create it.
|
||||
[file-data page-id start-pos]
|
||||
(get-or-add-library-page file-data)
|
||||
(cond-> file-data
|
||||
(d/not-empty? used-components)
|
||||
(absorb-components library-data used-components)
|
||||
|
||||
absorb-component
|
||||
(fn [file-data [component instances] position]
|
||||
(let [page (ctpl/get-page file-data page-id)
|
||||
(d/not-empty? used-colors)
|
||||
(absorb-colors library-data used-colors)
|
||||
|
||||
; Make a new main instance for the component
|
||||
[main-instance-shape main-instance-shapes]
|
||||
(ctn/instantiate-component page
|
||||
component
|
||||
(:id file-data)
|
||||
position)
|
||||
(d/not-empty? used-typographies)
|
||||
(absorb-typographies library-data used-typographies))))
|
||||
|
||||
; Add all shapes of the main instance to the library page
|
||||
add-main-instance-shapes
|
||||
(fn [page]
|
||||
(reduce (fn [page shape]
|
||||
(ctst/add-shape (:id shape)
|
||||
shape
|
||||
page
|
||||
(:frame-id shape)
|
||||
(:parent-id shape)
|
||||
nil ; <- As shapes are ordered, we can safely add each
|
||||
true)) ; one at the end of the parent's children list.
|
||||
page
|
||||
main-instance-shapes))
|
||||
|
||||
; Copy the component in the file local library
|
||||
copy-component
|
||||
(fn [file-data]
|
||||
(ctkl/add-component file-data
|
||||
(:id component)
|
||||
(:name component)
|
||||
(:path component)
|
||||
(:id main-instance-shape)
|
||||
page-id
|
||||
(vals (:objects component))))
|
||||
|
||||
; Change all existing instances to point to the local file
|
||||
redirect-instances
|
||||
(fn [file-data [container shapes]]
|
||||
(let [redirect-instance #(assoc % :component-file (:id file-data))]
|
||||
(update-container file-data
|
||||
container
|
||||
#(reduce (fn [container shape]
|
||||
(ctn/update-shape container
|
||||
(:id shape)
|
||||
redirect-instance))
|
||||
%
|
||||
shapes))))]
|
||||
|
||||
(as-> file-data $
|
||||
(ctpl/update-page $ page-id add-main-instance-shapes)
|
||||
(copy-component $)
|
||||
(reduce redirect-instances $ instances))))
|
||||
|
||||
; Absorb all used components into the local library. Position
|
||||
; the main instances in a grid in the library page.
|
||||
add-component-grid
|
||||
(fn [data used-components]
|
||||
(let [position-seq (ctst/generate-shape-grid
|
||||
(map #(cph/get-component-root (first %)) used-components)
|
||||
start-pos
|
||||
50)]
|
||||
(loop [data data
|
||||
components-seq (seq used-components)
|
||||
position-seq position-seq]
|
||||
(let [used-component (first components-seq)
|
||||
position (first position-seq)]
|
||||
(if (nil? used-component)
|
||||
data
|
||||
(recur (absorb-component data used-component position)
|
||||
(rest components-seq)
|
||||
(rest position-seq)))))))]
|
||||
|
||||
(add-component-grid file-data (sort-by #(:name (first %)) used-components))))))
|
||||
|
||||
;; Debug helpers
|
||||
|
||||
|
|
26
common/src/app/common/types/typographies_list.cljc
Normal file
26
common/src/app/common/types/typographies_list.cljc
Normal file
|
@ -0,0 +1,26 @@
|
|||
;; 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) UXBOX Labs SL
|
||||
|
||||
(ns app.common.types.typographies-list
|
||||
(:require
|
||||
[app.common.data :as d]))
|
||||
|
||||
(defn typographies-seq
|
||||
[file-data]
|
||||
(vals (:typographies file-data)))
|
||||
|
||||
(defn add-typography
|
||||
[file-data typography]
|
||||
(update file-data :typographies assoc (:id typography) typography))
|
||||
|
||||
(defn get-typography
|
||||
[file-data typography-id]
|
||||
(get-in file-data [:typographies typography-id]))
|
||||
|
||||
(defn update-typography
|
||||
[file-data typography-id f]
|
||||
(update-in file-data [:typographies typography-id] f))
|
||||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
(ns app.common.types.typography
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]))
|
||||
[app.common.text :as txt]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
||||
(s/def ::id uuid?)
|
||||
(s/def ::name string?)
|
||||
|
@ -35,4 +36,37 @@
|
|||
::text-transform]
|
||||
:opt-un [::path]))
|
||||
|
||||
(defn uses-library-typographies?
|
||||
"Check if the shape uses any typography in the given library."
|
||||
[shape library-id]
|
||||
(and (= (:type shape) :text)
|
||||
(->> shape
|
||||
:content
|
||||
;; Check if any node in the content has a reference for the library
|
||||
(txt/node-seq
|
||||
#(and (some? (:typography-ref-id %))
|
||||
(= (:typography-ref-file %) library-id))))))
|
||||
|
||||
(defn uses-library-typography?
|
||||
"Check if the shape uses the given library typography."
|
||||
[shape library-id typography]
|
||||
(and (= (:type shape) :text)
|
||||
(->> shape
|
||||
:content
|
||||
;; Check if any node in the content has a reference for the library
|
||||
(txt/node-seq
|
||||
#(and (= (:typography-ref-id %) (:id typography))
|
||||
(= (:typography-ref-file %) library-id))))))
|
||||
|
||||
(defn remap-typographies
|
||||
"Change the shape so that any use of the given typography now points to
|
||||
the given library."
|
||||
[shape library-id typography]
|
||||
(let [remap-typography #(assoc % :typography-ref-file library-id)]
|
||||
|
||||
(update shape :content
|
||||
(fn [content]
|
||||
(txt/transform-nodes #(= (:typography-ref-id %) (:id typography))
|
||||
remap-typography
|
||||
content)))))
|
||||
|
||||
|
|
150
common/test/app/common/test_helpers/components.cljc
Normal file
150
common/test/app/common/test_helpers/components.cljc
Normal file
|
@ -0,0 +1,150 @@
|
|||
(ns app.common.test-helpers.components
|
||||
(:require
|
||||
[cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]))
|
||||
|
||||
;; ---- Helpers to manage libraries and synchronization
|
||||
|
||||
(defn check-instance-root
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (some? (:component-id shape)))
|
||||
(t/is (= (:component-root? shape) true)))
|
||||
|
||||
(defn check-instance-subroot
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (some? (:component-id shape)))
|
||||
(t/is (nil? (:component-root? shape))))
|
||||
|
||||
(defn check-instance-child
|
||||
[shape]
|
||||
(t/is (some? (:shape-ref shape)))
|
||||
(t/is (nil? (:component-id shape)))
|
||||
(t/is (nil? (:component-file shape)))
|
||||
(t/is (nil? (:component-root? shape))))
|
||||
|
||||
(defn check-instance-inner
|
||||
[shape]
|
||||
(if (some? (:component-id shape))
|
||||
(check-instance-subroot shape)
|
||||
(check-instance-child shape)))
|
||||
|
||||
(defn check-noninstance
|
||||
[shape]
|
||||
(t/is (nil? (:shape-ref shape)))
|
||||
(t/is (nil? (:component-id shape)))
|
||||
(t/is (nil? (:component-file shape)))
|
||||
(t/is (nil? (:component-root? shape)))
|
||||
(t/is (nil? (:remote-synced? shape)))
|
||||
(t/is (nil? (:touched shape))))
|
||||
|
||||
(defn check-from-file
|
||||
[shape file]
|
||||
(t/is (= (:component-file shape)
|
||||
(:id file))))
|
||||
|
||||
(defn resolve-instance
|
||||
"Get the shape with the given id and all its children, and
|
||||
verify that they are a well constructed instance tree."
|
||||
[page root-inst-id]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
shapes-inst (cph/get-children-with-self (:objects page)
|
||||
root-inst-id)]
|
||||
(check-instance-root (first shapes-inst))
|
||||
(run! check-instance-inner (rest shapes-inst))
|
||||
|
||||
shapes-inst))
|
||||
|
||||
(defn resolve-noninstance
|
||||
"Get the shape with the given id and all its children, and
|
||||
verify that they are not a component instance."
|
||||
[page root-inst-id]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
shapes-inst (cph/get-children-with-self (:objects page)
|
||||
root-inst-id)]
|
||||
(run! check-noninstance shapes-inst)
|
||||
|
||||
shapes-inst))
|
||||
|
||||
(defn resolve-instance-and-main
|
||||
"Get the shape with the given id and all its children, and also
|
||||
the main component and all its shapes."
|
||||
[page root-inst-id libraries]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
|
||||
component (cph/get-component libraries (:component-id root-inst))
|
||||
|
||||
shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)
|
||||
shapes-main (cph/get-children-with-self (:objects component) (:shape-ref root-inst))
|
||||
|
||||
unique-refs (into #{} (map :shape-ref) shapes-inst)
|
||||
|
||||
main-exists? (fn [shape]
|
||||
(let [component-shape
|
||||
(cph/get-component-shape (:objects page) shape)
|
||||
|
||||
component
|
||||
(cph/get-component libraries (:component-id component-shape))
|
||||
|
||||
main-shape
|
||||
(ctn/get-shape component (:shape-ref shape))]
|
||||
|
||||
(t/is (some? main-shape))))]
|
||||
|
||||
;; Validate that the instance tree is well constructed
|
||||
(check-instance-root (first shapes-inst))
|
||||
(run! check-instance-inner (rest shapes-inst))
|
||||
(t/is (= (count shapes-inst)
|
||||
(count shapes-main)
|
||||
(count unique-refs)))
|
||||
(run! main-exists? shapes-inst)
|
||||
|
||||
[shapes-inst shapes-main component]))
|
||||
|
||||
(defn resolve-instance-and-main-allow-dangling
|
||||
"Get the shape with the given id and all its children, and also
|
||||
the main component and all its shapes. Allows shapes with the
|
||||
corresponding component shape missing."
|
||||
[page root-inst-id libraries]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
|
||||
component (cph/get-component libraries (:component-id root-inst))
|
||||
|
||||
shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)
|
||||
shapes-main (cph/get-children-with-self (:objects component) (:shape-ref root-inst))
|
||||
|
||||
unique-refs (into #{} (map :shape-ref) shapes-inst)
|
||||
|
||||
main-exists? (fn [shape]
|
||||
(let [component-shape
|
||||
(cph/get-component-shape (:objects page) shape)
|
||||
|
||||
component
|
||||
(cph/get-component libraries (:component-id component-shape))
|
||||
|
||||
main-shape
|
||||
(ctn/get-shape component (:shape-ref shape))]
|
||||
|
||||
(t/is (some? main-shape))))]
|
||||
|
||||
;; Validate that the instance tree is well constructed
|
||||
(check-instance-root (first shapes-inst))
|
||||
|
||||
[shapes-inst shapes-main component]))
|
||||
|
||||
(defn resolve-component
|
||||
"Get the component with the given id and all its shapes."
|
||||
[page component-id libraries]
|
||||
(let [component (cph/get-component libraries component-id)
|
||||
root-main (ctk/get-component-root component)
|
||||
shapes-main (cph/get-children-with-self (:objects component) (:id root-main))]
|
||||
|
||||
;; Validate that the component tree is well constructed
|
||||
(run! check-noninstance shapes-main)
|
||||
|
||||
[shapes-main component]))
|
||||
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
(ns app.common.test-helpers.files
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]))
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.colors-list :as ctcl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
(def ^:private idmap (atom {}))
|
||||
|
||||
|
@ -108,3 +110,38 @@
|
|||
%
|
||||
instance-shapes)))))))
|
||||
|
||||
(defn sample-color
|
||||
[file label props]
|
||||
(ctf/update-file-data
|
||||
file
|
||||
(fn [file-data]
|
||||
(let [id (uuid/next)
|
||||
props (merge {:id id
|
||||
:name "Color-1"
|
||||
:color "#000000"
|
||||
:opacity 1}
|
||||
props)]
|
||||
(swap! idmap assoc label id)
|
||||
(ctcl/add-color file-data props)))))
|
||||
|
||||
(defn sample-typography
|
||||
[file label props]
|
||||
(ctf/update-file-data
|
||||
file
|
||||
(fn [file-data]
|
||||
(let [id (uuid/next)
|
||||
props (merge {:id id
|
||||
:name "Typography-1"
|
||||
:font-id "sourcesanspro"
|
||||
:font-family "sourcesanspro"
|
||||
:font-size "14"
|
||||
:font-style "normal"
|
||||
:font-variant-id "regular"
|
||||
:font-weight "400"
|
||||
:line-height "1.2"
|
||||
:letter-spacing "0"
|
||||
:text-transform "none"}
|
||||
props)]
|
||||
(swap! idmap assoc label id)
|
||||
(ctyl/add-typography file-data props)))))
|
||||
|
||||
|
|
|
@ -6,25 +6,30 @@
|
|||
|
||||
(ns app.common.types.file-test
|
||||
(:require
|
||||
[clojure.test :as t]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.test-helpers.files :as thf]
|
||||
|
||||
[app.common.data :as d]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[cuerdas.core :as str]
|
||||
))
|
||||
;; Uncomment to debug
|
||||
;; [clojure.pprint :refer [pprint]]
|
||||
;; [cuerdas.core :as str]
|
||||
[clojure.test :as t]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.colors-list :as ctcl]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.components :as thk]))
|
||||
|
||||
(t/use-fixtures :each
|
||||
{:before thf/reset-idmap!})
|
||||
|
||||
(t/deftest test-absorb-assets
|
||||
(t/deftest test-absorb-components
|
||||
(let [library-id (uuid/custom 1 1)
|
||||
library-page-id (uuid/custom 2 2)
|
||||
file-id (uuid/custom 3 3)
|
||||
|
@ -52,7 +57,26 @@
|
|||
|
||||
absorbed-file (ctf/update-file-data
|
||||
file
|
||||
#(ctf/absorb-assets % (:data library)))]
|
||||
#(ctf/absorb-assets % (:data library)))
|
||||
|
||||
pages (ctpl/pages-seq (ctf/file-data absorbed-file))
|
||||
components (ctkl/components-seq (ctf/file-data absorbed-file))
|
||||
shapes-1 (ctn/shapes-seq (first pages))
|
||||
shapes-2 (ctn/shapes-seq (second pages))
|
||||
|
||||
[[p-group p-shape] [c-group1 c-shape1] component1]
|
||||
(thk/resolve-instance-and-main
|
||||
(first pages)
|
||||
(:id (second shapes-1))
|
||||
{file-id absorbed-file})
|
||||
|
||||
[[lp-group lp-shape] [c-group2 c-shape2] component2]
|
||||
(thk/resolve-instance-and-main
|
||||
(second pages)
|
||||
(:id (second shapes-2))
|
||||
{file-id absorbed-file})]
|
||||
|
||||
;; Uncomment to debug
|
||||
|
||||
;; (println "\n===== library")
|
||||
;; (ctf/dump-tree (:data library)
|
||||
|
@ -67,11 +91,118 @@
|
|||
;; true)
|
||||
|
||||
;; (println "\n===== absorbed file")
|
||||
;; (println (str "\n<" (:name (first pages)) ">"))
|
||||
;; (ctf/dump-tree (:data absorbed-file)
|
||||
;; file-page-id
|
||||
;; {}
|
||||
;; true)
|
||||
;; (:id (first pages))
|
||||
;; {file-id absorbed-file}
|
||||
;; false)
|
||||
;; (println (str "\n<" (:name (second pages)) ">"))
|
||||
;; (ctf/dump-tree (:data absorbed-file)
|
||||
;; (:id (second pages))
|
||||
;; {file-id absorbed-file}
|
||||
;; false)
|
||||
|
||||
(t/is (= library-id (:id library)))
|
||||
(t/is (= file-id (:id absorbed-file)))))
|
||||
(t/is (= (count pages) 2))
|
||||
(t/is (= (:name (first pages)) "Page-1"))
|
||||
(t/is (= (:name (second pages)) "Library page"))
|
||||
|
||||
(t/is (= (count components) 1))
|
||||
|
||||
(t/is (= (:name p-group) "Group1"))
|
||||
(t/is (ctk/instance-of? p-group file-id component1))
|
||||
(t/is (not (ctk/is-main-instance? (:id p-group) file-page-id component1)))
|
||||
(t/is (ctk/is-main-of? c-group1 p-group))
|
||||
|
||||
(t/is (= (:name p-shape) "Rect1"))
|
||||
(t/is (ctk/is-main-of? c-shape1 p-shape))))
|
||||
|
||||
|
||||
(t/deftest test-absorb-colors
|
||||
(let [library-id (uuid/custom 1 1)
|
||||
library-page-id (uuid/custom 2 2)
|
||||
file-id (uuid/custom 3 3)
|
||||
file-page-id (uuid/custom 4 4)
|
||||
|
||||
library (-> (thf/sample-file library-id library-page-id {:is-shared true})
|
||||
(thf/sample-color :color1 {:name "Test color"
|
||||
:color "#abcdef"}))
|
||||
|
||||
file (-> (thf/sample-file file-id file-page-id)
|
||||
(thf/sample-shape :shape1
|
||||
:rect
|
||||
file-page-id
|
||||
{:name "Rect1"
|
||||
:fills [{:fill-color "#abcdef"
|
||||
:fill-opacity 1
|
||||
:fill-color-ref-id (thf/id :color1)
|
||||
:fill-color-ref-file library-id}]}))
|
||||
|
||||
absorbed-file (ctf/update-file-data
|
||||
file
|
||||
#(ctf/absorb-assets % (:data library)))
|
||||
|
||||
colors (ctcl/colors-seq (ctf/file-data absorbed-file))
|
||||
page (ctpl/get-page (ctf/file-data absorbed-file) file-page-id)
|
||||
shape1 (ctn/get-shape page (thf/id :shape1))
|
||||
fill (first (:fills shape1))]
|
||||
|
||||
(t/is (= (count colors) 1))
|
||||
(t/is (= (:id (first colors)) (thf/id :color1)))
|
||||
(t/is (= (:name (first colors)) "Test color"))
|
||||
(t/is (= (:color (first colors)) "#abcdef"))
|
||||
|
||||
(t/is (= (:fill-color fill) "#abcdef"))
|
||||
(t/is (= (:fill-color-ref-id fill) (thf/id :color1)))
|
||||
(t/is (= (:fill-color-ref-file fill) file-id))))
|
||||
|
||||
(t/deftest test-absorb-typographies
|
||||
(let [library-id (uuid/custom 1 1)
|
||||
library-page-id (uuid/custom 2 2)
|
||||
file-id (uuid/custom 3 3)
|
||||
file-page-id (uuid/custom 4 4)
|
||||
|
||||
library (-> (thf/sample-file library-id library-page-id {:is-shared true})
|
||||
(thf/sample-typography :typography1 {:name "Test typography"}))
|
||||
|
||||
file (-> (thf/sample-file file-id file-page-id)
|
||||
(thf/sample-shape :shape1
|
||||
:text
|
||||
file-page-id
|
||||
{:name "Text1"
|
||||
:content {:type "root"
|
||||
:children [{:type "paragraph-set"
|
||||
:children [{:type "paragraph"
|
||||
:key "67uep"
|
||||
:children [{:text "Example text"
|
||||
:typography-ref-id (thf/id :typography1)
|
||||
:typography-ref-file library-id
|
||||
:line-height "1.2"
|
||||
:font-style "normal"
|
||||
:text-transform "none"
|
||||
:text-align "left"
|
||||
:font-id "sourcesanspro"
|
||||
:font-family "sourcesanspro"
|
||||
:font-size "14"
|
||||
:font-weight "400"
|
||||
:font-variant-id "regular"
|
||||
:text-decoration "none"
|
||||
:letter-spacing "0"
|
||||
:fills [{:fill-color "#000000"
|
||||
:fill-opacity 1}]}]
|
||||
}]}]}}))
|
||||
absorbed-file (ctf/update-file-data
|
||||
file
|
||||
#(ctf/absorb-assets % (:data library)))
|
||||
|
||||
typographies (ctyl/typographies-seq (ctf/file-data absorbed-file))
|
||||
page (ctpl/get-page (ctf/file-data absorbed-file) file-page-id)
|
||||
shape1 (ctn/get-shape page (thf/id :shape1))
|
||||
text-node (d/seek #(some? (:text %)) (txt/node-seq (:content shape1)))]
|
||||
|
||||
(t/is (= (count typographies) 1))
|
||||
(t/is (= (:id (first typographies)) (thf/id :typography1)))
|
||||
(t/is (= (:name (first typographies)) "Test typography"))
|
||||
|
||||
(t/is (= (:typography-ref-id text-node) (thf/id :typography1)))
|
||||
(t/is (= (:typography-ref-file text-node) file-id))))
|
||||
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
[app.common.spec :as us]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.typography :as cty]
|
||||
[app.main.data.workspace.groups :as dwg]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[cljs.spec.alpha :as s]
|
||||
|
@ -94,7 +96,7 @@
|
|||
(let [position (gpt/add (gpt/point (:x main-instance-shape) (:y main-instance-shape))
|
||||
(gpt/point (+ (:width main-instance-shape) 50) 0))
|
||||
|
||||
component-root (cph/get-component-root component)
|
||||
component-root (ctk/get-component-root component)
|
||||
|
||||
[new-component-shape new-component-shapes _]
|
||||
(ctst/clone-object component-root
|
||||
|
@ -243,13 +245,7 @@
|
|||
|
||||
(defmethod uses-assets? :typographies
|
||||
[_ shape library-id _]
|
||||
(and (= (:type shape) :text)
|
||||
(->> shape
|
||||
:content
|
||||
;; Check if any node in the content has a reference for the library
|
||||
(txt/node-seq
|
||||
#(and (some? (:typography-ref-id %))
|
||||
(= (:typography-ref-file %) library-id))))))
|
||||
(cty/uses-library-typographies? shape library-id))
|
||||
|
||||
(defmulti generate-sync-shape
|
||||
"Generate changes to synchronize one shape from all assets of the given type
|
||||
|
@ -433,7 +429,7 @@
|
|||
|
||||
root-inst shape-inst
|
||||
root-main (when component
|
||||
(cph/get-component-root component))]
|
||||
(ctk/get-component-root component))]
|
||||
|
||||
(if component
|
||||
(generate-sync-shape-direct-recursive changes
|
||||
|
@ -557,7 +553,7 @@
|
|||
initial-root? (:component-root? shape-inst)
|
||||
|
||||
root-inst shape-inst
|
||||
root-main (cph/get-component-root component)]
|
||||
root-main (ctk/get-component-root component)]
|
||||
|
||||
(if component
|
||||
(generate-sync-shape-inverse-recursive changes
|
||||
|
@ -691,13 +687,13 @@
|
|||
(reduce only-inst-cb changes children-inst)
|
||||
|
||||
:else
|
||||
(if (cph/is-main-of? child-main child-inst)
|
||||
(if (ctk/is-main-of? child-main child-inst)
|
||||
(recur (next children-inst)
|
||||
(next children-main)
|
||||
(both-cb changes child-inst child-main))
|
||||
|
||||
(let [child-inst' (d/seek #(cph/is-main-of? child-main %) children-inst)
|
||||
child-main' (d/seek #(cph/is-main-of? % child-inst) children-main)]
|
||||
(let [child-inst' (d/seek #(ctk/is-main-of? child-main %) children-inst)
|
||||
child-main' (d/seek #(ctk/is-main-of? % child-inst) children-main)]
|
||||
(cond
|
||||
(nil? child-inst')
|
||||
(recur children-inst
|
||||
|
@ -726,7 +722,7 @@
|
|||
[changes component-shape index component container root-instance root-main omit-touched? set-remote-synced?]
|
||||
(log/info :msg (str "ADD [P] " (:name component-shape)))
|
||||
(let [component-parent-shape (ctn/get-shape component (:parent-id component-shape))
|
||||
parent-shape (d/seek #(cph/is-main-of? component-parent-shape %)
|
||||
parent-shape (d/seek #(ctk/is-main-of? component-parent-shape %)
|
||||
(cph/get-children-with-self (:objects container)
|
||||
(:id root-instance)))
|
||||
all-parents (into [(:id parent-shape)]
|
||||
|
@ -794,7 +790,7 @@
|
|||
[changes shape index component page root-instance root-main]
|
||||
(log/info :msg (str "ADD [C] " (:name shape)))
|
||||
(let [parent-shape (ctn/get-shape page (:parent-id shape))
|
||||
component-parent-shape (d/seek #(cph/is-main-of? % parent-shape)
|
||||
component-parent-shape (d/seek #(ctk/is-main-of? % parent-shape)
|
||||
(cph/get-children-with-self (:objects component)
|
||||
(:id root-main)))
|
||||
all-parents (into [(:id component-parent-shape)]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
|
@ -230,7 +231,7 @@
|
|||
|
||||
main-instance?
|
||||
(when component
|
||||
(cph/is-main-instance? (:id shape) (:id page) component))]
|
||||
(ctk/is-main-instance? (:id shape) (:id page) component))]
|
||||
|
||||
(if main-instance?
|
||||
(conj components (:component-id shape))
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[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.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.collapse :as dwc]
|
||||
|
@ -106,7 +107,7 @@
|
|||
component (when (and (:component-id item) (:component-file item))
|
||||
(cph/get-component libraries (:component-file item) (:component-id item)))
|
||||
main-instance? (when component
|
||||
(cph/is-main-instance? (:id item) (:id page) component))
|
||||
(ctk/is-main-instance? (:id item) (:id page) component))
|
||||
|
||||
toggle-collapse
|
||||
(mf/use-fn
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui.workspace.sidebar.options.menus.component
|
||||
(:require
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
|
@ -35,7 +36,7 @@
|
|||
|
||||
component (when (and component-id library-id)
|
||||
(cph/get-component libraries library-id component-id))
|
||||
main-instance? (cph/is-main-instance? id current-page-id component)
|
||||
main-instance? (ctk/is-main-instance? id current-page-id component)
|
||||
|
||||
on-menu-click
|
||||
(mf/use-callback
|
||||
|
|
|
@ -2,16 +2,9 @@
|
|||
(:require
|
||||
[cljs.test :as t :include-macros true]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries-helpers :as dwlh]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
[app.test-helpers.pages :as thp]))
|
||||
|
||||
;; ---- Helpers to manage libraries and synchronization
|
||||
|
@ -156,7 +149,7 @@
|
|||
(let [page (thp/current-page state)
|
||||
libs (wsh/get-libraries state)
|
||||
component (cph/get-component libs component-id)
|
||||
root-main (cph/get-component-root component)
|
||||
root-main (ctk/get-component-root component)
|
||||
shapes-main (cph/get-children-with-self (:objects component) (:id root-main))]
|
||||
|
||||
;; Validate that the component tree is well constructed
|
||||
|
|
Loading…
Add table
Reference in a new issue