diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index f62f8bc6a..7a21a1241 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -869,7 +869,12 @@ ::sm/params schema:create-team-with-invitations} [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id emails role] :as params}] (db/with-atomic [conn pool] - (let [params (assoc params :profile-id profile-id) + + (let [features (-> (cfeat/get-enabled-features cf/flags) + (cfeat/check-client-features! (:features params))) + params (assoc params + :profile-id profile-id + :features features) cfg (assoc cfg ::db/conn conn) team (create-team cfg params) profile (db/get-by-id conn :profile profile-id) diff --git a/common/src/app/common/files/builder.cljc b/common/src/app/common/files/builder.cljc index d10b494d9..c30a2e8c8 100644 --- a/common/src/app/common/files/builder.cljc +++ b/common/src/app/common/files/builder.cljc @@ -16,6 +16,7 @@ [app.common.pprint :as pp] [app.common.schema :as sm] [app.common.svg :as csvg] + [app.common.text :as txt] [app.common.types.components-list :as ctkl] [app.common.types.container :as ctn] [app.common.types.file :as ctf] @@ -322,8 +323,19 @@ (defn create-path [file data] (create-shape file :path data)) +(defn- clean-text-content + "Clean the content data so it doesn't break the validation" + [content] + (letfn [(update-fill [fill] + (d/update-in-when fill [:fill-color-gradient :type] keyword))] + (txt/transform-nodes + (fn [node] + (d/update-when node :fills #(mapv update-fill %))) + content))) + (defn create-text [file data] - (create-shape file :text data)) + (let [data (d/update-when data :content clean-text-content)] + (create-shape file :text data))) (defn create-image [file data] (create-shape file :image data)) diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index efccf250c..d6c1178bd 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -495,9 +495,11 @@ (= layout-align-items :stretch)) (defn reverse? - [{:keys [layout-flex-dir]}] - (or (= :row-reverse layout-flex-dir) - (= :column-reverse layout-flex-dir))) + ([objects id] + (reverse? (get objects id))) + ([{:keys [layout-flex-dir]}] + (or (= :row-reverse layout-flex-dir) + (= :column-reverse layout-flex-dir)))) (defn space-between? [{:keys [layout-justify-content]}] diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index bde91339d..267e299e2 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -425,11 +425,11 @@ (let [{:keys [on-success on-error] :or {on-success identity on-error rx/throw}} (meta params) - features (features/get-enabled-features state)] - params {:name name - :emails #{emails} - :role role - :features features} + features (features/get-enabled-features state) + params {:name name + :emails emails + :role role + :features features}] (->> (rp/cmd! :create-team-with-invitations params) (rx/tap on-success) (rx/map team-created) diff --git a/frontend/src/app/main/data/preview.cljs b/frontend/src/app/main/data/preview.cljs index 7510fb089..e5865e19a 100644 --- a/frontend/src/app/main/data/preview.cljs +++ b/frontend/src/app/main/data/preview.cljs @@ -98,7 +98,8 @@ closed-preview (rx/subject) preview (.open js/window "/#/frame-preview") listener-fn #(rx/push! closed-preview true)] - (.addEventListener preview "beforeunload" listener-fn) + (when (some? preview) + (.addEventListener preview "beforeunload" listener-fn)) (->> (rx/from-atom (refs/all-children-objects shape-id) {:emit-current-value? true}) (rx/take-until closed-preview) (rx/debounce 1000) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 91a080b71..23e8dd546 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -2013,6 +2013,7 @@ (d/index-by :prev-id)) selected (:selected pdata) + objects (:objects pdata) position (deref ms/mouse-position) @@ -2036,6 +2037,10 @@ index 0) + selected (if (and (ctl/flex-layout? page-objects parent-id) (not (ctl/reverse? page-objects parent-id))) + (into (d/ordered-set) (reverse selected)) + selected) + objects (update-vals objects (partial process-shape file-id frame-id parent-id)) all-objects (merge page-objects objects) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index b552bee67..d4f8799f7 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -46,9 +46,10 @@ ;; When the interaction is finished (e.g. user releases mouse button), the ;; apply-modifiers event is done, that consolidates all modifiers into the base ;; geometric attributes of the shapes. + (defn- check-delta - "If the shape is a component instance, check its relative position respect the - root of the component, and see if it changes after applying a transformation." + "If the shape is a component instance, check its relative position and rotation respect + the root of the component, and see if it changes after applying a transformation." [shape root transformed-shape transformed-root] (let [shape-delta (when root @@ -65,6 +66,11 @@ (gpt/distance-vector shape-delta transformed-shape-delta) (gpt/point 0 0)) + rotation-delta + (if (and (some? (:rotation shape)) (some? (:rotation shape))) + (- (:rotation transformed-shape) (:rotation shape)) + 0) + selrect (:selrect shape) transformed-selrect (:selrect transformed-shape)] @@ -76,7 +82,8 @@ ;; shape position unchanged. But in this case we do not want to ignore it. (and (and (< (:x distance) 1) (< (:y distance) 1)) (mth/close? (:width selrect) (:width transformed-selrect)) - (mth/close? (:height selrect) (:height transformed-selrect))))) + (mth/close? (:height selrect) (:height transformed-selrect)) + (mth/close? rotation-delta 0)))) (defn calculate-ignore-tree "Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers" diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index b8d10264d..f3d7a72d6 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -547,11 +547,6 @@ :subsections [:shape] :fn #(emit-when-no-readonly (dw/create-bool :exclude))} - ;; PREVIEW - :preview-frame {:tooltip (ds/meta (ds/alt ds/enter)) - :command (ds/c-mod "alt+enter") - :fn #(emit-when-no-readonly (dp/open-preview-selected))} - ;; THEME :toggle-theme {:tooltip (ds/alt "M") :command (ds/a-mod "m") @@ -559,6 +554,12 @@ :fn #(st/emit! (with-meta (du/toggle-theme) {::ev/origin "workspace:shortcut"}))}}) +(def debug-shortcuts + ;; PREVIEW + {:preview-frame {:tooltip (ds/meta (ds/alt ds/enter)) + :command (ds/c-mod "alt+enter") + :fn #(emit-when-no-readonly (dp/open-preview-selected))}}) + (def opacity-shortcuts (into {} (->> (range 10) @@ -569,7 +570,9 @@ :fn #(emit-when-no-readonly (dwly/pressed-opacity n))}]))))) (def shortcuts - (merge base-shortcuts opacity-shortcuts dwtxts/shortcuts)) + (cond-> (merge base-shortcuts opacity-shortcuts dwtxts/shortcuts) + *assert* + (merge debug-shortcuts))) (defn get-tooltip [shortcut] (assert (contains? shortcuts shortcut) (str shortcut)) diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index c42a65378..f9c7cbc7c 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -287,7 +287,7 @@ (nil? (:fills node)) (assoc :fills (:fills txt/default-text-attrs)) - (and (d/not-empty? color-attrs) (nil? (:fills node))) + (and (d/not-empty? color-attrs) (empty? (:fills node))) (-> (dissoc :fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient) (assoc :fills [color-attrs]))))) diff --git a/frontend/src/app/main/ui/onboarding/team_choice.cljs b/frontend/src/app/main/ui/onboarding/team_choice.cljs index a3a007c38..86b710bcf 100644 --- a/frontend/src/app/main/ui/onboarding/team_choice.cljs +++ b/frontend/src/app/main/ui/onboarding/team_choice.cljs @@ -154,7 +154,7 @@ params (:clean-data @form) emails (:emails params) - roles (mf/use-memo #(get-available-roles)) + roles (mf/use-memo get-available-roles) on-success (mf/use-fn @@ -168,7 +168,7 @@ on-error (mf/use-fn - (fn [_form _response] + (fn [_form _cause] (st/emit! (msg/error "Error on creating team.")))) ;; The SKIP branch only creates the team, without invitations diff --git a/frontend/src/app/main/ui/shapes/text/styles.cljs b/frontend/src/app/main/ui/shapes/text/styles.cljs index c8fbf2053..7d46c98ed 100644 --- a/frontend/src/app/main/ui/shapes/text/styles.cljs +++ b/frontend/src/app/main/ui/shapes/text/styles.cljs @@ -101,9 +101,6 @@ :textRendering "geometricPrecision"} fills (cond - (some? (:fills data)) - (:fills data) - ;; DEPRECATED: still here for backward compatibility with ;; old penpot files that still has a single color. (or (some? (:fill-color data)) @@ -113,7 +110,10 @@ :fill-color-ref-id :fill-color-ref-file]))] (nil? (:fills data)) - [{:fill-color "#000000" :fill-opacity 1}]) + [{:fill-color "#000000" :fill-opacity 1}] + + :else + (:fills data)) font (some->> font-id (get fontsdb)) diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index bfcb839db..048314f55 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -118,12 +118,9 @@ on-change-tab (mf/use-fn - (fn [event] - (let [tab (-> (dom/get-current-target event) - (dom/get-data "tab") - (keyword))] - (reset! active-color-tab tab) - (dc/set-active-color-tab! tab)))) + (fn [tab] + (reset! active-color-tab tab) + (dc/set-active-color-tab! tab))) handle-change-mode (mf/use-fn diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 570b25faf..8921cc25d 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -248,18 +248,13 @@ {::mf/props :obj} [{:keys [item on-enter-group]}] (let [group-name (:name item) - path (cfh/butlast-path-with-dots group-name) on-group-click #(on-enter-group group-name)] [:div {:class (stl/css :component-group) :on-click on-group-click :title group-name} - [:div {:class (stl/css :path-wrapper)} - (when-not (str/blank? path) - [:span {:class (stl/css :component-group-path)} - (str "\u00A0\u2022\u00A0" path)]) - [:span {:class (stl/css :component-group-name)} - (cfh/last-path group-name)]] + [:span {:class (stl/css :component-group-name)} + (cfh/last-path group-name)] [:span {:class (stl/css :arrow-icon)} i/arrow]])) @@ -416,10 +411,7 @@ (mf/use-fn (fn [style] (swap! filters* assoc :listing-thumbs? (= style "grid")))) - - filters-but-last (cfh/butlast-path (:path filters)) - last-filters (cfh/last-path (:path filters)) - filter-path-with-dots (->> filters-but-last (cfh/split-path) (cfh/join-path-with-dot))] + filter-path-with-dots (->> (:path filters) (cfh/split-path) (cfh/join-path-with-dot))] [:div {:class (stl/css :component-swap)} [:div {:class (stl/css :element-set-title)} @@ -462,10 +454,8 @@ :on-click on-go-back :title filter-path-with-dots} [:span {:class (stl/css :back-arrow)} i/arrow] - (when-not (= "" filter-path-with-dots) - [:span {:class (stl/css :path-name)} - (dm/str "\u00A0\u2022\u00A0" filter-path-with-dots)]) - [:span {:class (stl/css :path-name-last)} last-filters]]) + [:span {:class (stl/css :path-name)} + filter-path-with-dots]]) (when (empty? items) [:div {:class (stl/css :component-list-empty)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss index d024187a7..3587d0fbe 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.scss @@ -254,14 +254,7 @@ direction: rtl; height: $s-32; padding: $s-8 0 $s-8 $s-2; -} - -.path-name-last { - @include bodySmallTypography; - @include textEllipsis; - height: $s-32; - padding: $s-8 0 $s-8 $s-2; - color: white; + margin-right: $s-4; } .component-list-empty {