mirror of
https://github.com/penpot/penpot.git
synced 2025-06-06 07:21:38 +02:00
Merge pull request #6214 from penpot/palba-cleanup-components-v2
♻️ Cleanup of componentsv2 ✨ Add check to avoid open files with components v1
This commit is contained in:
commit
af1d5b86e1
44 changed files with 346 additions and 1208 deletions
|
@ -1462,8 +1462,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
file-id
|
||||
true
|
||||
nil
|
||||
cfsh/prepare-create-artboard-from-selection)]
|
||||
|
||||
(shape-cb shape)
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
component-child (first component-children)]
|
||||
(if (or (nil? child) (nil? component-child))
|
||||
container
|
||||
(let [container (if (and (not (ctk/is-main-of? component-child child true))
|
||||
(let [container (if (and (not (ctk/is-main-of? component-child child))
|
||||
(nil? (ctk/get-swap-slot child))
|
||||
(ctk/instance-head? child))
|
||||
(let [slot (guess-swap-slot component-child component-container)]
|
||||
|
|
|
@ -104,7 +104,6 @@
|
|||
"Translate a flag to a feature name"
|
||||
[flag]
|
||||
(case flag
|
||||
:feature-components-v2 "components/v2"
|
||||
:feature-styles-v2 "styles/v2"
|
||||
:feature-fdata-objects-map "fdata/objects-map"
|
||||
:feature-fdata-pointer-map "fdata/pointer-map"
|
||||
|
@ -241,7 +240,13 @@
|
|||
:code :file-feature-mismatch
|
||||
:feature (first not-supported)
|
||||
:hint (str/ffmt "file features '%' not enabled"
|
||||
(str/join "," not-supported))))))
|
||||
(str/join "," not-supported)))))
|
||||
|
||||
;; Components v1 is deprecated
|
||||
(when-not (contains? file-features "components/v2")
|
||||
(ex/raise :type :restriction
|
||||
:code :file-in-components-v1
|
||||
:hint "components v1 is deprecated")))
|
||||
|
||||
enabled-features))
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[app.common.exceptions :as ex]
|
||||
[app.common.files.changes :as ch]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pprint :as pp]
|
||||
[app.common.schema :as sm]
|
||||
|
@ -38,20 +37,12 @@
|
|||
fail-on-spec?]
|
||||
:or {add-container? false
|
||||
fail-on-spec? false}}]
|
||||
(let [components-v2 (dm/get-in file [:data :options :components-v2])
|
||||
component-id (:current-component-id file)
|
||||
change (cond-> change
|
||||
(and add-container? (some? component-id) (not components-v2))
|
||||
(-> (assoc :component-id component-id)
|
||||
(cond-> (some? (:current-frame-id file))
|
||||
(assoc :frame-id (:current-frame-id file))))
|
||||
|
||||
(and add-container? (or (nil? component-id) components-v2))
|
||||
(let [change (cond-> change
|
||||
add-container?
|
||||
(assoc :page-id (:current-page-id file)
|
||||
:frame-id (:current-frame-id file)))
|
||||
|
||||
valid? (or (and components-v2
|
||||
(nil? (:component-id change))
|
||||
valid? (or (and (nil? (:component-id change))
|
||||
(nil? (:page-id change)))
|
||||
(ch/valid-change? change))]
|
||||
|
||||
|
@ -66,11 +57,11 @@
|
|||
|
||||
(cond-> file
|
||||
(and valid? (or (not add-container?) (some? (:component-id change)) (some? (:page-id change))))
|
||||
(-> (update :changes conjv change) ;; In components-v2 we do not add shapes
|
||||
(update :data ch/process-changes [change] false)) ;; inside a component
|
||||
(-> (update :changes conjv change)
|
||||
(update :data ch/process-changes [change] false))
|
||||
|
||||
(not valid?)
|
||||
(update :errors conjv change)))));)
|
||||
(update :errors conjv change)))))
|
||||
|
||||
(defn- lookup-objects
|
||||
([file]
|
||||
|
@ -185,12 +176,10 @@
|
|||
(update :parent-stack conjv (:id obj)))))
|
||||
|
||||
(defn close-artboard [file]
|
||||
(let [components-v2 (dm/get-in file [:data :options :components-v2])
|
||||
parent-id (-> file :parent-stack peek)
|
||||
(let [parent-id (-> file :parent-stack peek)
|
||||
parent (lookup-shape file parent-id)
|
||||
current-frame-id (or (:frame-id parent)
|
||||
(when (or (nil? (:current-component-id file)) components-v2)
|
||||
root-id))]
|
||||
root-id)]
|
||||
(-> file
|
||||
(assoc :current-frame-id current-frame-id)
|
||||
(update :parent-stack pop))))
|
||||
|
@ -514,58 +503,29 @@
|
|||
|
||||
(defn start-component
|
||||
([file data]
|
||||
(let [components-v2 (dm/get-in file [:data :options :components-v2])
|
||||
root-type (if components-v2 :frame :group)]
|
||||
(start-component file data root-type)))
|
||||
(start-component file data :frame))
|
||||
|
||||
([file data root-type]
|
||||
;; FIXME: data probably can be a shape instance, then we can use gsh/shape->rect
|
||||
(let [components-v2 (dm/get-in file [:data :options :components-v2])
|
||||
selrect (or (grc/make-rect (:x data) (:y data) (:width data) (:height data))
|
||||
grc/empty-rect)
|
||||
name (:name data)
|
||||
(let [name (:name data)
|
||||
path (:path data)
|
||||
main-instance-id (:main-instance-id data)
|
||||
main-instance-page (:main-instance-page data)
|
||||
|
||||
;; In components v1 we must create the root shape and set it inside
|
||||
;; the :objects attribute of the component. When in components-v2,
|
||||
;; this will be ignored as the root shape has already been created
|
||||
;; in its page, by the normal page import.
|
||||
attrs (-> data
|
||||
(assoc :type root-type)
|
||||
(assoc :x (:x selrect))
|
||||
(assoc :y (:y selrect))
|
||||
(assoc :width (:width selrect))
|
||||
(assoc :height (:height selrect))
|
||||
(assoc :selrect selrect)
|
||||
(dissoc :path)
|
||||
(dissoc :main-instance-id)
|
||||
(dissoc :main-instance-page)
|
||||
(dissoc :main-instance-x)
|
||||
(dissoc :main-instance-y))
|
||||
|
||||
obj (-> (cts/setup-shape attrs)
|
||||
(check-name file root-type)
|
||||
;; Components need to have nil values for frame and parent
|
||||
(assoc :frame-id nil)
|
||||
(assoc :parent-id nil))]
|
||||
obj-id (or (:id data) (uuid/next))]
|
||||
|
||||
(-> file
|
||||
(commit-change
|
||||
(cond-> {:type :add-component
|
||||
:id (:id obj)
|
||||
{:type :add-component
|
||||
:id obj-id
|
||||
:name name
|
||||
:path path
|
||||
:main-instance-id main-instance-id
|
||||
:main-instance-page main-instance-page}
|
||||
(not components-v2)
|
||||
(assoc :shapes [obj])))
|
||||
:main-instance-page main-instance-page})
|
||||
|
||||
(assoc :last-id (:id obj))
|
||||
(assoc :parent-stack [(:id obj)])
|
||||
(assoc :current-component-id (:id obj))
|
||||
(assoc :current-frame-id (if (= (:type obj) :frame) (:id obj) uuid/zero))))))
|
||||
(assoc :last-id obj-id)
|
||||
(assoc :parent-stack [obj-id])
|
||||
(assoc :current-component-id obj-id)
|
||||
(assoc :current-frame-id (if (= root-type :frame) obj-id uuid/zero))))))
|
||||
|
||||
(defn start-deleted-component
|
||||
[file data]
|
||||
|
@ -600,8 +560,7 @@
|
|||
|
||||
file
|
||||
(cond
|
||||
;; In components-v2 components haven't any shape inside them.
|
||||
(and component-data (:main-instance-id component-data))
|
||||
component-data
|
||||
(update file :data
|
||||
(fn [data]
|
||||
(ctkl/update-component data component-id dissoc :objects)))
|
||||
|
@ -677,17 +636,12 @@
|
|||
page (ctpl/get-page (:data file) page-id)
|
||||
component (ctkl/get-component (:data file) component-id)
|
||||
|
||||
components-v2 (dm/get-in file [:options :components-v2])
|
||||
|
||||
[shape shapes]
|
||||
(ctn/make-component-instance page
|
||||
component
|
||||
(:id file)
|
||||
(gpt/point x
|
||||
y)
|
||||
components-v2
|
||||
#_{:main-instance true
|
||||
:force-id main-instance-id})]
|
||||
y))]
|
||||
|
||||
(as-> file $
|
||||
(reduce #(commit-change %1
|
||||
|
|
|
@ -921,11 +921,11 @@
|
|||
(apply-changes-local))))
|
||||
|
||||
(defn add-component
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page]
|
||||
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page nil nil nil))
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation]
|
||||
(add-component changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation nil nil))
|
||||
([changes id path name new-shapes updated-shapes main-instance-id main-instance-page annotation variant-id variant-properties & {:keys [apply-changes-local-library?]}]
|
||||
([changes id path name updated-shapes main-instance-id main-instance-page]
|
||||
(add-component changes id path name updated-shapes main-instance-id main-instance-page nil nil nil))
|
||||
([changes id path name updated-shapes main-instance-id main-instance-page annotation]
|
||||
(add-component changes id path name updated-shapes main-instance-id main-instance-page annotation nil nil))
|
||||
([changes id path name updated-shapes main-instance-id main-instance-page annotation variant-id variant-properties & {:keys [apply-changes-local-library?]}]
|
||||
(assert-page-id! changes)
|
||||
(assert-objects! changes)
|
||||
(let [page-id (::page-id (meta changes))
|
||||
|
@ -965,8 +965,6 @@
|
|||
:main-instance-id main-instance-id
|
||||
:main-instance-page main-instance-page
|
||||
:annotation annotation}
|
||||
(some? new-shapes) ;; this will be null in components-v2
|
||||
(assoc :shapes (vec new-shapes))
|
||||
(some? variant-id)
|
||||
(assoc :variant-id variant-id)
|
||||
(seq variant-properties)
|
||||
|
@ -1000,7 +998,7 @@
|
|||
:main-instance-id (:main-instance-id new-component)
|
||||
:main-instance-page (:main-instance-page new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:objects (:objects new-component) ;; this won't exist in components-v2 (except for deleted components)
|
||||
:objects (:objects new-component) ;; for deleted components
|
||||
:modified-at (:modified-at new-component)}
|
||||
(some? (:variant-id new-component))
|
||||
(assoc :variant-id (:variant-id new-component))
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
:file-schema-validation
|
||||
;; Reports the schema validation errors internally.
|
||||
:soft-file-schema-validation
|
||||
;; Activates the referential integrity validation during update file; related to components-v2.
|
||||
;; Activates the referential integrity validation during update file.
|
||||
:file-validation
|
||||
;; Reports the referential integrity validation errors internally.
|
||||
:soft-file-validation
|
||||
|
|
|
@ -168,22 +168,17 @@
|
|||
|
||||
new-instance-shapes (into [] xf-shape new-instance-shapes)]
|
||||
|
||||
[nil nil new-instance-shape new-instance-shapes]))
|
||||
[new-instance-shape new-instance-shapes]))
|
||||
|
||||
(defn generate-duplicate-component
|
||||
"Create a new component copied from the one with the given id."
|
||||
[changes library component-id new-component-id components-v2 & {:keys [new-shape-id apply-changes-local-library? delta new-variant-id]}]
|
||||
[changes library component-id new-component-id & {:keys [new-shape-id apply-changes-local-library? delta new-variant-id]}]
|
||||
(let [component (ctkl/get-component (:data library) component-id)
|
||||
new-name (:name component)
|
||||
|
||||
main-instance-page (when components-v2
|
||||
(ctf/get-component-page (:data library) component))
|
||||
main-instance-page (ctf/get-component-page (:data library) component)
|
||||
|
||||
new-component-id (when components-v2
|
||||
new-component-id)
|
||||
|
||||
[new-component-shape new-component-shapes ; <- null in components-v2
|
||||
new-main-instance-shape new-main-instance-shapes]
|
||||
[new-main-instance-shape new-main-instance-shapes]
|
||||
(duplicate-component component new-component-id (:data library) new-shape-id delta new-variant-id)]
|
||||
|
||||
[new-main-instance-shape
|
||||
|
@ -191,12 +186,9 @@
|
|||
(pcb/with-page main-instance-page)
|
||||
(pcb/with-objects (:objects main-instance-page))
|
||||
(pcb/add-objects new-main-instance-shapes {:ignore-touched true})
|
||||
(pcb/add-component (if components-v2
|
||||
new-component-id
|
||||
(:id new-component-shape))
|
||||
(pcb/add-component new-component-id
|
||||
(:path component)
|
||||
new-name
|
||||
new-component-shapes
|
||||
[]
|
||||
(:id new-main-instance-shape)
|
||||
(:id main-instance-page)
|
||||
|
@ -226,14 +218,11 @@
|
|||
parent (when parent-id (get objects parent-id))
|
||||
library (get libraries file-id)
|
||||
|
||||
components-v2 (dm/get-in library [:data :options :components-v2])
|
||||
|
||||
[new-shape new-shapes]
|
||||
(ctn/make-component-instance page
|
||||
component
|
||||
(:data library)
|
||||
position
|
||||
components-v2
|
||||
(cond-> {}
|
||||
force-frame?
|
||||
(assoc :force-frame-id frame-id)))
|
||||
|
@ -427,8 +416,7 @@
|
|||
:file (pretty-file file-id libraries current-file-id)
|
||||
:library (pretty-file library-id libraries current-file-id))
|
||||
|
||||
(let [file (get-in libraries [file-id :data])
|
||||
components-v2 (get-in file [:options :components-v2])]
|
||||
(let [file (get-in libraries [file-id :data])]
|
||||
(loop [containers (ctf/object-containers-seq file)
|
||||
changes changes]
|
||||
(if-let [container (first containers)]
|
||||
|
@ -441,7 +429,6 @@
|
|||
asset-id
|
||||
library-id
|
||||
container
|
||||
components-v2
|
||||
libraries
|
||||
current-file-id))))
|
||||
changes))))
|
||||
|
@ -466,8 +453,7 @@
|
|||
:file (pretty-file file-id libraries current-file-id)
|
||||
:library (pretty-file library-id libraries current-file-id))
|
||||
|
||||
(let [file (get-in libraries [file-id :data])
|
||||
components-v2 (get-in file [:options :components-v2])]
|
||||
(let [file (get-in libraries [file-id :data])]
|
||||
(loop [local-components (ctkl/components-seq file)
|
||||
changes changes]
|
||||
(if-let [local-component (first local-components)]
|
||||
|
@ -479,7 +465,6 @@
|
|||
asset-id
|
||||
library-id
|
||||
(cfh/make-container local-component :component)
|
||||
components-v2
|
||||
libraries
|
||||
current-file-id)))
|
||||
changes))))
|
||||
|
@ -487,7 +472,7 @@
|
|||
(defn- generate-sync-container
|
||||
"Generate changes to synchronize all shapes in a particular container (a page
|
||||
or a component) that use assets of the given type in the given library."
|
||||
[changes asset-type asset-id library-id container components-v2 libraries current-file-id]
|
||||
[changes asset-type asset-id library-id container libraries current-file-id]
|
||||
|
||||
(if (cfh/page? container)
|
||||
(container-log :debug (:id container) :msg "Sync page in local file" :page-id (:id container))
|
||||
|
@ -506,7 +491,6 @@
|
|||
library-id
|
||||
container
|
||||
shape
|
||||
components-v2
|
||||
libraries
|
||||
current-file-id))
|
||||
changes))))
|
||||
|
@ -536,13 +520,13 @@
|
|||
(defmulti generate-sync-shape
|
||||
"Generate changes to synchronize one shape from all assets of the given type
|
||||
that is using, in the given library."
|
||||
(fn [asset-type _changes _library-id _container _shape _components-v2 _libraries _current-file-id] asset-type))
|
||||
(fn [asset-type _changes _library-id _container _shape _libraries _current-file-id] asset-type))
|
||||
|
||||
(defmethod generate-sync-shape :components
|
||||
[_ changes _library-id container shape components-v2 libraries current-file-id]
|
||||
[_ changes _library-id container shape libraries current-file-id]
|
||||
(let [shape-id (:id shape)
|
||||
file (get current-file-id libraries)]
|
||||
(generate-sync-shape-direct changes file libraries container shape-id false components-v2)))
|
||||
(generate-sync-shape-direct changes file libraries container shape-id false)))
|
||||
|
||||
(defmethod generate-sync-shape :colors
|
||||
[_ changes library-id _ shape _ libraries _]
|
||||
|
@ -718,7 +702,7 @@
|
|||
(defn generate-sync-shape-direct
|
||||
"Generate changes to synchronize one shape that is the root of a component
|
||||
instance, and all its children, from the given component."
|
||||
[changes file libraries container shape-id reset? components-v2]
|
||||
[changes file libraries container shape-id reset?]
|
||||
(shape-log :debug shape-id container
|
||||
:msg "Sync shape direct" :shape-inst (str shape-id) :reset? reset?)
|
||||
(let [shape-inst (ctn/get-shape container shape-id)
|
||||
|
@ -729,12 +713,12 @@
|
|||
(let [redirect-shaperef (partial redirect-shaperef container libraries)
|
||||
|
||||
shape-main (when component
|
||||
(if (and reset? components-v2)
|
||||
(if reset?
|
||||
;; the reset is against the ref-shape, not against the original shape of the component
|
||||
(ctf/find-ref-shape file container libraries shape-inst)
|
||||
(ctf/get-ref-shape library component shape-inst)))
|
||||
|
||||
shape-inst (if (and reset? components-v2)
|
||||
shape-inst (if reset?
|
||||
(redirect-shaperef shape-inst shape-main)
|
||||
shape-inst)
|
||||
|
||||
|
@ -756,13 +740,10 @@
|
|||
root-main
|
||||
reset?
|
||||
initial-root?
|
||||
redirect-shaperef
|
||||
components-v2)
|
||||
redirect-shaperef)
|
||||
;; If the component is not found, because the master component has been
|
||||
;; deleted or the library unlinked, do nothing in v2 or detach in v1.
|
||||
(if components-v2
|
||||
changes
|
||||
(generate-detach-instance changes libraries container shape-id))))
|
||||
;; deleted or the library unlinked, do nothing.
|
||||
changes))
|
||||
changes)))
|
||||
|
||||
(defn- find-main-container
|
||||
|
@ -783,7 +764,7 @@
|
|||
nil))))))
|
||||
|
||||
(defn- generate-sync-shape-direct-recursive
|
||||
[changes container shape-inst component library file libraries shape-main root-inst root-main reset? initial-root? redirect-shaperef components-v2]
|
||||
[changes container shape-inst component library file libraries shape-main root-inst root-main reset? initial-root? redirect-shaperef]
|
||||
(shape-log :debug (:id shape-inst) container
|
||||
:msg "Sync shape direct recursive"
|
||||
:shape-inst (str (:name shape-inst) " " (pretty-uuid (:id shape-inst)))
|
||||
|
@ -791,9 +772,7 @@
|
|||
|
||||
(if (nil? shape-main)
|
||||
;; This should not occur, but protect against it in any case
|
||||
(if components-v2
|
||||
changes
|
||||
(generate-detach-instance changes container {(:id library) library} (:id shape-inst)))
|
||||
(let [omit-touched? (not reset?)
|
||||
clear-remote-synced? (and initial-root? reset?)
|
||||
set-remote-synced? (and (not initial-root?) reset?)
|
||||
|
@ -832,7 +811,7 @@
|
|||
children-inst (vec (ctn/get-direct-children container shape-inst))
|
||||
children-main (vec (ctn/get-direct-children component-container shape-main))
|
||||
|
||||
children-inst (if (and reset? components-v2)
|
||||
children-inst (if reset?
|
||||
(map #(redirect-shaperef %) children-inst) children-inst)
|
||||
|
||||
only-inst (fn [changes child-inst]
|
||||
|
@ -864,8 +843,7 @@
|
|||
root-inst
|
||||
root-main
|
||||
omit-touched?
|
||||
set-remote-synced?
|
||||
components-v2)
|
||||
set-remote-synced?)
|
||||
changes))
|
||||
|
||||
both (fn [changes child-inst child-main]
|
||||
|
@ -885,8 +863,7 @@
|
|||
root-main
|
||||
reset?
|
||||
initial-root?
|
||||
redirect-shaperef
|
||||
components-v2))
|
||||
redirect-shaperef))
|
||||
|
||||
swapped (fn [changes child-inst child-main]
|
||||
(shape-log :trace (:id child-inst) container
|
||||
|
@ -924,8 +901,7 @@
|
|||
swapped
|
||||
moved
|
||||
false
|
||||
reset?
|
||||
components-v2)
|
||||
reset?)
|
||||
|
||||
changes
|
||||
(cond-> changes
|
||||
|
@ -941,27 +917,16 @@
|
|||
|
||||
(defn generate-rename-component
|
||||
"Generate the changes for rename the component with the given id, in the current file library."
|
||||
[changes id new-name library-data components-v2]
|
||||
(let [[path name] (cfh/parse-path-name new-name)
|
||||
update-fn
|
||||
(fn [component]
|
||||
(cond-> component
|
||||
:always
|
||||
(assoc :path path
|
||||
:name name)
|
||||
|
||||
(not components-v2)
|
||||
(update :objects
|
||||
;; Give the same name to the root shape
|
||||
#(assoc-in % [id :name] name))))]
|
||||
[changes id new-name library-data]
|
||||
(let [[path name] (cfh/parse-path-name new-name)]
|
||||
(-> changes
|
||||
(pcb/with-library-data library-data)
|
||||
(pcb/update-component id update-fn))))
|
||||
(pcb/update-component id #(assoc % :path path :name name)))))
|
||||
|
||||
(defn generate-sync-shape-inverse
|
||||
"Generate changes to update the component a shape is linked to, from
|
||||
the values in the shape and all its children."
|
||||
[changes file libraries container shape-id components-v2]
|
||||
[changes file libraries container shape-id]
|
||||
(shape-log :debug shape-id container :msg "Sync shape inverse" :shape (str shape-id))
|
||||
(let [redirect-shaperef (partial redirect-shaperef container libraries)
|
||||
shape-inst (ctn/get-shape container shape-id)
|
||||
|
@ -969,13 +934,9 @@
|
|||
component (ctkl/get-component library (:component-id shape-inst))
|
||||
|
||||
shape-main (when component
|
||||
(if components-v2
|
||||
(ctf/find-remote-shape container libraries shape-inst)
|
||||
(ctf/get-ref-shape library component shape-inst)))
|
||||
(ctf/find-remote-shape container libraries shape-inst))
|
||||
|
||||
shape-inst (if components-v2
|
||||
(redirect-shaperef shape-inst shape-main)
|
||||
shape-inst)
|
||||
shape-inst (redirect-shaperef shape-inst shape-main)
|
||||
|
||||
initial-root? (:component-root shape-inst)
|
||||
|
||||
|
@ -984,7 +945,7 @@
|
|||
|
||||
changes (cond-> changes
|
||||
(and component (contains? (:touched shape-inst) :name-group))
|
||||
(generate-rename-component (:component-id shape-inst) (:name shape-inst) library components-v2))]
|
||||
(generate-rename-component (:component-id shape-inst) (:name shape-inst) library))]
|
||||
|
||||
(if component
|
||||
(generate-sync-shape-inverse-recursive changes
|
||||
|
@ -998,12 +959,11 @@
|
|||
root-inst
|
||||
root-main
|
||||
initial-root?
|
||||
redirect-shaperef
|
||||
components-v2)
|
||||
redirect-shaperef)
|
||||
changes)))
|
||||
|
||||
(defn- generate-sync-shape-inverse-recursive
|
||||
[changes container shape-inst component library file libraries shape-main root-inst root-main initial-root? redirect-shaperef components-v2]
|
||||
[changes container shape-inst component library file libraries shape-main root-inst root-main initial-root? redirect-shaperef]
|
||||
(shape-log :trace (:id shape-inst) container
|
||||
:msg "Sync shape inverse recursive"
|
||||
:shape (str (:name shape-inst))
|
||||
|
@ -1060,9 +1020,7 @@
|
|||
children-main (mapv #(ctn/get-shape component-container %)
|
||||
(:shapes shape-main))
|
||||
|
||||
children-inst (if components-v2
|
||||
(map #(redirect-shaperef %) children-inst)
|
||||
children-inst)
|
||||
children-inst (map #(redirect-shaperef %) children-inst)
|
||||
|
||||
only-inst (fn [changes child-inst]
|
||||
(add-shape-to-main changes
|
||||
|
@ -1073,8 +1031,7 @@
|
|||
component-container
|
||||
container
|
||||
root-inst
|
||||
root-main
|
||||
components-v2))
|
||||
root-main))
|
||||
|
||||
only-main (fn [changes child-main]
|
||||
(remove-shape changes
|
||||
|
@ -1094,8 +1051,7 @@
|
|||
root-inst
|
||||
root-main
|
||||
initial-root?
|
||||
redirect-shaperef
|
||||
components-v2))
|
||||
redirect-shaperef))
|
||||
|
||||
swapped (fn [changes child-inst child-main]
|
||||
(shape-log :trace (:id child-inst) container
|
||||
|
@ -1129,8 +1085,7 @@
|
|||
swapped
|
||||
moved
|
||||
true
|
||||
true
|
||||
components-v2)
|
||||
true)
|
||||
|
||||
;; The inverse sync may be made on a component that is inside a
|
||||
;; remote library. We need to separate changes that are from
|
||||
|
@ -1148,7 +1103,7 @@
|
|||
;; ---- Operation generation helpers ----
|
||||
|
||||
(defn- compare-children
|
||||
[changes shape-inst children-inst children-main container-inst container-main file libraries only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset? components-v2]
|
||||
[changes shape-inst children-inst children-main container-inst container-main file libraries only-inst-cb only-main-cb both-cb swapped-cb moved-cb inverse? reset?]
|
||||
(shape-log :trace (:id shape-inst) container-inst :msg "Compare children")
|
||||
(loop [children-inst (seq (or children-inst []))
|
||||
children-main (seq (or children-main []))
|
||||
|
@ -1169,18 +1124,18 @@
|
|||
(reduce only-inst-cb changes children-inst)
|
||||
|
||||
:else
|
||||
(if (or (ctk/is-main-of? child-main child-inst components-v2)
|
||||
(if (or (ctk/is-main-of? child-main child-inst)
|
||||
(and (ctf/match-swap-slot? child-main child-inst container-inst container-main file libraries) (not reset?)))
|
||||
(recur (next children-inst)
|
||||
(next children-main)
|
||||
(if (ctk/is-main-of? child-main child-inst components-v2)
|
||||
(if (ctk/is-main-of? child-main child-inst)
|
||||
(both-cb changes child-inst child-main)
|
||||
(swapped-cb changes child-inst child-main)))
|
||||
|
||||
(let [child-inst' (d/seek #(or (ctk/is-main-of? child-main % components-v2)
|
||||
(let [child-inst' (d/seek #(or (ctk/is-main-of? child-main %)
|
||||
(and (ctf/match-swap-slot? child-main % container-inst container-main file libraries) (not reset?)))
|
||||
children-inst)
|
||||
child-main' (d/seek #(or (ctk/is-main-of? % child-inst components-v2)
|
||||
child-main' (d/seek #(or (ctk/is-main-of? % child-inst)
|
||||
(and (ctf/match-swap-slot? % child-inst container-inst container-main file libraries) (not reset?)))
|
||||
children-main)]
|
||||
(cond
|
||||
|
@ -1196,7 +1151,7 @@
|
|||
|
||||
:else
|
||||
(if inverse?
|
||||
(let [is-main? (ctk/is-main-of? child-inst child-main' components-v2)]
|
||||
(let [is-main? (ctk/is-main-of? child-inst child-main')]
|
||||
(recur (next children-inst)
|
||||
(remove #(= (:id %) (:id child-main')) children-main)
|
||||
(cond-> changes
|
||||
|
@ -1206,7 +1161,7 @@
|
|||
(swapped-cb child-inst child-main')
|
||||
:always
|
||||
(moved-cb child-inst child-main'))))
|
||||
(let [is-main? (ctk/is-main-of? child-inst' child-main components-v2)]
|
||||
(let [is-main? (ctk/is-main-of? child-inst' child-main)]
|
||||
(recur (remove #(= (:id %) (:id child-inst')) children-inst)
|
||||
(next children-main)
|
||||
(cond-> changes
|
||||
|
@ -1218,14 +1173,14 @@
|
|||
(moved-cb child-inst' child-main))))))))))))
|
||||
|
||||
(defn- add-shape-to-instance
|
||||
[changes component-shape index component-page container root-instance root-main omit-touched? set-remote-synced? components-v2]
|
||||
[changes component-shape index component-page container root-instance root-main omit-touched? set-remote-synced?]
|
||||
(shape-log :info (:id component-shape) component-page
|
||||
:msg (str "ADD [P " (pretty-uuid (:id container)) "] "
|
||||
(:name component-shape)
|
||||
" "
|
||||
(pretty-uuid (:id component-shape))))
|
||||
(let [component-parent-shape (ctn/get-shape component-page (:parent-id component-shape))
|
||||
parent-shape (d/seek #(ctk/is-main-of? component-parent-shape % components-v2)
|
||||
parent-shape (d/seek #(ctk/is-main-of? component-parent-shape %)
|
||||
(cfh/get-children-with-self (:objects container)
|
||||
(:id root-instance)))
|
||||
all-parents (into [(:id parent-shape)]
|
||||
|
@ -1294,14 +1249,14 @@
|
|||
changes')))
|
||||
|
||||
(defn- add-shape-to-main
|
||||
[changes shape index component component-container page root-instance root-main components-v2]
|
||||
[changes shape index component component-container page root-instance root-main]
|
||||
(shape-log :info (:id shape) page
|
||||
:msg (str "ADD [C " (pretty-uuid (:id component-container)) "] "
|
||||
(:name shape)
|
||||
" "
|
||||
(pretty-uuid (:id shape))))
|
||||
(let [parent-shape (ctn/get-shape page (:parent-id shape))
|
||||
component-parent-shape (d/seek #(ctk/is-main-of? % parent-shape components-v2)
|
||||
component-parent-shape (d/seek #(ctk/is-main-of? % parent-shape)
|
||||
(cfh/get-children-with-self (:objects component-container)
|
||||
(:id root-main)))
|
||||
all-parents (into [(:id component-parent-shape)]
|
||||
|
@ -1886,30 +1841,27 @@
|
|||
(assoc change :component-id (:id container))))
|
||||
|
||||
(defn generate-add-component-changes
|
||||
[changes root objects file-id page-id components-v2]
|
||||
[changes root objects file-id page-id]
|
||||
(let [name (:name root)
|
||||
[path name] (cfh/parse-path-name name)
|
||||
|
||||
[root-shape new-shapes updated-shapes]
|
||||
(if-not components-v2
|
||||
(ctn/make-component-shape root objects file-id components-v2)
|
||||
(ctn/convert-shape-in-component root objects file-id))
|
||||
[root-shape updated-shapes]
|
||||
(ctn/convert-shape-in-component root objects file-id)
|
||||
|
||||
changes (-> changes
|
||||
(pcb/add-component (:id root-shape)
|
||||
path
|
||||
name
|
||||
new-shapes
|
||||
updated-shapes
|
||||
(:id root)
|
||||
page-id))]
|
||||
[root-shape changes]))
|
||||
|
||||
(defn generate-add-component
|
||||
"If there is exactly one id, and it's a frame (or a group in v1), and not already a component,
|
||||
use it as root. Otherwise, create a frame (v2) or group (v1) that contains all ids. Then, make a
|
||||
"If there is exactly one id, and it's a frame, and not already a component,
|
||||
use it as root. Otherwise, create a frame that contains all ids. Then, make a
|
||||
component with it, and link all shapes to their corresponding one in the component."
|
||||
[changes shapes objects page-id file-id components-v2 prepare-create-group prepare-create-board]
|
||||
[changes shapes objects page-id file-id prepare-create-board]
|
||||
|
||||
(let [changes (pcb/with-page-id changes page-id)
|
||||
shapes-count (count shapes)
|
||||
|
@ -1921,9 +1873,7 @@
|
|||
|
||||
[root changes old-root-ids]
|
||||
(if (and (= shapes-count 1)
|
||||
(or (and (cfh/group-shape? first-shape)
|
||||
(not components-v2))
|
||||
(cfh/frame-shape? first-shape))
|
||||
(cfh/frame-shape? first-shape)
|
||||
(not (ctk/instance-head? first-shape)))
|
||||
[first-shape
|
||||
(-> changes
|
||||
|
@ -1938,13 +1888,6 @@
|
|||
shape-ids (into (d/ordered-set) (map :id) shapes)
|
||||
|
||||
[root changes]
|
||||
(if-not components-v2
|
||||
(prepare-create-group changes ; These functions needs to be passed as argument
|
||||
objects ; to avoid a circular dependence
|
||||
page-id
|
||||
shapes
|
||||
root-name
|
||||
(not (ctk/instance-head? first-shape)))
|
||||
(prepare-create-board changes
|
||||
(uuid/next)
|
||||
(:parent-id first-shape)
|
||||
|
@ -1952,7 +1895,7 @@
|
|||
shape-ids
|
||||
nil
|
||||
root-name
|
||||
true))]
|
||||
true)]
|
||||
|
||||
[root changes shape-ids]))
|
||||
|
||||
|
@ -1966,7 +1909,7 @@
|
|||
|
||||
objects' (assoc objects (:id root) root)
|
||||
|
||||
[root-shape changes] (generate-add-component-changes changes root objects' file-id page-id components-v2)
|
||||
[root-shape changes] (generate-add-component-changes changes root objects' file-id page-id)
|
||||
|
||||
changes (pcb/update-shapes changes
|
||||
old-root-ids
|
||||
|
@ -2052,8 +1995,7 @@
|
|||
[changes objects shape file page libraries id-new-component index target-cell keep-props-values]
|
||||
(let [[all-parents changes]
|
||||
(-> changes
|
||||
(cls/generate-delete-shapes file page objects (d/ordered-set (:id shape)) {:components-v2 true
|
||||
:component-swap true}))
|
||||
(cls/generate-delete-shapes file page objects (d/ordered-set (:id shape)) {:component-swap true}))
|
||||
[new-shape changes]
|
||||
(-> changes
|
||||
(generate-new-shape-for-swap shape file page libraries id-new-component index target-cell keep-props-values))]
|
||||
|
@ -2084,7 +2026,7 @@
|
|||
(generate-sync-file file-id :typographies asset-id library-id libraries current-file-id))))
|
||||
|
||||
(defn generate-sync-head
|
||||
[changes file-full libraries container id components-v2 reset?]
|
||||
[changes file-full libraries container id reset?]
|
||||
(let [shape-inst (ctn/get-shape container id)
|
||||
objects (:objects container)
|
||||
parent (get objects (:parent-id shape-inst))
|
||||
|
@ -2093,11 +2035,11 @@
|
|||
(-> changes
|
||||
(pcb/with-container container)
|
||||
(pcb/with-objects (:objects container))
|
||||
(generate-sync-shape-direct file-full libraries container (:id head) reset? components-v2))]
|
||||
(generate-sync-shape-direct file-full libraries container (:id head) reset?))]
|
||||
changes))
|
||||
|
||||
(defn generate-reset-component
|
||||
[changes file-full libraries container id components-v2]
|
||||
[changes file-full libraries container id]
|
||||
(let [objects (:objects container)
|
||||
swap-slot (-> (ctn/get-shape container id)
|
||||
(ctk/get-swap-slot))
|
||||
|
@ -2105,11 +2047,11 @@
|
|||
(-> changes
|
||||
(pcb/with-container container)
|
||||
(pcb/with-objects objects)
|
||||
(generate-sync-shape-direct file-full libraries container id true components-v2))]
|
||||
(generate-sync-shape-direct file-full libraries container id true))]
|
||||
|
||||
(cond-> changes
|
||||
(some? swap-slot)
|
||||
(generate-sync-head file-full libraries container id components-v2 true))))
|
||||
(generate-sync-head file-full libraries container id true))))
|
||||
|
||||
(defn generate-duplicate-flows
|
||||
[changes shapes page ids-map]
|
||||
|
@ -2174,7 +2116,6 @@
|
|||
library
|
||||
(:component-id component-shape)
|
||||
new-component-id
|
||||
true
|
||||
{:apply-changes-local-library? true
|
||||
:delta delta
|
||||
:new-variant-id parent-id})]
|
||||
|
@ -2271,8 +2212,7 @@
|
|||
|
||||
regenerate-component
|
||||
(fn [changes shape]
|
||||
(let [components-v2 (dm/get-in library-data [:options :components-v2])
|
||||
[_ changes] (generate-add-component-changes changes shape objects file-id (:id page) components-v2)]
|
||||
(let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page))]
|
||||
changes))
|
||||
|
||||
new-obj
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
(pcb/update-shapes ids update-fn {:attrs #{:blocked :hidden}}))))
|
||||
|
||||
(defn generate-delete-shapes
|
||||
[changes file page objects ids {:keys [components-v2 ignore-touched component-swap]}]
|
||||
[changes file page objects ids {:keys [ignore-touched component-swap]}]
|
||||
(let [ids (cfh/clean-loops objects ids)
|
||||
|
||||
in-component-copy?
|
||||
|
@ -97,7 +97,6 @@
|
|||
(not component-swap))))
|
||||
|
||||
[ids-to-delete ids-to-hide]
|
||||
(if components-v2
|
||||
(loop [ids-seq (seq ids)
|
||||
ids-to-delete []
|
||||
ids-to-hide []]
|
||||
|
@ -111,7 +110,7 @@
|
|||
(recur (rest ids-seq)
|
||||
(conj ids-to-delete id)
|
||||
ids-to-hide)))))
|
||||
[ids []])
|
||||
|
||||
|
||||
changes (-> changes
|
||||
(pcb/with-page page)
|
||||
|
@ -190,7 +189,6 @@
|
|||
#{})
|
||||
|
||||
components-to-delete
|
||||
(if components-v2
|
||||
(reduce (fn [components id]
|
||||
(let [shape (get objects id)]
|
||||
(if (and (= (:component-file shape) (:id file)) ;; Main instances should exist only in local file
|
||||
|
@ -199,7 +197,7 @@
|
|||
components)))
|
||||
[]
|
||||
(into ids-to-delete all-children))
|
||||
[])
|
||||
|
||||
|
||||
ids-set (set ids-to-delete)
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
{:data data}
|
||||
component-id
|
||||
new-component-id
|
||||
true
|
||||
{:new-shape-id new-shape-id :apply-changes-local-library? true}))]
|
||||
(-> changes
|
||||
(clvp/generate-update-property-value new-component-id prop-num value)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"Need that root is already a frame"
|
||||
(cfh/frame-shape? root))
|
||||
|
||||
(let [[_new-root _new-shapes updated-shapes]
|
||||
(let [[_new-root updated-shapes]
|
||||
(ctn/convert-shape-in-component root (:objects page) (:id file))
|
||||
|
||||
updated-root (first updated-shapes) ; Can't use new-root because it has a new id
|
||||
|
@ -54,8 +54,7 @@
|
|||
:name name
|
||||
:path path
|
||||
:main-instance-id (:id updated-root)
|
||||
:main-instance-page (:id page)
|
||||
:shapes updated-shapes))))))))
|
||||
:main-instance-page (:id page)))))))))
|
||||
|
||||
(defn update-component
|
||||
[file component-label & {:keys [] :as params}]
|
||||
|
@ -98,7 +97,6 @@
|
|||
component
|
||||
(:data library)
|
||||
(gpt/point 100 100)
|
||||
true
|
||||
{:force-id (thi/new-id! copy-root-label)
|
||||
:force-frame-id frame-id})
|
||||
|
||||
|
|
|
@ -336,8 +336,7 @@
|
|||
file
|
||||
{file-id file}
|
||||
(ctn/make-container container :page)
|
||||
(:id shape)
|
||||
true))
|
||||
(:id shape)))
|
||||
file' (thf/apply-changes file changes)]
|
||||
(if propagate-fn
|
||||
(propagate-fn file')
|
||||
|
@ -361,7 +360,7 @@
|
|||
(:objects page)
|
||||
#{(-> (ths/get-shape file shape-tag :page-label page-label)
|
||||
:id)}
|
||||
{:components-v2 true})
|
||||
{})
|
||||
file' (thf/apply-changes file changes)]
|
||||
(if propagate-fn
|
||||
(propagate-fn file')
|
||||
|
|
|
@ -182,10 +182,8 @@
|
|||
(= (:component-file shape) file-id)))
|
||||
|
||||
(defn is-main-of?
|
||||
[shape-main shape-inst components-v2]
|
||||
(or (= (:shape-ref shape-inst) (:id shape-main))
|
||||
(and (= (:shape-ref shape-inst) (:shape-ref shape-main))
|
||||
(not components-v2))))
|
||||
[shape-main shape-inst]
|
||||
(= (:shape-ref shape-inst) (:id shape-main)))
|
||||
|
||||
(defn main-instance?
|
||||
"Check if this shape is the root of the main instance of some
|
||||
|
|
|
@ -34,20 +34,12 @@
|
|||
(assoc component :modified-at (dt/now)))
|
||||
|
||||
(defn add-component
|
||||
[fdata {:keys [id name path main-instance-id main-instance-page shapes annotation variant-id variant-properties]}]
|
||||
(let [components-v2 (dm/get-in fdata [:options :components-v2])
|
||||
fdata (update fdata :components assoc id (touch {:id id :name name :path path}))]
|
||||
(if components-v2
|
||||
[fdata {:keys [id name path main-instance-id main-instance-page annotation variant-id variant-properties]}]
|
||||
(let [fdata (update fdata :components assoc id (touch {:id id :name name :path path}))]
|
||||
(cond-> (update-in fdata [:components id] assoc :main-instance-id main-instance-id :main-instance-page main-instance-page)
|
||||
annotation (update-in [:components id] assoc :annotation annotation)
|
||||
variant-id (update-in [:components id] assoc :variant-id variant-id)
|
||||
variant-properties (update-in [:components id] assoc :variant-properties variant-properties))
|
||||
|
||||
(let [wrap-object-fn cfeat/*wrap-with-objects-map-fn*]
|
||||
(assoc-in fdata [:components id :objects]
|
||||
(->> shapes
|
||||
(d/index-by :id)
|
||||
(wrap-object-fn)))))))
|
||||
variant-properties (update-in [:components id] assoc :variant-properties variant-properties))))
|
||||
|
||||
(defn mod-component
|
||||
[file-data {:keys [id name path main-instance-id main-instance-page objects annotation variant-id variant-properties modified-at]}]
|
||||
|
|
|
@ -267,67 +267,8 @@
|
|||
new-children (->> (cfh/get-children objects (:id root))
|
||||
(map #(dissoc % :component-root)))]
|
||||
[(assoc new-root :id new-id)
|
||||
nil
|
||||
(into [new-root] new-children)]))
|
||||
|
||||
(defn make-component-shape ;; Only used for components v1
|
||||
"Clone the shape and all children. Generate new ids and detach
|
||||
from parent and frame. Update the original shapes to have links
|
||||
to the new ones."
|
||||
[shape objects file-id components-v2]
|
||||
(assert (nil? (:component-id shape)))
|
||||
(assert (nil? (:component-file shape)))
|
||||
(assert (nil? (:shape-ref shape)))
|
||||
(let [frame-ids-map (volatile! {})
|
||||
|
||||
;; Ensure that the component root is not an instance
|
||||
update-new-shape (fn [new-shape original-shape]
|
||||
(when (= (:type original-shape) :frame)
|
||||
(vswap! frame-ids-map assoc (:id original-shape) (:id new-shape)))
|
||||
|
||||
(cond-> new-shape
|
||||
true
|
||||
(dissoc :component-root)
|
||||
|
||||
(nil? (:parent-id new-shape))
|
||||
(dissoc :component-id
|
||||
:component-file
|
||||
:shape-ref)))
|
||||
|
||||
;; Make the original shape an instance of the new component.
|
||||
;; If one of the original shape children already was a component
|
||||
;; instance, maintain this instanceness untouched.
|
||||
update-original-shape (fn [original-shape new-shape]
|
||||
(cond-> original-shape
|
||||
(nil? (:shape-ref original-shape))
|
||||
(-> (assoc :shape-ref (:id new-shape))
|
||||
(dissoc :touched))
|
||||
|
||||
(nil? (:parent-id new-shape))
|
||||
(assoc :component-id (:id new-shape)
|
||||
:component-file file-id
|
||||
:component-root true)
|
||||
|
||||
(and (nil? (:parent-id new-shape)) components-v2)
|
||||
(assoc :main-instance true)
|
||||
|
||||
(some? (:parent-id new-shape))
|
||||
(dissoc :component-root)))
|
||||
|
||||
[new-root-shape new-shapes updated-shapes]
|
||||
(ctst/clone-shape shape
|
||||
nil
|
||||
objects
|
||||
:update-new-shape update-new-shape
|
||||
:update-original-shape update-original-shape)
|
||||
|
||||
;; If frame-id points to a shape inside the component, remap it to the
|
||||
;; corresponding new frame shape. If not, set it to nil.
|
||||
remap-frame-id (fn [shape]
|
||||
(update shape :frame-id #(get @frame-ids-map % nil)))]
|
||||
|
||||
[new-root-shape (map remap-frame-id new-shapes) updated-shapes]))
|
||||
|
||||
(defn remove-swap-keep-attrs
|
||||
"Remove flex children properties except the fit-content for flex layouts. These are properties
|
||||
that we don't have to propagate to copies but will be respected when swapping components"
|
||||
|
@ -352,20 +293,18 @@
|
|||
WARNING: This process does not remap media references (on fills, strokes, ...); that is
|
||||
delegated to an async process on the backend side that checks unreferenced shapes and
|
||||
automatically creates correct references."
|
||||
([page component library-data position components-v2]
|
||||
(make-component-instance page component library-data position components-v2 {}))
|
||||
([page component library-data position components-v2
|
||||
([page component library-data position]
|
||||
(make-component-instance page component library-data position {}))
|
||||
([page component library-data position
|
||||
{:keys [main-instance? force-id force-frame-id keep-ids?]
|
||||
:or {main-instance? false force-id nil force-frame-id nil keep-ids? false}}]
|
||||
(let [component-page (when components-v2
|
||||
(ctpl/get-page library-data (:main-instance-page component)))
|
||||
(let [component-page (ctpl/get-page library-data (:main-instance-page component))
|
||||
|
||||
component-shape (if components-v2
|
||||
(-> (get-shape component-page (:main-instance-id component))
|
||||
component-shape (-> (get-shape component-page (:main-instance-id component))
|
||||
(assoc :parent-id nil) ;; On v2 we force parent-id to nil in order to behave like v1
|
||||
(assoc :frame-id uuid/zero)
|
||||
(remove-swap-keep-attrs))
|
||||
(get-shape component (:id component)))
|
||||
|
||||
|
||||
orig-pos (gpt/point (:x component-shape) (:y component-shape))
|
||||
delta (gpt/subtract position orig-pos)
|
||||
|
@ -395,8 +334,7 @@
|
|||
update-new-shape
|
||||
(fn [new-shape original-shape]
|
||||
(let [new-name (:name new-shape)
|
||||
root? (or (ctk/instance-root? original-shape) ; If shape is inside a component (not components-v2)
|
||||
(nil? (:parent-id original-shape)))] ; we detect it by having no parent)
|
||||
root? (ctk/instance-root? original-shape)]
|
||||
|
||||
(when root?
|
||||
(vswap! unames conj new-name))
|
||||
|
@ -417,10 +355,8 @@
|
|||
main-instance?
|
||||
(dissoc :shape-ref)
|
||||
|
||||
(and (not main-instance?)
|
||||
(or components-v2 ; In v1, shape-ref points to the remote instance
|
||||
(nil? (:shape-ref original-shape)))) ; in v2, shape-ref points to the near instance
|
||||
(assoc :shape-ref (:id original-shape))
|
||||
(not main-instance?)
|
||||
(assoc :shape-ref (:id original-shape)) ; shape-ref points to the near instance
|
||||
|
||||
(nil? (:parent-id original-shape))
|
||||
(assoc :component-id (:id component)
|
||||
|
@ -428,14 +364,14 @@
|
|||
:component-root true
|
||||
:name new-name)
|
||||
|
||||
(or (some? (:parent-id original-shape)) ; On v2 we have removed the parent-id for component roots (see above)
|
||||
(or (some? (:parent-id original-shape)) ; On v2 we have removed the parent-id for component roots
|
||||
(some? component-frame))
|
||||
(dissoc :component-root))))
|
||||
|
||||
[new-shape new-shapes _]
|
||||
(ctst/clone-shape component-shape
|
||||
frame-id
|
||||
(if components-v2 (:objects component-page) (:objects component))
|
||||
(:objects component-page)
|
||||
:update-new-shape update-new-shape
|
||||
:force-id force-id
|
||||
:keep-ids? keep-ids?
|
||||
|
@ -593,8 +529,7 @@
|
|||
|
||||
;; TODO: the check of :width and :height probably may be
|
||||
;; removed after the check added in
|
||||
;; data/workspace/modifiers/check-delta function. Better check
|
||||
;; it and test toroughly when activating components-v2 mode.
|
||||
;; data/workspace/modifiers/check-delta function.
|
||||
in-copy?
|
||||
(ctk/in-component-copy? shape)
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
(some? page-id)
|
||||
(ctpl/add-page page)
|
||||
|
||||
(contains? cfeat/*current* "components/v2")
|
||||
:always
|
||||
(assoc-in [:options :components-v2] true)))))
|
||||
|
||||
(defn make-file
|
||||
|
@ -221,31 +221,28 @@
|
|||
(ctpl/get-page file-data (:main-instance-page component)))
|
||||
|
||||
(defn get-component-container
|
||||
"Retrieve the container that holds the component shapes (the page in components-v2
|
||||
or the component itself in v1 or deleted component)."
|
||||
"Retrieve the container that holds the component shapes (the page
|
||||
or the component itself on deleted component)."
|
||||
[file-data component]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 (not (:deleted component)))
|
||||
(if (not (:deleted component))
|
||||
(let [component-page (get-component-page file-data component)]
|
||||
(cfh/make-container component-page :page))
|
||||
(cfh/make-container component :component))))
|
||||
(cfh/make-container component :component)))
|
||||
|
||||
(defn get-component-root
|
||||
"Retrieve the root shape of the component."
|
||||
[file-data component]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 (not (:deleted component)))
|
||||
(if (not (:deleted component))
|
||||
(-> file-data
|
||||
(get-component-page component)
|
||||
(ctn/get-shape (:main-instance-id component)))
|
||||
(ctk/get-component-root component))))
|
||||
(ctk/get-component-root component)))
|
||||
|
||||
(defn get-component-shape
|
||||
"Retrieve one shape in the component by id. If with-context? is true, add the
|
||||
file and container where the shape resides in its metadata."
|
||||
[file-data component shape-id & {:keys [with-context?] :or {with-context? false}}]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 (not (:deleted component)))
|
||||
(if (not (:deleted component))
|
||||
(let [component-page (get-component-page file-data component)]
|
||||
(when component-page
|
||||
(let [child (cfh/get-child (:objects component-page)
|
||||
|
@ -262,7 +259,7 @@
|
|||
(and shape with-context?)
|
||||
(with-meta {:file {:id (:id file-data)
|
||||
:data file-data}
|
||||
:container (ctn/make-container component :component)}))))))
|
||||
:container (ctn/make-container component :component)})))))
|
||||
|
||||
(defn get-ref-shape
|
||||
"Retrieve the shape in the component that is referenced by the instance shape."
|
||||
|
@ -384,12 +381,11 @@
|
|||
(defn get-component-shapes
|
||||
"Retrieve all shapes of the component"
|
||||
[file-data component]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2
|
||||
(not (:deleted component))) ;; the deleted components have its children in the :objects property
|
||||
|
||||
(if (not (:deleted component)) ;; the deleted components have its children in the :objects property
|
||||
(let [instance-page (get-component-page file-data component)]
|
||||
(cfh/get-children-with-self (:objects instance-page) (:main-instance-id component)))
|
||||
(vals (:objects component)))))
|
||||
(vals (:objects component))))
|
||||
|
||||
;; Return true if the object is a component that exists on the file or its libraries (even a deleted one)
|
||||
(defn is-main-of-known-component?
|
||||
|
@ -406,8 +402,7 @@
|
|||
([file-data component]
|
||||
(load-component-objects file-data component (gpt/point 0 0)))
|
||||
([file-data component delta]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 component (empty? (:objects component))) ;; This operation may be called twice, e.g. in an idempotent change
|
||||
(if (and component (empty? (:objects component))) ;; This operation may be called twice, e.g. in an idempotent change
|
||||
(let [component-page (get-component-page file-data component)
|
||||
page-objects (:objects component-page)
|
||||
objects (->> (cons (:main-instance-id component)
|
||||
|
@ -418,15 +413,14 @@
|
|||
(map #(gsh/move % delta))
|
||||
(d/index-by :id))]
|
||||
(assoc component :objects objects))
|
||||
component))))
|
||||
component)))
|
||||
|
||||
(defn delete-component
|
||||
"Mark a component as deleted and store the main instance shapes iside it, to
|
||||
be able to be recovered later."
|
||||
[file-data component-id skip-undelete? delta]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])
|
||||
delta (or delta (gpt/point 0 0))]
|
||||
(if (or (not components-v2) skip-undelete?)
|
||||
(let [delta (or delta (gpt/point 0 0))]
|
||||
(if skip-undelete?
|
||||
(ctkl/delete-component file-data component-id)
|
||||
(-> file-data
|
||||
(ctkl/update-component component-id #(load-component-objects file-data % delta))
|
||||
|
@ -435,8 +429,7 @@
|
|||
(defn restore-component
|
||||
"Recover a deleted component and all its shapes and put all this again in place."
|
||||
[file-data component-id page-id parent-id]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])
|
||||
update-page? (and components-v2 (not (nil? page-id)))
|
||||
(let [update-page? (not (nil? page-id))
|
||||
component (ctkl/get-component file-data component-id true)
|
||||
update-variant? (and (some? parent-id)
|
||||
(ctk/is-variant? component))]
|
||||
|
@ -563,7 +556,6 @@
|
|||
component
|
||||
library-data
|
||||
position
|
||||
(dm/get-in file-data [:options :components-v2])
|
||||
{:main-instance? true
|
||||
:keep-ids? true})
|
||||
|
||||
|
@ -595,8 +587,7 @@
|
|||
:name (:name component)
|
||||
:path (:path component)
|
||||
:main-instance-id (:id main-instance-shape)
|
||||
:main-instance-page page-id
|
||||
:shapes (get-component-shapes library-data component)}))
|
||||
:main-instance-page page-id}))
|
||||
|
||||
; Change all existing instances to point to the local file
|
||||
remap-instances
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
nil)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -74,8 +72,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
cfsh/prepare-create-artboard-from-selection)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -111,8 +107,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
cfsh/prepare-create-artboard-from-selection)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -151,8 +145,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
cfsh/prepare-create-artboard-from-selection)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -191,8 +183,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
nil)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -232,8 +222,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
(:id file)
|
||||
true
|
||||
nil
|
||||
cfsh/prepare-create-artboard-from-selection)
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
@ -265,8 +253,7 @@
|
|||
changes (cll/generate-rename-component (pcb/empty-changes)
|
||||
(:id component)
|
||||
"Test component after"
|
||||
(:data file)
|
||||
true)
|
||||
(:data file))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -445,8 +432,8 @@
|
|||
(t/is (some? copy1-child'))
|
||||
(t/is (ctk/instance-root? copy1-root'))
|
||||
(t/is (ctk/instance-of? copy1-root' (:id file') (:id component')))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root'))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child'))
|
||||
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
|
||||
|
||||
(t/deftest test-instantiate-component-from-lib
|
||||
|
@ -489,8 +476,8 @@
|
|||
(t/is (some? copy1-child'))
|
||||
(t/is (ctk/instance-root? copy1-root'))
|
||||
(t/is (ctk/instance-of? copy1-root' (:id library) (:id component')))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root'))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child'))
|
||||
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
|
||||
|
||||
(t/deftest test-instantiate-nested-component
|
||||
|
@ -533,8 +520,8 @@
|
|||
(t/is (some? copy1-child'))
|
||||
(t/is (ctk/instance-root? copy1-root'))
|
||||
(t/is (ctk/instance-of? copy1-root' (:id file') (:id component')))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root'))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child'))
|
||||
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
|
||||
|
||||
(t/deftest test-instantiate-nested-component-from-lib
|
||||
|
@ -580,8 +567,8 @@
|
|||
(t/is (some? copy1-child'))
|
||||
(t/is (ctk/instance-root? copy1-root'))
|
||||
(t/is (ctk/instance-of? copy1-root' (:id library) (:id component')))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root' true))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child' true))
|
||||
(t/is (ctk/is-main-of? main1-root' copy1-root'))
|
||||
(t/is (ctk/is-main-of? main1-child' copy1-child'))
|
||||
(t/is (ctst/parent-of? copy1-root' copy1-child'))))
|
||||
|
||||
(t/deftest test-detach-copy
|
||||
|
|
|
@ -47,8 +47,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy-root)
|
||||
true)
|
||||
(:id copy-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -99,8 +98,7 @@
|
|||
{(:id file-mdf) file-mdf
|
||||
(:id library) library}
|
||||
page-mdf
|
||||
(:id copy-root)
|
||||
true)
|
||||
(:id copy-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -151,8 +149,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy-root)
|
||||
true)
|
||||
(:id copy-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -198,8 +195,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy-root)
|
||||
true)
|
||||
(:id copy-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -246,8 +242,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy-root)
|
||||
true)
|
||||
(:id copy-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -291,8 +286,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy2-root)
|
||||
true)
|
||||
(:id copy2-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
@ -338,8 +332,7 @@
|
|||
file-mdf
|
||||
{(:id file-mdf) file-mdf}
|
||||
page-mdf
|
||||
(:id copy2-root)
|
||||
true)
|
||||
(:id copy2-root))
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
(t/is (= (:touched copy-root') nil))
|
||||
(t/is (= (:touched copy-new-child') nil))
|
||||
(t/is (ctst/parent-of? copy-root' copy-new-child'))
|
||||
(t/is (ctk/is-main-of? main-free-shape' copy-new-child' true))))
|
||||
(t/is (ctk/is-main-of? main-free-shape' copy-new-child'))))
|
||||
|
||||
(t/deftest test-sync-when-deleting-shape
|
||||
(let [;; ==== Setup
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
(t/is (= (count components') 1))
|
||||
|
||||
(t/is (ctk/instance-of? copy-root' (:id file') (:id component')))
|
||||
(t/is (ctk/is-main-of? main-root' copy-root' true))
|
||||
(t/is (ctk/is-main-of? main-root' copy-root'))
|
||||
(t/is (ctk/main-instance-of? (:id main-root') (:id (second pages')) component'))))
|
||||
|
||||
(t/deftest absorb-colors
|
||||
|
|
|
@ -582,7 +582,6 @@
|
|||
component
|
||||
fdata
|
||||
(gpt/point (:x shape) (:y shape))
|
||||
true
|
||||
{:keep-ids? true :force-frame-id (:frame-id shape)})
|
||||
children (into {} (map (fn [shape] [(:id shape) shape]) new-shapes))
|
||||
objs (assoc objs id new-shape)]
|
||||
|
|
|
@ -395,9 +395,9 @@
|
|||
|
||||
(defn- add-component2
|
||||
"This is the second step of the component creation."
|
||||
([selected components-v2]
|
||||
(add-component2 nil selected components-v2))
|
||||
([id-ref selected components-v2]
|
||||
([selected]
|
||||
(add-component2 nil selected))
|
||||
([id-ref selected]
|
||||
(ptk/reify ::add-component2
|
||||
ev/Event
|
||||
(-data [_]
|
||||
|
@ -413,8 +413,7 @@
|
|||
parents (into #{} (map :parent-id) shapes)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[root component-id changes]
|
||||
(cll/generate-add-component (pcb/empty-changes it) shapes objects page-id file-id components-v2
|
||||
dwg/prepare-create-group
|
||||
(cll/generate-add-component (pcb/empty-changes it) shapes objects page-id file-id
|
||||
cfsh/prepare-create-artboard-from-selection)]
|
||||
(when id-ref
|
||||
(reset! id-ref component-id))
|
||||
|
@ -439,12 +438,11 @@
|
|||
selected (->> (d/nilv ids (dsh/lookup-selected state))
|
||||
(cfh/clean-loops objects))
|
||||
selected-objects (map #(get objects %) selected)
|
||||
components-v2 (features/active-feature? state "components/v2")
|
||||
;; We don't want to change the structure of component copies
|
||||
can-make-component (every? true? (map #(ctn/valid-shape-for-component? objects %) selected-objects))]
|
||||
|
||||
(when can-make-component
|
||||
(rx/of (add-component2 id-ref selected components-v2))))))))
|
||||
(rx/of (add-component2 id-ref selected))))))))
|
||||
|
||||
(defn add-multiple-components
|
||||
"Add several new components to current file library, from the currently selected shapes."
|
||||
|
@ -452,15 +450,14 @@
|
|||
(ptk/reify ::add-multiple-components
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [components-v2 (features/active-feature? state "components/v2")
|
||||
objects (dsh/lookup-page-objects state)
|
||||
(let [objects (dsh/lookup-page-objects state)
|
||||
selected (->> (dsh/lookup-selected state)
|
||||
(cfh/clean-loops objects))
|
||||
selected-objects (map #(get objects %) selected)
|
||||
;; We don't want to change the structure of component copies
|
||||
can-make-component (every? true? (map #(ctn/valid-shape-for-component? objects %) selected-objects))
|
||||
added-components (map (fn [id]
|
||||
(with-meta (add-component2 [id] components-v2)
|
||||
(with-meta (add-component2 [id])
|
||||
{:multiple true}))
|
||||
selected)
|
||||
undo-id (js/Symbol)]
|
||||
|
@ -489,7 +486,7 @@
|
|||
(rx/empty)
|
||||
(let [data (dsh/lookup-file-data state)
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(cll/generate-rename-component id new-name data true))]
|
||||
(cll/generate-rename-component id new-name data))]
|
||||
(rx/of (dch/commit-changes changes))))))))
|
||||
|
||||
(defn rename-component-and-main-instance
|
||||
|
@ -512,7 +509,6 @@
|
|||
(rx/concat
|
||||
(rx/of (rename-component component-id clean-name))
|
||||
|
||||
;; NOTE: only when components-v2 is enabled
|
||||
(when (and shape-id page-id)
|
||||
(rx/of (dwsh/update-shapes [shape-id] #(assoc % :name clean-name) {:page-id page-id :stack-undo? true}))))))))))
|
||||
|
||||
|
@ -526,11 +522,10 @@
|
|||
(watch [it state _]
|
||||
(let [libraries (dsh/lookup-libraries state)
|
||||
library (get libraries library-id)
|
||||
components-v2 (features/active-feature? state "components/v2")
|
||||
|
||||
[main-instance changes]
|
||||
(-> (pcb/empty-changes it nil)
|
||||
(cll/generate-duplicate-component library component-id new-component-id components-v2))]
|
||||
(cll/generate-duplicate-component library component-id new-component-id))]
|
||||
(rx/of
|
||||
(ptk/data-event :layout/update {:ids [(:id main-instance)]})
|
||||
(dch/commit-changes changes)))))))
|
||||
|
@ -560,8 +555,7 @@
|
|||
[all-parents changes]
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
;; Deleting main root triggers component delete
|
||||
(cls/generate-delete-shapes fdata page objects #{root-id} {:components-v2 true
|
||||
:undo-group undo-group
|
||||
(cls/generate-delete-shapes fdata page objects #{root-id} {:undo-group undo-group
|
||||
:undo-id undo-id}))]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
@ -827,7 +821,7 @@
|
|||
|
||||
changes
|
||||
(-> (pcb/empty-changes it)
|
||||
(cll/generate-reset-component file libraries container id true))]
|
||||
(cll/generate-reset-component file libraries container id))]
|
||||
|
||||
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
|
||||
(:redo-changes changes)
|
||||
|
@ -879,7 +873,7 @@
|
|||
(-> (pcb/empty-changes it)
|
||||
(pcb/set-undo-group undo-group)
|
||||
(pcb/with-container container)
|
||||
(cll/generate-sync-shape-inverse fdata libraries container id true))
|
||||
(cll/generate-sync-shape-inverse fdata libraries container id))
|
||||
|
||||
ldata (->> (:component-file shape)
|
||||
(dsh/lookup-file-data state))
|
||||
|
@ -1269,10 +1263,8 @@
|
|||
[]
|
||||
(ptk/reify ::watch-component-changes
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [components-v2? (features/active-feature? state "components/v2")
|
||||
|
||||
stopper-s
|
||||
(watch [_ _ stream]
|
||||
(let [stopper-s
|
||||
(->> stream
|
||||
(rx/filter #(or (= ::dw/finalize-page (ptk/type %))
|
||||
(= ::watch-component-changes (ptk/type %)))))
|
||||
|
@ -1335,7 +1327,7 @@
|
|||
(rx/debounce 5000)
|
||||
(rx/tap #(log/trc :hint "buffer initialized")))]
|
||||
|
||||
(when (and components-v2? (contains? cf/flags :component-thumbnails))
|
||||
(when (contains? cf/flags :component-thumbnails)
|
||||
(->> (rx/merge
|
||||
changes-s
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.media :as dmm]
|
||||
[app.main.data.notifications :as ntf]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.svg-upload :as svg]
|
||||
[app.main.repo :as rp]
|
||||
|
@ -235,16 +234,6 @@
|
|||
(rx/catch #(handle-media-error % on-error))
|
||||
(rx/finalize #(st/emit! (ntf/hide :tag :media-loading))))))))
|
||||
|
||||
;; Deprecated in components-v2
|
||||
(defn upload-media-asset
|
||||
[params]
|
||||
(let [params (assoc params
|
||||
:force-media true
|
||||
:local? false
|
||||
:on-image #(st/emit! (dwl/add-media %))
|
||||
:on-svg #(st/emit! (dwl/add-media %)))]
|
||||
(process-media-objects params)))
|
||||
|
||||
(defn upload-media-workspace
|
||||
[{:keys [position file-id] :as params}]
|
||||
(let [params (assoc params
|
||||
|
@ -378,7 +367,7 @@
|
|||
|
||||
(defn- add-shapes-and-component
|
||||
[it file-data page name [shape children]]
|
||||
(let [[component-shape component-shapes updated-shapes]
|
||||
(let [[component-shape updated-shapes]
|
||||
(ctn/convert-shape-in-component shape children (:id file-data))
|
||||
|
||||
changes (-> (pcb/empty-changes it)
|
||||
|
@ -389,7 +378,6 @@
|
|||
(pcb/add-component (:id component-shape)
|
||||
""
|
||||
name
|
||||
component-shapes
|
||||
updated-shapes
|
||||
(:id shape)
|
||||
(:id page)))]
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
[app.main.data.workspace.edition :as dwe]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
|
@ -171,12 +170,10 @@
|
|||
page (dsh/get-page fdata page-id)
|
||||
objects (:objects page)
|
||||
|
||||
components-v2 (features/active-feature? state "components/v2")
|
||||
undo-id (or (:undo-id options) (js/Symbol))
|
||||
[all-parents changes] (-> (pcb/empty-changes it (:id page))
|
||||
(cls/generate-delete-shapes fdata page objects ids
|
||||
{:components-v2 components-v2
|
||||
:ignore-touched (:component-swap options)
|
||||
{:ignore-touched (:component-swap options)
|
||||
:undo-group (:undo-group options)
|
||||
:undo-id undo-id}))]
|
||||
|
||||
|
|
|
@ -260,6 +260,14 @@
|
|||
(let [message (tr "errors.feature-not-supported" (:feature error))]
|
||||
(st/emit! (modal/show {:type :alert :message message})))
|
||||
|
||||
(= :file-in-components-v1 code)
|
||||
(st/emit! (modal/show {:type :alert
|
||||
:message (tr "errors.deprecated")
|
||||
:link-message {:before (tr "errors.deprecated.contact.before")
|
||||
:text (tr "errors.deprecated.contact.text")
|
||||
:after (tr "errors.deprecated.contact.after")
|
||||
:on-click #(st/emit! (rt/nav :settings-feedback))}}))
|
||||
|
||||
:else
|
||||
(print-cause! "Restriction Error" error)))
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.link :as lk]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
|
@ -21,6 +22,7 @@
|
|||
::mf/register-as :alert}
|
||||
[{:keys [message
|
||||
scd-message
|
||||
link-message
|
||||
title
|
||||
on-accept
|
||||
hint
|
||||
|
@ -59,8 +61,16 @@
|
|||
[:div {:class (stl/css :modal-content)}
|
||||
(when (and (string? message) (not= message ""))
|
||||
[:h3 {:class (stl/css :modal-msg)} message])
|
||||
(when (seq link-message)
|
||||
[:h3 {:class (stl/css :modal-msg)}
|
||||
[:span (:before link-message)]
|
||||
[:& lk/link {:action (:on-click link-message)
|
||||
:class (stl/css :link)}
|
||||
(:text link-message)]
|
||||
[:span (:after link-message)]])
|
||||
(when (and (string? scd-message) (not= scd-message ""))
|
||||
[:h3 {:class (stl/css :modal-scd-msg)} scd-message])
|
||||
|
||||
(when (string? hint)
|
||||
[:p {:class (stl/css :modal-hint)} hint])]
|
||||
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
|
||||
.modal-overlay {
|
||||
@extend .modal-overlay-base;
|
||||
|
||||
&.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@extend .modal-container-base;
|
||||
}
|
||||
|
@ -48,6 +50,7 @@
|
|||
|
||||
.accept-btn {
|
||||
@extend .modal-accept-btn;
|
||||
|
||||
&.danger {
|
||||
@extend .modal-danger-btn;
|
||||
}
|
||||
|
@ -60,3 +63,15 @@
|
|||
color: var(--modal-text-foreground-color);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.link::before {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.link::after {
|
||||
content: " ";
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
(def render-thumbnails (mf/create-context nil))
|
||||
|
||||
(def libraries (mf/create-context nil))
|
||||
(def components-v2 (mf/create-context nil))
|
||||
(def design-tokens (mf/create-context nil))
|
||||
|
||||
(def current-scroll (mf/create-context nil))
|
||||
|
|
|
@ -159,7 +159,7 @@
|
|||
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space
|
||||
[:div {:class (stl/css :asset-list)}
|
||||
(for [component (:sample components)]
|
||||
(let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library
|
||||
(let [root-id (:main-instance-id component)]
|
||||
[:div {:class (stl/css :asset-list-item)
|
||||
:key (str "assets-component-" (:id component))}
|
||||
[:& render/component-svg {:root-shape (get-in component [:objects root-id])
|
||||
|
|
|
@ -200,7 +200,6 @@
|
|||
[:> (mf/provider ctx/current-project-id) {:value project-id}
|
||||
[:> (mf/provider ctx/current-file-id) {:value file-id}
|
||||
[:> (mf/provider ctx/current-page-id) {:value page-id}
|
||||
[:> (mf/provider ctx/components-v2) {:value true}
|
||||
[:> (mf/provider ctx/design-tokens) {:value design-tokens?}
|
||||
[:> (mf/provider ctx/workspace-read-only?) {:value read-only?}
|
||||
[:> modal-container*]
|
||||
|
@ -216,4 +215,4 @@
|
|||
:file file
|
||||
:wglobal wglobal
|
||||
:layout layout}]
|
||||
[:> workspace-loader*])]]]]]]]))
|
||||
[:> workspace-loader*])]]]]]]))
|
||||
|
|
|
@ -555,7 +555,7 @@
|
|||
objects (deref refs/workspace-page-objects)
|
||||
can-make-component (every? true? (map #(ctn/valid-shape-for-component? objects %) shapes))
|
||||
heads (filter ctk/instance-head? shapes)
|
||||
components-menu-entries (cmm/generate-components-menu-entries heads true)
|
||||
components-menu-entries (cmm/generate-components-menu-entries heads)
|
||||
variant-container? (and single? (ctk/is-variant-container? (first shapes)))
|
||||
do-add-component #(st/emit! (dwl/add-component))
|
||||
do-add-multiple-components #(st/emit! (dwl/add-multiple-components))
|
||||
|
|
|
@ -75,8 +75,7 @@
|
|||
{::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
[{:keys [size file-id]}]
|
||||
(let [components-v2 (mf/use-ctx ctx/components-v2)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
(let [read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
filters* (mf/use-state
|
||||
{:term ""
|
||||
:section "all"
|
||||
|
@ -148,11 +147,6 @@
|
|||
:id "components"
|
||||
:handler on-section-filter-change}
|
||||
|
||||
(when (not components-v2)
|
||||
{:name (tr "workspace.assets.graphics")
|
||||
:id "graphics"
|
||||
:handler on-section-filter-change})
|
||||
|
||||
{:name (tr "workspace.assets.colors")
|
||||
:id "colors"
|
||||
:handler on-section-filter-change}
|
||||
|
|
|
@ -322,7 +322,7 @@
|
|||
:is-hidden is-hidden}])))
|
||||
|
||||
(defn generate-components-menu-entries
|
||||
[shapes components-v2]
|
||||
[shapes]
|
||||
(let [multi (> (count shapes) 1)
|
||||
copies (filter ctk/in-component-copy? shapes)
|
||||
|
||||
|
@ -350,13 +350,13 @@
|
|||
|
||||
touched-not-dangling (filter #(and (cfh/component-touched? objects (:id %))
|
||||
(find-component % false)) copies)
|
||||
can-reset-overrides? (or (not components-v2) (seq touched-not-dangling))
|
||||
can-reset-overrides? (seq touched-not-dangling)
|
||||
|
||||
|
||||
;; For when it's only one shape
|
||||
shape (first shapes)
|
||||
id (:id shape)
|
||||
main-instance? (if components-v2 (ctk/main-instance? shape) true)
|
||||
main-instance? (ctk/main-instance? shape)
|
||||
|
||||
component-id (:component-id shape)
|
||||
library-id (:component-file shape)
|
||||
|
@ -372,10 +372,9 @@
|
|||
|
||||
can-update-main? (and (not multi)
|
||||
(not is-dangling?)
|
||||
(or (not components-v2)
|
||||
(and (not main-instance?)
|
||||
(not (ctn/has-any-copy-parent? objects shape))
|
||||
(cfh/component-touched? objects (:id shape)))))
|
||||
(cfh/component-touched? objects (:id shape))))
|
||||
|
||||
can-detach? (and (seq copies)
|
||||
(every? #(not (ctn/has-any-copy-parent? objects %)) copies))
|
||||
|
@ -450,7 +449,7 @@
|
|||
menu-entries [(when (and (not multi) main-instance?)
|
||||
{:title (tr "workspace.shape.menu.show-in-assets")
|
||||
:action do-show-in-assets})
|
||||
(when (and (not multi) main-instance? local-component? lacks-annotation? components-v2)
|
||||
(when (and (not multi) main-instance? local-component? lacks-annotation?)
|
||||
{:title (tr "workspace.shape.menu.create-annotation")
|
||||
:action do-create-annotation})
|
||||
(when can-detach?
|
||||
|
@ -462,7 +461,7 @@
|
|||
(when can-reset-overrides?
|
||||
{:title (tr "workspace.shape.menu.reset-overrides")
|
||||
:action do-reset-component})
|
||||
(when (and (seq restorable-copies) components-v2)
|
||||
(when (seq restorable-copies)
|
||||
{:title (tr "workspace.shape.menu.restore-main")
|
||||
:action do-restore-component})
|
||||
(when can-show-component?
|
||||
|
|
|
@ -308,7 +308,6 @@
|
|||
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
toggle-list-style (mf/use-ctx cmm/assets-toggle-list-style)
|
||||
|
||||
selected (:components selected)
|
||||
|
@ -521,7 +520,7 @@
|
|||
:title (tr "workspace.assets.grid-view")
|
||||
:id "opt-grid"}]]])
|
||||
|
||||
(when (and components-v2 (not read-only?) is-local)
|
||||
(when (and (not read-only?) is-local)
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:aria-label (tr "workspace.assets.components.add-component")
|
||||
:on-click add-component
|
||||
|
@ -561,9 +560,7 @@
|
|||
:id "assets-rename-component"
|
||||
:handler on-rename})
|
||||
(when (and is-local (not (or multi-assets? read-only? any-variant?)))
|
||||
{:name (if components-v2
|
||||
(tr "workspace.assets.duplicate-main")
|
||||
(tr "workspace.assets.duplicate"))
|
||||
{:name (tr "workspace.assets.duplicate-main")
|
||||
:id "assets-duplicate-component"
|
||||
:handler on-duplicate})
|
||||
|
||||
|
@ -576,7 +573,7 @@
|
|||
:id "assets-group-component"
|
||||
:handler on-group})
|
||||
|
||||
(when (and components-v2 (not multi-assets?))
|
||||
(when (not multi-assets?)
|
||||
{:name (tr "workspace.shape.menu.show-main")
|
||||
:id "assets-show-main-component"
|
||||
:handler on-show-main})]}]]]))
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
[app.main.ui.workspace.sidebar.assets.colors :refer [colors-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.components :refer [components-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.graphics :refer [graphics-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.typographies :refer [typographies-section]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
|
@ -145,11 +144,10 @@
|
|||
|
||||
(mf/defc file-library-content*
|
||||
{::mf/private true}
|
||||
[{:keys [file is-local is-loaded open-status-ref on-clear-selection filters colors media typographies components count-variants]}]
|
||||
[{:keys [file is-local is-loaded open-status-ref on-clear-selection filters colors typographies components count-variants]}]
|
||||
(let [open-status (mf/deref open-status-ref)
|
||||
|
||||
file-id (:id file)
|
||||
project-id (:project-id file)
|
||||
|
||||
filters-section (:section filters)
|
||||
has-filters-term? (not ^boolean (str/empty? (:term filters)))
|
||||
|
@ -165,11 +163,6 @@
|
|||
(or (pos? (count components))
|
||||
(not has-filters-term?)))
|
||||
|
||||
show-graphics?
|
||||
(and (or (= filters-section "all")
|
||||
(= filters-section "graphics"))
|
||||
(pos? (count media)))
|
||||
|
||||
show-colors?
|
||||
(and (or (= filters-section "all")
|
||||
(= filters-section "colors"))
|
||||
|
@ -188,9 +181,6 @@
|
|||
force-open-colors?
|
||||
(when ^boolean has-filters-term? (> 60 (count colors)))
|
||||
|
||||
force-open-graphics?
|
||||
(when ^boolean has-filters-term? (> 60 (count media)))
|
||||
|
||||
force-open-typographies?
|
||||
(when ^boolean has-filters-term? (> 60 (count typographies)))
|
||||
|
||||
|
@ -214,9 +204,6 @@
|
|||
on-component-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :components))
|
||||
|
||||
on-graphics-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :graphics))
|
||||
|
||||
on-colors-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :colors))
|
||||
|
||||
|
@ -266,23 +253,6 @@
|
|||
:on-clear-selection on-clear-selection
|
||||
:count-variants count-variants}])
|
||||
|
||||
(when ^boolean show-graphics?
|
||||
[:& graphics-section
|
||||
{:file-id file-id
|
||||
:project-id project-id
|
||||
:local? is-local
|
||||
:objects media
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:open? (or ^boolean force-open-graphics?
|
||||
^boolean (get open-status :graphics false))
|
||||
:force-open? force-open-graphics?
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-graphics-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-colors?
|
||||
[:& colors-section
|
||||
{:file-id file-id
|
||||
|
@ -315,7 +285,6 @@
|
|||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when (and (not ^boolean show-components?)
|
||||
(not ^boolean show-graphics?)
|
||||
(not ^boolean show-colors?)
|
||||
(not ^boolean show-typography?))
|
||||
[:div {:class (stl/css :asset-title)}
|
||||
|
@ -333,7 +302,6 @@
|
|||
library (use-library-ref file-id)
|
||||
|
||||
colors (:colors library)
|
||||
media (:media library)
|
||||
typographies (:typographies library)
|
||||
|
||||
filters-term (:term filters)
|
||||
|
@ -350,11 +318,6 @@
|
|||
(cmm/apply-filters $ filters)
|
||||
(remove #(cfv/is-secondary-variant? % library) $)))
|
||||
|
||||
filtered-media
|
||||
(mf/with-memo [filters media]
|
||||
(-> (vals media)
|
||||
(cmm/apply-filters filters)))
|
||||
|
||||
filtered-typographies
|
||||
(mf/with-memo [filters typographies]
|
||||
(-> (vals typographies)
|
||||
|
@ -372,7 +335,6 @@
|
|||
(and (not (str/blank? filters-term))
|
||||
(or (> 60 (count filtered-colors))
|
||||
(> 60 (count filtered-components))
|
||||
(> 60 (count filtered-media))
|
||||
(> 60 (count filtered-typographies))))
|
||||
|
||||
open?
|
||||
|
@ -415,7 +377,6 @@
|
|||
:filters filters
|
||||
:colors filtered-colors
|
||||
:components filtered-components
|
||||
:media filtered-media
|
||||
:typographies filtered-typographies
|
||||
:on-clear-selection unselect-all
|
||||
:open-status-ref open-status-ref
|
||||
|
|
|
@ -1,432 +0,0 @@
|
|||
;; 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.ui.workspace.sidebar.assets.graphics
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.media :as cm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.editable-label :refer [editable-label]]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.v2.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc graphics-item
|
||||
[{:keys [object renaming listing-thumbs? selected-objects file-id
|
||||
on-asset-click on-context-menu on-drag-start do-rename cancel-rename
|
||||
selected-full selected-graphics-paths]}]
|
||||
(let [item-ref (mf/use-ref)
|
||||
visible? (h/use-visible item-ref :once? true)
|
||||
object-id (:id object)
|
||||
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging* selected-objects selected-full selected-graphics-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset event object dragging* selected-objects selected-full
|
||||
selected-graphics-paths dwl/rename-media)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging* selected-objects selected-graphics-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset event object dragging* selected-objects selected-graphics-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-grahic-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps object file-id selected-objects item-ref on-drag-start read-only?)
|
||||
(fn [event]
|
||||
(if read-only?
|
||||
(dom/prevent-default event)
|
||||
(cmm/on-asset-drag-start event file-id object selected-objects item-ref :graphics on-drag-start))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps object-id)
|
||||
(partial on-context-menu object-id))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps object-id on-asset-click)
|
||||
(fn [event]
|
||||
(on-asset-click event object-id)))]
|
||||
|
||||
[:div {:ref item-ref
|
||||
:class-name (stl/css-case
|
||||
:selected (contains? selected-objects object-id)
|
||||
:grid-cell listing-thumbs?
|
||||
:enum-item (not listing-thumbs?))
|
||||
:draggable (not read-only?)
|
||||
:on-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-grahic-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when visible?
|
||||
[:*
|
||||
[:img {:src (when visible? (cf/resolve-file-media object true))
|
||||
:class (stl/css :graphic-image)
|
||||
:draggable false}] ;; Also need to add css pointer-events: none
|
||||
|
||||
(let [renaming? (= renaming (:id object))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class (stl/css-case
|
||||
:cell-name listing-thumbs?
|
||||
:item-name (not listing-thumbs?)
|
||||
:editing renaming?)
|
||||
:value (cfh/merge-path-item (:path object) (:name object))
|
||||
:tooltip (cfh/merge-path-item (:path object) (:name object))
|
||||
:display-value (:name object)
|
||||
:editing renaming?
|
||||
:disable-dbl-click true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (stl/css :dragging)}])])])]))
|
||||
|
||||
(mf/defc graphics-group
|
||||
[{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected-objects on-asset-click
|
||||
on-drag-start do-rename cancel-rename on-rename-group on-ungroup
|
||||
on-context-menu selected-full]}]
|
||||
(let [group-open? (get open-groups prefix true)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
selected-paths
|
||||
(mf/with-memo [selected-full]
|
||||
(into #{}
|
||||
(comp (map :path) (d/nilv ""))
|
||||
selected-full))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths selected-full)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-media)))]
|
||||
[:div {:class (stl/css :graphics-group)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title
|
||||
{:file-id file-id
|
||||
:section :graphics
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [objects (get groups "" [])]
|
||||
[:div {:class-name (stl/css-case
|
||||
:asset-grid listing-thumbs?
|
||||
:asset-enum (not listing-thumbs?)
|
||||
:drop-space (and
|
||||
(empty? objects)
|
||||
(some? groups)
|
||||
(not dragging?)))
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (stl/css :grid-placeholder)} "\u00A0"])
|
||||
|
||||
(when (and (empty? objects)
|
||||
(some? groups))
|
||||
[:div {:class (stl/css :drop-space)}])
|
||||
|
||||
(for [object objects]
|
||||
[:& graphics-item
|
||||
{:key (dm/str "object-" (:id object))
|
||||
:file-id file-id
|
||||
:object object
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}])])
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& graphics-group {:file-id file-id
|
||||
:key path-item
|
||||
:prefix (cfh/merge-path-item prefix path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:force-open? force-open?
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}]))])]))
|
||||
|
||||
(mf/defc graphics-section
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id project-id local? objects listing-thumbs? open? force-open? open-status-ref selected reverse-sort?
|
||||
on-asset-click on-assets-delete on-clear-selection]}]
|
||||
(let [input-ref (mf/use-ref nil)
|
||||
state (mf/use-state {:renaming nil :object-id nil})
|
||||
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
open-groups-ref (mf/with-memo [open-status-ref]
|
||||
(-> (l/in [:groups :graphics])
|
||||
(l/derived open-status-ref)))
|
||||
open-groups (mf/deref open-groups-ref)
|
||||
|
||||
selected (:graphics selected)
|
||||
selected-full (into #{} (filter #(contains? selected (:id %))) objects)
|
||||
multi-objects? (> (count selected) 1)
|
||||
multi-assets? (or (seq (:components selected))
|
||||
(seq (:colors selected))
|
||||
(seq (:typographies selected)))
|
||||
|
||||
objects (mf/with-memo [objects]
|
||||
(mapv dwl/extract-path-if-missing objects))
|
||||
|
||||
groups (mf/with-memo [objects reverse-sort?]
|
||||
(grp/group-assets objects reverse-sort?))
|
||||
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
team-id (mf/use-ctx ctx/current-team-id)
|
||||
|
||||
add-graphic
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/set-assets-section-open file-id :graphics true))
|
||||
(dom/click (mf/ref-val input-ref))))
|
||||
|
||||
on-file-selected
|
||||
(mf/use-fn
|
||||
(mf/deps file-id project-id team-id)
|
||||
(fn [blobs]
|
||||
(let [params {:file-id file-id
|
||||
:blobs (seq blobs)}]
|
||||
(st/emit! (dwm/upload-media-asset params)
|
||||
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
|
||||
:asset-type "graphics"
|
||||
:file-id file-id
|
||||
:project-id project-id
|
||||
:team-id team-id})))))
|
||||
on-delete
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-objects? multi-assets?)
|
||||
(fn []
|
||||
(if (or multi-objects? multi-assets?)
|
||||
(on-assets-delete)
|
||||
(st/emit! (dwl/delete-media {:id (:object-id @state)})))))
|
||||
|
||||
on-rename
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state (fn [state]
|
||||
(assoc state :renaming (:object-id state))))))
|
||||
cancel-rename
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
do-rename
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn [new-name]
|
||||
(st/emit! (dwl/rename-media (:renaming @state) new-name))
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps selected on-clear-selection read-only?)
|
||||
(fn [object-id event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(when (and local? (not read-only?))
|
||||
(when-not (contains? selected object-id)
|
||||
(on-clear-selection))
|
||||
(swap! state assoc :object-id object-id)
|
||||
(swap! menu-state cmm/open-context-menu pos)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state cmm/close-context-menu)))
|
||||
|
||||
create-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected on-clear-selection (:object-id @state))
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(if multi-objects?
|
||||
(contains? selected (:id %))
|
||||
(= (:object-id @state) (:id %))))
|
||||
(map #(dwl/rename-media (:id %) (cmm/add-group % group-name)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-media (:id %) (cmm/rename-group % path last-path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected create-group)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:path path
|
||||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-media (:id %) (cmm/ungroup % path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-fn
|
||||
(fn [{:keys [name id mtype]} event]
|
||||
(dnd/set-data! event "text/asset-id" (str id))
|
||||
(dnd/set-data! event "text/asset-name" name)
|
||||
(dnd/set-data! event "text/asset-type" mtype)
|
||||
(dnd/set-allowed-effect! event "move")))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
||||
|
||||
[:& cmm/asset-section {:file-id file-id
|
||||
:title (tr "workspace.assets.graphics")
|
||||
:section :graphics
|
||||
:assets-count (count objects)
|
||||
:open? open?}
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when (and (not components-v2) (not read-only?))
|
||||
[:button {:class (stl/css :assets-btn)
|
||||
:on-click add-graphic}
|
||||
i/add
|
||||
[:& file-uploader {:accept cm/str-image-types
|
||||
:multi true
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected}]])])
|
||||
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:& graphics-group {:file-id file-id
|
||||
:prefix ""
|
||||
:groups groups
|
||||
:open-groups open-groups
|
||||
:force-open? force-open?
|
||||
:renaming (:renaming @state)
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected selected
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options [(when-not (or multi-objects? multi-assets?)
|
||||
{:name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-graphics"
|
||||
:handler on-rename})
|
||||
{:name (tr "workspace.assets.delete")
|
||||
:id "assets-delete-graphics"
|
||||
:handler on-delete}
|
||||
(when-not multi-assets?
|
||||
{:name (tr "workspace.assets.group")
|
||||
:id "assets-group-graphics"
|
||||
:handler on-group})]}])]]))
|
|
@ -1,188 +0,0 @@
|
|||
// 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
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.graphics-group {
|
||||
.drop-space {
|
||||
height: $s-12;
|
||||
}
|
||||
.asset-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: $s-4;
|
||||
margin-left: $s-8;
|
||||
.grid-cell {
|
||||
@include flexCenter;
|
||||
position: relative;
|
||||
padding: $s-8;
|
||||
border: $s-2 solid transparent;
|
||||
border-radius: $br-8;
|
||||
aspect-ratio: 1/1;
|
||||
background-color: var(--color-foreground-secondary);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
img {
|
||||
height: auto;
|
||||
width: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
svg {
|
||||
height: 10vh;
|
||||
}
|
||||
.cell-name {
|
||||
@include bodySmallTypography;
|
||||
@include textEllipsis;
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
|
||||
&.editing {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.editable-label-input {
|
||||
height: unset;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.editable-label-close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.cell-name {
|
||||
display: block;
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
background: linear-gradient(to top, rgba(52, 57, 59, 1) 0%, rgba(52, 57, 59, 0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
|
||||
.dragging {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--assets-item-background-color-drag);
|
||||
border: $s-2 solid var(--assets-item-border-color-drag);
|
||||
}
|
||||
}
|
||||
}
|
||||
.asset-enum {
|
||||
padding-bottom: $s-4;
|
||||
.enum-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-36;
|
||||
margin-bottom: $s-4;
|
||||
padding: $s-2;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
cursor: pointer;
|
||||
|
||||
svg,
|
||||
img {
|
||||
@include flexCenter;
|
||||
padding: $s-2;
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-6;
|
||||
background-color: var(--assets-component-background-color);
|
||||
}
|
||||
|
||||
.item-name {
|
||||
@include bodySmallTypography;
|
||||
@include textEllipsis;
|
||||
padding-left: $s-8;
|
||||
color: var(--assets-item-name-foreground-color);
|
||||
|
||||
&.editing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.editable-label-input {
|
||||
height: $s-24;
|
||||
}
|
||||
|
||||
.editable-label-close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.item-name {
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-placeholder {
|
||||
height: $s-2;
|
||||
background-color: var(--color-accent-primary);
|
||||
margin-bottom: $s-2;
|
||||
}
|
||||
}
|
||||
.listing-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.listing-option-btn {
|
||||
@include flexCenter;
|
||||
cursor: pointer;
|
||||
|
||||
&.first {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
}
|
||||
}
|
||||
}
|
||||
.add-component {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
margin-left: $s-2;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
||||
|
||||
.assets-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: calc($s-24 + $s-4);
|
||||
padding: 0;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
}
|
|
@ -53,8 +53,7 @@
|
|||
parent-board? (and (cfh/frame-shape? item)
|
||||
(= uuid/zero (:parent-id item)))
|
||||
absolute? (ctl/item-absolute? item)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
main-instance? (or (not components-v2) (:main-instance item))
|
||||
main-instance? (:main-instance item)
|
||||
variants? (features/use-feature "variants/v1")
|
||||
is-variant? (when variants? (ctk/is-variant? item))
|
||||
variant-name (when is-variant? (:variant-name item))
|
||||
|
|
|
@ -679,7 +679,7 @@
|
|||
(fn []
|
||||
(swap! state* update :render inc)))
|
||||
|
||||
menu-entries (cmm/generate-components-menu-entries shapes true)
|
||||
menu-entries (cmm/generate-components-menu-entries shapes)
|
||||
show-menu? (seq menu-entries)
|
||||
path (->> component (:path) (cfh/split-path) (cfh/join-path-with-dot))]
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
[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-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]
|
||||
|
@ -70,7 +69,6 @@
|
|||
[:div {:class (stl/css :options)}
|
||||
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
|
||||
[:> measures-menu* {:type type :ids measure-ids :values measure-values :shape shape}]
|
||||
[:& component-menu {:shapes [shape]}] ;;remove this in components-v2
|
||||
|
||||
[:& layout-container-menu
|
||||
{:type type
|
||||
|
|
|
@ -251,8 +251,7 @@
|
|||
on-frame-enter (unchecked-get props "on-frame-enter")
|
||||
on-frame-leave (unchecked-get props "on-frame-leave")
|
||||
on-frame-select (unchecked-get props "on-frame-select")
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
shapes (ctt/get-frames objects {:skip-copies? components-v2})
|
||||
shapes (ctt/get-frames objects {:skip-copies? true})
|
||||
shapes (if (dbg/enabled? :shape-titles)
|
||||
(into (set shapes)
|
||||
(map (d/getf objects))
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
[app.plugins :as plugins]
|
||||
[app.util.timers :as tm]))
|
||||
|
||||
(defn ^:export is-components-v2 []
|
||||
(features/active-feature? @st/state "components/v2"))
|
||||
|
||||
(defn ^:export grid []
|
||||
(tm/schedule-on-idle #(st/emit! (features/toggle-feature "layout/grid")))
|
||||
nil)
|
||||
|
|
|
@ -146,8 +146,6 @@
|
|||
(:objects page)
|
||||
(:id page)
|
||||
current-file-id
|
||||
true
|
||||
dwg/prepare-create-group
|
||||
cfsh/prepare-create-artboard-from-selection)]
|
||||
|
||||
(swap! idmap assoc instance-label (:id group)
|
||||
|
|
|
@ -1237,6 +1237,18 @@ msgstr ""
|
|||
"features of the file you are trying to open. Migrations for '%s' need to be "
|
||||
"applied before the file can be opened."
|
||||
|
||||
msgid "errors.deprecated"
|
||||
msgstr "Sorry! This is an old file that uses a deprecated type of Penpot assets and you can't open it."
|
||||
|
||||
msgid "errors.deprecated.contact.before"
|
||||
msgstr "Although Penpot no longer support this type of Assets, you can"
|
||||
|
||||
msgid "errors.deprecated.contact.text"
|
||||
msgstr "contact us"
|
||||
|
||||
msgid "errors.deprecated.contact.after"
|
||||
msgstr "so we can help you."
|
||||
|
||||
#: src/app/main/data/auth.cljs:322, src/app/main/ui/auth/login.cljs:81, src/app/main/ui/auth/login.cljs:122, src/app/main/ui/auth/register.cljs:66, src/app/main/ui/auth/register.cljs:207, src/app/main/ui/auth/verify_token.cljs:94, src/app/main/ui/dashboard/team.cljs:193, src/app/main/ui/onboarding/team_choice.cljs:112, src/app/main/ui/settings/access_tokens.cljs:80, src/app/main/ui/settings/feedback.cljs:49
|
||||
msgid "errors.generic"
|
||||
msgstr "Something wrong has happened."
|
||||
|
|
|
@ -1245,6 +1245,18 @@ msgstr ""
|
|||
"del fichero que se esta intentando abrir. Falta aplicar migraciones para "
|
||||
"'%s' antes de poder abrir el fichero."
|
||||
|
||||
msgid "errors.deprecated"
|
||||
msgstr "¡Lo sentimos! Este es un fichero antiguo que utiliza un tipo de recurso de Penpot obsoleto, y no puedes abrirlo."
|
||||
|
||||
msgid "errors.deprecated.contact.before"
|
||||
msgstr "Aunque Penpot ya no da soporte a este tipo de Recursos, puedes"
|
||||
|
||||
msgid "errors.deprecated.contact.text"
|
||||
msgstr "contactar con nosotros"
|
||||
|
||||
msgid "errors.deprecated.contact.after"
|
||||
msgstr "para que podamos ayudarte."
|
||||
|
||||
#: src/app/main/data/auth.cljs:322, src/app/main/ui/auth/login.cljs:81, src/app/main/ui/auth/login.cljs:122, src/app/main/ui/auth/register.cljs:66, src/app/main/ui/auth/register.cljs:207, src/app/main/ui/auth/verify_token.cljs:94, src/app/main/ui/dashboard/team.cljs:193, src/app/main/ui/onboarding/team_choice.cljs:112, src/app/main/ui/settings/access_tokens.cljs:80, src/app/main/ui/settings/feedback.cljs:49
|
||||
msgid "errors.generic"
|
||||
msgstr "Ha ocurrido algún error."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue