diff --git a/CHANGES.md b/CHANGES.md index 1fcdc6259..792bf7ae7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,12 @@ ### :bug: Bugs fixed - Fix components groups items show the component name in list mode [Taiga #4770](https://tree.taiga.io/project/penpot/issue/4770) - Fix typing CMD+Z on MacOS turns the cursor into a Zoom cursor [Taiga #4778](https://tree.taiga.io/project/penpot/issue/4778) +- Fix white space on small screens [Taiga #4774](https://tree.taiga.io/project/penpot/issue/4774) +- Fix button spacing on delete acount modal [Taiga #4762](https://tree.taiga.io/project/penpot/issue/4762) +- Fix invitations input on team management and onboarding modal [Taiga #4760](https://tree.taiga.io/project/penpot/issue/4760) +- Fix weird numeration creating new elements in dashboard [Taiga #4755](https://tree.taiga.io/project/penpot/issue/4755) +- Fix can move shape with lens zoom active [Taiga #4787](https://tree.taiga.io/project/penpot/issue/4787) +- Fix social links broken [Taiga #4759](https://tree.taiga.io/project/penpot/issue/4759) ## 1.17.0 diff --git a/backend/resources/app/emails-mjml/change-email/en.mjml b/backend/resources/app/emails-mjml/change-email/en.mjml index 392452a0a..f69c418dc 100644 --- a/backend/resources/app/emails-mjml/change-email/en.mjml +++ b/backend/resources/app/emails-mjml/change-email/en.mjml @@ -48,8 +48,8 @@ - - + + diff --git a/backend/resources/app/emails-mjml/invite-to-team/en.mjml b/backend/resources/app/emails-mjml/invite-to-team/en.mjml index 82816304c..886c7d1d6 100644 --- a/backend/resources/app/emails-mjml/invite-to-team/en.mjml +++ b/backend/resources/app/emails-mjml/invite-to-team/en.mjml @@ -41,8 +41,8 @@ - - + + diff --git a/backend/resources/app/emails-mjml/password-recovery/en.mjml b/backend/resources/app/emails-mjml/password-recovery/en.mjml index f43b8eade..89bc817b5 100644 --- a/backend/resources/app/emails-mjml/password-recovery/en.mjml +++ b/backend/resources/app/emails-mjml/password-recovery/en.mjml @@ -50,8 +50,8 @@ - - + + diff --git a/backend/resources/app/emails-mjml/register/en.mjml b/backend/resources/app/emails-mjml/register/en.mjml index cb539fc2d..38b774e13 100644 --- a/backend/resources/app/emails-mjml/register/en.mjml +++ b/backend/resources/app/emails-mjml/register/en.mjml @@ -47,8 +47,8 @@ - - + + diff --git a/backend/resources/app/emails/change-email/en.html b/backend/resources/app/emails/change-email/en.html index 3120f86ba..ad95fa641 100644 --- a/backend/resources/app/emails/change-email/en.html +++ b/backend/resources/app/emails/change-email/en.html @@ -103,9 +103,9 @@ @@ -143,7 +143,7 @@ - + @@ -157,9 +157,9 @@ @@ -225,7 +225,7 @@
- + @@ -239,9 +239,9 @@ @@ -271,7 +271,7 @@
- + @@ -285,9 +285,9 @@ @@ -425,7 +425,7 @@
@@ -321,7 +321,7 @@
@@ -341,7 +341,7 @@
@@ -361,7 +361,7 @@
@@ -370,7 +370,7 @@
@@ -381,7 +381,7 @@
- +
@@ -390,7 +390,7 @@
@@ -401,7 +401,7 @@
- +
@@ -411,9 +411,9 @@
- + @@ -439,9 +439,9 @@ diff --git a/backend/resources/app/emails/invite-to-team/en.html b/backend/resources/app/emails/invite-to-team/en.html index 340ac3429..881af47f4 100644 --- a/backend/resources/app/emails/invite-to-team/en.html +++ b/backend/resources/app/emails/invite-to-team/en.html @@ -103,9 +103,9 @@ @@ -143,7 +143,7 @@
- + @@ -157,9 +157,9 @@ @@ -215,7 +215,7 @@
- + @@ -229,9 +229,9 @@ @@ -261,7 +261,7 @@
- + @@ -275,9 +275,9 @@ @@ -415,7 +415,7 @@
@@ -311,7 +311,7 @@
@@ -331,7 +331,7 @@
@@ -351,7 +351,7 @@
@@ -360,7 +360,7 @@
@@ -371,7 +371,7 @@
- +
@@ -380,7 +380,7 @@
@@ -391,7 +391,7 @@
- +
@@ -401,9 +401,9 @@
- + @@ -429,9 +429,9 @@ diff --git a/backend/resources/app/emails/password-recovery/en.html b/backend/resources/app/emails/password-recovery/en.html index 2b2db5a21..14fe1a5f2 100644 --- a/backend/resources/app/emails/password-recovery/en.html +++ b/backend/resources/app/emails/password-recovery/en.html @@ -103,9 +103,9 @@ @@ -143,7 +143,7 @@
- + @@ -157,9 +157,9 @@ @@ -220,7 +220,7 @@
- + @@ -234,9 +234,9 @@ @@ -266,7 +266,7 @@
- + @@ -280,9 +280,9 @@ @@ -420,7 +420,7 @@
@@ -316,7 +316,7 @@
@@ -336,7 +336,7 @@
@@ -356,7 +356,7 @@
@@ -365,7 +365,7 @@
@@ -376,7 +376,7 @@
- +
@@ -385,7 +385,7 @@
@@ -396,7 +396,7 @@
- +
@@ -406,9 +406,9 @@
- + @@ -434,9 +434,9 @@ diff --git a/backend/resources/app/emails/register/en.html b/backend/resources/app/emails/register/en.html index d60e1dac8..4a425b69f 100644 --- a/backend/resources/app/emails/register/en.html +++ b/backend/resources/app/emails/register/en.html @@ -103,9 +103,9 @@ @@ -143,7 +143,7 @@
- + @@ -157,9 +157,9 @@ @@ -215,7 +215,7 @@
- + @@ -229,9 +229,9 @@ @@ -261,7 +261,7 @@
- + @@ -275,9 +275,9 @@ @@ -415,7 +415,7 @@
@@ -311,7 +311,7 @@
@@ -331,7 +331,7 @@
@@ -351,7 +351,7 @@
@@ -360,7 +360,7 @@
@@ -371,7 +371,7 @@
- +
@@ -380,7 +380,7 @@
@@ -391,7 +391,7 @@
- +
@@ -401,9 +401,9 @@
- + @@ -429,9 +429,9 @@ diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index 18fdfd0de..850ec70c0 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -474,7 +474,7 @@ (s/def ::team-id ::us/uuid) (s/def ::member-id ::us/uuid) ;; Temporarily disabled viewer role -;; https://tree.taiga.io/project/uxboxproject/issue/1083 +;; https://tree.taiga.io/project/penpot/issue/1083 ;; (s/def ::role #{:owner :admin :editor :viewer}) (s/def ::role #{:owner :admin :editor}) diff --git a/backend/test/backend_tests/rpc_comment_test.clj b/backend/test/backend_tests/rpc_comment_test.clj index d088f8b06..0cb812bad 100644 --- a/backend/test/backend_tests/rpc_comment_test.clj +++ b/backend/test/backend_tests/rpc_comment_test.clj @@ -154,7 +154,7 @@ (t/is (th/success? out)) (let [[thread :as result] (:result out)] (t/is (= 1 (count result))) - (t/is (= "Page-1" (:page-name thread))) + (t/is (= "Page 1" (:page-name thread))) (t/is (= "hello world" (:content thread))) (t/is (= 2 (:count-comments thread))) (t/is (true? (:is-resolved thread)))))) diff --git a/common/src/app/common/file_builder.cljc b/common/src/app/common/file_builder.cljc index 627ffc8a8..e2d61fa43 100644 --- a/common/src/app/common/file_builder.cljc +++ b/common/src/app/common/file_builder.cljc @@ -200,7 +200,7 @@ (assert (nil? (:current-component-id file))) (let [page-id (or (:id data) (uuid/next)) - page (-> (ctp/make-empty-page page-id "Page-1") + page (-> (ctp/make-empty-page page-id "Page 1") (d/deep-merge data))] (-> file (commit-change diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index be95e3416..5158ed32e 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -43,13 +43,13 @@ (defn bounding-box "Returns a rect that wraps the shape after all transformations applied." [shape] - ; TODO: perhaps we need to store this calculation in a shape attribute + ;; TODO: perhaps we need to store this calculation in a shape attribute (gpr/points->rect (:points shape))) (defn left-bound "Returns the lowest x coord of the shape BEFORE applying transformations." - ; TODO: perhaps some day we want after transformations, but for the - ; moment it's enough as is now. + ;; TODO: perhaps some day we want after transformations, but for the + ;; moment it's enough as is now. [shape] (or (:x shape) (:x (:selrect shape)))) ; Paths don't have :x attribute @@ -106,8 +106,8 @@ ([attr val1 val2 precision] (let [close-val? (fn [num1 num2] - (when (and (number? num1) (number? num2)) - (< (mth/abs (- num1 num2)) precision)))] + (when (and (number? num1) (number? num2)) + (< (mth/abs (- num1 num2)) precision)))] (cond (and (number? val1) (number? val2)) (close-val? val1 val2) diff --git a/common/src/app/common/geom/shapes/constraints.cljc b/common/src/app/common/geom/shapes/constraints.cljc index 6cdf6c5d9..6c4f24cc3 100644 --- a/common/src/app/common/geom/shapes/constraints.cljc +++ b/common/src/app/common/geom/shapes/constraints.cljc @@ -210,7 +210,7 @@ ;; after-vec will contain the side length of the grown side ;; we scale the shape by the diference and translate it by the start ;; displacement (so its left+top position is constant) - scale (/ (gpt/length after-vec) (gpt/length before-vec)) + scale (/ (gpt/length after-vec) (max 0.01 (gpt/length before-vec))) resize-origin (gpo/origin child-points-after) @@ -268,11 +268,11 @@ scale-x (if (= :scale constraints-h) 1 - (/ (gpo/width-points child-bb-before) (gpo/width-points child-bb-after))) + (/ (gpo/width-points child-bb-before) (max 0.01 (gpo/width-points child-bb-after)))) scale-y (if (= :scale constraints-v) 1 - (/ (gpo/height-points child-bb-before) (gpo/height-points child-bb-after))) + (/ (gpo/height-points child-bb-before) (max 0.01 (gpo/height-points child-bb-after)))) resize-vector (gpt/point scale-x scale-y) resize-origin (gpo/origin transformed-child-bounds) diff --git a/common/src/app/common/geom/shapes/flex_layout/lines.cljc b/common/src/app/common/geom/shapes/flex_layout/lines.cljc index a31e13ca5..00349c995 100644 --- a/common/src/app/common/geom/shapes/flex_layout/lines.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/lines.cljc @@ -238,6 +238,30 @@ (and col? (< total-min-width rest-layout-width total-max-width) (not (ctl/auto-width? parent))) (distribute-space :line-width :line-min-width :line-max-width total-min-width rest-layout-width)) + ;; Add information to limit the growth of width: 100% shapes to the bounds of the layout + layout-lines + (cond + row? + (->> layout-lines + (reduce + (fn [[result rest-layout-height] {:keys [line-height] :as line}] + [(conj result (assoc line :to-bound-height rest-layout-height)) + (- rest-layout-height line-height layout-gap-row)]) + [[] layout-height]) + (first)) + + col? + (->> layout-lines + (reduce + (fn [[result rest-layout-width] {:keys [line-width] :as line}] + [(conj result (assoc line :to-bound-width rest-layout-width)) + (- rest-layout-width line-width layout-gap-col)]) + [[] layout-width]) + (first)) + + :else + layout-lines) + [total-width total-height] (->> layout-lines (reduce add-lines [0 0])) base-p (flp/get-base-line parent layout-bounds total-width total-height num-lines)] diff --git a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc index 072eed1b3..72994b873 100644 --- a/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/modifiers.cljc @@ -20,7 +20,7 @@ transform-inverse child child-origin child-width - {:keys [children-data line-width] :as layout-data}] + {:keys [children-data line-width to-bound-width] :as layout-data}] (cond (ctl/row? parent) @@ -30,8 +30,9 @@ :modifiers (ctm/resize-modifiers (gpt/point fill-scale 1) child-origin transform transform-inverse)}) (ctl/col? parent) - (let [target-width (max (- line-width (ctl/child-width-margin child)) 0.01) - max-width (ctl/child-max-width child) + (let [line-width (min line-width (or to-bound-width line-width)) + target-width (max (- line-width (ctl/child-width-margin child)) 0.01) + max-width (max (ctl/child-max-width child) 0.01) target-width (min max-width target-width) fill-scale (/ target-width child-width)] {:width target-width @@ -43,7 +44,7 @@ transform transform-inverse child child-origin child-height - {:keys [children-data line-height] :as layout-data}] + {:keys [children-data line-height to-bound-height] :as layout-data}] (cond (ctl/col? parent) @@ -53,8 +54,9 @@ :modifiers (ctm/resize-modifiers (gpt/point 1 fill-scale) child-origin transform transform-inverse)}) (ctl/row? parent) - (let [target-height (max (- line-height (ctl/child-height-margin child)) 0.01) - max-height (ctl/child-max-height child) + (let [line-height (min line-height (or to-bound-height line-height)) + target-height (max (- line-height (ctl/child-height-margin child)) 0.01) + max-height (max (ctl/child-max-height child) 0.01) target-height (min max-height target-height) fill-scale (/ target-height child-height)] {:height target-height @@ -71,8 +73,13 @@ (when (or (ctl/fill-width? child) (ctl/fill-height? child)) (gtr/calculate-geometry @parent-bounds)) - fill-width (when (ctl/fill-width? child) (calc-fill-width-data parent transform transform-inverse child child-origin child-width layout-line)) - fill-height (when (ctl/fill-height? child) (calc-fill-height-data parent transform transform-inverse child child-origin child-height layout-line)) + fill-width + (when (ctl/fill-width? child) + (calc-fill-width-data parent transform transform-inverse child child-origin child-width layout-line)) + + fill-height + (when (ctl/fill-height? child) + (calc-fill-height-data parent transform transform-inverse child child-origin child-height layout-line)) child-width (or (:width fill-width) child-width) child-height (or (:height fill-height) child-height) diff --git a/common/src/app/common/geom/shapes/flex_layout/positions.cljc b/common/src/app/common/geom/shapes/flex_layout/positions.cljc index 2e2e44bfd..77ce23d0b 100644 --- a/common/src/app/common/geom/shapes/flex_layout/positions.cljc +++ b/common/src/app/common/geom/shapes/flex_layout/positions.cljc @@ -20,9 +20,13 @@ hv (partial gpo/start-hv layout-bounds) vv (partial gpo/start-vv layout-bounds) - end? (ctl/content-end? parent) - center? (ctl/content-center? parent) - around? (ctl/content-around? parent) + wrap? (ctl/wrap? parent) + + end? (or (and wrap? (ctl/content-end? parent)) + (and (not wrap?) (ctl/align-items-end? parent))) + center? (or (and wrap? (ctl/content-center? parent)) + (and (not wrap?) (ctl/align-items-center? parent))) + around? (and wrap? (ctl/content-around? parent)) ;; Adjust the totals so it takes into account the gaps [layout-gap-row layout-gap-col] (ctl/gaps parent) diff --git a/common/src/app/common/geom/shapes/points.cljc b/common/src/app/common/geom/shapes/points.cljc index d04ad06a0..206494d49 100644 --- a/common/src/app/common/geom/shapes/points.cljc +++ b/common/src/app/common/geom/shapes/points.cljc @@ -54,11 +54,11 @@ (defn width-points [[p0 p1 _ _]] - (gpt/length (gpt/to-vec p0 p1))) + (max 0.01 (gpt/length (gpt/to-vec p0 p1)))) (defn height-points [[p0 _ _ p3]] - (gpt/length (gpt/to-vec p0 p3))) + (max 0.01 (gpt/length (gpt/to-vec p0 p3)))) (defn pad-points [[p0 p1 p2 p3 :as points] pad-top pad-right pad-bottom pad-left] diff --git a/common/src/app/common/math.cljc b/common/src/app/common/math.cljc index 7760a974c..d3f724ee9 100644 --- a/common/src/app/common/math.cljc +++ b/common/src/app/common/math.cljc @@ -34,7 +34,7 @@ (defn abs [v] #?(:cljs (js/Math.abs v) - :clj (Math/abs v))) + :clj (Math/abs (double v)))) (defn sin "Returns the sine of a number" diff --git a/common/src/app/common/pages.cljc b/common/src/app/common/pages.cljc index 0af339722..2d52f03c4 100644 --- a/common/src/app/common/pages.cljc +++ b/common/src/app/common/pages.cljc @@ -19,6 +19,8 @@ (dm/export common/file-version) (dm/export common/default-color) (dm/export common/component-sync-attrs) +(dm/export common/retrieve-used-names) +(dm/export common/generate-unique-name) ;; Focus (dm/export focus/focus-objects) diff --git a/common/src/app/common/pages/common.cljc b/common/src/app/common/pages/common.cljc index c738b22d4..7e392cc92 100644 --- a/common/src/app/common/pages/common.cljc +++ b/common/src/app/common/pages/common.cljc @@ -7,7 +7,10 @@ (ns app.common.pages.common (:require [app.common.colors :as clr] - [app.common.uuid :as uuid])) + [app.common.data :as d] + [app.common.spec :as us] + [app.common.uuid :as uuid] + [clojure.spec.alpha :as s])) (def file-version 20) (def default-color clr/gray-20) @@ -580,3 +583,31 @@ :layout-item-min-w :layout-item-align-self}}) +(defn retrieve-used-names + "Return a set with the all unique names used in the + elements (any entity thas has a :name)" + [elements] + (into #{} (comp (map :name) (remove nil?)) (vals elements))) + +(defn- extract-numeric-suffix + [basename] + (if-let [[_ p1 p2] (re-find #"(.*) ([0-9]+)$" basename)] + [p1 (+ 1 (d/parse-integer p2))] + [basename 1])) + +(s/def ::set-of-strings + (s/every ::us/string :kind set?)) + +(defn generate-unique-name + "A unique name generator" + [used basename] + (us/assert! ::set-of-strings used) + (us/assert! ::us/string basename) + (if-not (contains? used basename) + basename + (let [[prefix initial] (extract-numeric-suffix basename)] + (loop [counter initial] + (let [candidate (str prefix " " counter)] + (if (contains? used candidate) + (recur (inc counter)) + candidate)))))) diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index 973c1a714..f3f6f0dbb 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -109,6 +109,20 @@ (recur (conj result parent-id) parent-id) result)))) +(defn get-parent-ids-with-index + "Returns a tuple with the list of parents and a map with the position within each parent" + [objects shape-id] + (loop [parent-list [] + parent-indices {} + current shape-id] + (let [parent-id (dm/get-in objects [current :parent-id]) + parent (get objects parent-id)] + (if (and (some? parent) (not= parent-id current)) + (let [parent-list (conj parent-list parent-id) + parent-indices (assoc parent-indices parent-id (d/index-of (:shapes parent) current))] + (recur parent-list parent-indices parent-id)) + [parent-list parent-indices])))) + (defn get-siblings-ids [objects id] (let [parent (get-parent objects id)] diff --git a/common/src/app/common/types/container.cljc b/common/src/app/common/types/container.cljc index 53185b092..7c9950a8b 100644 --- a/common/src/app/common/types/container.cljc +++ b/common/src/app/common/types/container.cljc @@ -9,6 +9,7 @@ [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.pages.common :as common] [app.common.spec :as us] [app.common.types.shape-tree :as ctst] [clojure.spec.alpha :as s])) @@ -130,7 +131,7 @@ delta (gpt/subtract position orig-pos) objects (:objects container) - unames (volatile! (ctst/retrieve-used-names objects)) + unames (volatile! (common/retrieve-used-names objects)) frame-id (ctst/frame-id-by-position objects (gpt/add orig-pos delta)) frame-ids-map (volatile! {}) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index d2143101b..8bc075b1e 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -73,7 +73,7 @@ ([file-id page-id] (let [page (when (some? page-id) - (ctp/make-empty-page page-id "Page-1"))] + (ctp/make-empty-page page-id "Page 1"))] (cond-> (-> empty-file-data (assoc :id file-id)) diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 8d619cc6c..9be46671f 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -275,6 +275,21 @@ (or (= :stretch layout-align-content) (nil? layout-align-content))) +(defn align-items-center? + [{:keys [layout-align-items]}] + (= layout-align-items :center)) + +(defn align-items-start? + [{:keys [layout-align-items]}] + (= layout-align-items :start)) + +(defn align-items-end? + [{:keys [layout-align-items]}] + (= layout-align-items :end)) + +(defn align-items-stretch? + [{:keys [layout-align-items]}] + (= layout-align-items :stretch)) (defn reverse? [{:keys [layout-flex-dir]}] diff --git a/common/src/app/common/types/shape_tree.cljc b/common/src/app/common/types/shape_tree.cljc index aebcb9d1c..e6a41b5d8 100644 --- a/common/src/app/common/types/shape_tree.cljc +++ b/common/src/app/common/types/shape_tree.cljc @@ -132,43 +132,34 @@ (defn get-base [objects id-a id-b] - (let [parents-a (reverse (cons id-a (cph/get-parent-ids objects id-a))) - parents-b (reverse (cons id-b (cph/get-parent-ids objects id-b))) + (let [[parents-a parents-a-index] (cph/get-parent-ids-with-index objects id-a) + [parents-b parents-b-index] (cph/get-parent-ids-with-index objects id-b) - [base base-child-a base-child-b] - (loop [parents-a (rest parents-a) - parents-b (rest parents-b) - base uuid/zero] - (cond - (not= (first parents-a) (first parents-b)) - [base (first parents-a) (first parents-b)] + parents-a (cons id-a parents-a) + parents-b (into #{id-b} parents-b) - (or (empty? parents-a) (empty? parents-b)) - [uuid/zero (first parents-a) (first parents-b)] + ;; Search for the common frame in order + base (or (d/seek parents-b parents-a) uuid/zero) - :else - (recur (rest parents-a) (rest parents-b) (first parents-a)))) + idx-a (get parents-a-index base) + idx-b (get parents-b-index base)] - index-base-a (when base-child-a (cph/get-position-on-parent objects base-child-a)) - index-base-b (when base-child-b (cph/get-position-on-parent objects base-child-b))] - - [base index-base-a index-base-b])) + [base idx-a idx-b])) (defn is-shape-over-shape? [objects base-shape-id over-shape-id] (let [[base index-a index-b] (get-base objects base-shape-id over-shape-id)] (cond + ;; The base the base shape, so the other item is bellow (= base base-shape-id) - (let [object (get objects base-shape-id)] - (or (cph/frame-shape? object) - (cph/root-frame? object))) + false + ;; The base is the testing over, so it's over (= base over-shape-id) - (let [object (get objects over-shape-id)] - (or (not (cph/frame-shape? object)) - (not (cph/root-frame? object)))) + true + ;; Check which index is lower :else (< index-a index-b)))) @@ -284,35 +275,6 @@ [frame] (not (mth/almost-zero? (:rotation frame 0)))) -(defn retrieve-used-names - [objects] - (into #{} (comp (map :name) (remove nil?)) (vals objects))) - -(defn- extract-numeric-suffix - [basename] - (if-let [[_ p1 p2] (re-find #"(.*)-([0-9]+)$" basename)] - [p1 (+ 1 (d/parse-integer p2))] - [basename 1])) - -(s/def ::set-of-strings - (s/every ::us/string :kind set?)) - -(defn generate-unique-name - "A unique name generator" - [used basename] - (us/assert! ::set-of-strings used) - (us/assert! ::us/string basename) - ;; We have add a condition because UX doesn't want numbers on - ;; layer names. - (if-not (contains? used basename) - basename - (let [[prefix initial] (extract-numeric-suffix basename)] - (loop [counter initial] - (let [candidate (str prefix "-" counter)] - (if (contains? used candidate) - (recur (inc counter)) - candidate)))))) - (defn clone-object "Gets a copy of the object and all its children, with new ids and with the parent-children links correctly set. Admits functions diff --git a/common/test/common_tests/helpers/files.cljc b/common/test/common_tests/helpers/files.cljc index 694505139..66fe15034 100644 --- a/common/test/common_tests/helpers/files.cljc +++ b/common/test/common_tests/helpers/files.cljc @@ -126,7 +126,7 @@ (fn [file-data] (let [id (uuid/next) props (merge {:id id - :name "Color-1" + :name "Color 1" :color "#000000" :opacity 1} props)] @@ -140,7 +140,7 @@ (fn [file-data] (let [id (uuid/next) props (merge {:id id - :name "Typography-1" + :name "Typography 1" :font-id "sourcesanspro" :font-family "sourcesanspro" :font-size "14" diff --git a/common/test/common_tests/types_file_test.cljc b/common/test/common_tests/types_file_test.cljc index d4af3db5b..bf8a04423 100644 --- a/common/test/common_tests/types_file_test.cljc +++ b/common/test/common_tests/types_file_test.cljc @@ -101,7 +101,7 @@ ;; false) (t/is (= (count pages) 2)) - (t/is (= (:name (first pages)) "Page-1")) + (t/is (= (:name (first pages)) "Page 1")) (t/is (= (:name (second pages)) "Library backup")) (t/is (= (count components) 1)) diff --git a/frontend/resources/styles/main/partials/dashboard-team.scss b/frontend/resources/styles/main/partials/dashboard-team.scss index ed8733583..edc8d4f5a 100644 --- a/frontend/resources/styles/main/partials/dashboard-team.scss +++ b/frontend/resources/styles/main/partials/dashboard-team.scss @@ -29,7 +29,35 @@ .custom-input { width: 100%; - height: 115px; + min-height: 116px; + max-height: 176px; + overflow-y: hidden; + input { + &.no-padding { + padding-top: 12px; + } + min-height: 40px; + } + .selected-items { + gap: 8px; + padding: 8px; + max-height: 132px; + overflow-y: scroll; + .selected-item { + .around { + height: 24px; + display: flex; + align-items: center; + justify-content: flex-start; + width: fit-content; + .icon { + display: flex; + align-items: center; + justify-content: center; + } + } + } + } } .custom-select { diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss index 456364fb6..580ffe0f6 100644 --- a/frontend/resources/styles/main/partials/modal.scss +++ b/frontend/resources/styles/main/partials/modal.scss @@ -184,6 +184,7 @@ .modal-footer .action-buttons { justify-content: space-around; + gap: 15px; } .fields-container { @@ -1541,8 +1542,52 @@ .onboarding-team-members { .team-left { + padding: 42px 64px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: auto; form { - margin-top: 32px; + margin-top: 5px; + .invite-row { + .custom-input { + width: 100%; + min-height: 80px; + height: fit-content; + max-height: 176px; + overflow-y: hidden; + input { + &.no-padding { + padding-top: 12px; + } + min-height: 40px; + } + .selected-items { + gap: 7px; + padding: 7px; + max-height: 132px; + overflow-y: scroll; + .selected-item { + .around { + height: 24px; + display: flex; + align-items: center; + justify-content: flex-start; + width: fit-content; + .icon { + display: flex; + align-items: center; + justify-content: center; + } + } + } + } + } + } + .buttons { + margin-top: 12px; + } } } } diff --git a/frontend/resources/styles/main/partials/workspace.scss b/frontend/resources/styles/main/partials/workspace.scss index 1128ba62f..1331b47e0 100644 --- a/frontend/resources/styles/main/partials/workspace.scss +++ b/frontend/resources/styles/main/partials/workspace.scss @@ -17,7 +17,7 @@ $height-palette-max: 80px; #workspace { width: 100vw; - height: 100vh; + height: 100%; user-select: none; background-color: $color-canvas; display: grid; @@ -37,6 +37,8 @@ $height-palette-max: 80px; .left-toolbar { grid-area: toolbar; width: $width-left-toolbar; + overflow-y: scroll; + overflow-x: hidden; } .settings-bar.settings-bar-left { diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index fc7176c21..94d1ca7ac 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -7,6 +7,7 @@ (ns app.main.data.dashboard (:require [app.common.data :as d] + [app.common.pages :as cp] [app.common.spec :as us] [app.common.uuid :as uuid] [app.config :as cf] @@ -664,10 +665,12 @@ (ptk/reify ::create-project ptk/WatchEvent (watch [_ state _] - (let [name (name (gensym (str (tr "dashboard.new-project-prefix") " "))) - team-id (:current-team-id state) - params {:name name - :team-id team-id} + (let [projects (get state :dashboard-projects) + unames (cp/retrieve-used-names projects) + name (cp/generate-unique-name unames (str (tr "dashboard.new-project-prefix") " 1")) + team-id (:current-team-id state) + params {:name name + :team-id team-id} {:keys [on-success on-error] :or {on-success identity on-error rx/throw}} (meta params)] @@ -875,7 +878,9 @@ :or {on-success identity on-error rx/throw}} (meta params) - name (name (gensym (str (tr "dashboard.new-file-prefix") " "))) + files (get state :dashboard-files) + unames (cp/retrieve-used-names files) + name (cp/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1")) features (cond-> #{} (features/active-feature? state :components-v2) (conj "components/v2")) @@ -1067,8 +1072,12 @@ pparams (:path-params route) in-project? (contains? pparams :project-id) name (if in-project? - (name (gensym (str (tr "dashboard.new-file-prefix") " "))) - (name (gensym (str (tr "dashboard.new-project-prefix") " ")))) + (let [files (get state :dashboard-files) + unames (cp/retrieve-used-names files)] + (cp/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1"))) + (let [projects (get state :dashboard-projects) + unames (cp/retrieve-used-names projects)] + (cp/generate-unique-name unames (str (tr "dashboard.new-project-prefix") " 1")))) params (if in-project? {:project-id (:project-id pparams) :name name} diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 18bb14300..717182b9a 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -15,6 +15,7 @@ [app.common.geom.proportions :as gpp] [app.common.geom.shapes :as gsh] [app.common.logging :as log] + [app.common.pages :as cp] [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] [app.common.spec :as us] @@ -408,8 +409,8 @@ ptk/WatchEvent (watch [it state _] (let [pages (get-in state [:workspace-data :pages-index]) - unames (ctst/retrieve-used-names pages) - name (ctst/generate-unique-name unames "Page-1") + unames (cp/retrieve-used-names pages) + name (cp/generate-unique-name unames "Page 1") changes (-> (pcb/empty-changes it) (pcb/add-empty-page id name))] @@ -423,9 +424,9 @@ (watch [it state _] (let [id (uuid/next) pages (get-in state [:workspace-data :pages-index]) - unames (ctst/retrieve-used-names pages) + unames (cp/retrieve-used-names pages) page (get-in state [:workspace-data :pages-index page-id]) - name (ctst/generate-unique-name unames (:name page)) + name (cp/generate-unique-name unames (:name page)) no_thumbnails_objects (->> (:objects page) (d/mapm (fn [_ val] (dissoc val :use-for-thumbnail?)))) diff --git a/frontend/src/app/main/data/workspace/interactions.cljs b/frontend/src/app/main/data/workspace/interactions.cljs index 3eefbff6c..9a141f22d 100644 --- a/frontend/src/app/main/data/workspace/interactions.cljs +++ b/frontend/src/app/main/data/workspace/interactions.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.geom.point :as gpt] + [app.common.pages :as cp] [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] [app.common.spec :as us] @@ -33,7 +34,7 @@ flows (get-in page [:options :flows] []) unames (into #{} (map :name flows)) - name (ctst/generate-unique-name unames "Flow-1") + name (cp/generate-unique-name unames "Flow 1") new-flow {:id (uuid/next) :name name diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 78c80455a..261b3ba5b 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -73,7 +73,7 @@ (pcb/with-objects objects))] (let [group-name (if (= 1 (count shapes)) (:name (first shapes)) - "Component-1")] + "Component 1")] (dwg/prepare-create-group it objects page-id diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 48d1b4424..6ad54b229 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -15,7 +15,6 @@ [app.common.pages.helpers :as cph] [app.common.spec :as us] [app.common.types.page :as ctp] - [app.common.types.shape-tree :as ctt] [app.common.types.shape.interactions :as ctsi] [app.common.uuid :as uuid] [app.main.data.modal :as md] @@ -290,7 +289,7 @@ move to the desired position, and recalculate parents and frames as needed." [all-objects page ids delta it] (let [shapes (map (d/getf all-objects) ids) - unames (volatile! (ctt/retrieve-used-names (:objects page))) + unames (volatile! (cp/retrieve-used-names (:objects page))) update-unames! (fn [new-name] (vswap! unames conj new-name)) all-ids (reduce #(into %1 (cons %2 (cph/get-children-ids all-objects %2))) (d/ordered-set) ids) ids-map (into {} (map #(vector % (uuid/next))) all-ids) @@ -367,7 +366,7 @@ (let [update-flows (fn [flows] (reduce (fn [flows frame] - (let [name (ctt/generate-unique-name @unames "Flow-1") + (let [name (cp/generate-unique-name @unames "Flow 1") _ (vswap! unames conj name) new-flow {:id (uuid/next) :name name diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 9734c6179..6e7c6df84 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -271,16 +271,89 @@ (ptk/data-event :layout/update ids) (dwu/commit-undo-transaction undo-id)))))) +(defn fix-child-sizing + [objects parent-changes shape] + + (let [parent (-> (cph/get-parent objects (:id shape)) + (d/deep-merge parent-changes)) + + auto-width? (ctl/auto-width? parent) + auto-height? (ctl/auto-height? parent) + col? (ctl/col? parent) + row? (ctl/row? parent) + + all-children (->> parent :shapes (map (d/getf objects)))] + + (cond-> shape + ;; If the parent is hug width and the direction column + ;; change to fixed when ALL children are fill + (and col? auto-width? (every? ctl/fill-width? all-children)) + (assoc :layout-item-h-sizing :fix) + + ;; If the parent is hug height and the direction is column + ;; change to fixed when ANY children is fill + (and col? auto-height? (ctl/fill-height? shape)) + (assoc :layout-item-v-sizing :fix) + + ;; If the parent is hug width and the direction row + ;; change to fixed when ANY children is fill + (and row? auto-width? (ctl/fill-width? shape)) + (assoc :layout-item-h-sizing :fix) + + ;; If the parent is hug height and the direction row + ;; change to fixed when ALL children are fill + (and row? auto-height? (every? ctl/fill-height? all-children)) + (assoc :layout-item-v-sizing :fix)))) + +(defn fix-parent-sizing + [objects ids-set changes parent] + + (let [auto-width? (ctl/auto-width? parent) + auto-height? (ctl/auto-height? parent) + col? (ctl/col? parent) + row? (ctl/row? parent) + + all-children + (->> parent :shapes + (map (d/getf objects)) + (map (fn [shape] + (if (contains? ids-set (:id shape)) + (d/deep-merge shape changes) + shape))))] + + (cond-> parent + ;; Col layout and parent is hug-width if all children are fill-width + ;; change parent to fixed + (and col? auto-width? (every? ctl/fill-width? all-children)) + (assoc :layout-item-h-sizing :fix) + + ;; Col layout and parent is hug-height if any children is fill-height + ;; change parent to fixed + (and col? auto-height? (some ctl/fill-height? all-children)) + (assoc :layout-item-v-sizing :fix) + + ;; Row layout and parent is hug-width if any children is fill-width + ;; change parent to fixed + (and row? auto-width? (some ctl/fill-width? all-children)) + (assoc :layout-item-h-sizing :fix) + + ;; Row layout and parent is hug-height if all children are fill-height + ;; change parent to fixed + (and row? auto-height? (every? ctl/fill-height? all-children)) + (assoc :layout-item-v-sizing :fix)))) + (defn update-layout-child [ids changes] (ptk/reify ::update-layout-child ptk/WatchEvent (watch [_ state _] (let [objects (wsh/lookup-page-objects state) + children-ids (->> ids (mapcat #(cph/get-children-ids objects %))) parent-ids (->> ids (map #(cph/get-parent-id objects %))) - layout-ids (->> ids (filter (comp ctl/layout? (d/getf objects)))) undo-id (js/Symbol)] (rx/of (dwu/start-undo-transaction undo-id) (dwc/update-shapes ids #(d/deep-merge (or % {}) changes)) - (ptk/data-event :layout/update (d/concat-vec layout-ids parent-ids)) + (dwc/update-shapes children-ids (partial fix-child-sizing objects changes)) + (dwc/update-shapes parent-ids (partial fix-parent-sizing objects (set ids) changes)) + (ptk/data-event :layout/update ids) (dwu/commit-undo-transaction undo-id)))))) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 07b510349..e807d1937 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -12,6 +12,7 @@ [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.math :as mth] + [app.common.pages :as cp] [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] [app.common.spec :as us :refer [max-safe-int min-safe-int]] @@ -493,7 +494,7 @@ (- y vb-y (/ vb-height 2)) y)) - unames (ctst/retrieve-used-names objects) + unames (cp/retrieve-used-names objects) svg-name (str/replace (:name svg-data) ".svg" "") diff --git a/frontend/src/app/main/data/workspace/thumbnails.cljs b/frontend/src/app/main/data/workspace/thumbnails.cljs index 78740ac67..d012264d0 100644 --- a/frontend/src/app/main/data/workspace/thumbnails.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails.cljs @@ -77,6 +77,11 @@ ;; Delete the thumbnail first so if we interrupt we can regenerate after (->> (rp/cmd! :upsert-file-object-thumbnail params) (rx/catch #(rx/empty))) + + ;; Remove the thumbnail temporary. If the user changes pages the thumbnail is regenerated + (rx/of #(update % :workspace-thumbnails assoc object-id nil)) + + ;; Send the update to the back-end (->> blob-result (rx/merge-map (fn [blob] diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 262aa8139..59c91bbd6 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -484,6 +484,15 @@ (some (partial ctl/layout-immediate-child? objects)))) workspace-page-objects)) +(defn all-layout-child? + [ids] + (l/derived + (fn [objects] + (->> ids + (map (d/getf objects)) + (every? (partial ctl/layout-immediate-child? objects)))) + workspace-page-objects)) + (defn get-flex-child-viewer [ids page-id] (l/derived diff --git a/frontend/src/app/main/ui/components/forms.cljs b/frontend/src/app/main/ui/components/forms.cljs index f25358719..fab3f476c 100644 --- a/frontend/src/app/main/ui/components/forms.cljs +++ b/frontend/src/app/main/ui/components/forms.cljs @@ -130,7 +130,7 @@ (cond (and touched? (:message error)) [:span.error {:id (dm/str "error-" input-name) - :data-test (clojure.string/join [data-test "-error"]) }(tr (:message error))] + :data-test (clojure.string/join [data-test "-error"])} (tr (:message error))] (string? hint) [:span.hint hint])]])) @@ -328,7 +328,13 @@ remove-item! (mf/use-fn (fn [item] - (swap! items #(into [] (remove (fn [x] (= x item))) %))))] + (swap! items #(into [] (remove (fn [x] (= x item))) %)))) + + manage-key-down + (mf/use-fn + (fn [item event] + (when (kbd/enter? event) + (remove-item! item))))] (mf/with-effect [result @value] (let [val (cond-> @value trim str/trim) @@ -337,14 +343,6 @@ (update-form! values))) [:div {:class klass} - (when-let [items (seq @items)] - [:div.selected-items - (for [item items] - [:div.selected-item {:key (:text item)} - [:span.around {:class (when-not (:valid item) "invalid")} - [:span.text (:text item)] - [:span.icon {:on-click #(remove-item! item)} i/cross]]])]) - [:input {:id (name input-name) :class in-klass :type "text" @@ -355,4 +353,14 @@ :value @value :on-change on-change :placeholder (when empty? label)}] - [:label {:for (name input-name)} label]])) + [:label {:for (name input-name)} label] + + (when-let [items (seq @items)] + [:div.selected-items + (for [item items] + [:div.selected-item {:key (:text item) + :tab-index "0" + :on-key-down (partial manage-key-down item)} + [:span.around {:class (when-not (:valid item) "invalid")} + [:span.text (:text item)] + [:span.icon {:on-click #(remove-item! item)} i/cross]]])])])) diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index 983b73d04..da8d7c0e1 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -82,7 +82,7 @@ (when (:is-admin permissions) {:value "admin" :label (tr "labels.admin")}) ;; Temporarily disabled viewer roles - ;; https://tree.taiga.io/project/uxboxproject/issue/1083 + ;; https://tree.taiga.io/project/penpot/issue/1083 ;; {:value "viewer" :label (tr "labels.viewer")} ] (filterv identity))) @@ -209,7 +209,7 @@ [:li {:on-click set-admin} (tr "labels.admin")] [:li {:on-click set-editor} (tr "labels.editor")] ;; Temporarily disabled viewer role - ;; https://tree.taiga.io/project/uxboxproject/issue/1083 + ;; https://tree.taiga.io/project/penpot/issue/1083 ;; [:li {:on-click set-viewer} (tr "labels.viewer")] (when you-owner? [:li {:on-click (partial set-owner member)} (tr "labels.owner")])]]])) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs index 0900b8b75..697998f20 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs @@ -27,23 +27,21 @@ (defn- draw-thumbnail-canvas! [canvas-node img-node] - (ts/raf - (fn [] - (try - (when (and (some? canvas-node) (some? img-node)) - (let [canvas-context (.getContext canvas-node "2d") - canvas-width (.-width canvas-node) - canvas-height (.-height canvas-node)] - (.clearRect canvas-context 0 0 canvas-width canvas-height) - (.drawImage canvas-context img-node 0 0 canvas-width canvas-height) + (try + (when (and (some? canvas-node) (some? img-node)) + (let [canvas-context (.getContext canvas-node "2d") + canvas-width (.-width canvas-node) + canvas-height (.-height canvas-node)] + (.clearRect canvas-context 0 0 canvas-width canvas-height) + (.drawImage canvas-context img-node 0 0 canvas-width canvas-height) - ;; Set a true on the next animation frame, we make sure the drawImage is completed - (ts/raf - #(dom/set-data! canvas-node "ready" "true")) - true)) - (catch :default err - (.error js/console err) - false))))) + ;; Set a true on the next animation frame, we make sure the drawImage is completed + (ts/raf + #(dom/set-data! canvas-node "ready" "true")) + true)) + (catch :default err + (.error js/console err) + false))) (defn- remove-image-loading "Remove the changes related to change a url for its embed value. This is necessary @@ -78,8 +76,12 @@ (gsh/selection-rect (concat [shape] all-children)) (-> shape :points gsh/points->selrect)) - fixed-width (mth/clamp width 250 2000) - fixed-height (/ (* height fixed-width) width) + [fixed-width fixed-height] + (if (> width height) + [(mth/clamp width 250 2000) + (/ (* height (mth/clamp width 250 2000)) width)] + [(/ (* width (mth/clamp height 250 2000)) height) + (mth/clamp height 250 2000)]) image-url (mf/use-state nil) observer-ref (mf/use-var nil) @@ -91,6 +93,10 @@ thumbnail-data-ref (mf/use-memo (mf/deps page-id id) #(refs/thumbnail-frame-data page-id id)) thumbnail-data (mf/deref thumbnail-data-ref) + ;; We only need the zoom level in Safari. For other browsers we don't want to activate this because + ;; will render for every zoom change + zoom (when (cf/check-browser? :safari) (mf/deref refs/selected-zoom)) + prev-thumbnail-data (hooks/use-previous thumbnail-data) ;; State to indicate to the parent that should render the frame @@ -108,7 +114,9 @@ (let [canvas-node (mf/ref-val frame-canvas-ref) img-node (mf/ref-val frame-image-ref)] (when (draw-thumbnail-canvas! canvas-node img-node) - (reset! image-url nil) + (when-not (cf/check-browser? :safari) + (reset! image-url nil)) + (when @show-frame-thumbnail (reset! show-frame-thumbnail false)) ;; If we don't have the thumbnail data saved (normally the first load) we update the data @@ -266,12 +274,16 @@ {:key (dm/str "thumbnail-canvas-" (:id shape)) :ref frame-canvas-ref :data-object-id (dm/str page-id (:id shape)) - :width fixed-width - :height fixed-height - ;; DEBUG - :style {:filter (when (and (not (cf/check-browser? :safari)) (debug? :thumbnails)) "invert(1)") - :width "100%" - :height "100%"}}]] + :width width + :height height + :style {;; Safari has a problem with the positioning of the canvas. All this is to fix Safari behavior + ;; https://bugs.webkit.org/show_bug.cgi?id=23113 + :display (when (cf/check-browser? :safari) "none") + :position "fixed" + :transform-origin "top left" + :transform (when (cf/check-browser? :safari) (dm/fmt "scale(%)" zoom)) + ;; DEBUG + :filter (when (debug? :thumbnails) "invert(1)")}}]] ;; Safari don't support filters so instead we add a rectangle around the thumbnail (when (and (cf/check-browser? :safari) (debug? :thumbnails)) @@ -285,10 +297,10 @@ (when (some? @image-url) [:foreignObject {:x x :y y - :width width - :height height} + :width fixed-width + :height fixed-height} [:img {:ref frame-image-ref :src @image-url - :width width - :height height + :width fixed-width + :height fixed-height :on-load on-image-load}]])])])) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index f8e76adf1..3ca283c50 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -11,6 +11,7 @@ [app.common.geom.shapes :as gsh] [app.common.pages.common :as cpc] [app.common.text :as txt] + [app.common.types.shape.layout :as ctl] [app.main.data.workspace.texts :as dwt] [app.main.refs :as refs] [app.main.ui.hooks :as hooks] @@ -26,7 +27,7 @@ [app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-attrs shadow-menu]] [app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]] [app.main.ui.workspace.sidebar.options.menus.text :as ot] - [rumext.v2 :as mf])) + [rumext.v2 :as mf])) ;; Define how to read each kind of attribute depending on the shape type: ;; - shape: read the attribute directly from the shape. @@ -298,6 +299,13 @@ has-text? (contains? all-types :text) + has-layout-container? (->> shapes (some ctl/layout?)) + + all-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/all-layout-child? ids)) + all-layout-child? (mf/deref all-layout-child-ref) + + all-layout-container? (->> shapes (every? ctl/layout?)) + [measure-ids measure-values] (get-attrs shapes objects :measure) [layer-ids layer-values @@ -332,14 +340,15 @@ (when-not (empty? measure-ids) [:& measures-menu {:type type :all-types all-types :ids measure-ids :values measure-values :shape shapes}]) - [:& layout-container-menu {:type type :ids layout-container-ids :values layout-container-values :multiple true}] + (when has-layout-container? + [:& layout-container-menu {:type type :ids layout-container-ids :values layout-container-values :multiple true}]) - (when is-layout-child? + (when (or is-layout-child? has-layout-container?) [:& layout-item-menu {:type type :ids layout-item-ids - :is-layout-child? true - :is-layout-container? true + :is-layout-child? all-layout-child? + :is-layout-container? all-layout-container? :values layout-item-values}]) (when-not (or (empty? constraint-ids) is-layout-child?) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index f54cc621a..bde29f132 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -162,14 +162,14 @@ on-drag-over (actions/on-drag-over) on-drop (actions/on-drop file) on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing? - drawing-path? create-comment? space? panning workspace-read-only?) + drawing-path? create-comment? space? panning z? workspace-read-only?) on-mouse-up (actions/on-mouse-up disable-paste) on-pointer-down (actions/on-pointer-down) on-pointer-enter (actions/on-pointer-enter in-viewport?) on-pointer-leave (actions/on-pointer-leave in-viewport?) on-pointer-move (actions/on-pointer-move move-stream) on-pointer-up (actions/on-pointer-up) - on-move-selected (actions/on-move-selected hover hover-ids selected space? workspace-read-only?) + on-move-selected (actions/on-move-selected hover hover-ids selected space? z? workspace-read-only?) on-menu-selected (actions/on-menu-selected hover hover-ids selected workspace-read-only?) on-frame-enter (actions/on-frame-enter frame-hover) diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs index 4c9ab2cf5..8cf782224 100644 --- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs @@ -34,70 +34,71 @@ (defn on-mouse-down [{:keys [id blocked hidden type]} selected edition drawing-tool text-editing? - node-editing? drawing-path? create-comment? space? panning workspace-read-only?] + node-editing? drawing-path? create-comment? space? panning z? workspace-read-only?] (mf/use-callback (mf/deps id blocked hidden type selected edition drawing-tool text-editing? - node-editing? drawing-path? create-comment? @space? + node-editing? drawing-path? create-comment? @z? @space? panning workspace-read-only?) (fn [bevent] (when (or (dom/class? (dom/get-target bevent) "viewport-controls") (dom/class? (dom/get-target bevent) "viewport-selrect")) (dom/stop-propagation bevent) - (let [event (.-nativeEvent bevent) - ctrl? (kbd/ctrl? event) - meta? (kbd/meta? event) - shift? (kbd/shift? event) - alt? (kbd/alt? event) - mod? (kbd/mod? event) + (when-not @z? + (let [event (.-nativeEvent bevent) + ctrl? (kbd/ctrl? event) + meta? (kbd/meta? event) + shift? (kbd/shift? event) + alt? (kbd/alt? event) + mod? (kbd/mod? event) - left-click? (and (not panning) (= 1 (.-which event))) - middle-click? (and (not panning) (= 2 (.-which event)))] + left-click? (and (not panning) (= 1 (.-which event))) + middle-click? (and (not panning) (= 2 (.-which event)))] - (cond - (or middle-click? (and left-click? @space?)) - (do - (dom/prevent-default bevent) - (if mod? - (let [raw-pt (dom/get-client-position event) - pt (uwvv/point->viewport raw-pt)] - (st/emit! (dw/start-zooming pt))) - (st/emit! (dw/start-panning)))) + (cond + (or middle-click? (and left-click? @space?)) + (do + (dom/prevent-default bevent) + (if mod? + (let [raw-pt (dom/get-client-position event) + pt (uwvv/point->viewport raw-pt)] + (st/emit! (dw/start-zooming pt))) + (st/emit! (dw/start-panning)))) - left-click? - (do - (st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?)) + left-click? + (do + (st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?)) - (when (and (not= edition id) text-editing?) - (st/emit! dw/clear-edition-mode)) + (when (and (not= edition id) text-editing?) + (st/emit! dw/clear-edition-mode)) - (when (and (not text-editing?) - (not blocked) - (not hidden) - (not create-comment?) - (not drawing-path?)) - (cond - node-editing? + (when (and (not text-editing?) + (not blocked) + (not hidden) + (not create-comment?) + (not drawing-path?)) + (cond + node-editing? ;; Handle path node area selection - (when-not workspace-read-only? - (st/emit! (dwdp/handle-area-selection shift?))) + (when-not workspace-read-only? + (st/emit! (dwdp/handle-area-selection shift?))) - drawing-tool - (when-not workspace-read-only? - (st/emit! (dd/start-drawing drawing-tool))) + drawing-tool + (when-not workspace-read-only? + (st/emit! (dd/start-drawing drawing-tool))) - (or (not id) mod?) - (st/emit! (dw/handle-area-selection shift? mod?)) + (or (not id) mod?) + (st/emit! (dw/handle-area-selection shift? mod?)) - (not drawing-tool) - (when-not workspace-read-only? - (st/emit! (dw/start-move-selected id shift?)))))))))))) + (not drawing-tool) + (when-not workspace-read-only? + (st/emit! (dw/start-move-selected id shift?))))))))))))) (defn on-move-selected - [hover hover-ids selected space? workspace-read-only?] + [hover hover-ids selected space? z? workspace-read-only?] (mf/use-callback - (mf/deps @hover @hover-ids selected @space? workspace-read-only?) + (mf/deps @hover @hover-ids selected @space? @z? workspace-read-only?) (fn [bevent] (let [event (.-nativeEvent bevent) shift? (kbd/shift? event) @@ -110,7 +111,7 @@ (not @space?)) (dom/prevent-default bevent) (dom/stop-propagation bevent) - (when-not workspace-read-only? + (when-not (or workspace-read-only? @z?) (st/emit! (dw/start-move-selected)))))))) (defn on-frame-select diff --git a/frontend/test/frontend_tests/state_components_sync_test.cljs b/frontend/test/frontend_tests/state_components_sync_test.cljs index bdf8a9b4a..538a809e9 100644 --- a/frontend/test/frontend_tests/state_components_sync_test.cljs +++ b/frontend/test/frontend_tests/state_components_sync_test.cljs @@ -166,12 +166,12 @@ ; ; [Page] ; Root Frame - ; Component-1* #--> Component-1 + ; Component 1* #--> Component 1 ; #{:shapes-group} ; Rect 2 ---> Rect 2 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 1 ; Rect 2 ; @@ -180,14 +180,14 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) #{:shapes-group})) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape2) "Rect 2")) (t/is (= (:touched shape2) nil)) (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape2) "Rect 1")) @@ -227,14 +227,14 @@ ; ; [Page] ; Root Frame - ; Component-1* #--> Component-1 + ; Component 1* #--> Component 1 ; #{:shapes-group} ; Rect 2 ---> Rect 2 ; Rect 1 ---> Rect 1 ; Rect 3 ---> Rect 3 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 1 ; Rect 2 ; Rect 3 @@ -245,7 +245,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) #{:shapes-group})) (t/is (= (:name shape1) "Rect 2")) (t/is (= (:touched shape1) nil)) @@ -257,7 +257,7 @@ (t/is (= (:touched shape3) nil)) (t/is (not= (:shape-ref shape3) nil)) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) @@ -389,7 +389,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -478,7 +478,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -567,7 +567,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -737,12 +737,12 @@ ; ; [Page] ; Root Frame - ; Component-1 #--> Component-1 + ; Component 1 #--> Component 1 ; Rect 1 ---> Rect 1 ; Rect 2 ---> Rect 2 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 1 ; Rect 2 ; @@ -752,7 +752,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Rect 1")) @@ -762,7 +762,7 @@ (t/is (= (:touched shape2) nil)) (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) @@ -803,13 +803,13 @@ ; ; [Page] ; Root Frame - ; Component-1 #--> Component-1 + ; Component 1 #--> Component 1 ; Rect 1 ---> Rect 1 ; Rect 2 ---> Rect 2 ; Rect 3 ---> Rect 3 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 1 ; Rect 2 ; Rect 3 @@ -819,7 +819,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Rect 1")) @@ -832,7 +832,7 @@ (t/is (= (:touched shape3) nil)) (t/is (not= (:shape-ref shape3) nil)) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) @@ -1144,7 +1144,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -1517,11 +1517,11 @@ ; ; [Page] ; Root Frame - ; Component-1 #--> Component-1 + ; Component 1 #--> Component 1 ; Rect 2 ---> Rect 2 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 2 ; (let [[[group shape2] [c-group c-shape2] component] @@ -1529,14 +1529,14 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape2) "Rect 2")) (t/is (= (:touched shape2) nil)) (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape2) "Rect 2")) @@ -1576,13 +1576,13 @@ ; ; [Page] ; Root Frame - ; Component-1 #--> Component-1 + ; Component 1 #--> Component 1 ; Rect 2 ---> Rect 2 ; Rect 1 ---> Rect 1 ; Rect 3 ---> Rect 3 ; - ; [Component-1] - ; Component-1 + ; [Component 1] + ; Component 1 ; Rect 2 ; Rect 1 ; Rect 3 @@ -1592,7 +1592,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Component-1")) + (t/is (= (:name group) "Component 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:touched shape1) nil)) @@ -1605,7 +1605,7 @@ (t/is (not= (:shape-ref shape3) nil)) (t/is (= (:name shape3) "Rect 3")) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name c-group) "Component 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 2")) @@ -1737,7 +1737,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -1826,7 +1826,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) @@ -1916,7 +1916,7 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group 1] (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) diff --git a/frontend/test/frontend_tests/state_components_test.cljs b/frontend/test/frontend_tests/state_components_test.cljs index 8b83e1e75..e0bfdfe84 100644 --- a/frontend/test/frontend_tests/state_components_test.cljs +++ b/frontend/test/frontend_tests/state_components_test.cljs @@ -30,7 +30,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"})) + {:name "Rect 1"})) store (the/prepare-store state done (fn [new-state] @@ -43,12 +43,12 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; (let [shape1 (thp/get-shape new-state :shape1) @@ -59,11 +59,11 @@ file (wsh/get-local-file new-state)] - (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name group) "Rect-1")) - (t/is (= (:name component) "Rect-1")) - (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-group) "Rect-1")) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:name group) "Rect 1")) + (t/is (= (:name component) "Rect 1")) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:name c-group) "Rect 1")) (thl/is-from-file group file))))] @@ -81,7 +81,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}))] + {:name "Rect 1"}))] (->> state (the/do-update (dw/select-shape (thp/id :shape1))) @@ -97,11 +97,11 @@ file (wsh/get-local-file new-state)] - (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name group) "Component-1")) - (t/is (= (:name component) "Component-1")) - (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-group) "Component-1")) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:name group) "Component 1")) + (t/is (= (:name component) "Component 1")) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:name c-group) "Component 1")) (thl/is-from-file group file)))) @@ -113,7 +113,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/sample-shape :shape2 :rect {:name "Rect-2"})) @@ -123,13 +123,13 @@ ; ; [Page] ; Root Frame - ; Component-1 #--> Component-1 - ; Rect-1 ---> Rect-1 + ; Component 1 #--> Component 1 + ; Rect 1 ---> Rect 1 ; Rect-2 ---> Rect-2 ; - ; [Component-1] - ; Component-1 - ; Rect-1 + ; [Component 1] + ; Component 1 + ; Rect 1 ; Rect-2 ; (let [shape1 (thp/get-shape new-state :shape1) @@ -143,12 +143,12 @@ file (wsh/get-local-file new-state)] - (t/is (= (:name group) "Component-1")) - (t/is (= (:name shape1) "Rect-1")) + (t/is (= (:name group) "Component 1")) + (t/is (= (:name shape1) "Rect 1")) (t/is (= (:name shape2) "Rect-2")) - (t/is (= (:name component) "Component-1")) - (t/is (= (:name c-group) "Component-1")) - (t/is (= (:name c-shape1) "Rect-1")) + (t/is (= (:name component) "Component 1")) + (t/is (= (:name c-group) "Component 1")) + (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:name c-shape2) "Rect-2")) (thl/is-from-file group file))))] @@ -166,7 +166,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/sample-shape :shape2 :rect {:name "Rect-2"}) (thp/group-shapes :group1 @@ -180,12 +180,12 @@ ; [Page] ; Root Frame ; Group #--> Group - ; Rect-1 ---> Rect-1 + ; Rect 1 ---> Rect 1 ; Rect-2 ---> Rect-2 ; ; [Group] ; Group - ; Rect-1 + ; Rect 1 ; Rect-2 ; (let [[[group shape1 shape2] @@ -197,11 +197,11 @@ file (wsh/get-local-file new-state)] - (t/is (= (:name shape1) "Rect-1")) + (t/is (= (:name shape1) "Rect 1")) (t/is (= (:name shape2) "Rect-2")) (t/is (= (:name group) "Group")) (t/is (= (:name component) "Group")) - (t/is (= (:name c-shape1) "Rect-1")) + (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:name c-shape2) "Rect-2")) (t/is (= (:name c-group) "Group")) @@ -219,7 +219,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component1 [(thp/id :shape1)])) @@ -229,18 +229,18 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; (let [[[instance1 shape1] [c-instance1 c-shape1] @@ -257,19 +257,19 @@ new-state (:parent-id instance1))] - (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name instance1) "Rect-1")) - (t/is (= (:name component1) "Rect-1")) - (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-instance1) "Rect-1")) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:name instance1) "Rect 1")) + (t/is (= (:name component1) "Rect 1")) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:name c-instance1) "Rect 1")) - (t/is (= (:name shape1') "Rect-1")) - (t/is (= (:name instance1') "Rect-1")) - (t/is (= (:name instance2) "Rect-1")) - (t/is (= (:name component2) "Rect-1")) - (t/is (= (:name c-shape1') "Rect-1")) - (t/is (= (:name c-instance1') "Rect-1")) - (t/is (= (:name c-instance2) "Rect-1")))))] + (t/is (= (:name shape1') "Rect 1")) + (t/is (= (:name instance1') "Rect 1")) + (t/is (= (:name instance2) "Rect 1")) + (t/is (= (:name component2) "Rect 1")) + (t/is (= (:name c-shape1') "Rect 1")) + (t/is (= (:name c-instance1') "Rect 1")) + (t/is (= (:name c-instance2) "Rect 1")))))] (ptk/emit! store @@ -283,7 +283,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)])) @@ -296,11 +296,11 @@ ; [Page] ; Root Frame ; Rect-2 #--> Renamed component - ; Rect-1 ---> Rect-1 + ; Rect 1 ---> Rect 1 ; ; [Renamed] ; Renamed component - ; Rect-1 + ; Rect 1 (let [libs (wsh/get-libraries new-state) component (cph/get-component libs (:component-file instance1) @@ -319,7 +319,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)])) @@ -332,16 +332,16 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; (let [new-component-id (->> (get-in new-state [:workspace-data @@ -363,7 +363,7 @@ new-state new-component-id)] - (t/is (= (:name component2) "Rect-1")))))] + (t/is (= (:name component2) "Rect 1")))))] (ptk/emit! store @@ -376,7 +376,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)])) @@ -392,7 +392,7 @@ ; [Page] ; Root Frame ; Rect-2 - ; Rect-1 + ; Rect 1 ; (let [[instance1 shape1] (thl/resolve-noninstance @@ -420,7 +420,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)])) @@ -434,14 +434,14 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 ---> Rect-1 - ; Rect-1 #--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 ---> Rect 1 + ; Rect 1 #--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; (let [new-instance-id (-> new-state wsh/lookup-selected @@ -456,10 +456,10 @@ (t/is (not= (:id instance1) (:id instance2))) (t/is (= (:id component) component-id)) - (t/is (= (:name instance2) "Rect-1")) - (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name c-instance2) "Rect-1")) - (t/is (= (:name c-shape2) "Rect-1")) + (t/is (= (:name instance2) "Rect 1")) + (t/is (= (:name shape2) "Rect 1")) + (t/is (= (:name c-instance2) "Rect 1")) + (t/is (= (:name c-shape2) "Rect 1")) (t/is (= (:component-file instance2) thp/current-file-id)))))] @@ -476,7 +476,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)]) (thp/move-to-library :lib1 "Library 1") @@ -491,8 +491,8 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 ---> Rect 1 ; (let [new-instance-id (-> new-state wsh/lookup-selected @@ -506,10 +506,10 @@ new-instance-id)] (t/is (= (:id component) component-id)) - (t/is (= (:name instance2) "Rect-1")) - (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name c-instance2) "Rect-1")) - (t/is (= (:name c-shape2) "Rect-1")) + (t/is (= (:name instance2) "Rect 1")) + (t/is (= (:name shape2) "Rect 1")) + (t/is (= (:name c-instance2) "Rect 1")) + (t/is (= (:name c-shape2) "Rect 1")) (t/is (= (:component-file instance2) library-id)))))] (ptk/emit! @@ -525,7 +525,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)])) @@ -539,11 +539,11 @@ ; [Page] ; Root Frame ; Rect-2 - ; Rect-1 + ; Rect 1 ; ; [Rect-2] ; Rect-2 - ; Rect-1 + ; Rect 1 ; (let [[instance1 shape1] (thl/resolve-noninstance @@ -564,7 +564,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"})) + {:name "Rect 1"})) file (wsh/get-local-file state) instance1 (thp/get-shape state :instance1) @@ -577,17 +577,17 @@ ; [Page] ; Root Frame ; Group #--> Group - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; ; [Group] ; Group - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; (let [page (thp/current-page new-state) shape1 (thp/get-shape new-state :shape1) @@ -601,12 +601,12 @@ (:parent-id parent1))] (t/is (= (:name group) "Group")) - (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name shape2) "Rect-1")) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:name shape2) "Rect 1")) (t/is (= (:name component) "Group")) (t/is (= (:name c-group) "Group")) - (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-shape2) "Rect-1")))))] + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:name c-shape2) "Rect 1")))))] (ptk/emit! store @@ -622,7 +622,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)]) (thp/group-shapes :group1 @@ -641,21 +641,21 @@ ; ; [Page] ; Root Frame - ; Rect-1 #--> Rect-1 - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 - ; Rect-1 #--> Rect-1 - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 #--> Rect 1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 + ; Rect 1 #--> Rect 1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 ; - ; [Rect-1] - ; Rect-1 - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; [Rect 1] + ; Rect 1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; (let [new-instance-id (-> new-state wsh/lookup-selected @@ -672,12 +672,12 @@ (t/is (not= (:id instance1) (:id instance3))) (t/is (= (:id component) component-id)) - (t/is (= (:name instance3) "Rect-1")) - (t/is (= (:name shape3) "Rect-1")) - (t/is (= (:name shape4) "Rect-1")) - (t/is (= (:name c-instance3) "Rect-1")) - (t/is (= (:name c-shape3) "Rect-1")) - (t/is (= (:name c-shape4) "Rect-1")))))] + (t/is (= (:name instance3) "Rect 1")) + (t/is (= (:name shape3) "Rect 1")) + (t/is (= (:name shape4) "Rect 1")) + (t/is (= (:name c-instance3) "Rect 1")) + (t/is (= (:name c-shape3) "Rect 1")) + (t/is (= (:name c-shape4) "Rect 1")))))] (ptk/emit! store @@ -692,7 +692,7 @@ (let [state (-> thp/initial-state (thp/sample-page) (thp/sample-shape :shape1 :rect - {:name "Rect-1"}) + {:name "Rect 1"}) (thp/make-component :instance1 :component-1 [(thp/id :shape1)]) (thp/move-to-library :lib1 "Library 1") @@ -711,13 +711,13 @@ ; [Page] ; Root Frame ; Group #--> Group - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; ; [Group] ; Group - ; Rect-1 @--> Rect-1 - ; Rect-1 ---> Rect-1 + ; Rect 1 @--> Rect 1 + ; Rect 1 ---> Rect 1 ; (let [instance2 (thp/get-shape new-state :instance2) @@ -727,11 +727,11 @@ (:parent-id instance2))] (t/is (= (:name group1) "Group")) - (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name shape2) "Rect-1")) + (t/is (= (:name shape1) "Rect 1")) + (t/is (= (:name shape2) "Rect 1")) (t/is (= (:name c-group1) "Group")) - (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-shape2) "Rect-1")) + (t/is (= (:name c-shape1) "Rect 1")) + (t/is (= (:name c-shape2) "Rect 1")) (t/is (= (:component-file group1) thp/current-file-id)) (t/is (= (:component-file shape1) library-id)) (t/is (= (:component-file shape2) nil)) diff --git a/frontend/test/frontend_tests/util_snap_data_test.cljs b/frontend/test/frontend_tests/util_snap_data_test.cljs index 1ede8838a..31c4b03ba 100644 --- a/frontend/test/frontend_tests/util_snap_data_test.cljs +++ b/frontend/test/frontend_tests/util_snap_data_test.cljs @@ -19,7 +19,7 @@ (t/testing "Add empty page (only root-frame)" (let [page (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/get-current-page)) data (-> (sd/make-snap-data) @@ -28,7 +28,7 @@ (t/testing "Create simple shape on root" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/create-rect {:x 0 :y 0 @@ -57,7 +57,7 @@ (t/testing "Add page with single empty frame" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 0 :y 0 @@ -81,7 +81,7 @@ (t/testing "Add page with some shapes inside frames" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 0 :y 0 @@ -112,7 +112,7 @@ (t/testing "Add a global guide" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-guide {:position 50 :axis :x}) (fb/add-artboard {:x 200 :y 200 :width 100 :height 100}) (fb/close-artboard)) @@ -140,7 +140,7 @@ (t/testing "Add a frame guide" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 200 :y 200 :width 100 :height 100}) (fb/close-artboard)) @@ -171,7 +171,7 @@ (t/deftest test-update-index (t/testing "Create frame on root and then remove it." (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 0 :y 0 @@ -201,7 +201,7 @@ (t/testing "Create simple shape on root. Then remove it" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/create-rect {:x 0 :y 0 @@ -229,7 +229,7 @@ (t/testing "Create shape inside frame, then remove it" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 0 :y 0 @@ -260,7 +260,7 @@ (t/testing "Create global guide then remove it" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-guide {:position 50 :axis :x})) guide-id (:last-id file) @@ -293,7 +293,7 @@ (t/testing "Create frame guide then remove it" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 200 :y 200 :width 100 :height 100}) (fb/close-artboard)) @@ -324,7 +324,7 @@ (t/testing "Update frame coordinates" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-artboard {:x 0 :y 0 @@ -358,7 +358,7 @@ (t/testing "Update shape coordinates" (let [file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/create-rect {:x 0 :y 0 @@ -388,7 +388,7 @@ (t/testing "Update global guide" (let [guide {:position 50 :axis :x} file (-> (fb/create-file "Test") - (fb/add-page {:name "Page-1"}) + (fb/add-page {:name "Page 1"}) (fb/add-guide guide)) guide-id (:last-id file)