mirror of
https://github.com/penpot/penpot.git
synced 2026-06-15 20:02:17 +00:00
♻️ Refurbish create team slide
This commit is contained in:
parent
6eae360ddf
commit
efeff85646
1
frontend/resources/images/form/slide-final-team.svg
Normal file
1
frontend/resources/images/form/slide-final-team.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 77 KiB |
@ -5,13 +5,18 @@
|
||||
;; Copyright (c) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
(ns app.main.ui.forms
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.controls.input :refer [input*]]
|
||||
[app.main.ui.ds.controls.select :refer [select*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.forms :as fm]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.keyboard :as k]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def context (mf/create-context nil))
|
||||
@ -49,8 +54,123 @@
|
||||
|
||||
[:> input* props]))
|
||||
|
||||
(defn- conj-dedup
|
||||
"Adds item into a vector and removes possible duplicates."
|
||||
[coll item]
|
||||
(into [] (distinct) (conj coll item)))
|
||||
|
||||
(mf/defc form-multi-input*
|
||||
[{:keys [name trim valid-item-fn caution-item-fn] :rest props}]
|
||||
(let [form (mf/use-ctx context)
|
||||
|
||||
touched? (and (contains? (:data @form) name)
|
||||
(get-in @form [:touched name]))
|
||||
|
||||
value (mf/use-state "")
|
||||
focus? (mf/use-state false)
|
||||
|
||||
items
|
||||
(mf/use-state
|
||||
(fn []
|
||||
(let [initial (get-in @form [:data name])]
|
||||
(if (or (vector? initial) (set? initial))
|
||||
(mapv (fn [val]
|
||||
{:text val
|
||||
:valid (valid-item-fn val)
|
||||
:caution (caution-item-fn val)})
|
||||
initial)
|
||||
[]))))
|
||||
|
||||
on-focus
|
||||
(mf/use-fn
|
||||
#(reset! focus? true))
|
||||
|
||||
on-change
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [content (-> event dom/get-target dom/get-input-value)]
|
||||
(reset! value content))))
|
||||
|
||||
on-key-down
|
||||
(mf/use-fn
|
||||
(mf/deps @value form name valid-item-fn caution-item-fn trim)
|
||||
(fn [event]
|
||||
(let [val (cond-> @value trim str/trim)]
|
||||
(cond
|
||||
(or (k/enter? event) (k/comma? event) (k/space? event))
|
||||
(do
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(swap! form assoc-in [:touched name] true)
|
||||
(when (and (valid-item-fn val) (not (str/empty? @value)))
|
||||
(reset! value "")
|
||||
(swap! form assoc-in [:touched name] false)
|
||||
(doseq [v (str/split val #",|\s+")]
|
||||
(let [v (str/trim v)]
|
||||
(swap! items conj-dedup {:text v
|
||||
:valid (valid-item-fn v)
|
||||
:caution (caution-item-fn v)})))))
|
||||
|
||||
(and (k/backspace? event) (str/empty? @value))
|
||||
(do
|
||||
(dom/prevent-default event)
|
||||
(dom/stop-propagation event)
|
||||
(swap! items (fn [items]
|
||||
(if (empty? items) items (pop items)))))))))
|
||||
|
||||
on-blur
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(reset! focus? false)
|
||||
(when-not (get-in @form [:touched name])
|
||||
(swap! form assoc-in [:touched name] true))))
|
||||
|
||||
on-remove-item
|
||||
(mf/use-fn
|
||||
(fn [item]
|
||||
(swap! items #(filterv (fn [x] (not= x item)) %))))
|
||||
|
||||
props
|
||||
(mf/spread-props props {:value @value
|
||||
:on-change on-change
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-key-down on-key-down
|
||||
:hint-type (when (and touched?
|
||||
(not (str/empty? @value))
|
||||
(not (valid-item-fn @value))) "error")})]
|
||||
|
||||
;; Sync form data whenever items or input value changes.
|
||||
;; This ensures the current (unconfirmed) input value is included in the
|
||||
;; form data when the user submits without pressing Enter/Space/Comma.
|
||||
(mf/with-effect [@items @value]
|
||||
(let [items-text (mapv :text @items)
|
||||
val (cond-> @value trim str/trim)
|
||||
combined (if (and (valid-item-fn val) (not (str/empty? val)))
|
||||
(conj items-text val)
|
||||
items-text)
|
||||
data (str/join " " combined)]
|
||||
(fm/update-input-value! form name data)))
|
||||
|
||||
[:div {:class (stl/css :multi-input)}
|
||||
[:> input* props]
|
||||
|
||||
(when-let [items-seq (seq @items)]
|
||||
[:div {:class (stl/css :multi-input-chips)}
|
||||
(for [item items-seq]
|
||||
[:div {:class (stl/css :multi-input-chip)
|
||||
:key (:text item)}
|
||||
[:span {:class (stl/css :multi-input-chip-text)}
|
||||
(:text item)]
|
||||
[:> icon-button* {:variant "ghost"
|
||||
:class (stl/css :multi-input-chip-icon)
|
||||
:icon i/close
|
||||
:icon-size "s"
|
||||
:aria-label (tr "labels.remove")
|
||||
:on-click (partial on-remove-item item)}]])])]))
|
||||
|
||||
(mf/defc form-select*
|
||||
[{:keys [name] :as props}]
|
||||
[{:keys [name] :rest props}]
|
||||
(let [select-name name
|
||||
form (mf/use-ctx context)
|
||||
value (get-in @form [:data select-name] "")
|
||||
|
||||
43
frontend/src/app/main/ui/forms.scss
Normal file
43
frontend/src/app/main/ui/forms.scss
Normal file
@ -0,0 +1,43 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
@use "ds/typography.scss" as t;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_utils.scss" as *;
|
||||
|
||||
.multi-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-s);
|
||||
}
|
||||
|
||||
.multi-input-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.multi-input-chip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-xs);
|
||||
block-size: $sz-24;
|
||||
padding-inline-start: var(--sp-s);
|
||||
border-radius: $br-6;
|
||||
background-color: var(--color-background-tertiary);
|
||||
}
|
||||
|
||||
.multi-input-chip-text {
|
||||
@include t.use-typography("body-small");
|
||||
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.multi-input-chip-icon {
|
||||
inline-size: $sz-24;
|
||||
block-size: $sz-24;
|
||||
}
|
||||
@ -14,47 +14,60 @@
|
||||
[app.main.data.profile :as du]
|
||||
[app.main.data.team :as dtm]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.icons :as deprecated-icon]
|
||||
[app.main.ui.notifications.context-notification :refer [context-notification]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.main.ui.ds.foundations.typography :as t]
|
||||
[app.main.ui.ds.foundations.typography.heading :refer [heading*]]
|
||||
[app.main.ui.ds.foundations.typography.text :refer [text*]]
|
||||
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
|
||||
[app.main.ui.forms :as fc]
|
||||
[app.util.forms :as fm]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc left-sidebar*
|
||||
(mf/defc team-info-feature*
|
||||
{::mf/private true}
|
||||
[{:keys [icon-id text]}]
|
||||
[:li {:class (stl/css :modal-info-item)}
|
||||
[:div {:class (stl/css :modal-info-icon)}
|
||||
[:> icon* {:icon-id icon-id :size "m"}]]
|
||||
[:> text* {:as "div"
|
||||
:typography t/body-medium
|
||||
:class (stl/css :color-light)}
|
||||
text]])
|
||||
|
||||
(mf/defc team-info*
|
||||
{::mf/private true}
|
||||
[]
|
||||
[:div {:class (stl/css :modal-left)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
[:div {:class (stl/css :modal-info)}
|
||||
[:img {:src "images/form/slide-final-team.svg"}]
|
||||
|
||||
[:> heading* {:level 2
|
||||
:typography t/title-medium
|
||||
:class (stl/css :color-light)}
|
||||
(tr "onboarding.team-modal.team-definition")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
|
||||
[:> text* {:as "div"
|
||||
:typography t/body-medium
|
||||
:class (stl/css :color-dimmed :margin-bottom)}
|
||||
(tr "onboarding.team-modal.create-team-desc")]
|
||||
[:ul {:class (stl/css :team-features)}
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} deprecated-icon/document]
|
||||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-1")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} deprecated-icon/move]
|
||||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-2")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} deprecated-icon/tree]
|
||||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-3")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} deprecated-icon/user]
|
||||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-4")]]
|
||||
[:li {:class (stl/css :feature)}
|
||||
[:span {:class (stl/css :icon)} deprecated-icon/tick]
|
||||
[:p {:class (stl/css :modal-desc)}
|
||||
(tr "onboarding.team-modal.create-team-feature-5")]]]])
|
||||
|
||||
[:ul {:class (stl/css :modal-info-features)}
|
||||
[:> team-info-feature* {:icon-id i/document
|
||||
:text (tr "onboarding.team-modal.create-team-feature-1")}]
|
||||
[:> team-info-feature* {:icon-id i/move
|
||||
:text (tr "onboarding.team-modal.create-team-feature-2")}]
|
||||
[:> team-info-feature* {:icon-id i/tree
|
||||
:text (tr "onboarding.team-modal.create-team-feature-3")}]
|
||||
[:> team-info-feature* {:icon-id i/user
|
||||
:text (tr "onboarding.team-modal.create-team-feature-4")}]
|
||||
[:> team-info-feature* {:icon-id i/tick
|
||||
:text (tr "onboarding.team-modal.create-team-feature-5")}]]])
|
||||
|
||||
(defn- get-available-roles
|
||||
[]
|
||||
[{:value "viewer" :label (tr "labels.viewer")}
|
||||
{:value "editor" :label (tr "labels.editor")}
|
||||
{:value "admin" :label (tr "labels.admin")}])
|
||||
[{:id "viewer" :value "viewer" :label (tr "labels.viewer")}
|
||||
{:id "editor" :value "editor" :label (tr "labels.editor")}
|
||||
{:id "admin" :value "admin" :label (tr "labels.admin")}])
|
||||
|
||||
(def ^:private schema:team-form
|
||||
[:map {:title "TeamForm"}
|
||||
@ -68,8 +81,8 @@
|
||||
(let [initial (mf/with-memo []
|
||||
{:role "editor"})
|
||||
|
||||
form (fm/use-form :schema schema:team-form
|
||||
:initial initial)
|
||||
form (fm/use-form :schema schema:team-form
|
||||
:initial initial)
|
||||
|
||||
roles (mf/use-memo get-available-roles)
|
||||
|
||||
@ -109,7 +122,7 @@
|
||||
:else
|
||||
(swap! error* (tr "errors.generic"))))))
|
||||
|
||||
on-invite-later
|
||||
on-create-without-invitations
|
||||
(mf/use-fn
|
||||
(fn [{:keys [name]}]
|
||||
(let [mdata {:on-success on-success
|
||||
@ -117,126 +130,125 @@
|
||||
params {:name name}]
|
||||
(st/emit! (-> (dtm/create-team (with-meta params mdata))
|
||||
(with-meta {::ev/origin :onboarding-without-invitations}))
|
||||
(ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite-later"
|
||||
:team-name name
|
||||
:step 8})
|
||||
(ev/event
|
||||
{::ev/name "onboarding-finish"})))))
|
||||
(ev/event {::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite-later"
|
||||
:team-name name
|
||||
:step 8})
|
||||
(ev/event {::ev/name "onboarding-finish"})))))
|
||||
|
||||
on-invite-now
|
||||
on-create-with-invitations
|
||||
(mf/use-fn
|
||||
(fn [{:keys [name emails] :as params}]
|
||||
(let [mdata {:on-success on-success
|
||||
:on-error on-error}]
|
||||
|
||||
(st/emit! (-> (dtm/create-team-with-invitations (with-meta params mdata))
|
||||
(with-meta {::ev/origin :onboarding-with-invitations}))
|
||||
(ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite"
|
||||
:invites (count emails)
|
||||
:team-name name
|
||||
:role (:role params)
|
||||
:step 8})
|
||||
(ev/event
|
||||
{::ev/name "onboarding-finish"})))))
|
||||
(ev/event {::ev/name "onboarding-step"
|
||||
:label "team:create-team-and-invite"
|
||||
:invites (count emails)
|
||||
:team-name name
|
||||
:role (:role params)
|
||||
:step 8})
|
||||
(ev/event {::ev/name "onboarding-finish"})))))
|
||||
|
||||
on-submit*
|
||||
on-submit
|
||||
(mf/use-fn
|
||||
(fn [form]
|
||||
(let [params (:clean-data @form)
|
||||
emails (:emails params)]
|
||||
(if (> (count emails) 0)
|
||||
(on-invite-now params)
|
||||
(on-invite-later params)))))
|
||||
(on-create-with-invitations params)
|
||||
(on-create-without-invitations params)))))
|
||||
|
||||
on-skip
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (du/update-profile-props {:onboarding-viewed true})
|
||||
(ev/event
|
||||
{::ev/name "onboarding-step"
|
||||
:label "team:skip-team-creation"
|
||||
:step 7})
|
||||
(ev/event
|
||||
{::ev/name "onboarding-finish"}))))]
|
||||
[:*
|
||||
[:div {:class (stl/css :modal-right)}
|
||||
[:div {:class (stl/css :first-block)}
|
||||
[:& fm/form {:form form
|
||||
:class (stl/css :modal-form)
|
||||
:on-submit on-submit*}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]
|
||||
(ev/event {::ev/name "onboarding-step"
|
||||
:label "team:skip-team-creation"
|
||||
:step 7})
|
||||
(ev/event {::ev/name "onboarding-finish"}))))]
|
||||
|
||||
[:div {:class (stl/css :modal-team)}
|
||||
[:> fc/form* {:form form
|
||||
:class (stl/css :modal-team-form)
|
||||
:on-submit on-submit}
|
||||
|
||||
[:& fm/input {:type "text"
|
||||
:class (stl/css :team-name-input)
|
||||
:name :name
|
||||
:auto-focus? true
|
||||
:placeholder "Team name"
|
||||
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
[:div {:class (stl/css :modal-team-block)}
|
||||
[:> heading* {:level 2
|
||||
:typography t/title-medium
|
||||
:class (stl/css :color-light)}
|
||||
(tr "onboarding.team-modal.create-team")]
|
||||
|
||||
[:h2 {:class (stl/css :modal-subtitle :invite-subtitle)} (tr "onboarding.choice.team-up.invite-members")]
|
||||
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
|
||||
[:> fc/form-input* {:type "text"
|
||||
:name :name
|
||||
:auto-focus true
|
||||
:auto-complete "off"
|
||||
:placeholder (tr "onboarding.choice.team-up.create-team-placeholder")}]
|
||||
|
||||
(when-let [content (deref error*)]
|
||||
[:& context-notification {:content content :level :error}])
|
||||
[:> text* {:as "div"
|
||||
:typography t/body-small
|
||||
:class (stl/css :color-dimmed)}
|
||||
(tr "onboarding.choice.team-up.create-team-desc")]]
|
||||
|
||||
[:div {:class (stl/css :role-select)}
|
||||
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
|
||||
[:& fm/select {:name :role :options roles}]]
|
||||
[:div {:class (stl/css :modal-team-block)}
|
||||
[:> heading* {:level 2
|
||||
:typography t/title-medium
|
||||
:class (stl/css :color-light)}
|
||||
(tr "onboarding.choice.team-up.invite-members")]
|
||||
|
||||
[:div {:class (stl/css :invitation-row)}
|
||||
[:& fm/multi-input {:type "email"
|
||||
:name :emails
|
||||
:trim true
|
||||
:valid-item-fn sm/parse-email
|
||||
:caution-item-fn #{}
|
||||
:label (tr "modals.invite-member.emails")}]]
|
||||
(when-let [content (deref error*)]
|
||||
[:> context-notification* {:level :error}
|
||||
content])
|
||||
|
||||
[:div {:class (stl/css :modal-team-sub-block)}
|
||||
[:> fc/form-select* {:name :role
|
||||
:options roles}]
|
||||
[:> fc/form-multi-input* {:type "email"
|
||||
:name :emails
|
||||
:trim true
|
||||
:valid-item-fn sm/parse-email
|
||||
:caution-item-fn #{}
|
||||
:auto-complete "off"
|
||||
:placeholder (tr "modals.invite-member.emails")}]]
|
||||
[:> text* {:as "div"
|
||||
:typography t/body-small
|
||||
:class (stl/css :color-dimmed)}
|
||||
(tr "onboarding.choice.team-up.invite-members-info")]
|
||||
|
||||
(let [params (:clean-data @form)
|
||||
emails (:emails params)]
|
||||
[:*
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
(let [params (:clean-data @form)
|
||||
emails (:emails params)
|
||||
num-emails (count emails)]
|
||||
[:*
|
||||
[:div {:class (stl/css :flex-align-right)}
|
||||
[:> fc/form-submit* {:variant "primary"}
|
||||
(if (> num-emails 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))]]
|
||||
|
||||
[:> fm/submit-button*
|
||||
{:class (stl/css :accept-button)
|
||||
:label (if (> (count emails) 0)
|
||||
(tr "onboarding.choice.team-up.create-team-and-invite")
|
||||
(tr "onboarding.choice.team-up.create-team-without-invite"))}]]
|
||||
(when (= num-emails 0)
|
||||
[:> text* {:as "div"
|
||||
:typography t/body-small
|
||||
:class (stl/css :color-dimmed :text-align-right)}
|
||||
"(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")"])])]]
|
||||
|
||||
(when (= (count emails) 0)
|
||||
[:> :div {:class (stl/css :modal-hint)}
|
||||
"(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")"])])]]
|
||||
|
||||
[:div {:class (stl/css :second-block)}
|
||||
[:h2 {:class (stl/css :modal-subtitle)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team")]
|
||||
[:p {:class (stl/css :modal-text)}
|
||||
(tr "onboarding.choice.team-up.start-without-a-team-description")]
|
||||
|
||||
[:div {:class (stl/css :action-buttons)}
|
||||
[:button {:class (stl/css :accept-button)
|
||||
:on-click on-skip}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]]))
|
||||
[:> text* {:as "div"
|
||||
:typography t/headline-small
|
||||
:class (stl/css :link)
|
||||
:on-click on-skip
|
||||
:tab-index "0"}
|
||||
(tr "onboarding.choice.team-up.continue-without-a-team")]]))
|
||||
|
||||
(mf/defc onboarding-team-modal*
|
||||
[{:keys [go-to-team]}]
|
||||
|
||||
[:div {:class (stl/css-case
|
||||
:modal-overlay true)}
|
||||
|
||||
[:div {:class (stl/css-case :modal-overlay true)}
|
||||
[:div.animated.fade-in {:class (stl/css :modal-container)}
|
||||
[:h1 {:class (stl/css :modal-title)}
|
||||
[:> heading* {:level 1
|
||||
:typography t/title-large
|
||||
:class (stl/css :color-light)}
|
||||
(tr "onboarding-v2.welcome.title")]
|
||||
[:div {:class (stl/css :modal-sections)}
|
||||
[:> left-sidebar*]
|
||||
[:div {:class (stl/css :separator)}]
|
||||
[:> team-info*]
|
||||
[:div {:class (stl/css :modal-separator)}
|
||||
[:div {:class (stl/css :modal-separator-line)}]]
|
||||
[:> team-form* {:go-to-team go-to-team}]]]])
|
||||
|
||||
|
||||
@ -5,216 +5,131 @@
|
||||
// Copyright (c) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
@use "refactor/common-refactor.scss" as deprecated;
|
||||
@use "ds/_borders.scss" as *;
|
||||
@use "ds/_sizes.scss" as *;
|
||||
@use "ds/_utils.scss" as *;
|
||||
|
||||
.color-light {
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
|
||||
.color-dimmed {
|
||||
color: var(--color-foreground-secondary);
|
||||
}
|
||||
|
||||
.text-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.flex-align-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.margin-bottom {
|
||||
margin-bottom: var(--sp-xxl);
|
||||
}
|
||||
|
||||
.link {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-align: center;
|
||||
color: var(--color-foreground-secondary);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
@extend %modal-overlay-base;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
position: relative;
|
||||
width: deprecated.$s-908;
|
||||
max-height: deprecated.$s-800;
|
||||
height: 100%;
|
||||
padding-inline: deprecated.$s-100;
|
||||
padding-block: deprecated.$s-40 deprecated.$s-40;
|
||||
border-radius: deprecated.$br-8;
|
||||
background-color: var(--modal-background-color);
|
||||
border: deprecated.$s-2 solid var(--modal-border-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: deprecated.$s-24;
|
||||
gap: var(--sp-xxl);
|
||||
position: relative;
|
||||
inline-size: px2rem(908);
|
||||
padding: $sz-64 px2rem(100);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--color-background-primary);
|
||||
border: $b-2 solid var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
.modal-sections {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr deprecated.$s-32 1fr;
|
||||
gap: deprecated.$s-24;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
grid-template-columns: px2rem(310) $sz-32 1fr;
|
||||
gap: var(--sp-xxl);
|
||||
block-size: 100%;
|
||||
}
|
||||
|
||||
.paginator {
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
position: absolute;
|
||||
top: deprecated.$s-40;
|
||||
right: deprecated.$s-100;
|
||||
padding: deprecated.$s-4;
|
||||
border-radius: deprecated.$br-6;
|
||||
color: var(--color-foreground-secondary);
|
||||
.modal-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-xl);
|
||||
border: $b-1 solid var(--color-foreground-secondary);
|
||||
padding: var(--sp-m);
|
||||
border-radius: $br-12;
|
||||
background-color: var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
// MODAL LEFT
|
||||
.modal-left {
|
||||
.modal-info-features {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-m);
|
||||
}
|
||||
|
||||
.modal-info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-l);
|
||||
}
|
||||
|
||||
.modal-info-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
inline-size: $sz-32;
|
||||
block-size: $sz-32;
|
||||
border-radius: $br-circle;
|
||||
border: $b-1 solid var(--color-accent-primary);
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.modal-separator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-separator-line {
|
||||
inline-size: px2rem(8);
|
||||
block-size: 100%;
|
||||
border-radius: $br-8;
|
||||
opacity: 0.5;
|
||||
background-color: var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
.modal-team {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-xl);
|
||||
}
|
||||
|
||||
.modal-team-form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: deprecated.$s-32 auto auto 1fr;
|
||||
gap: deprecated.$s-16;
|
||||
overflow: auto;
|
||||
gap: var(--sp-xxl);
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
@include deprecated.big-title-typography;
|
||||
|
||||
color: var(--modal-title-foreground-color);
|
||||
.modal-team-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-m);
|
||||
}
|
||||
|
||||
.modal-subtitle {
|
||||
@include deprecated.med-title-typography;
|
||||
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.invite-subtitle {
|
||||
padding-top: deprecated.$s-16;
|
||||
}
|
||||
|
||||
.modal-text {
|
||||
@include deprecated.body-large-typography;
|
||||
|
||||
color: var(--modal-text-foreground-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal-desc {
|
||||
@include deprecated.small-title-typography;
|
||||
|
||||
margin: 0;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.team-features {
|
||||
@include deprecated.flex-column;
|
||||
|
||||
gap: deprecated.$s-16;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.feature {
|
||||
@include deprecated.flex-row;
|
||||
|
||||
gap: deprecated.$s-16;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@include deprecated.flex-center;
|
||||
|
||||
height: deprecated.$s-32;
|
||||
width: deprecated.$s-32;
|
||||
border-radius: deprecated.$br-circle;
|
||||
border: deprecated.$s-1 solid var(--color-accent-primary);
|
||||
|
||||
svg {
|
||||
@extend %button-icon;
|
||||
|
||||
stroke: var(--color-accent-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
@extend %modal-action-btns;
|
||||
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.accept-button {
|
||||
@extend %modal-accept-btn;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@extend %modal-cancel-btn;
|
||||
}
|
||||
|
||||
// SEPARATOR
|
||||
.separator {
|
||||
width: deprecated.$s-8;
|
||||
height: 100%;
|
||||
border-radius: deprecated.$br-8;
|
||||
opacity: 0.42;
|
||||
background-color: var(--modal-separator-background-color);
|
||||
}
|
||||
|
||||
// MODAL RIGHT TEAM
|
||||
.modal-right {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: deprecated.$s-24;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.first-block {
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.first-block,
|
||||
.second-block {
|
||||
@include deprecated.flex-column;
|
||||
|
||||
gap: deprecated.$s-16;
|
||||
}
|
||||
|
||||
.modal-form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: deprecated.$s-16;
|
||||
}
|
||||
|
||||
.team-name-input {
|
||||
@extend %input-element-label;
|
||||
|
||||
label {
|
||||
@include deprecated.flex-column;
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
height: 100%;
|
||||
|
||||
input {
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
margin-top: deprecated.$s-8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MODAL RIGHT INVITATIONS
|
||||
|
||||
.modal-right-invitations {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto auto 1fr;
|
||||
gap: deprecated.$s-16;
|
||||
max-height: deprecated.$s-512;
|
||||
}
|
||||
|
||||
.modal-form-invitations {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto 1fr auto auto;
|
||||
margin-block-end: deprecated.$s-72;
|
||||
gap: deprecated.$s-8;
|
||||
}
|
||||
|
||||
.role-title {
|
||||
@include deprecated.uppercase-title-typography;
|
||||
|
||||
margin-block-end: deprecated.$s-8;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.invitation-row {
|
||||
margin: 0;
|
||||
color: var(--modal-title-foreground-color);
|
||||
}
|
||||
|
||||
.modal-hint {
|
||||
@include deprecated.body-small-typography;
|
||||
|
||||
color: var(--modal-text-foreground-color);
|
||||
text-align: right;
|
||||
.modal-team-sub-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-s);
|
||||
}
|
||||
|
||||
@ -4750,7 +4750,7 @@ msgstr "Invite members"
|
||||
#: src/app/main/ui/onboarding/team_choice.cljs:187
|
||||
msgid "onboarding.choice.team-up.invite-members-info"
|
||||
msgstr ""
|
||||
"Remember to include everyone. Developers, designers, managers... diversity "
|
||||
"Remember to include everyone. Developers, designers, managers... Diversity "
|
||||
"adds up :)"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs:258, src/app/main/ui/onboarding/team_choice.cljs:193
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user