From 06c8ada6f7f7be72a4c0fea90efa67c4134e8b9b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Oct 2023 11:13:07 +0200 Subject: [PATCH 1/2] :zap: Improve performance for constraints --- .../app/common/geom/shapes/constraints.cljc | 46 +++++++++++++------ .../src/app/common/geom/shapes/modifiers.cljc | 7 ++- common/src/app/common/geom/shapes/points.cljc | 11 +++++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/common/src/app/common/geom/shapes/constraints.cljc b/common/src/app/common/geom/shapes/constraints.cljc index 6a9885e69..cda192609 100644 --- a/common/src/app/common/geom/shapes/constraints.cljc +++ b/common/src/app/common/geom/shapes/constraints.cljc @@ -314,21 +314,37 @@ (let [transformed-parent-bounds @transformed-parent-bounds modifiers (ctm/select-child modifiers) - transformed-child-bounds (gtr/transform-bounds child-bounds modifiers) - modifiers (normalize-modifiers constraints-h constraints-v modifiers - child-bounds transformed-child-bounds parent-bounds transformed-parent-bounds) - transformed-child-bounds (gtr/transform-bounds child-bounds modifiers) - child-points-before (gpo/parent-coords-bounds child-bounds parent-bounds) - child-points-after (gpo/parent-coords-bounds transformed-child-bounds transformed-parent-bounds) + reset-modifiers? + (and (gpo/axis-aligned? parent-bounds) + (gpo/axis-aligned? child-bounds) + (gpo/axis-aligned? transformed-parent-bounds)) - modifiers-h (constraint-modifier (constraints-h const->type+axis) :x - child-points-before parent-bounds - child-points-after transformed-parent-bounds) + modifiers + (if reset-modifiers? + (ctm/empty) + (normalize-modifiers constraints-h constraints-v modifiers + child-bounds (gtr/transform-bounds child-bounds modifiers) + parent-bounds transformed-parent-bounds)) - modifiers-v (constraint-modifier (constraints-v const->type+axis) :y - child-points-before parent-bounds - child-points-after transformed-parent-bounds)] - (-> modifiers - (ctm/add-modifiers modifiers-h) - (ctm/add-modifiers modifiers-v)))))) + transformed-child-bounds (if reset-modifiers? + child-bounds + (gtr/transform-bounds child-bounds modifiers))] + + ;; If the parent is a layout we don't need to calculate its constraints. Finish + ;; after normalize the children (to keep proper proportions) + (if (ctl/any-layout? parent) + modifiers + (let [child-points-before (gpo/parent-coords-bounds child-bounds parent-bounds) + child-points-after (gpo/parent-coords-bounds transformed-child-bounds transformed-parent-bounds) + + modifiers-h (constraint-modifier (constraints-h const->type+axis) :x + child-points-before parent-bounds + child-points-after transformed-parent-bounds) + + modifiers-v (constraint-modifier (constraints-v const->type+axis) :y + child-points-before parent-bounds + child-points-after transformed-parent-bounds)] + (-> modifiers + (ctm/add-modifiers modifiers-h) + (ctm/add-modifiers modifiers-v)))))))) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index fb033a49b..bfcaf6519 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -100,7 +100,11 @@ [modif-tree children objects bounds parent transformed-parent-bounds ignore-constraints] (let [modifiers (dm/get-in modif-tree [(:id parent) :modifiers])] ;; Move modifiers don't need to calculate constraints - (if (ctm/only-move? modifiers) + (cond + (ctm/empty? modifiers) + modif-tree + + (ctm/only-move? modifiers) (loop [modif-tree modif-tree children (seq children)] (if-let [current (first children)] @@ -109,6 +113,7 @@ modif-tree)) ;; Check the constraints, then resize + :else (let [parent-id (:id parent) parent-bounds (gtr/transform-bounds @(get bounds parent-id) (ctm/select-parent modifiers))] (loop [modif-tree modif-tree diff --git a/common/src/app/common/geom/shapes/points.cljc b/common/src/app/common/geom/shapes/points.cljc index 3722beb9e..348472bd2 100644 --- a/common/src/app/common/geom/shapes/points.cljc +++ b/common/src/app/common/geom/shapes/points.cljc @@ -91,6 +91,17 @@ :else 0))) +(defn axis-aligned? + "Check if the points are parallel to the coordinate axis." + [[p1 p2 _ p4 :as pts]] + (and (= (count pts) 4) + (let [hv (gpt/to-vec p1 p2) + vv (gpt/to-vec p1 p4)] + (and (mth/almost-zero? (:y hv)) + (mth/almost-zero? (:x vv)) + (> (:x hv) 0) + (> (:y vv) 0))))) + (defn parent-coords-bounds [child-bounds [p1 p2 _ p4 :as parent-bounds]] From 96bbc350423340162594a0b9dce1076f61edcfc8 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 20 Oct 2023 06:58:28 +0200 Subject: [PATCH 2/2] :tada: Improve onboarding team creation and invite workflow --- .../resources/styles/main/partials/modal.scss | 19 +++---- .../app/main/ui/onboarding/team_choice.cljs | 49 ++++++++++++------- frontend/translations/en.po | 33 ++++++++----- frontend/translations/es.po | 33 ++++++++----- 4 files changed, 79 insertions(+), 55 deletions(-) diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss index 3636416c4..3e4e0ee9f 100644 --- a/frontend/resources/styles/main/partials/modal.scss +++ b/frontend/resources/styles/main/partials/modal.scss @@ -1437,19 +1437,19 @@ font-size: $fs26; font-weight: $fw700; color: $color-gray-60; - margin-bottom: 6px; + margin-bottom: 8px; } .info { font-size: $fs14; color: $color-black; } form { - margin-top: 60px; flex-grow: 1; display: flex; flex-direction: column; - justify-content: space-between; + justify-content: start; align-items: flex-start; + row-gap: 1.5rem; .custom-input { width: 100%; } @@ -1507,7 +1507,6 @@ text-align: left; font-size: $fs12; color: $color-gray-30; - cursor: pointer; } } @@ -1540,14 +1539,10 @@ .onboarding-team-members { .team-left { - padding: 42px 64px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: auto; form { - margin-top: 5px; + align-items: stretch; + margin-top: 24px; + row-gap: normal; .invite-row { .custom-input { width: 100%; @@ -1584,7 +1579,7 @@ } } .buttons { - margin: 12px 0; + margin: 32px 0 16px 0; button { height: auto; } diff --git a/frontend/src/app/main/ui/onboarding/team_choice.cljs b/frontend/src/app/main/ui/onboarding/team_choice.cljs index fd1f3ead2..e37244969 100644 --- a/frontend/src/app/main/ui/onboarding/team_choice.cljs +++ b/frontend/src/app/main/ui/onboarding/team_choice.cljs @@ -6,7 +6,6 @@ (ns app.main.ui.onboarding.team-choice (:require - [app.common.data :as d] [app.common.spec :as us] [app.main.data.dashboard :as dd] [app.main.data.events :as ev] @@ -20,7 +19,6 @@ [app.util.router :as rt] [app.util.timers :as tm] [cljs.spec.alpha :as s] - [cuerdas.core :as str] [potok.core :as ptk] [rumext.v2 :as mf])) @@ -80,7 +78,7 @@ [:div.modal-overlay [:div.modal-container.onboarding-team.animated.fadeIn [:div.team-left - [:h2.title (tr "onboarding.choice.team-up.create-team")] + [:h2.title (tr "onboarding.team-modal.create-team")] [:p.info (tr "onboarding.choice.team-up.create-team-desc")] [:& fm/form {:form form :on-submit on-submit} @@ -89,9 +87,13 @@ :label (tr "onboarding.choice.team-up.create-team-placeholder")}] [:& fm/submit-button - {:label (tr "labels.continue")}]] + {:label (tr "onboarding.choice.team-up.continue-creating-team")}]] - [:button.skip-action {:on-click on-skip} (tr "onboarding.choice.team-up.create-later")]] + [:h2.title (tr "onboarding.choice.team-up.start-without-a-team")] + [:p.info (tr "onboarding.choice.team-up.start-without-a-team-description")] + + [:div + [:button.btn-primary.btn-large {:on-click on-skip} (tr "onboarding.choice.team-up.continue-without-a-team")]]] [:& team-modal-right] [:div.paginator "1/2"] @@ -107,7 +109,7 @@ [{:value "editor" :label (tr "labels.editor")} {:value "admin" :label (tr "labels.admin")}]) -(s/def ::emails (s/and ::us/set-of-valid-emails d/not-empty?)) +(s/def ::emails (s/and ::us/set-of-valid-emails)) (s/def ::role ::us/keyword) (s/def ::invite-form (s/keys :req-un [::role ::emails])) @@ -124,12 +126,11 @@ :name name})) form (fm/use-form :spec ::invite-form :initial initial) - + params (:clean-data @form) + emails (:emails params) + roles (mf/use-memo #(get-available-roles)) - profile (mf/deref refs/profile) - email (-> profile :email str/lower) - on-success (mf/use-callback (fn [_form response] @@ -146,7 +147,7 @@ (st/emit! (dm/error "Error on creating team.")))) ;; The SKIP branch only creates the team, without invitations - on-skip + on-invite-later (mf/use-callback (fn [_] (let [mdata {:on-success (partial on-success form) @@ -159,14 +160,13 @@ :step 2}))))) ;; The SUBMIT branch creates the team with the invitations - on-submit + on-invite-now (mf/use-callback - (fn [form _] + (fn [_] (let [mdata {:on-success (partial on-success form) :on-error (partial on-error form)} params (:clean-data @form) - emails (disj (:emails params) email) - params (assoc params :emails emails)] + emails (:emails params)] (st/emit! (if (> (count emails) 0) ;; If the user is only inviting to itself we don't call to create-team-with-invitations @@ -177,7 +177,16 @@ :invites (count emails) :role (:role params) :name name - :step 2})))))] + :step 2}))))) + + on-submit + (mf/use-callback + (fn [_] + (let [params (:clean-data @form) + emails (:emails params)] + (if (> (count emails) 0) + (on-invite-now form) + (on-invite-later form)))))] [:div.modal-overlay [:div.modal-container.onboarding-team-members.animated.fadeIn @@ -210,10 +219,12 @@ :step 2}))} (tr "labels.back")] [:& fm/submit-button - {:label (tr "onboarding.choice.team-up.invite-members-submit")}]] + {:label + (if (> (count emails) 0) + (tr "onboarding.choice.team-up.create-team-and-send-invites") + (tr "onboarding.choice.team-up.create-team-without-inviting"))}]] [:div.skip-action - {:on-click on-skip} - [:div.action (tr "onboarding.choice.team-up.invite-members-skip")]]]] + (tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]] [:& team-modal-right] [:div.paginator "2/2"] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 0605e8cd0..e8bd9cdf1 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2238,18 +2238,33 @@ msgstr "Contributing guide" msgid "onboarding-v2.welcome.title" msgstr "Welcome to Penpot!" -msgid "onboarding.choice.team-up.create-later" -msgstr "Create a team later" - -msgid "onboarding.choice.team-up.create-team" -msgstr "Your team name" - msgid "onboarding.choice.team-up.create-team-desc" msgstr "After naming your team, you will be able to invite people to join." msgid "onboarding.choice.team-up.create-team-placeholder" msgstr "Enter the name of the team" +msgid "onboarding.choice.team-up.continue-creating-team" +msgstr "Continue creating team" + +msgid "onboarding.choice.team-up.start-without-a-team" +msgstr "Start without a team" + +msgid "onboarding.choice.team-up.start-without-a-team-description" +msgstr "You will be able to create a team later." + +msgid "onboarding.choice.team-up.continue-without-a-team" +msgstr "Continue without team" + +msgid "onboarding.choice.team-up.create-team-and-send-invites" +msgstr "Create team and send invites" + +msgid "onboarding.choice.team-up.create-team-without-inviting" +msgstr "Create team without inviting" + +msgid "onboarding.choice.team-up.create-team-and-send-invites-description" +msgstr "You'll be able to invite later" + msgid "onboarding.choice.team-up.invite-members" msgstr "Invite members" @@ -2258,12 +2273,6 @@ msgstr "" "Remember to include everyone. Developers, designers, managers... diversity " "adds up :)" -msgid "onboarding.choice.team-up.invite-members-skip" -msgstr "Create team and invite later" - -msgid "onboarding.choice.team-up.invite-members-submit" -msgstr "Create team and send invites" - msgid "onboarding.choice.team-up.roles" msgstr "Invite with the role:" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 0bab82043..8dc32d34d 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -2307,18 +2307,33 @@ msgstr "Guía de contribución" msgid "onboarding-v2.welcome.title" msgstr "¡Te damos la bienvenida a Penpot!" -msgid "onboarding.choice.team-up.create-later" -msgstr "Crea un equipo más tarde" - -msgid "onboarding.choice.team-up.create-team" -msgstr "El nombre de tu equipo" - msgid "onboarding.choice.team-up.create-team-desc" msgstr "Tras nombrar tu equipo podrás invitar a personas para que se unan." msgid "onboarding.choice.team-up.create-team-placeholder" msgstr "Introduce el nombre del equipo" +msgid "onboarding.choice.team-up.continue-creating-team" +msgstr "Continuar creando equipo" + +msgid "onboarding.choice.team-up.start-without-a-team" +msgstr "Comenzar sin equipo" + +msgid "onboarding.choice.team-up.start-without-a-team-description" +msgstr "Podrás crear un equipo después." + +msgid "onboarding.choice.team-up.continue-without-a-team" +msgstr "Seguir sin equipo" + +msgid "onboarding.choice.team-up.create-team-and-send-invites" +msgstr "Crear equipo y enviar invitaciones" + +msgid "onboarding.choice.team-up.create-team-without-inviting" +msgstr "Crear equipo sin invitar" + +msgid "onboarding.choice.team-up.create-team-and-send-invites-description" +msgstr "Podrás enviar invitaciones después" + msgid "onboarding.choice.team-up.invite-members" msgstr "Invitar integrantes" @@ -2327,12 +2342,6 @@ msgstr "" "No olvides incluir personas de desarrollo, diseño, gestión… la diversidad " "suma :)" -msgid "onboarding.choice.team-up.invite-members-skip" -msgstr "Crear equipo e invitar después" - -msgid "onboarding.choice.team-up.invite-members-submit" -msgstr "Crear equipo y enviar invitaciones" - msgid "onboarding.choice.team-up.roles" msgstr "Invitar con el rol:"