diff --git a/common/src/app/common/geom/shapes/constraints.cljc b/common/src/app/common/geom/shapes/constraints.cljc index 5aeb5e3d4..9b3e9d0e1 100644 --- a/common/src/app/common/geom/shapes/constraints.cljc +++ b/common/src/app/common/geom/shapes/constraints.cljc @@ -322,21 +322,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 ebb1db8e0..bbc07180e 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -103,7 +103,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)] @@ -112,6 +116,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 dbd1bfcf7..8783d76f3 100644 --- a/common/src/app/common/geom/shapes/points.cljc +++ b/common/src/app/common/geom/shapes/points.cljc @@ -100,6 +100,17 @@ [(gpt/to-vec p0 p1) p0 p3])] (gsi/line-line-intersect point (gpt/add point other-vec) start end))) +(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]] (if (empty? child-bounds) diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss index 35a7ec3bc..7498ef5b2 100644 --- a/frontend/resources/styles/main/partials/modal.scss +++ b/frontend/resources/styles/main/partials/modal.scss @@ -1512,19 +1512,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%; } @@ -1582,7 +1582,6 @@ text-align: left; font-size: $fs12; color: $color-gray-30; - cursor: pointer; } } @@ -1615,14 +1614,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%; @@ -1659,7 +1654,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 ee0e047bd..06785c02a 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} @@ -88,10 +86,14 @@ :name :name :label (tr "onboarding.choice.team-up.create-team-placeholder")}] - [:> fm/submit-button* - {:label (tr "labels.continue")}]] + [:& fm/submit-button* + {: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 @@ -209,12 +218,13 @@ :name name :step 2}))} (tr "labels.back")] - [:> fm/submit-button* - {:label (tr "onboarding.choice.team-up.invite-members-submit")}]] - + [:& fm/submit-button* + {: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 d70cb351d..8766883f2 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2209,18 +2209,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" @@ -2229,12 +2244,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 3c096f801..321496ae9 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -2266,18 +2266,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" @@ -2286,12 +2301,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:"