0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-27 07:01:27 -05:00

♻️ Remove new-css-system from modals

This commit is contained in:
Eva 2024-01-03 13:23:06 +01:00
parent 7a3525febc
commit 3f151f16ce
41 changed files with 2359 additions and 4385 deletions

View file

@ -9,7 +9,6 @@
(:require
[app.main.data.modal :as modal]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -27,8 +26,8 @@
hint
accept-label
accept-style] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-accept (or on-accept identity)
(let [on-accept (or on-accept identity)
message (or message (tr "ds.alert-title"))
accept-label (or accept-label (tr "ds.alert-ok"))
accept-style (or accept-style :danger)
@ -50,7 +49,6 @@
(on-accept props)))]
(->> (events/listen js/document "keydown" on-keydown)
(partial events/unlistenByKey))))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -73,31 +71,4 @@
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]
[:div.modal-overlay
[:div.modal-container.alert-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 title]]
[:div.modal-close-button
{:on-click accept-fn} i/close]]
[:div.modal-content
(when (and (string? message) (not= message ""))
[:h3 message])
(when (and (string? scd-message) (not= scd-message ""))
[:h3 scd-message])
(when (string? hint)
[:p hint])]
[:div.modal-footer
[:div.action-buttons
[:input.accept-button
{:class (dom/classnames
:danger (= accept-style :danger)
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]])))
:on-click accept-fn}]]]]]))

View file

@ -11,40 +11,46 @@
&.transparent {
background-color: transparent;
}
.modal-container {
}
.modal-container {
@extend .modal-container-base;
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content {
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.modal-hint {
}
.modal-hint {
@include titleTipography;
}
}
.modal-footer {
.action-buttons {
}
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}
.modal-scd-msg,

View file

@ -12,7 +12,6 @@
[app.main.ui.auth.recovery :refer [recovery-page]]
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
[app.main.ui.auth.register :refer [register-page register-success-page register-validate-page]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -20,12 +19,10 @@
(mf/defc terms-login
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
(let [show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
show-terms? (some? cf/terms-of-service-uri)
show-privacy? (some? cf/privacy-policy-uri)]
(if new-css-system
(when show-all?
[:div {:class (stl/css :terms-login)}
(when show-terms?
@ -35,30 +32,17 @@
[:span (tr "labels.and")])
(when show-privacy?
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])
(when show-all?
[:div.terms-login
(when show-terms?
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
(when show-all?
[:span (tr "labels.and")])
(when show-privacy?
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])]))))
[:a {:href cf/privacy-policy-uri :target "_blank"} (tr "auth.privacy-policy")])])))
(mf/defc auth
[{:keys [route] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
section (get-in route [:data :name])
(let [section (get-in route [:data :name])
params (:query-params route)
show-illustration? (contains? cf/flags :login-illustration)]
(mf/use-effect
#(dom/set-html-title (tr "title.default")))
(if new-css-system
[:main {:class (stl/css-case :auth-section true
:no-illustration (not show-illustration?))}
(when show-illustration?
@ -67,7 +51,7 @@
[:section {:class (stl/css :auth-content)}
[:*
[:a {:href "#/" :class (stl/css :logo-btn)}i/logo]
[:a {:href "#/" :class (stl/css :logo-btn)} i/logo]
(case section
:auth-register
[:& register-page {:params params}]
@ -88,34 +72,4 @@
[:& recovery-page {:params params}])]
(when (contains? #{:auth-login :auth-register} section)
[:& terms-login])]]
;; OLD
[:main.auth
[:section.auth-sidebar
[:a.logo {:href "#/"}
[:span {:aria-hidden true} i/logo]
[:span.hidden-name "Home"]]
[:span.tagline (tr "auth.sidebar-tagline")]]
[:section.auth-content
(case section
:auth-register
[:& register-page {:params params}]
:auth-register-validate
[:& register-validate-page {:params params}]
:auth-register-success
[:& register-success-page {:params params}]
:auth-login
[:& login-page {:params params}]
:auth-recovery-request
[:& recovery-request-page]
:auth-recovery
[:& recovery-page {:params params}])
[:& terms-login {}]]])))
[:& terms-login])]]))

View file

@ -18,7 +18,6 @@
[app.main.ui.components.button-link :as bl]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.dom :as dom]
@ -94,8 +93,7 @@
(mf/defc login-form
[{:keys [params on-success-callback origin] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (mf/deps params) (constantly params))
(let [initial (mf/use-memo (mf/deps params) (constantly params))
error (mf/use-state false)
form (fm/use-form :spec ::login-form
:validators [handle-error-messages]
@ -157,7 +155,6 @@
(mf/use-fn
#(st/emit! (rt/nav :auth-recovery-request)))]
(if new-css-system
[:*
(when-let [message @error]
[:& msgs/inline-banner
@ -201,58 +198,15 @@
(when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]]
;; OLD
[:*
(when-let [message @error]
[:& msgs/inline-banner
{:type :warning
:content message
:on-close #(reset! error nil)
:data-test "login-banner"
:role "alert"}])
[:& fm/form {:on-submit on-submit :form form}
[:div.fields-row
[:& fm/input
{:name :email
:type "email"
:help-icon i/at
:label (tr "auth.email")
:class (stl/css :form-field)}]]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password
:help-icon i/eye
:label (tr "auth.password")
:class (stl/css :form-field)}]]
[:div.buttons-stack
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:> fm/submit-button*
{:label (tr "auth.login-submit")
:data-test "login-submit"}])
(when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]])))
:on-click on-submit-ldap}])]]]))
(mf/defc login-buttons
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
(let [login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
login-with-github (mf/use-fn (mf/deps params) #(login-with-oidc % :github params))
login-with-gitlab (mf/use-fn (mf/deps params) #(login-with-oidc % :gitlab params))
login-with-oidc (mf/use-fn (mf/deps params) #(login-with-oidc % :oidc params))]
(if new-css-system
[:div {:class (stl/css :auth-buttons)}
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
@ -276,37 +230,11 @@
[:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class (stl/css :login-btn :btn-oidc-auth)}])]
[:div.auth-buttons
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
:icon i/brand-google
:label (tr "auth.login-with-google-submit")
:class "btn-google-auth"}])
(when (contains? cf/flags :login-with-github)
[:& bl/button-link {:on-click login-with-github
:icon i/brand-github
:label (tr "auth.login-with-github-submit")
:class "btn-github-auth"}])
(when (contains? cf/flags :login-with-gitlab)
[:& bl/button-link {:on-click login-with-gitlab
:icon i/brand-gitlab
:label (tr "auth.login-with-gitlab-submit")
:class "btn-gitlab-auth"}])
(when (contains? cf/flags :login-with-oidc)
[:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class "btn-github-auth"}])])))
:class (stl/css :login-btn :btn-oidc-auth)}])]))
(mf/defc login-button-oidc
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
login-oidc
(let [login-oidc
(mf/use-fn
(mf/deps params)
(fn [event]
@ -317,26 +245,15 @@
(fn [event]
(when (k/enter? event)
(login-oidc event))))]
(if new-css-system
(when (contains? cf/flags :login-with-oidc)
[:div {:class (stl/css :link-entry :link-oidc)}
[:a {:tab-index "0"
:on-key-down handle-key-down
:on-click login-oidc}
(tr "auth.login-with-oidc-submit")]])
;; OLD
(when (contains? cf/flags :login-with-oidc)
[:div.link-entry.link-oidc
[:a {:tab-index "0"
:on-key-down handle-key-down
:on-click login-oidc}
(tr "auth.login-with-oidc-submit")]]))))
(tr "auth.login-with-oidc-submit")]])))
(mf/defc login-methods
[{:keys [params on-success-callback origin] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(when show-alt-login-buttons?
[:*
@ -350,36 +267,11 @@
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback :origin origin}])]
;; OLD
[:*
(when show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
[:& login-buttons {:params params}]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback}])])))
[:& login-form {:params params :on-success-callback on-success-callback :origin origin}])])
(mf/defc login-page
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
go-register
(let [go-register
(mf/use-fn
#(st/emit! (rt/nav :auth-register {} params)))
@ -391,7 +283,6 @@
(mf/use-fn
#(st/emit! (du/create-demo-profile)))]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "login-title"} (tr "auth.login-title")]
@ -420,35 +311,5 @@
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action on-create-demo-profile
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]])]
;; OLD
[:div.generic-form.login-form
[:div.form-container
[:h1 {:data-test "login-title"} (tr "auth.login-title")]
[:& login-methods {:params params}]
[:div.links
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:div.link-entry
[:& lk/link {:action on-pass-recovery
:data-test "forgot-password"}
(tr "auth.forgot-password")]])
(when (contains? cf/flags :registration)
[:div.link-entry
[:span (tr "auth.register") " "]
[:& lk/link {:action go-register
:data-test "register-submit"}
(tr "auth.register-submit")]])]
(when (contains? cf/flags :demo-users)
[:div.links.demo
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action on-create-demo-profile
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]]])]])))
(tr "auth.create-demo-account")]])]))

View file

@ -14,8 +14,6 @@
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[beicon.v2.core :as rx]
@ -34,8 +32,7 @@
(mf/defc recovery-form
[{:keys [on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::recovery-request-form
(let [form (fm/use-form :spec ::recovery-request-form
:validators [handle-error-messages]
:initial {})
submitted (mf/use-state false)
@ -77,7 +74,6 @@
(reset! form nil)
(st/emit! (du/request-profile-recovery params)))))]
(if new-css-system
[:& fm/form {:on-submit on-submit
:form form}
[:div {:class (stl/css :fields-row)}
@ -89,30 +85,15 @@
[:> fm/submit-button*
{:label (tr "auth.recovery-request-submit")
:data-test "recovery-resquest-submit"
:class (stl/css :recover-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :email
:label (tr "auth.email")
:help-icon i/at
:type "text"}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-request-submit")
:data-test "recovery-resquest-submit"}]])))
:class (stl/css :recover-btn)}]]))
;; --- Recovery Request Page
(mf/defc recovery-request-page
[{:keys [params on-success-callback go-back-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
default-go-back #(st/emit! (rt/nav :auth-login))
(let [default-go-back #(st/emit! (rt/nav :auth-login))
go-back (or go-back-callback default-go-back)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)} (tr "auth.recovery-request-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.recovery-request-subtitle")]
@ -123,16 +104,4 @@
[:div {:class (stl/css :link-entry)}
[:& lk/link {:action go-back
:data-test "go-back-link"}
(tr "labels.go-back")]]]
;; old
[:section.generic-form
[:div.form-container
[:h1 (tr "auth.recovery-request-title")]
[:div.subtitle (tr "auth.recovery-request-subtitle")]
[:& recovery-form {:params params :on-success-callback on-success-callback}]
[:div.links
[:div.link-entry
[:& lk/link {:action go-back
:data-test "go-back-link"}
(tr "labels.go-back")]]]]])))
(tr "labels.go-back")]]]))

View file

@ -17,7 +17,6 @@
[app.main.ui.auth.login :as login]
[app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.i18n :refer [tr tr-html]]
@ -88,8 +87,7 @@
(mf/defc register-form
[{:keys [params on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (mf/deps params) (constantly params))
(let [initial (mf/use-memo (mf/deps params) (constantly params))
form (fm/use-form :spec ::register-form
:validators [validate
(fm/validate-not-empty :password (tr "auth.password-not-empty"))]
@ -114,7 +112,6 @@
(partial handle-prepare-register-error form))))))]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "email"
@ -135,65 +132,21 @@
{:label (tr "auth.register-submit")
:disabled @submitted?
:data-test "register-form-submit"
:class (stl/css :register-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "email"
:name :email
:help-icon i/at
:label (tr "auth.email")
:data-test "email-input"}]]
[:div.fields-row
[:& fm/input {:name :password
:hint (tr "auth.password-length-hint")
:label (tr "auth.password")
:type "password"}]]
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:data-test "register-form-submit"}]])))
:class (stl/css :register-btn)}]]))
(mf/defc register-methods
[{:keys [params on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
(when login/show-alt-login-buttons?
[:*
[:hr {:class (stl/css :separator)}]
[:& login/login-buttons {:params params}]])
[:hr {:class (stl/css :separator)}]
[:& register-form {:params params :on-success-callback on-success-callback}]]
;; OLD
[:*
(when login/show-alt-login-buttons?
[:*
[:span.separator
[:span.line]
[:span.text (tr "labels.continue-with")]
[:span.line]]
[:& login/login-buttons {:params params}]
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-ldap))
[:span.separator
[:span.line]
[:span.text (tr "labels.or")]
[:span.line]])])
[:& register-form {:params params :on-success-callback on-success-callback}]])))
[:& register-form {:params params :on-success-callback on-success-callback}]])
(mf/defc register-page
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "registration-title"} (tr "auth.register-title")]
@ -216,31 +169,7 @@
[:div {:class (stl/css :link-entry :demo-users)}
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]]
;; OLD
[:div.form-container
[:h1 {:data-test "registration-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
(when (contains? cf/flags :demo-warning)
[:& demo-warning])
[:& register-methods {:params params}]
[:div.links
[:div.link-entry
[:span (tr "auth.already-have-account") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
:data-test "login-here-link"}
(tr "auth.login-here")]]
(when (contains? cf/flags :demo-users)
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]])))
(tr "auth.create-demo-account")]])]])
;; --- PAGE: register validation
@ -284,8 +213,7 @@
(mf/defc register-validate-form
[{:keys [params on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::register-validate-form
(let [form (fm/use-form :spec ::register-validate-form
:validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))
(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))]
:initial params)
@ -306,7 +234,6 @@
(rx/subs! on-success
(partial handle-register-error form))))))]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:name :fullname
@ -331,37 +258,11 @@
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?
:class (stl/css :register-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:name :fullname
:label (tr "auth.fullname")
:type "text"}]]
(when (contains? cf/flags :terms-and-privacy-checkbox)
[:div.fields-row.input-visible.accept-terms-and-privacy-wrapper
[:& fm/input {:name :accept-terms-and-privacy
:class "check-primary"
:type "checkbox"}
[:span
(tr "auth.terms-privacy-agreement")]]
[:div.auth-links
[:a {:href "https://penpot.app/terms" :target "_blank"} (tr "auth.terms-of-service")]
[:span ",\u00A0"]
[:a {:href "https://penpot.app/privacy" :target "_blank"} (tr "auth.privacy-policy")]]])
[:> fm/submit-button*
{:label (tr "auth.register-submit")
:disabled @submitted?}]])))
:class (stl/css :register-btn)}]]))
(mf/defc register-validate-page
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
:data-test "register-title"} (tr "auth.register-title")]
@ -374,35 +275,14 @@
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry :go-back)}
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]]
;; OLD
[:div.form-container
[:h1 {:data-test "register-title"} (tr "auth.register-title")]
[:div.subtitle (tr "auth.register-subtitle")]
[:& register-validate-form {:params params}]
[:div.links
[:div.link-entry
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]])))
(tr "labels.go-back")]]]])
(mf/defc register-success-page
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form :register-success)}
[:div {:class (stl/css :notification-icon)} i/icon-verify]
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
[:div {:class (stl/css :notification-text-email)} (:email params "")]
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]]
;; OLD
[:div.form-container
[:div.notification-icon i/icon-verify]
[:div.notification-text (tr "auth.verification-email-sent")]
[:div.notification-text-email (:email params "")]
[:div.notification-text (tr "auth.check-your-email")]])))
[:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]])

View file

@ -18,7 +18,6 @@
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -81,8 +80,7 @@
(set! (.-height (.-style node)) "0")
(set! (.-height (.-style node)) (str (+ 2 (.-scrollHeight node)) "px")))))
[:textarea
{:ref local-ref
[:textarea {:ref local-ref
:auto-focus autofocus?
:on-key-down on-key-down
:on-focus on-focus*
@ -93,8 +91,7 @@
(mf/defc reply-form
[{:keys [thread] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show-buttons? (mf/use-state false)
(let [show-buttons? (mf/use-state false)
content (mf/use-state "")
disabled? (or (fm/all-spaces? @content)
@ -123,7 +120,6 @@
(fn []
(st/emit! (dcm/add-comment thread @content))
(on-cancel)))]
(if new-css-system
[:div {:class (stl/css :reply-form)}
[:& resizing-textarea {:value @content
:placeholder "Reply"
@ -145,32 +141,11 @@
:global/disabled disabled?)
:value "Post"
:on-click on-submit
:disabled disabled?}]])]
[:div.reply-form
[:& resizing-textarea {:value @content
:placeholder "Reply"
:on-blur on-blur
:on-focus on-focus
:on-ctrl-enter on-submit
:on-change on-change}]
(when (or @show-buttons? (seq @content))
[:div.buttons
[:input.btn-primary
{:type "button"
:value "Post"
:on-click on-submit
:disabled disabled?}]
[:input.btn-secondary
{:type "button"
:value "Cancel"
:on-click on-cancel}]])])))
:disabled disabled?}]])]))
(mf/defc draft-thread
[{:keys [draft zoom on-cancel on-submit position-modifier]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
position (cond-> (:position draft)
(let [position (cond-> (:position draft)
(some? position-modifier)
(gpt/transform position-modifier))
content (:content draft)
@ -201,8 +176,6 @@
(mf/deps draft)
(partial on-submit draft))]
(if new-css-system
[:*
[:div
{:class (stl/css :floating-thread-bubble)
@ -234,40 +207,11 @@
:value "Post"
:class (stl/css-case :post-btn true
:global/disabled disabled?)
:disabled disabled?}]]]]]
[:*
[:div.thread-bubble
{:style {:top (str pos-y "px")
:left (str pos-x "px")}
:on-click dom/stop-propagation}
[:span "?"]]
[:div.thread-content
{:style {:top (str (- pos-y 14) "px")
:left (str (+ pos-x 14) "px")}
:on-click dom/stop-propagation}
[:div.reply-form
[:& resizing-textarea {:placeholder (tr "labels.write-new-comment")
:value (or content "")
:autofocus true
:on-esc on-esc
:on-ctrl-enter on-submit
:on-change on-change}]
[:div.buttons
[:input.btn-primary
{:on-click on-submit
:type "button"
:value "Post"
:disabled disabled?}]
[:input.btn-secondary
{:on-click on-esc
:type "button"
:value "Cancel"}]]]]])))
:disabled disabled?}]]]]]))
(mf/defc edit-form
[{:keys [content on-submit on-cancel] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
content (mf/use-state content)
(let [content (mf/use-state content)
on-change
(mf/use-fn
@ -281,7 +225,6 @@
disabled? (or (fm/all-spaces? @content)
(str/empty-or-nil? @content))]
(if new-css-system
[:div {:class (stl/css :edit-form)}
[:& resizing-textarea {:value @content
:autofocus true
@ -299,26 +242,11 @@
:global/disabled disabled?)
:value "Post"
:on-click on-submit*
:disabled disabled?}]]]
[:div.reply-form.edit-form
[:& resizing-textarea {:value @content
:autofocus true
:select-on-focus true
:on-ctrl-enter on-submit*
:on-change on-change}]
[:div.buttons
[:input.btn-primary {:type "button"
:value "Post"
:on-click on-submit*
:disabled disabled?}]
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]])))
:disabled disabled?}]]]))
(mf/defc comment-item
[{:keys [comment thread users origin] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
owner (get users (:owner-id comment))
(let [owner (get users (:owner-id comment))
profile (mf/deref refs/profile)
options (mf/use-state false)
edition? (mf/use-state false)
@ -382,7 +310,6 @@
(dom/stop-propagation event)
(st/emit! (dcm/update-comment-thread (update thread :is-resolved not)))))]
(if new-css-system
[:div {:class (stl/css :comment-container)}
[:div {:class (stl/css :comment)}
[:div {:class (stl/css :author)}
@ -422,42 +349,7 @@
(tr "labels.delete-comment-thread")]
[:li {:class (stl/css :context-menu-option)
:on-click on-delete-comment}
(tr "labels.delete-comment")])]]]
[:div.comment-container
[:div.comment
[:div.author
[:div.avatar
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
[:div.name
[:div.fullname (:fullname owner)]
[:div.timeago (dt/timeago (:modified-at comment))]]
(when (some? thread)
[:div.options-resolve {:on-click toggle-resolved}
(if (:is-resolved thread)
[:span i/checkbox-checked]
[:span i/checkbox-unchecked])])
(when (= (:id profile) (:id owner))
[:div.options
[:div.options-icon {:on-click on-toggle-options} i/actions]])]
[:div.content
(if @edition?
[:& edit-form {:content (:content comment)
:on-submit on-submit
:on-cancel on-cancel}]
[:span.text (:content comment)])]]
[:& dropdown {:show @options
:on-close on-hide-options}
[:ul.dropdown.comment-options-dropdown
[:li {:on-click on-edit-clicked} (tr "labels.edit")]
(if thread
[:li {:on-click on-delete-thread} (tr "labels.delete-comment-thread")]
[:li {:on-click on-delete-comment} (tr "labels.delete-comment")])]]])))
(tr "labels.delete-comment")])]]]))
(defn make-comments-ref
[thread-id]
@ -466,8 +358,7 @@
(mf/defc thread-comments
{::mf/wrap [mf/memo]}
[{:keys [thread zoom users origin position-modifier]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
ref (mf/use-ref)
(let [ref (mf/use-ref)
thread-id (:id thread)
@ -477,12 +368,8 @@
(some? position-modifier)
(gpt/transform position-modifier))
pos-x (if new-css-system
(+ (* (:x pos) zoom) 24)
(+ (* (:x pos) zoom) 14))
pos-y (if new-css-system
(- (* (:y pos) zoom) 28)
(- (* (:y pos) zoom) 14))
pos-x (+ (* (:x pos) zoom) 24)
pos-y (- (* (:y pos) zoom) 28)
comments-ref (mf/with-memo [thread-id]
@ -504,7 +391,6 @@
(mf/with-layout-effect [thread-pos comments-map]
(when-let [node (mf/ref-val ref)]
(dom/scroll-into-view-if-needed! node)))
(if new-css-system
(when (some? comment)
[:div {:class (stl/css :thread-content)
:style {:top (str pos-y "px")
@ -522,28 +408,7 @@
:users users
:origin origin}]])
[:div {:ref ref}]]
[:& reply-form {:thread thread}]])
(when (some? comment)
[:div.thread-content
{:style {:top (str pos-y "px")
:left (str pos-x "px")}
:on-click dom/stop-propagation}
[:div.comments
[:& comment-item {:comment comment
:users users
:thread thread
:origin origin}]
(for [item (rest comments)]
[:* {:key (dm/str (:id item))}
[:hr]
[:& comment-item {:comment item
:users users
:origin origin}]])
[:div {:ref ref}]]
[:& reply-form {:thread thread}]]))))
[:& reply-form {:thread thread}]])))
(defn use-buble
[zoom {:keys [position frame-id]}]
@ -602,8 +467,7 @@
(mf/defc thread-bubble
{::mf/wrap [mf/memo]}
[{:keys [thread zoom open? on-click origin position-modifier]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
pos (cond-> (:position thread)
(let [pos (cond-> (:position thread)
(some? position-modifier)
(gpt/transform position-modifier))
@ -658,7 +522,6 @@
(dom/stop-propagation event)
(when (= origin :viewer)
(on-click thread))))]
(if new-css-system
[:div {:style {:top (str pos-y "px")
:left (str pos-x "px")}
:on-pointer-down on-pointer-down*
@ -670,25 +533,11 @@
:floating-thread-bubble true
:resolved (:is-resolved thread)
:unread (pos? (:count-unread-comments thread)))}
[:span (:seqn thread)]]
[:div.thread-bubble
{:style {:top (str pos-y "px")
:left (str pos-x "px")}
:on-pointer-down on-pointer-down*
:on-pointer-up on-pointer-up*
:on-pointer-move on-pointer-move*
:on-click on-click*
:on-lost-pointer-capture on-lost-pointer-capture
:class (dom/classnames
:resolved (:is-resolved thread)
:unread (pos? (:count-unread-comments thread)))}
[:span (:seqn thread)]])))
[:span (:seqn thread)]]))
(mf/defc comment-thread
[{:keys [item users on-click]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
owner (get users (:owner-id item))
(let [owner (get users (:owner-id item))
on-click*
(mf/use-fn
(mf/deps item)
@ -698,7 +547,6 @@
(when (fn? on-click)
(on-click item))))]
(if new-css-system
[:div {:class (stl/css :comment)
:on-click on-click*}
[:div {:class (stl/css :author)}
@ -725,41 +573,10 @@
(when (and (> total 1) (> unread 0))
(if (= unread 1)
[:span {:class (stl/css :new-replies)} "1 new reply"]
[:span {:class (stl/css :new-replies)} (str unread " new replies")]))])]]
[:div.comment {:on-click on-click*}
[:div.author
[:div.thread-bubble
{:class (dom/classnames
:resolved (:is-resolved item)
:unread (pos? (:count-unread-comments item)))}
(:seqn item)]
[:div.avatar
[:img {:src (cfg/resolve-profile-photo-url owner)}]]
[:div.name
[:div.fullname (:fullname owner) ", "]
[:div.timeago (dt/timeago (:modified-at item))]]]
[:div.content
[:span.text (:content item)]]
[:div.content.replies
(let [unread (:count-unread-comments item ::none)
total (:count-comments item 1)]
[:*
(when (> total 1)
(if (= total 2)
[:span.total-replies "1 reply"]
[:span.total-replies (str (dec total) " replies")]))
(when (and (> total 1) (> unread 0))
(if (= unread 1)
[:span.new-replies "1 new reply"]
[:span.new-replies (str unread " new replies")]))])]])))
[:span {:class (stl/css :new-replies)} (str unread " new replies")]))])]]))
(mf/defc comment-thread-group
[{:keys [group users on-thread-click]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :thread-group)}
(if (:file-name group)
[:div {:class (stl/css :section-title)}
@ -776,21 +593,4 @@
{:item item
:on-click on-thread-click
:users users
:key (:id item)}])]]
[:div.thread-group
(if (:file-name group)
[:div.section-title
[:span.label.filename (:file-name group) ", "]
[:span.label (:page-name group)]]
[:div.section-title
[:span.icon i/file-html]
[:span.label (:page-name group)]])
[:div.threads
(for [item (:items group)]
[:& comment-thread
{:item item
:on-click on-thread-click
:users users
:key (:id item)}])]])))
:key (:id item)}])]])

View file

@ -13,19 +13,28 @@
border-radius: $br-8;
padding: $s-8 $s-16;
.section-title {
&:hover {
background: $db-primary;
}
}
.section-title {
@include titleTipography;
height: $s-32;
display: flex;
align-items: center;
margin-bottom: $s-8;
.file-name {
}
.file-name {
color: var(--comment-subtitle-color);
}
.page-name {
}
.page-name {
color: var(--comment-subtitle-color);
}
.icon {
}
.icon {
display: flex;
align-items: center;
padding: 0 $s-6 0 $s-4;
@ -36,17 +45,12 @@
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
}
.threads {
}
.threads {
display: flex;
flex-direction: column;
gap: $s-24;
}
&:hover {
background: $db-primary;
}
}
// Comment-thread
@ -55,10 +59,14 @@
display: flex;
flex-direction: column;
gap: $s-12;
.author {
}
.author {
display: flex;
gap: $s-8;
.thread-bubble {
}
.thread-bubble {
@extend .comment-bubbles;
&.resolved {
@extend .resolved-comment-bubble;
@ -66,16 +74,18 @@
&.unread {
@extend .unread-comment-bubble;
}
}
.avatar {
}
.avatar {
height: $s-32;
width: $s-32;
border-radius: $br-circle;
img {
border-radius: $br-circle;
}
}
.name {
}
.name {
flex-grow: 1;
.fullname {
@include textEllipsis;
@ -85,24 +95,24 @@
@include textEllipsis;
color: var(--comment-subtitle-color);
}
}
}
.content {
@include titleTipography;
color: var(--color-foreground-primary);
}
.replies {
display: flex;
gap: $s-8;
.total-replies {
color: var(--color-foreground-secondary);
}
.new-replies {
color: var(--color-accent-primary);
}
}
}
.content {
@include titleTipography;
color: var(--color-foreground-primary);
}
.replies {
display: flex;
gap: $s-8;
}
.total-replies {
color: var(--color-foreground-secondary);
}
.new-replies {
color: var(--color-accent-primary);
}
// Thread-bubble
.floating-thread-bubble {

View file

@ -30,8 +30,7 @@
(when label-text
[:label {:for input-id :class-name label-class} label-text])
[:input
{:style {:display "none"
[:input {:style {:display "none"
:width 0}
:id input-id
:multiple multi

View file

@ -9,7 +9,6 @@
(:require
[app.main.data.modal :as modal]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr t]]
@ -31,8 +30,7 @@
cancel-label
accept-label
accept-style] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
locale (mf/deref i18n/locale)
(let [locale (mf/deref i18n/locale)
on-accept (or on-accept identity)
on-cancel (or on-cancel identity)
@ -67,7 +65,6 @@
(partial events/unlistenByKey))))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -109,45 +106,4 @@
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]
[:div.modal-overlay
[:div.modal-container.confirm-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 title]]
[:div.modal-close-button
{:on-click cancel-fn} i/close]]
[:div.modal-content
(when (and (string? message) (not= message ""))
[:h3 message])
(when (and (string? scd-message) (not= scd-message ""))
[:h3 scd-message])
(when (string? hint)
[:p hint])
(when (> (count items) 0)
[:*
[:p (tr "ds.component-subtitle")]
[:ul.component-list
(for [item items]
[:li.modal-item-element
[:span.modal-component-icon i/component]
[:span (:name item)]])]])]
[:div.modal-footer
[:div.action-buttons
(when-not (= cancel-label :omit)
[:input.cancel-button
{:type "button"
:value cancel-label
:on-click cancel-fn}])
[:input.accept-button
{:class (dom/classnames
:danger (= accept-style :danger)
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]])))
:on-click accept-fn}]]]]]))

View file

@ -11,25 +11,35 @@
&.transparent {
background-color: transparent;
}
.modal-container {
}
.modal-container {
@extend .modal-container-base;
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content {
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.component-list {
.modal-item-element {
}
.modal-item-element {
@include flexRow;
.modal-component-icon {
}
.modal-component-icon {
@include flexCenter;
height: $s-16;
width: $s-16;
@ -37,31 +47,28 @@
@extend .button-icon-small;
stroke: var(--color);
}
}
.modal-component-name {
}
.modal-component-name {
@include titleTipography;
}
}
}
.modal-hint {
}
.modal-hint {
@extend .modal-hint-base;
}
}
.modal-footer {
.action-buttons {
}
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}
.modal-scd-msg,

View file

@ -12,7 +12,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
@ -26,8 +25,7 @@
{::mf/register modal/components
::mf/register-as :leave-and-reassign}
[{:keys [profile team accept]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::leave-modal-form :initial {})
(let [form (fm/use-form :spec ::leave-modal-form :initial {})
members-map (mf/deref refs/dashboard-team-members)
members (vals members-map)
@ -42,7 +40,6 @@
(let [member-id (get-in @form [:clean-data :member-id])]
(accept member-id)))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -76,37 +73,4 @@
:global/disabled (not (:valid @form)))
:disabled (not (:valid @form))
:value (tr "modals.leave-and-reassign.promote-and-leave")
:on-click on-accept}]]]]]
[:div.modal-overlay
[:div.modal-container.confirm-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 (tr "modals.leave-and-reassign.title")]]
[:div.modal-close-button
{:on-click on-cancel} i/close]]
[:div.modal-content.generic-form
[:p (tr "modals.leave-and-reassign.hint1" (:name team))]
(if (empty? members)
[:p (tr "modals.leave-and-reassign.forbidden")]
[:*
[:& fm/form {:form form}
[:& fm/select {:name :member-id
:options options}]]])]
[:div.modal-footer
[:div.action-buttons
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click on-cancel}]
[:input.accept-button
{:type "button"
:class (if (:valid @form) "danger" "btn-disabled")
:disabled (not (:valid @form))
:value (tr "modals.leave-and-reassign.promote-and-leave")
:on-click on-accept}]]]]])))
:on-click on-accept}]]]]]))

View file

@ -8,39 +8,46 @@
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
}
.modal-container {
@extend .modal-container-base;
border: $s-1 solid var(--modal-border-color);
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content {
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.input-wrapper {
}
.input-wrapper {
@extend .input-with-label;
}
}
.modal-footer {
.action-buttons {
}
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}

View file

@ -11,7 +11,6 @@
[app.common.data.macros :as dm]
[app.main.data.modal :as modal]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.worker :as uw]
[app.util.dom :as dom]
@ -24,9 +23,6 @@
(mf/defc export-entry
{::mf/wrap-props false}
[{:keys [file]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css-case :file-entry true
:loading (:loading? file)
:success (:export-success? file)
@ -39,21 +35,7 @@
(:loading? file) i/loader-pencil)]
[:div {:class (stl/css :file-name-label)}
(:name file)]]]
[:div.file-entry
{:class (dom/classnames
:loading (:loading? file)
:success (:export-success? file)
:error (:export-error? file))}
[:div.file-name
[:div.file-icon
(cond (:export-success? file) i/tick
(:export-error? file) i/close
(:loading? file) i/loader-pencil)]
[:div.file-name-label (:name file)]]])))
(:name file)]]])
(defn- mark-file-error
[files file-id]
@ -79,8 +61,7 @@
::mf/register-as :export
::mf/wrap-props false}
[{:keys [team-id files has-libraries? binary? features]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
state* (mf/use-state
(let [state* (mf/use-state
#(let [files (mapv (fn [file] (assoc file :loading? true)) files)]
{:status :prepare
:selected :all
@ -140,7 +121,6 @@
(when-not has-libraries?
(start-export)))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -207,69 +187,4 @@
:type "button"
:value (tr "labels.close")
:disabled (->> state :files (some :loading?))
:on-click on-cancel}]]]])]]
[:div.modal-overlay
[:div.modal-container.export-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 (tr "dashboard.export.title")]]
[:div.modal-close-button
{:on-click on-cancel} i/close]]
(cond
(= status :prepare)
[:*
[:div.modal-content
[:p.explain (tr "dashboard.export.explain")]
[:p.detail (tr "dashboard.export.detail")]
(for [type export-types]
[:div.export-option {:class (when (= selected type) "selected")
:key (name type)}
[:label.option-container
;; Execution time translation strings:
;; dashboard.export.options.all.message
;; dashboard.export.options.all.title
;; dashboard.export.options.detach.message
;; dashboard.export.options.detach.title
;; dashboard.export.options.merge.message
;; dashboard.export.options.merge.title
[:h3 (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
[:p (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]
[:input {:type "radio"
:checked (= selected type)
:data-type (name type)
:on-change on-change
:name "export-option"}]
[:span {:class "option-radio-check"}]]])]
[:div.modal-footer
[:div.action-buttons
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click on-cancel}]
[:input.accept-button
{:class "primary"
:type "button"
:value (tr "labels.continue")
:on-click on-accept}]]]]
(= status :exporting)
[:*
[:div.modal-content
(for [file (:files state)]
[:& export-entry {:file file :key (dm/str (:id file))}])]
[:div.modal-footer
[:div.action-buttons
[:input.accept-button
{:class "primary"
:type "button"
:value (tr "labels.close")
:disabled (->> state :files (some :loading?))
:on-click on-cancel}]]]])]])))
:on-click on-cancel}]]]])]]))

View file

@ -8,24 +8,31 @@
.modal-overlay {
@extend .modal-overlay-base;
}
.modal-container {
.modal-container {
@extend .modal-container-base;
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
.modal-close-btn {
@extend .modal-close-btn-base;
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.export-option {
}
.export-option {
@extend .input-checkbox;
width: 100%;
align-items: flex-start;
@ -39,28 +46,26 @@
span {
margin-top: $s-8;
}
.option-content {
}
.option-content {
@include flexColumn;
@include titleTipography;
}
}
}
}
.modal-footer {
.action-buttons {
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}
.modal-scd-msg,

View file

@ -18,7 +18,6 @@
[app.main.features :as features]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.worker :as uw]
[app.util.dom :as dom]
@ -152,8 +151,7 @@
(mf/defc import-entry
[{:keys [state file editing? can-be-deleted?]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
loading? (or (= :analyzing (:status file))
(let [loading? (or (= :analyzing (:status file))
(= :importing (:status file)))
analyze-error? (= :analyze-error (:status file))
import-finish? (= :import-finish (:status file))
@ -191,7 +189,6 @@
(fn []
(swap! state update :files remove-file (:file-id file))))]
(if new-css-system
[:div {:class (stl/css-case :file-entry true
:loading loading?
:success (and import-finish? (not import-warn?) (not import-error?))
@ -245,68 +242,13 @@
(when (some? library-data)
[:div {:class (stl/css-case :linked-library-tag true
:error error?)}
i/detach-refactor (:name library-data)])))]]
[:div.file-entry
{:class (dom/classnames
:loading loading?
:success (and import-finish? (not import-warn?) (not import-error?))
:warning (and import-finish? import-warn? (not import-error?))
:error (or import-error? analyze-error?)
:editable (and ready? (not editing?)))}
[:div.file-name
[:div.file-icon
(cond loading? i/loader-pencil
ready? i/logo-icon
import-warn? i/msg-warning
import-error? i/close
import-finish? i/tick
analyze-error? i/close)]
(if editing?
[:div.file-name-edit
[:input {:type "text"
:auto-focus true
:default-value (:name file)
:on-key-press handle-edit-key-press
:on-blur handle-edit-blur}]]
[:div.file-name-label (:name file) (when is-shared? i/library)])
[:div.edit-entry-buttons
(when (= "application/zip" (:type file))
[:button {:on-click handle-edit-entry} i/pencil])
(when can-be-deleted?
[:button {:on-click handle-remove-entry} i/trash])]]
(cond
analyze-error?
[:div.error-message
(tr "dashboard.import.analyze-error")]
import-error?
[:div.error-message
(tr "dashboard.import.import-error")]
(and (not import-finish?) (some? progress))
[:div.progress-message (parse-progress-message progress)])
[:div.linked-libraries
(for [library-id (:libraries file)]
(let [library-data (->> @state :files (d/seek #(= library-id (:file-id %))))
error? (or (:deleted? library-data) (:import-error library-data))]
(when (some? library-data)
[:div.linked-library-tag {:class (when error? "error")}
(if error? i/unchain i/chain) (:name library-data)])))]])))
i/detach-refactor (:name library-data)])))]]))
(mf/defc import-dialog
{::mf/register modal/components
::mf/register-as :import}
[{:keys [project-id files template on-finish-import]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
state (mf/use-state
(let [state (mf/use-state
{:status :analyzing
:editing nil
:importing-templates 0
@ -425,7 +367,6 @@
#(doseq [file files]
(wapi/revoke-uri (:uri file)))))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -482,65 +423,4 @@
:type "button"
:value (tr "labels.accept")
:disabled (or pending-import? (not valid-files?))
:on-click handle-accept}])]]]]
[:div.modal-overlay
[:div.modal-container.import-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 (tr "dashboard.import")]]
[:div.modal-close-button
{:on-click handle-cancel} i/close]]
[:div.modal-content
(when (and (= :importing (:status @state)) (not pending-import?))
(if (> warning-files 0)
[:div.feedback-banner.warning
[:div.icon i/msg-warning]
[:div.message (tr "dashboard.import.import-warning" warning-files success-files)]]
[:div.feedback-banner
[:div.icon i/checkbox-checked]
[:div.message (tr "dashboard.import.import-message" (i18n/c (if (some? template) 1 success-files)))]]))
(for [file files]
(let [editing? (and (some? (:file-id file))
(= (:file-id file) (:editing @state)))]
[:& import-entry {:state state
:key (dm/str (:uri file))
:file file
:editing? editing?
:can-be-deleted? (> (count files) 1)}]))
(when (some? template)
[:& import-entry {:state state
:file (assoc template :status (if (= 1 (:importing-templates @state)) :importing :ready))
:editing? false
:can-be-deleted? false}])]
[:div.modal-footer
[:div.action-buttons
(when (= :analyzing (:status @state))
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click handle-cancel}])
(when (= :analyzing (:status @state))
[:input.accept-button
{:class "primary"
:type "button"
:value (tr "labels.continue")
:disabled (or pending-analysis? (not valid-files?))
:on-click handle-continue}])
(when (= :importing (:status @state))
[:input.accept-button
{:class "primary"
:type "button"
:value (tr "labels.accept")
:disabled (or pending-import? (not valid-files?))
:on-click handle-accept}])]]]])))
:on-click handle-accept}])]]]]))

View file

@ -8,25 +8,32 @@
.modal-overlay {
@extend .modal-overlay-base;
}
.modal-container {
.modal-container {
@extend .modal-container-base;
border: $s-1 solid var(--modal-border-color);
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
.modal-close-btn {
@extend .modal-close-btn-base;
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.feedback-banner {
}
.feedback-banner {
@include flexRow;
height: $s-32;
width: 100%;
@ -54,24 +61,20 @@
stroke: var(--alert-foreground-color-warning);
}
}
}
}
}
.modal-footer {
.action-buttons {
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}
.modal-scd-msg,
@ -122,6 +125,7 @@
.error-message,
.progress-message {
height: $s-32;
color: var(--modal-text-foreground-color);
}
.linked-libraries {

View file

@ -21,7 +21,6 @@
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.change-owner]
[app.main.ui.dashboard.team-form]
[app.main.ui.icons :as i]
@ -36,8 +35,7 @@
{::mf/wrap [mf/memo]
::mf/wrap-props false}
[{:keys [section team]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
(let [on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
on-nav-settings (mf/use-fn #(st/emit! (dd/go-to-team-settings)))
on-nav-invitations (mf/use-fn #(st/emit! (dd/go-to-team-invitations)))
on-nav-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks)))
@ -56,7 +54,6 @@
:team team
:origin :team}))))]
(if new-css-system
[:header {:class (stl/css :dashboard-header :team)}
[:div {:class (stl/css :dashboard-title)}
[:h1 (cond
@ -83,35 +80,7 @@
:on-click on-invite-member
:data-test "invite-member"}
(tr "dashboard.invite-profile")]
[:div {:class (stl/css :blank-space)}])]]
;; OLD
[:header.dashboard-header.team
[:div.dashboard-title
[:h1 (cond
members-section? (tr "labels.members")
settings-section? (tr "labels.settings")
invitations-section? (tr "labels.invitations")
webhooks-section? (tr "labels.webhooks")
:else nil)]]
[:nav.dashboard-header-menu
[:ul.dashboard-header-options
[:li {:class (when members-section? "active")}
[:a {:on-click on-nav-members} (tr "labels.members")]]
[:li {:class (when invitations-section? "active")}
[:a {:on-click on-nav-invitations} (tr "labels.invitations")]]
(when (contains? cfg/flags :webhooks)
[:li {:class (when webhooks-section? "active")}
[:a {:on-click on-nav-webhooks} (tr "labels.webhooks")]])
[:li {:class (when settings-section? "active")}
[:a {:on-click on-nav-settings} (tr "labels.settings")]]]]
[:div.dashboard-buttons
(if (and (or invitations-section? members-section?) (:is-admin permissions))
[:a.btn-secondary.btn-small
{:on-click on-invite-member
:data-test "invite-member"}
(tr "dashboard.invite-profile")]
[:div.blank-space])]])))
[:div {:class (stl/css :blank-space)}])]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INVITATIONS MODAL
@ -140,8 +109,7 @@
::mf/register-as :invite-members
::mf/wrap-props false}
[{:keys [team origin]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
members-map (mf/deref refs/dashboard-team-members)
(let [members-map (mf/deref refs/dashboard-team-members)
perms (:permissions team)
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
@ -188,7 +156,6 @@
(dd/fetch-team-invitations))))]
(if new-css-system
[:div {:class (stl/css-case :modal-team-container true
:hero (= origin :hero))}
[:& fm/form {:on-submit on-submit :form form}
@ -223,45 +190,7 @@
[:> fm/submit-button*
{:label (tr "modals.invite-member-confirm.accept")
:disabled (and (boolean (some current-data-emails current-members-emails))
(empty? (remove current-members-emails current-data-emails)))}]]]]
[:div.modal.dashboard-invite-modal.form-container
{:class (dom/classnames
:hero (= origin :hero))}
[:& fm/form {:on-submit on-submit :form form}
[:div.title
[:span.text (tr "modals.invite-team-member.title")]]
(when-not (= "" @error-text)
[:div.error
[:span.icon i/msg-error]
[:span.text @error-text]])
(when (some current-data-emails current-members-emails)
[:div.warning
[:span.icon i/msg-warning]
[:span.text (tr "modals.invite-member.repeated-invitation")]])
[:div.form-row
[:p.label (tr "onboarding.choice.team-up.roles")]
[:& fm/select {:name :role :options roles}]]
[:div.form-row
[:& fm/multi-input {:type "email"
:name :emails
:auto-focus? true
:trim true
:valid-item-fn us/parse-email
:caution-item-fn current-members-emails
:label (tr "modals.invite-member.emails")
:on-submit on-submit}]]
[:div.action-buttons
[:> fm/submit-button*
{:label (tr "modals.invite-member-confirm.accept")
:disabled (and (boolean (some current-data-emails current-members-emails))
(empty? (remove current-members-emails current-data-emails)))}]]]])))
(empty? (remove current-members-emails current-data-emails)))}]]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MEMBERS SECTION
@ -270,9 +199,7 @@
(mf/defc member-info
{::mf/wrap-props false}
[{:keys [member profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
is-you? (= (:id profile) (:id member))]
(if new-css-system
(let [is-you? (= (:id profile) (:id member))]
[:*
[:div {:class (stl/css :member-image)}
[:img {:src (cfg/resolve-profile-photo-url member)}]]
@ -280,23 +207,12 @@
[:div {:class (stl/css :member-name)} (:name member)
(when is-you?
[:span {:class (stl/css :you)} (tr "labels.you")])]
[:div {:class (stl/css :member-email)} (:email member)]]]
;; OLD
[:*
[:div.member-image
[:img {:src (cfg/resolve-profile-photo-url member)}]]
[:div.member-info
[:div.member-name (:name member)
(when is-you?
[:span.you (tr "labels.you")])]
[:div.member-email (:email member)]]])))
[:div {:class (stl/css :member-email)} (:email member)]]]))
(mf/defc rol-info
{::mf/wrap-props false}
[{:keys [member team on-set-admin on-set-editor on-set-owner profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
member-is-owner? (:is-owner member)
(let [member-is-owner? (:is-owner member)
member-is-admin? (and (:is-admin member) (not member-is-owner?))
member-is-editor? (and (:can-edit member) (and (not member-is-admin?) (not member-is-owner?)))
show? (mf/use-state false)
@ -316,7 +232,6 @@
on-show (mf/use-fn #(reset! show? true))
on-hide (mf/use-fn #(reset! show? false))]
(if new-css-system
[:*
(if (and can-change-rol? not-superior? (not (and is-you? you-owner?)))
[:div {:class (stl/css :rol-selector :has-priv)
@ -334,32 +249,12 @@
;; https://tree.taiga.io/project/penpot/issue/1083
;; [:li {:on-click set-viewer} (tr "labels.viewer")]
(when you-owner?
[:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]]
;; OLD
[:*
(if (and can-change-rol? not-superior? (not (and is-you? you-owner?)))
[:div.rol-selector.has-priv {:on-click on-show}
[:span.rol-label (tr role)]
[:span.icon i/arrow-down]]
[:div.rol-selector
[:span.rol-label (tr role)]])
[:& dropdown {:show @show? :on-close on-hide}
[:ul.dropdown.options-dropdown
[:li {:on-click on-set-admin} (tr "labels.admin")]
[:li {:on-click on-set-editor} (tr "labels.editor")]
;; Temporarily disabled viewer role
;; https://tree.taiga.io/project/penpot/issue/1083
;; [:li {:on-click set-viewer} (tr "labels.viewer")]
(when you-owner?
[:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]])))
[:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]]))
(mf/defc member-actions
{::mf/wrap-props false}
[{:keys [member team on-delete on-leave profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
is-owner? (:is-owner member)
(let [is-owner? (:is-owner member)
owner? (dm/get-in team [:permissions :is-owner])
admin? (dm/get-in team [:permissions :is-admin])
show? (mf/use-state false)
@ -369,7 +264,6 @@
on-show (mf/use-fn #(reset! show? true))
on-hide (mf/use-fn #(reset! show? false))]
(if new-css-system
[:*
(when (or is-you? (and can-delete? (not (and is-owner? (not owner?)))))
[:span {:class (stl/css :icon)
@ -380,19 +274,7 @@
(when is-you?
[:li {:on-click on-leave} (tr "dashboard.leave-team")])
(when (and can-delete? (not is-you?) (not (and is-owner? (not owner?))))
[:li {:on-click on-delete} (tr "labels.remove-member")])]]]
;; OLD
[:*
(when (or is-you? (and can-delete? (not (and is-owner? (not owner?)))))
[:span.icon {:on-click on-show} [i/actions]])
[:& dropdown {:show @show? :on-close on-hide}
[:ul.dropdown.actions-dropdown
(when is-you?
[:li {:on-click on-leave} (tr "dashboard.leave-team")])
(when (and can-delete? (not is-you?) (not (and is-owner? (not owner?))))
[:li {:on-click on-delete} (tr "labels.remove-member")])]]])))
[:li {:on-click on-delete} (tr "labels.remove-member")])]]]))
(defn- set-role! [member-id role]
(let [params {:member-id member-id :role role}]
@ -403,8 +285,7 @@
::mf/wrap-props false}
[{:keys [team member members profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
member-id (:id member)
(let [member-id (:id member)
on-set-admin (mf/use-fn (mf/deps member-id) (partial set-role! member-id :admin))
on-set-editor (mf/use-fn (mf/deps member-id) (partial set-role! member-id :editor))
owner? (dm/get-in team [:permissions :is-owner])
@ -513,7 +394,6 @@
(= true owner?) on-change-owner-and-leave
:else on-leave)]
(if new-css-system
[:div {:class (stl/css :table-row)}
[:div {:class (stl/css :table-field :name)}
[:& member-info {:member member :profile profile}]]
@ -531,32 +411,12 @@
:profile profile
:team team
:on-delete on-delete
:on-leave on-leave'}]]]
;; OLD
[:div.table-row
[:div.table-field.name
[:& member-info {:member member :profile profile}]]
[:div.table-field.roles
[:& rol-info {:member member
:team team
:on-set-admin on-set-admin
:on-set-editor on-set-editor
:on-set-owner on-set-owner
:profile profile}]]
[:div.table-field.actions
[:& member-actions {:member member
:profile profile
:team team
:on-delete on-delete
:on-leave on-leave'}]]])))
:on-leave on-leave'}]]]))
(mf/defc team-members
{::mf/wrap-props false}
[{:keys [members-map team profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
members (mf/with-memo [members-map]
(let [members (mf/with-memo [members-map]
(->> (vals members-map)
(sort-by :created-at)
(remove :is-owner)))
@ -564,7 +424,6 @@
(->> (vals members-map)
(d/seek :is-owner)))]
(if new-css-system
[:div {:class (stl/css :dashboard-table :team-members)}
[:div {:class (stl/css :table-header)}
[:div {:class (stl/css :table-field :name)} (tr "labels.member")]
@ -583,34 +442,12 @@
:team team
:profile profile
:key (:id item)
:members members-map}])]]
;; OLD
[:div.dashboard-table.team-members
[:div.table-header
[:div.table-field.name (tr "labels.member")]
[:div.table-field.role (tr "labels.role")]]
[:div.table-rows
[:& team-member
{:member owner
:team team
:profile profile
:members members-map}]
(for [item members]
[:& team-member
{:member item
:team team
:profile profile
:key (:id item)
:members members-map}])]])))
:members members-map}])]]))
(mf/defc team-members-page
{::mf/wrap-props false}
[{:keys [team profile]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
members-map (mf/deref refs/dashboard-team-members)]
(let [members-map (mf/deref refs/dashboard-team-members)]
(mf/with-effect [team]
(dom/set-html-title
@ -622,23 +459,13 @@
(mf/with-effect [team]
(st/emit! (dd/fetch-team-members (:id team))))
(if new-css-system
[:*
[:& header {:section :dashboard-team-members :team team}]
[:section {:class (stl/css :dashboard-container :dashboard-team-members)}
[:& team-members
{:profile profile
:team team
:members-map members-map}]]]
;; OLD
[:*
[:& header {:section :dashboard-team-members :team team}]
[:section.dashboard-container.dashboard-team-members
[:& team-members
{:profile profile
:team team
:members-map members-map}]]])))
:members-map members-map}]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INVITATIONS SECTION
@ -647,8 +474,7 @@
(mf/defc invitation-role-selector
{::mf/wrap-props false}
[{:keys [can-invite? role status on-change]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show? (mf/use-state false)
(let [show? (mf/use-state false)
label (cond
(= role :owner) (tr "labels.owner")
(= role :admin) (tr "labels.admin")
@ -667,7 +493,6 @@
(keyword))]
(on-change role event))))]
(if new-css-system
[:*
(if (and can-invite? (= status :pending))
[:div {:class (stl/css :rol-selector :has-priv)
@ -680,27 +505,11 @@
[:& dropdown {:show @show? :on-close on-hide}
[:ul {:class (stl/css :dropdown :options-dropdown)}
[:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")]
[:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]]
;; OLD
[:*
(if (and can-invite? (= status :pending))
[:div.rol-selector.has-priv {:on-click on-show}
[:span.rol-label label]
[:span.icon i/arrow-down]]
[:div.rol-selector
[:span.rol-label label]])
[:& dropdown {:show @show? :on-close on-hide}
[:ul.dropdown.options-dropdown
[:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")]
[:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]])))
[:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]]))
(mf/defc invitation-status-badge
{::mf/wrap-props false}
[{:keys [status]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div
{:class (stl/css-case
:status-badge true
@ -709,23 +518,12 @@
[:span {:class (stl/css :status-label)}
(if (= status :expired)
(tr "labels.expired-invitation")
(tr "labels.pending-invitation"))]]
;; OLD
[:div.status-badge
{:class (dom/classnames
:expired (= status :expired)
:pending (= status :pending))}
[:span.status-label
(if (= status :expired)
(tr "labels.expired-invitation")
(tr "labels.pending-invitation"))]])))
(tr "labels.pending-invitation"))]])
(mf/defc invitation-actions
{::mf/wrap-props false}
[{:keys [invitation team-id]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show? (mf/use-state false)
(let [show? (mf/use-state false)
email (:email invitation)
role (:role invitation)
@ -800,7 +598,6 @@
on-hide (mf/use-fn #(reset! show? false))
on-show (mf/use-fn #(reset! show? true))]
(if new-css-system
[:*
[:span {:class (stl/css :icon)
:on-click on-show} [i/actions]]
@ -808,24 +605,14 @@
[:ul {:class (stl/css :dropdown :actions-dropdown)}
[:li {:on-click on-copy} (tr "labels.copy-invitation-link")]
[:li {:on-click on-resend} (tr "labels.resend-invitation")]
[:li {:on-click on-delete} (tr "labels.delete-invitation")]]]]
;; OLD
[:*
[:span.icon {:on-click on-show} [i/actions]]
[:& dropdown {:show @show? :on-close on-hide}
[:ul.dropdown.actions-dropdown
[:li {:on-click on-copy} (tr "labels.copy-invitation-link")]
[:li {:on-click on-resend} (tr "labels.resend-invitation")]
[:li {:on-click on-delete} (tr "labels.delete-invitation")]]]])))
[:li {:on-click on-delete} (tr "labels.delete-invitation")]]]]))
(mf/defc invitation-row
{::mf/wrap [mf/memo]
::mf/wrap-props false}
[{:keys [invitation can-invite? team-id] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
expired? (:expired invitation)
(let [expired? (:expired invitation)
email (:email invitation)
role (:role invitation)
status (if expired? :expired :pending)
@ -838,7 +625,6 @@
mdata {:on-success #(st/emit! (dd/fetch-team-invitations))}]
(st/emit! (dd/update-team-invitation-role (with-meta params mdata))))))]
(if new-css-system
[:div {:class (stl/css :table-row)}
[:div {:class (stl/css :table-field :mail)} email]
@ -856,53 +642,23 @@
(when can-invite?
[:& invitation-actions
{:invitation invitation
:team-id team-id}])]]
;; OLD
[:div.table-row
[:div.table-field.mail email]
[:div.table-field.roles
[:& invitation-role-selector
{:can-invite? can-invite?
:role role
:status status
:on-change on-change-role}]]
[:div.table-field.status
[:& invitation-status-badge {:status status}]]
[:div.table-field.actions
(when can-invite?
[:& invitation-actions
{:invitation invitation
:team-id team-id}])]])))
:team-id team-id}])]]))
(mf/defc empty-invitation-table
[{:keys [can-invite?] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :empty-invitations)}
[:span (tr "labels.no-invitations")]
(when can-invite?
[:& i18n/tr-html {:label "labels.no-invitations-hint"
:tag-name "span"}])]
;; OLD
[:div.empty-invitations
[:span (tr "labels.no-invitations")]
(when can-invite?
[:& i18n/tr-html {:label "labels.no-invitations-hint"
:tag-name "span"}])])))
:tag-name "span"}])])
(mf/defc invitation-section
[{:keys [team invitations] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
owner? (dm/get-in team [:permissions :is-owner])
(let [owner? (dm/get-in team [:permissions :is-owner])
admin? (dm/get-in team [:permissions :is-admin])
can-invite? (or owner? admin?)
team-id (:id team)]
(if new-css-system
[:div {:class (stl/css :dashboard-table :invitations)}
[:div {:class (stl/css :table-header)}
[:div {:class (stl/css :table-field :name)} (tr "labels.invitations")]
@ -916,28 +672,11 @@
{:key (:email invitation)
:invitation invitation
:can-invite? can-invite?
:team-id team-id}])])]
;; OLD
[:div.dashboard-table.invitations
[:div.table-header
[:div.table-field.name (tr "labels.invitations")]
[:div.table-field.role (tr "labels.role")]
[:div.table-field.status (tr "labels.status")]]
(if (empty? invitations)
[:& empty-invitation-table {:can-invite? can-invite?}]
[:div.table-rows
(for [invitation invitations]
[:& invitation-row
{:key (:email invitation)
:invitation invitation
:can-invite? can-invite?
:team-id team-id}])])])))
:team-id team-id}])])]))
(mf/defc team-invitations-page
[{:keys [team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
invitations (mf/deref refs/dashboard-team-invitations)]
(let [invitations (mf/deref refs/dashboard-team-invitations)]
(mf/with-effect [team]
(dom/set-html-title
@ -949,21 +688,12 @@
(mf/with-effect []
(st/emit! (dd/fetch-team-invitations)))
(if new-css-system
[:*
[:& header {:section :dashboard-team-invitations
:team team}]
[:section {:class (stl/css :dashboard-container :dashboard-team-invitations)}
[:& invitation-section {:team team
:invitations invitations}]]]
;; OLD
[:*
[:& header {:section :dashboard-team-invitations
:team team}]
[:section.dashboard-container.dashboard-team-invitations
[:& invitation-section {:team team
:invitations invitations}]]])))
:invitations invitations}]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; WEBHOOKS SECTION
@ -987,8 +717,7 @@
::mf/register-as :webhook}
[{:keys [webhook] :as props}]
;; FIXME: this is a workaround because input fields do not support rendering hooks
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str))
(let [initial (mf/use-memo (fn [] (or (some-> webhook (update :uri str))
{:is-active false :mtype "application/json"})))
form (fm/use-form :spec ::webhook-form
:initial initial
@ -1052,7 +781,6 @@
(on-create-submit form)))))
on-modal-close #(st/emit! (modal/hide))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:& fm/form {:form form :on-submit on-submit}
@ -1094,62 +822,12 @@
[:> fm/submit-button*
{:label (if webhook
(tr "modals.edit-webhook.submit-label")
(tr "modals.create-webhook.submit-label"))}]]]]]]
;; OLD
[:div.modal-overlay
[:div.modal-container.webhooks-modal
[:& fm/form {:form form :on-submit on-submit}
[:div.modal-header
[:div.modal-header-title
(if webhook
[:h2 (tr "modals.edit-webhook.title")]
[:h2 (tr "modals.create-webhook.title")])]
[:div.modal-close-button
{:on-click #(st/emit! (modal/hide))} i/close]]
[:div.modal-content.generic-form
[:div.fields-container
[:div.fields-row
[:& fm/input {:type "text"
:auto-focus? true
:form form
:name :uri
:label (tr "modals.create-webhook.url.label")
:placeholder (tr "modals.create-webhook.url.placeholder")}]]
[:div.fields-row
[:& fm/select {:options valid-webhook-mtypes
:label (tr "dashboard.webhooks.content-type")
:default "application/json"
:name :mtype}]]]
[:div.fields-row
[:div.input-checkbox.check-primary
[:& fm/input {:type "checkbox"
:form form
:name :is-active
:label (tr "dashboard.webhooks.active")}]]
[:div.explain (tr "dashboard.webhooks.active.explain")]]]
[:div.modal-footer
[:div.action-buttons
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click #(modal/hide!)}]
[:> fm/submit-button*
{:label (if webhook
(tr "modals.edit-webhook.submit-label")
(tr "modals.create-webhook.submit-label"))}]]]]]])))
(tr "modals.create-webhook.submit-label"))}]]]]]]))
(mf/defc webhooks-hero
{::mf/wrap-props false}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :webhooks-hero-container)}
[:div {:class (stl/css :webhooks-hero)}
[:div {:class (stl/css :desc)}
@ -1159,74 +837,39 @@
[:div
{:class (stl/css :btn-primary)
:on-click #(st/emit! (modal/show :webhook {}))}
[:span (tr "dashboard.webhooks.create")]]]]
;; OLD
[:div.webhooks-hero-container
[:div.webhooks-hero
[:div.desc
[:h2 (tr "labels.webhooks")]
[:& i18n/tr-html {:label "dashboard.webhooks.description"}]]
[:div.btn-primary
{:on-click #(st/emit! (modal/show :webhook {}))}
[:span (tr "dashboard.webhooks.create")]]]])))
[:span (tr "dashboard.webhooks.create")]]]])
(mf/defc webhook-actions
{::mf/wrap-props false}
[{:keys [on-edit on-delete]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show? (mf/use-state false)
(let [show? (mf/use-state false)
on-show (mf/use-fn #(reset! show? true))
on-hide (mf/use-fn #(reset! show? false))]
(if new-css-system
[:*
[:span {:class (stl/css :icon)
:on-click on-show} [i/actions]]
[:& dropdown {:show @show? :on-close on-hide}
[:ul {:class (stl/css :dropdown :actions-dropdown)}
[:li {:on-click on-edit} (tr "labels.edit")]
[:li {:on-click on-delete} (tr "labels.delete")]]]]
;; OLD
[:*
[:span.icon {:on-click on-show} [i/actions]]
[:& dropdown {:show @show? :on-close on-hide}
[:ul.dropdown.actions-dropdown
[:li {:on-click on-edit} (tr "labels.edit")]
[:li {:on-click on-delete} (tr "labels.delete")]]]])))
[:li {:on-click on-delete} (tr "labels.delete")]]]]))
(mf/defc last-delivery-icon
{::mf/wrap-props false}
[{:keys [success? text]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :last-delivery-icon)}
[:div {:class (stl/css :tooltip)}
[:div {:class (stl/css :label)} text]
[:div {:class (stl/css :arrow-down)}]]
(if success?
[:span {:class (stl/css :icon :success)} i/msg-success]
[:span {:class (stl/css :icon :failure)} i/msg-warning])]
;; OLD
[:div.last-delivery-icon
[:div.tooltip
[:div.label text]
[:div.arrow-down]]
(if success?
[:span.icon.success i/msg-success]
[:span.icon.failure i/msg-warning])])))
[:span {:class (stl/css :icon :failure)} i/msg-warning])])
(mf/defc webhook-item
{::mf/wrap [mf/memo]}
[{:keys [webhook] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
error-code (:error-code webhook)
(let [error-code (:error-code webhook)
id (:id webhook)
on-edit
@ -1266,7 +909,6 @@
(dm/str " " (tr "errors.webhooks.unexpected-status" (extract-status error-code))))))]
(if new-css-system
[:div {:class (stl/css :table-row)}
[:div {:class (stl/css :table-field :last-delivery)}
[:div {:class (stl/css :icon-container)}
@ -1282,47 +924,20 @@
[:div {:class (stl/css :table-field :actions)}
[:& webhook-actions
{:on-edit on-edit
:on-delete on-delete}]]]
;; OLD
[:div.table-row
[:div.table-field.last-delivery
[:div.icon-container
[:& last-delivery-icon
{:success? (nil? error-code)
:text last-delivery-text}]]]
[:div.table-field.uri
[:div (dm/str (:uri webhook))]]
[:div.table-field.active
[:div (if (:is-active webhook)
(tr "labels.active")
(tr "labels.inactive"))]]
[:div.table-field.actions
[:& webhook-actions
{:on-edit on-edit
:on-delete on-delete}]]])))
:on-delete on-delete}]]]))
(mf/defc webhooks-list
{::mf/wrap-props false}
[{:keys [webhooks]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :dashboard-table)}
[:div {:class (stl/css :table-rows)}
(for [webhook webhooks]
[:& webhook-item {:webhook webhook :key (:id webhook)}])]]
;; OLD
[:div.dashboard-table
[:div.table-rows
(for [webhook webhooks]
[:& webhook-item {:webhook webhook :key (:id webhook)}])]])))
[:& webhook-item {:webhook webhook :key (:id webhook)}])]])
(mf/defc team-webhooks-page
{::mf/wrap-props false}
[{:keys [team]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
webhooks (mf/deref refs/dashboard-team-webhooks)]
(let [webhooks (mf/deref refs/dashboard-team-webhooks)]
(mf/with-effect [team]
(dom/set-html-title
@ -1334,7 +949,6 @@
(mf/with-effect [team]
(st/emit! (dd/fetch-team-webhooks)))
(if new-css-system
[:*
[:& header {:team team :section :dashboard-team-webhooks}]
[:section {:class (stl/css :dashboard-container :dashboard-team-webhooks)}
@ -1344,19 +958,7 @@
[:div {:class (stl/css :webhooks-empty)}
[:div (tr "dashboard.webhooks.empty.no-webhooks")]
[:div (tr "dashboard.webhooks.empty.add-one")]]
[:& webhooks-list {:webhooks webhooks}])]]]
;; OLD
[:*
[:& header {:team team :section :dashboard-team-webhooks}]
[:section.dashboard-container.dashboard-team-webhooks
[:*
[:& webhooks-hero]
(if (empty? webhooks)
[:div.webhooks-empty
[:div (tr "dashboard.webhooks.empty.no-webhooks")]
[:div (tr "dashboard.webhooks.empty.add-one")]]
[:& webhooks-list {:webhooks webhooks}])]]])))
[:& webhooks-list {:webhooks webhooks}])]]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SETTINGS SECTION
@ -1365,8 +967,7 @@
(mf/defc team-settings-page
{::mf/wrap-props false}
[{:keys [team]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
finput (mf/use-ref)
(let [finput (mf/use-ref)
members-map (mf/deref refs/dashboard-team-members)
owner (->> (vals members-map)
@ -1398,7 +999,6 @@
(st/emit! (dd/fetch-team-members team-id)
(dd/fetch-team-stats team-id))))
(if new-css-system
[:*
[:& header {:section :dashboard-team-settings :team team}]
[:section {:class (stl/css :dashboard-container :dashboard-team-settings)}
@ -1434,41 +1034,5 @@
[:span {:class (stl/css :text)} (tr "labels.num-of-projects" (i18n/c (dec (:projects stats))))]]
[:div {:class (stl/css :files)}
[:span {:class (stl/css :icon)} i/file-html]
[:span {:class (stl/css :text)} (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]]
[:*
[:& header {:section :dashboard-team-settings :team team}]
[:section.dashboard-container.dashboard-team-settings
[:div.team-settings
[:div.horizontal-blocks
[:div.block.info-block
[:div.label (tr "dashboard.team-info")]
[:div.name (:name team)]
[:div.icon
(when can-edit?
[:span.update-overlay {:on-click on-image-click} i/image])
[:img {:src (cfg/resolve-team-photo-url team)}]
(when can-edit?
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref finput
:on-selected on-file-selected}])]]
[:div.block.owner-block
[:div.label (tr "dashboard.team-members")]
[:div.owner
[:span.icon [:img {:src (cfg/resolve-profile-photo-url owner)}]]
[:span.text (str (:name owner) " (" (tr "labels.owner") ")")]]
[:div.summary
[:span.icon i/user]
[:span.text (tr "dashboard.num-of-members" (count members-map))]]]
[:div.block.stats-block
[:div.label (tr "dashboard.team-projects")]
[:div.projects
[:span.icon i/folder]
[:span.text (tr "labels.num-of-projects" (i18n/c (dec (:projects stats))))]]
[:div.files
[:span.icon i/file-html]
[:span.text (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]])))
[:span {:class (stl/css :text)} (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]]))

View file

@ -13,7 +13,6 @@
[app.main.data.modal :as modal]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
@ -70,15 +69,13 @@
(mf/defc team-form-modal {::mf/register modal/components
::mf/register-as :team-form}
[{:keys [team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (fn [] (or team {})))
(let [initial (mf/use-memo (fn [] (or team {})))
form (fm/use-form :spec ::team-form
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))]
:initial initial)
on-close #(st/emit! (modal/hide))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:& fm/form {:form form :on-submit on-submit}
@ -108,35 +105,6 @@
{:label (if team
(tr "labels.update-team")
(tr "labels.create-team"))
:className (stl/css :accept-btn)}]]]]]]
[:div.modal-overlay
[:div.modal-container.team-form-modal
[:& fm/form {:form form :on-submit on-submit}
[:div.modal-header
[:div.modal-header-title
(if team
[:h2 (tr "labels.rename-team")]
[:h2 (tr "labels.create-team")])]
[:div.modal-close-button
{:on-click #(st/emit! (modal/hide))} i/close]]
[:div.modal-content.generic-form
[:& fm/input {:type "text"
:auto-focus? true
:form form
:name :name
:label (tr "labels.create-team.placeholder")}]]
[:div.modal-footer
[:div.action-buttons
[:> fm/submit-button*
{:label (if team
(tr "labels.update-team")
(tr "labels.create-team"))}]]]]]])))
:className (stl/css :accept-btn)}]]]]]]))

View file

@ -11,7 +11,6 @@
[app.main.data.modal :as modal]
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -27,8 +26,7 @@
::mf/register-as :delete-shared-libraries
::mf/wrap-props false}
[{:keys [ids on-accept on-cancel accept-style origin count-libraries]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
references* (mf/use-state {})
(let [references* (mf/use-state {})
references (deref references*)
on-accept (or on-accept noop)
@ -96,7 +94,6 @@
(let [key (events/listen js/document "keydown" on-keydown)]
(partial events/unlistenByKey key))))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -119,7 +116,7 @@
:key (dm/str file-id)}
[:span "- " file-name]])]]
(when (and (string? hint) (not= hint ""))
[:h3 {:class (stl/css :modal-hint)}hint])]
[:h3 {:class (stl/css :modal-hint)} hint])]
[:*
[:h3 {:class (stl/css :modal-msg)} no-files-msg]]))]
@ -136,51 +133,4 @@
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]
[:div.modal-overlay
[:div.modal-container.confirm-dialog
[:div.modal-header
[:div.modal-header-title
[:h2 title]]
[:div.modal-close-button
{:on-click cancel-fn} i/close]]
[:div.modal-content.delete-shared
(when (and (string? subtitle) (not= subtitle ""))
[:h3 subtitle])
(when (not= 0 count-libraries)
(if (pos? (count references))
[:*
[:div
(when (and (string? scd-msg) (not= scd-msg ""))
[:h3 scd-msg])
[:ul.file-list
(for [[file-id file-name] references]
[:li.modal-item-element
{:key (dm/str file-id)}
[:span "- " file-name]])]]
(when (and (string? hint) (not= hint ""))
[:h3 hint])]
[:*
[:h3 no-files-msg]]))]
[:div.modal-footer
[:div.action-buttons
(when-not (= cancel-label :omit)
[:input.cancel-button
{:type "button"
:value cancel-label
:on-click cancel-fn}])
[:input.accept-button
{:class (dom/classnames
:danger (= accept-style :danger)
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]
)
))
:on-click accept-fn}]]]]]))

View file

@ -11,46 +11,54 @@
&.transparent {
background-color: transparent;
}
.modal-container {
}
.modal-container {
@extend .modal-container-base;
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content {
}
.modal-content {
@include titleTipography;
margin-bottom: $s-24;
.modal-hint {
}
.modal-hint {
@extend .modal-hint-base;
}
.element-list {
}
.element-list {
@include titleTipography;
.list-item {
@include titleTipography;
}
}
}
.modal-footer {
.action-buttons {
}
.action-buttons {
@extend .modal-action-btns;
.cancel-button {
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}
.modal-scd-msg,

View file

@ -14,15 +14,11 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.link-button :as lb]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(mf/defc banner
[{:keys [type position status controls content links actions on-close data-test role] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css-case :banner true
:warning (= type :warning)
:error (= type :error)
@ -63,47 +59,7 @@
(:label action)])])]
(when (= controls :close)
[:button {:class (stl/css :btn-close)
:on-click on-close} i/close-refactor])]]
[:div.banner {:class (dom/classnames
:warning (= type :warning)
:error (= type :error)
:success (= type :success)
:info (= type :info)
:fixed (= position :fixed)
:floating (= position :floating)
:inline (= position :inline)
:hide (= status :hide))}
[:div.wrapper
[:div.icon (case type
:warning i/msg-warning
:error i/msg-error
:success i/msg-success
:info i/msg-info
i/msg-error)]
[:div.content {:class (dom/classnames
:inline-actions (= controls :inline-actions)
:bottom-actions (= controls :bottom-actions))
:data-test data-test
:role role}
[:span
content
(for [[index link] (d/enumerate links)]
[:* {:key (dm/str "link-" index)}
" " [:& lb/link-button {:class "link"
:on-click (:callback link)
:value (:label link)}]])]
(when (or (= controls :bottom-actions) (= controls :inline-actions))
[:div.actions
(for [action actions]
[:div.btn-secondary.btn-small {:key (uuid/next)
:on-click (:callback action)}
(:label action)])])]
(when (= controls :close)
[:div.btn-close {:on-click on-close} i/close])]])))
:on-click on-close} i/close-refactor])]])
(mf/defc notifications
[]

View file

@ -100,15 +100,6 @@
@include titleTipography;
}
.inline-actions {
}
.bottom-actions {
}
.actions {
}
.action-btn {
@extend .button-tertiary;
height: $s-32;

View file

@ -51,7 +51,6 @@
(let [data (unchecked-get props "data")
wrapper-ref (mf/use-ref nil)
components (mf/deref dm/components)
new-css-system (mf/use-ctx ctx/new-css-system)
allow-click-outside (:allow-click-outside data)
@ -78,9 +77,7 @@
(when-let [component (get components (:type data))]
[:div {:ref wrapper-ref
:class (stl/css-case
:modal-wrapper new-css-system
:global/modal-wrapper (not new-css-system))}
:class (stl/css :modal-wrapper)}
(mf/element component (:props data))])))
(def modal-ref

View file

@ -13,7 +13,6 @@
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.onboarding.newsletter]
[app.main.ui.onboarding.questions]
[app.main.ui.onboarding.team-choice]
@ -33,12 +32,10 @@
(mf/defc onboarding-welcome
[{:keys [next] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
go-next
(let [go-next
(fn []
(send-event "onboarding-step1-continue")
(next))]
(if new-css-system
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-left)}
[:img {:src "images/onboarding-welcome.png"
@ -82,46 +79,14 @@
[:div {:class (stl/css :modal-footer)}
[:button {:on-click go-next
:data-test "onboarding-next-btn"}
(tr "labels.continue")]]]]
[:div.modal-container.onboarding.onboarding-v2
[:div.modal-left.welcome
[:img {:src "images/onboarding-welcome.png" :border "0" :alt (tr "onboarding.welcome.alt")}]]
[:div.modal-right
[:div.release-container [:span.release "Version " (:main cf/version)]]
[:div.right-content
[:div.modal-title
[:h2 {:data-test "onboarding-welcome"} (tr "onboarding-v2.welcome.title")]]
[:div.modal-content
[:p (tr "onboarding-v2.welcome.desc1")]
[:div.welcome-card
[:img {:src "images/community.svg" :border "0"}]
[:div
[:div.title [:a {:href "https://community.penpot.app/" :target "_blank" :on-click #(send-event "onboarding-community-link")} (tr "onboarding-v2.welcome.desc2.title")]]
[:div.description (tr "onboarding-v2.welcome.desc2")]]]
[:div.welcome-card
[:img {:src "images/contributing.svg" :border "0"}]
[:div
[:div.title [:a {:href "https://help.penpot.app/contributing-guide/" :target "_blank" :on-click #(send-event "onboarding-contributing-link")} (tr "onboarding-v2.welcome.desc3.title")]]
[:div.description (tr "onboarding-v2.welcome.desc3")]]]]]
[:div.modal-navigation
[:button.btn-secondary {:on-click go-next :data-test "onboarding-next-btn"} (tr "labels.continue")]]
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
(tr "labels.continue")]]]]))
(mf/defc onboarding-before-start
[{:keys [next] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
go-next
(let [go-next
(fn []
(send-event "onboarding-step2-continue")
(next))]
(if new-css-system
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-left)}
[:img {:src "images/onboarding-people.png"
@ -166,45 +131,14 @@
[:div {:class (stl/css :modal-footer)}
[:button {:on-click go-next
:data-test "onboarding-next-btn"}
(tr "labels.continue")]]]]
[:div.modal-container.onboarding.onboarding-v2
[:div.modal-left.welcome
[:img {:src "images/onboarding-people.png" :border "0" :alt (tr "onboarding.welcome.alt")}]]
[:div.modal-right
[:div.release-container [:span.release "Version " (:main cf/version)]]
[:div.right-content
[:div.modal-title
[:h2 {:data-test "onboarding-welcome"} (tr "onboarding-v2.before-start.title")]]
[:div.modal-content
[:p (tr "onboarding-v2.before-start.desc1")]
[:div.welcome-card
[:img {:src "images/user-guide.svg" :border "0"}]
[:div
[:div.title [:a {:href "https://help.penpot.app/user-guide/" :target "_blank" :on-click #(send-event "onboarding-user-guide-link")} (tr "onboarding-v2.before-start.desc2.title")]]
[:div.description (tr "onboarding-v2.before-start.desc2")]]]
[:div.welcome-card
[:img {:src "images/video-tutorials.svg" :border "0"}]
[:div
[:div.title [:a {:href "https://www.youtube.com/c/Penpot" :target "_blank" :on-click #(send-event "onboarding-video-tutorials-link")} (tr "onboarding-v2.before-start.desc3.title")]]
[:div.description (tr "onboarding-v2.before-start.desc3")]]]]]
[:div.modal-navigation
[:button.btn-secondary {:on-click go-next :data-test "onboarding-next-btn"} (tr "labels.continue")]]
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
(tr "labels.continue")]]]]))
(mf/defc onboarding-modal
{::mf/register modal/components
::mf/register-as :onboarding}
[_]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
slide (mf/use-state :start)
(let [slide (mf/use-state :start)
klass (mf/use-state "fadeInDown")
navigate
@ -230,15 +164,8 @@
(reset! klass nil)
(tm/dispose! sem))))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div.animated {:class(dm/str @klass " " (stl/css :animated))}
[:div.animated {:class (dm/str @klass " " (stl/css :animated))}
(case @slide
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
:opensource [:& onboarding-before-start {:next skip}])]]
[:div.modal-overlay
[:div.animated {:class @klass}
(case @slide
:start [:& onboarding-welcome {:next #(navigate :opensource)}]
:opensource [:& onboarding-before-start {:next skip}])]])))
:opensource [:& onboarding-before-start {:next skip}])]]))

View file

@ -11,7 +11,6 @@
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@ -20,8 +19,7 @@
{::mf/register modal/components
::mf/register-as :onboarding-newsletter-modal}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
message (tr "onboarding.newsletter.acceptance-message")
(let [message (tr "onboarding.newsletter.acceptance-message")
newsletter-updates (mf/use-state false)
newsletter-news (mf/use-state false)
toggle
@ -39,7 +37,6 @@
(modal/show {:type :onboarding-team})
(du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div.animated.fadeInDown {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -85,32 +82,4 @@
[:img {:class (stl/css-case :deco true
:top true)
:src "images/deco-newsletter.png" :border "0"}]]]
[:div.modal-overlay
[:div.modal-container.onboarding.newsletter.animated.fadeInDown
[:div.modal-top
[:h1.newsletter-title {:data-test "onboarding-newsletter-title"} (tr "onboarding.newsletter.title")]
[:p (tr "onboarding-v2.newsletter.desc")]]
[:div.modal-bottom
[:div.newsletter-options
[:div.input-checkbox.check-primary
[:input {:type "checkbox"
:id "newsletter-updates"
:on-change #(toggle newsletter-updates)}]
[:label {:for "newsletter-updates"} (tr "onboarding-v2.newsletter.updates")]]
[:div.input-checkbox.check-primary
[:input {:type "checkbox"
:id "newsletter-news"
:on-change #(toggle newsletter-news)}]
[:label {:for "newsletter-news"} (tr "onboarding-v2.newsletter.news")]]]
[:p (tr "onboarding-v2.newsletter.privacy1") [:a {:target "_blank" :href "https://penpot.app/privacy"} (tr "onboarding.newsletter.policy")]]
[:p (tr "onboarding-v2.newsletter.privacy2")]]
[:div.modal-footer
[:button.btn-primary {:on-click accept} (tr "labels.continue")]]
[:img.deco.top {:src "images/deco-newsletter.png" :border "0"}]
[:img.deco.newsletter-left {:src "images/deco-news-left.png" :border "0"}]
[:img.deco.newsletter-right {:src "images/deco-news-right.png" :border "0"}]]])
))
:src "images/deco-newsletter.png" :border "0"}]]]))

View file

@ -15,7 +15,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
@ -30,9 +29,6 @@
(mf/defc team-modal-right
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :modal-right)}
[:h2 {:class (stl/css :modal-subtitle)}
(tr "onboarding.team-modal.create-team")]
@ -58,36 +54,13 @@
[:li {:class (stl/css :feature)}
[:span {:class (stl/css :icon)} i/tick-refactor]
[:p {:class (stl/css :modal-text)}
(tr "onboarding.team-modal.create-team-feature-5")]]]]
[:div.team-right
[:h2.subtitle (tr "onboarding.team-modal.create-team")]
[:p.info (tr "onboarding.team-modal.create-team-desc")]
[:ul.team-features
[:li.feature
[:span.icon i/file-html]
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-1")]]
[:li.feature
[:span.icon i/pointer-inner]
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-2")]]
[:li.feature
[:span.icon i/tree]
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-3")]]
[:li.feature
[:span.icon i/user]
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-4")]]
[:li.feature
[:span.icon i/tick]
[:p.feature-txt (tr "onboarding.team-modal.create-team-feature-5")]]]])))
(tr "onboarding.team-modal.create-team-feature-5")]]]])
(mf/defc onboarding-team-modal
{::mf/register modal/components
::mf/register-as :onboarding-team}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::team-form
(let [form (fm/use-form :spec ::team-form
:initial {}
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space"))
(fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
@ -109,7 +82,6 @@
teams (mf/deref refs/teams)]
(if new-css-system
(if (< (count teams) 2)
[:div {:class (stl/css :modal-overlay)}
[:div.animated.fadeIn {:class (stl/css :modal-container)}
@ -146,39 +118,7 @@
[:& team-modal-right]
[:div {:class (stl/css :paginator)} "1/2"]]]
(st/emit! (modal/hide)))
(if (< (count teams) 2)
[:div.modal-overlay
[:div.modal-container.onboarding-team.animated.fadeIn
[:div.team-left
[: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}
[:& fm/input {:type "text"
:name :name
:label (tr "onboarding.choice.team-up.create-team-placeholder")}]
[:& fm/submit-button*
{:label (tr "onboarding.choice.team-up.continue-creating-team")}]]
[: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"]
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]]
(st/emit! (modal/hide))))))
(st/emit! (modal/hide)))))
(defn get-available-roles
[]
@ -197,8 +137,7 @@
{::mf/register modal/components
::mf/register-as :onboarding-team-invitations}
[{:keys [name] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (constantly
(let [initial (mf/use-memo (constantly
{:role "editor"
:name name}))
form (fm/use-form :spec ::invite-form
@ -265,7 +204,6 @@
(on-invite-now form)
(on-invite-later form)))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div.animated.fadeIn {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-left)}
@ -308,53 +246,6 @@
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
[:& team-modal-right]
[:div {:class (stl/css :paginator)} "2/2"]]]
[:div.modal-overlay
[:div.modal-container.onboarding-team-members.animated.fadeIn
[:div.team-left
[:h2.title (tr "onboarding.choice.team-up.invite-members")]
[:p.info (tr "onboarding.choice.team-up.invite-members-info")]
[:& fm/form {:form form
:on-submit on-submit}
[:div.invite-row
[:div.role-wrapper
[:span.rol (tr "onboarding.choice.team-up.roles")]
[:& fm/select {:name :role :options roles}]]
[:& fm/multi-input {:type "email"
:name :emails
:auto-focus? true
:trim true
:valid-item-fn us/parse-email
:caution-item-fn #{}
:on-submit on-submit
:label (tr "modals.invite-member.emails")}]]
[:div.buttons
[:button.btn-secondary.btn-large
{:on-click #(st/emit! (modal/show {:type :onboarding-team})
(ptk/event ::ev/event {::ev/name "invite-members-back"
::ev/origin "onboarding"
:name name
:step 2}))}
(tr "labels.back")]
[:& 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
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
[:& team-modal-right]
[:div.paginator "2/2"]
[:img.deco.square {:src "images/deco-square.svg" :border "0"}]
[:img.deco.circle {:src "images/deco-circle.svg" :border "0"}]
[:img.deco.line1 {:src "images/deco-line1.svg" :border "0"}]
[:img.deco.line2 {:src "images/deco-line2.svg" :border "0"}]]])))
[:div {:class (stl/css :paginator)} "2/2"]]]))

View file

@ -14,7 +14,6 @@
[app.main.store :as st]
[app.main.ui.components.context-menu-a11y :refer [context-menu-a11y]]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -51,8 +50,7 @@
{::mf/register modal/components
::mf/register-as :access-token}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form
(let [form (fm/use-form
:initial initial-data
:spec ::access-token-form
:validators [name-validator
@ -107,7 +105,6 @@
:content (tr "dashboard.access-tokens.copied-success")
:timeout 1000}))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:& fm/form {:form form :on-submit on-submit}
@ -161,7 +158,7 @@
[:button {:class (stl/css :copy-btn)
:title (tr "modals.create-access-token.copy-token")
:on-click copy-token}
[:span {:class (stl/css :token-value)}(:token created "")]
[:span {:class (stl/css :token-value)} (:token created "")]
[:span {:class (stl/css :icon)}
i/clipboard-refactor]])]]
@ -179,78 +176,11 @@
:value (tr "labels.cancel")
:on-click #(modal/hide!)}]
[:> fm/submit-button*
{:label (tr "modals.create-access-token.submit-label")}]])]]]]]
[:div.modal-overlay
[:div.modal-container.access-tokens-modal
[:& fm/form {:form form :on-submit on-submit}
[:div.modal-header
[:div.modal-header-title
[:h2 (tr "modals.create-access-token.title")]]
[:div.modal-close-button
{:on-click on-close} i/close]]
[:div.modal-content.generic-form
[:div.fields-container
[:div.fields-row
[:& fm/input {:type "text"
:auto-focus? true
:form form
:name :name
:disabled @created?
:label (tr "modals.create-access-token.name.label")
:placeholder (tr "modals.create-access-token.name.placeholder")}]]
[:div.fields-row
[:& fm/select {:options [{:label (tr "dashboard.access-tokens.expiration-never") :value "never" :key "never"}
{:label (tr "dashboard.access-tokens.expiration-30-days") :value "720h" :key "720h"}
{:label (tr "dashboard.access-tokens.expiration-60-days") :value "1440h" :key "1440h"}
{:label (tr "dashboard.access-tokens.expiration-90-days") :value "2160h" :key "2160h"}
{:label (tr "dashboard.access-tokens.expiration-180-days") :value "4320h" :key "4320h"}]
:label (tr "modals.create-access-token.expiration-date.label")
:default "never"
:disabled @created?
:name :expiration-date}]
(when @created?
[:span.token-created-info
(if (:expires-at created)
(tr "dashboard.access-tokens.token-will-expire" (dt/format-date-locale (:expires-at created) {:locale locale}))
(tr "dashboard.access-tokens.token-will-not-expire"))])]
[:div.fields-row.access-token-created
(when @created?
[:div.custom-input.with-icon
[:input {:type "text"
:value (:token created "")
:placeholder (tr "modals.create-access-token.token")
:read-only true}]
[:button.help-icon {:title (tr "modals.create-access-token.copy-token")
:on-click copy-token}
i/copy]])]]]
[:div.modal-footer
[:div.action-buttons
(if @created?
[:input.cancel-button
{:type "button"
:value (tr "labels.close")
:on-click #(modal/hide!)}]
[:*
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")
:on-click #(modal/hide!)}]
[:> fm/submit-button*
{:label (tr "modals.create-access-token.submit-label")}]])]]]]])))
{:label (tr "modals.create-access-token.submit-label")}]])]]]]]))
(mf/defc access-tokens-hero
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))]
(if new-css-system
(let [on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))]
[:div {:class (stl/css :access-tokens-hero-container)}
[:div {:class (stl/css :access-tokens-hero)}
[:div {:class (stl/css :desc)}
@ -260,23 +190,11 @@
[:button
{:class (stl/css :btn-primary)
:on-click on-click}
[:span (tr "dashboard.access-tokens.create")]]]]
;; OLD
[:div.access-tokens-hero-container
[:div.access-tokens-hero
[:div.desc
[:h2 (tr "dashboard.access-tokens.personal")]
[:p (tr "dashboard.access-tokens.personal.description")]]
[:button.btn-primary
{:on-click on-click}
[:span (tr "dashboard.access-tokens.create")]]]])))
[:span (tr "dashboard.access-tokens.create")]]]]))
(mf/defc access-token-actions
[{:keys [on-delete]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
local (mf/use-state {:menu-open false})
(let [local (mf/use-state {:menu-open false})
show? (:menu-open @local)
options (mf/with-memo [on-delete]
[{:option-name (tr "labels.delete")
@ -302,9 +220,7 @@
(dom/stop-propagation event)
(on-menu-click event))))]
(if new-css-system
[:div
{:class (stl/css :icon)
[:div {:class (stl/css :icon)
:tab-index "0"
:ref menu-ref
:on-click on-menu-click
@ -317,32 +233,12 @@
:min-width? true
:top "auto"
:left "auto"
:options options}]]
;; OLD
[:div.icon
{:tab-index "0"
:ref menu-ref
:on-click on-menu-click
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/stop-propagation event)
(on-menu-click event)))}
i/actions
[:& context-menu-a11y
{:on-close on-menu-close
:show show?
:fixed? true
:min-width? true
:top "auto"
:left "auto"
:options options}]])))
:options options}]]))
(mf/defc access-token-item
{::mf/wrap [mf/memo]}
[{:keys [token] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
locale (mf/deref i18n/locale)
(let [locale (mf/deref i18n/locale)
expires-at (:expires-at token)
expires-txt (some-> expires-at (dt/format-date-locale {:locale locale}))
expired? (and (some? expires-at) (> (dt/now) expires-at))
@ -366,7 +262,6 @@
:accept-label (tr "modals.delete-acces-token.accept")
:on-accept delete-fn}))))]
(if new-css-system
[:div {:class (stl/css :table-row)}
[:div {:class (stl/css :table-field :name)}
(str (:name token))]
@ -379,31 +274,15 @@
:else (tr "dashboard.access-tokens.expires-on" expires-txt))]]
[:div {:class (stl/css :table-field :actions)}
[:& access-token-actions
{:on-delete on-delete}]]]
;; OLD
[:div.table-row
[:div.table-field.name
(str (:name token))]
[:div.table-field.expiration-date
[:span.content {:class (when expired? "expired")}
(cond
(nil? expires-at) (tr "dashboard.access-tokens.no-expiration")
expired? (tr "dashboard.access-tokens.expired-on" expires-txt)
:else (tr "dashboard.access-tokens.expires-on" expires-txt))]]
[:div.table-field.actions
[:& access-token-actions
{:on-delete on-delete}]]])))
{:on-delete on-delete}]]]))
(mf/defc access-tokens-page
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
tokens (mf/deref tokens-ref)]
(let [tokens (mf/deref tokens-ref)]
(mf/with-effect []
(dom/set-html-title (tr "title.settings.access-tokens"))
(st/emit! (du/fetch-access-tokens)))
(if new-css-system
[:div {:class (stl/css :dashboard-access-tokens)}
[:div
[:& access-tokens-hero]
@ -414,18 +293,5 @@
[:div {:class (stl/css :dashboard-table)}
[:div {:class (stl/css :table-rows)}
(for [token tokens]
[:& access-token-item {:token token :key (:id token)}])]])]]
;; OLD
[:div.dashboard-access-tokens
[:div
[:& access-tokens-hero]
(if (empty? tokens)
[:div.access-tokens-empty
[:div (tr "dashboard.access-tokens.empty.no-access-tokens")]
[:div (tr "dashboard.access-tokens.empty.add-one")]]
[:div.dashboard-table
[:div.table-rows
(for [token tokens]
[:& access-token-item {:token token :key (:id token)}])]])]])))
[:& access-token-item {:token token :key (:id token)}])]])]]))

View file

@ -12,8 +12,9 @@
font-size: $fs-16;
margin-top: $s-20;
width: $s-800;
}
.table-header {
.table-header {
color: $df-secondary;
display: grid;
font-size: $fs-12;
@ -23,9 +24,9 @@
padding: 0 $s-16;
text-transform: uppercase;
width: 100%;
}
}
.table-rows {
.table-rows {
color: $db-secondary;
display: flex;
flex-direction: column;
@ -33,9 +34,9 @@
max-width: $s-1000;
padding-top: 0;
width: 100%;
}
}
.table-row {
.table-row {
align-items: center;
background-color: $db-tertiary;
border-radius: $br-8;
@ -51,9 +52,9 @@
&:not(:first-child) {
margin-top: $s-8;
}
}
}
.table-field {
.table-field {
display: flex;
align-items: center;
@ -92,13 +93,12 @@
&.actions {
position: relative;
}
}
}
svg {
svg {
width: $s-12;
height: $s-12;
fill: $df-primary;
}
}
.dashboard-access-tokens {

View file

@ -16,7 +16,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.i18n :as i18n :refer [tr]]
@ -76,8 +75,7 @@
{::mf/register modal/components
::mf/register-as :change-email}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile (mf/deref refs/profile)
(let [profile (mf/deref refs/profile)
form (fm/use-form :spec ::email-change-form
:validators [email-equality]
:initial profile)
@ -99,7 +97,6 @@
(when (and different-emails-error? (= email-1 email-2))
(swap! form d/dissoc-in [:errors :email-2])))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:& fm/form {:form form
@ -138,43 +135,6 @@
:data-test "change-email-submit"}
[:> fm/submit-button*
{:label (tr "modals.change-email.submit")}]]]]]]
[:div.modal-overlay
[:div.modal-container.change-email-modal.form-container
[:& fm/form {:form form
:on-submit on-submit}
[:div.modal-header
[:div.modal-header-title
[:h2 {:data-test "change-email-title"}
(tr "modals.change-email.title")]]
[:div.modal-close-button
{:on-click on-close} i/close]]
[:div.modal-content
[:& msgs/inline-banner
{:type :info
:content (tr "modals.change-email.info" (:email profile))}]
[:div.fields-container
[:div.fields-row
[:& fm/input {:type "email"
:name :email-1
:label (tr "modals.change-email.new-email")
:trim true
:on-change-value on-email-change}]]
[:div.fields-row
[:& fm/input {:type "email"
:name :email-2
:label (tr "modals.change-email.confirm-email")
:trim true
:on-change-value on-email-change}]]]]
[:div.modal-footer
[:div.action-buttons {:data-test "change-email-submit"}
[:> fm/submit-button*
{:label (tr "modals.change-email.submit")}]]]]]])
))

View file

@ -8,46 +8,50 @@
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
}
.modal-container {
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
.modal-close-btn {
@extend .modal-close-btn-base;
}
.modal-content {
@include flexColumn;
@include titleTipography;
gap: $s-24;
margin-bottom: $s-24;
}
.fields-row {
.fields-row {
@include flexColumn;
.select-title {
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
}
}
}
.modal-footer {
.action-buttons {
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
}
.cancel-button {
@extend .modal-cancel-btn;
}
}
}
}
}
.cancel-button {
@extend .modal-cancel-btn;
}

View file

@ -11,7 +11,6 @@
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.messages :as msgs]
[app.util.i18n :as i18n :refer [tr]]
@ -29,8 +28,7 @@
{::mf/register modal/components
::mf/register-as :delete-account}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-close
(let [on-close
(mf/use-callback #(st/emit! (modal/hide)))
on-accept
@ -39,7 +37,6 @@
(du/request-account-deletion
(with-meta {} {:on-error on-error}))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
@ -63,28 +60,5 @@
:danger true)
:on-click on-accept
:data-test "delete-account-btn"}
(tr "modals.delete-account.confirm")]]]]]
[:div.modal-overlay
[:div.modal-container.change-email-modal
[:div.modal-header
[:div.modal-header-title
[:h2 (tr "modals.delete-account.title")]]
[:div.modal-close-button
{:on-click on-close} i/close]]
[:div.modal-content
[:& msgs/inline-banner
{:type :warning
:content (tr "modals.delete-account.info")}]]
[:div.modal-footer
[:div.action-buttons
[:button.btn-danger.btn-large {:on-click on-accept
:data-test "delete-account-btn"}
(tr "modals.delete-account.confirm")]
[:button.btn-secondary.btn-large {:on-click on-close}
(tr "modals.delete-account.cancel")]]]]])))
(tr "modals.delete-account.confirm")]]]]]))

View file

@ -8,50 +8,54 @@
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
}
.modal-container {
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
.modal-close-btn {
@extend .modal-close-btn-base;
}
.modal-content {
@include flexColumn;
@include titleTipography;
gap: $s-24;
margin-bottom: $s-24;
}
.fields-row {
.fields-row {
@include flexColumn;
.select-title {
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
}
}
}
.modal-footer {
.action-buttons {
.action-buttons {
@extend .modal-action-btns;
}
.cancel-button {
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-button {
}
.accept-button {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
}
}
}
}

View file

@ -14,7 +14,6 @@
[app.main.ui.auth.login :refer [login-methods]]
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
[app.main.ui.auth.register :refer [register-methods register-validate-form register-success-page]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -27,8 +26,7 @@
{::mf/register modal/components
::mf/register-as :login-register}
[_]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
uri (. (. js/document -location) -href)
(let [uri (. (. js/document -location) -href)
user-email (mf/use-state "")
register-token (mf/use-state "")
@ -71,7 +69,6 @@
(mf/with-effect []
(swap! storage assoc :redirect-url uri))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -126,59 +123,4 @@
(when main-section
[:div {:class (stl/css :links)}
[:& terms-login]])]]]
;;OLD
[:div.modal-overlay
[:div.modal-container.login-register
[:div.title
[:div.modal-close-button {:on-click close :title (tr "labels.close")}
i/close]
(when main-section
[:h2 (tr "labels.continue-with-penpot")])]
[:div.modal-bottom.auth-content
(case current-section
:login
[:div.generic-form.login-form
[:div.form-container
[:& login-methods {:on-success-callback success-login}]
[:div.links
[:div.link-entry
[:a {:on-click #(set-current-section :recovery-request)}
(tr "auth.forgot-password")]]
[:div.link-entry
[:span (tr "auth.register") " "]
[:a {:on-click #(set-current-section :register)}
(tr "auth.register-submit")]]]]]
:register
[:div.form-container
[:& register-methods {:on-success-callback success-register}]
[:div.links
[:div.link-entry
[:span (tr "auth.already-have-account") " "]
[:a {:on-click #(set-current-section :login)}
(tr "auth.login-here")]]]]
:register-validate
[:div.form-container
[:& register-validate-form {:params {:token @register-token}
:on-success-callback success-email-sent}]
[:div.links
[:div.link-entry
[:a {:on-click #(set-current-section :register)}
(tr "labels.go-back")]]]]
:recovery-request
[:& recovery-request-page {:go-back-callback #(set-current-section :login)
:on-success-callback success-email-sent}]
:email-sent
[:div.form-container
[:& register-success-page {:params {:email @user-email}}]])]
(when main-section
[:div.modal-footer.links
[:& terms-login]])]])))
[:& terms-login]])]]]))

View file

@ -18,7 +18,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.select :refer [select]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -40,8 +39,7 @@
::mf/register-as :share-link
::mf/wrap-props false}
[{:keys [file page]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
current-page page
(let [current-page page
current-page-id (:id page)
slinks (mf/deref refs/share-links)
router (mf/deref refs/router)
@ -165,7 +163,6 @@
(reset! confirm* false)
(swap! options* assoc :who-comment value))]
(if new-css-system
[:div {:class (stl/css :share-modal)}
[:div {:class (stl/css :share-link-dialog)}
[:div {:class (stl/css :share-link-header)}
@ -310,129 +307,7 @@
:default-value (dm/str (:who-inspect options))
:options [{:value "team" :label (tr "common.share-link.team-members")}
{:value "all" :label (tr "common.share-link.all-users")}]
:on-change on-inspect-change}]]]])])]]]
;;OLD
[:div.modal-overlay.transparent.share-modal
[:div.modal-container.share-link-dialog
[:div.modal-content.initial
[:div.title
[:h2 (tr "common.share-link.title")]
[:div.modal-close-button
{:on-click on-close
:title (tr "labels.close")}
i/close]]]
[:div.modal-content
[:div.share-link-section
(when (and (not confirm?) (some? current-link))
[:div.custom-input.with-icon
[:input {:type "text"
:value (or current-link "")
:placeholder (tr "common.share-link.placeholder")
:read-only true}]
[:div.help-icon {:title (tr "viewer.header.share.copy-link")
:on-click copy-link}
i/copy]])
[:div.hint-wrapper
(when (not ^boolean confirm?)
[:div.hint (tr "common.share-link.permissions-hint")])
(cond
(true? confirm?)
[:div.confirm-dialog
[:div.description (tr "common.share-link.confirm-deletion-link-description")]
[:div.actions
[:input.btn-secondary
{:type "button"
:on-click #(reset! confirm* false)
:value (tr "labels.cancel")}]
[:input.btn-danger
{:type "button"
:on-click delete-link
:value (tr "common.share-link.destroy-link")}]]]
(some? current-link)
[:input.btn-secondary
{:type "button"
:class "primary"
:on-click try-delete-link
:value (tr "common.share-link.destroy-link")}]
:else
[:input.btn-primary
{:type "button"
:class "primary"
:on-click create-link
:value (tr "common.share-link.get-link")}])]]]
[:div.modal-content.ops-section
[:div.manage-permissions
{:on-click toggle-perms-visibility}
[:span.icon i/picker-hsv]
[:div.title (tr "common.share-link.manage-ops")]]
(when ^boolean perms-visible?
[:*
(let [all-selected? (:all-pages options)
pages (->> (get-in file [:data :pages])
(map #(get-in file [:data :pages-index %])))
selected (:pages options)]
[:*
[:div.view-mode
[:div.subtitle
[:span.icon i/play]
(tr "common.share-link.permissions-pages")]
[:div.items
(if (= 1 (count pages))
[:div.input-checkbox.check-primary
[:input {:type "checkbox"
:id (dm/str "page-" current-page-id)
:data-page-id (dm/str current-page-id)
:on-change on-mark-checked-page
:checked true}]
[:label {:for (str "page-" current-page-id)} (:name current-page)]
[:span (str " " (tr "common.share-link.current-tag"))]]
[:*
[:div.row
[:div.input-checkbox.check-primary
[:input {:type "checkbox"
:id "view-all"
:checked all-selected?
:name "pages-mode"
:on-change on-toggle-all}]
[:label {:for "view-all"} (tr "common.share-link.view-all")]]
[:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
[:ul.pages-selection
(for [{:keys [id name]} pages]
[:li.input-checkbox.check-primary {:key (dm/str id)}
[:input {:type "checkbox"
:id (dm/str "page-" id)
:data-page-id (dm/str id)
:on-change on-mark-checked-page
:checked (contains? selected id)}]
(if (= current-page-id id)
[:*
[:label {:for (dm/str "page-" id)} name]
[:span.current-tag (dm/str " " (tr "common.share-link.current-tag"))]]
[:label {:for (dm/str "page-" id)} name])])]])]]])
[:div.access-mode
[:div.subtitle
[:span.icon i/chat]
(tr "common.share-link.permissions-can-comment")]
[:div.items
[:select.input-select {:on-change on-comment-change
:value (:who-comment options)}
[:option {:value "team"} (tr "common.share-link.team-members")]
[:option {:value "all"} (tr "common.share-link.all-users")]]]]
[:div.inspect-mode
[:div.subtitle
[:span.icon i/code]
(tr "common.share-link.permissions-can-inspect")]
[:div.items
[:select.input-select {:on-change on-inspect-change
:value (:who-inspect options)}
[:option {:value "team"} (tr "common.share-link.team-members")]
[:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]])))
:on-change on-inspect-change}]]]])])]]]))

View file

@ -19,7 +19,8 @@
height: $s-32;
margin-right: $s-4;
svg {
height: $s-32;
min-height: $s-32;
width: $s-32;
fill: var(--icon-foreground-hover);
}
}

View file

@ -39,9 +39,11 @@
stroke: var(--icon-foreground);
}
}
.modal-title {
@include tabTitleTipography;
margin-bottom: $s-16;
color: var(--modal-title-foreground-color);
}
.modal-content {
@ -161,6 +163,7 @@
.section-list-empty {
@include titleTipography;
@include flexCenter;
color: var(--empty-message-foreground-color);
svg {
@extend .button-icon-small;

View file

@ -12,7 +12,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -32,8 +31,7 @@
{::mf/register modal/components
::mf/register-as :nudge-option}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile (mf/deref refs/profile)
(let [profile (mf/deref refs/profile)
nudge (or (get-in profile [:props :nudge]) {:big 10 :small 1})
update-big (mf/use-fn #(st/emit! (dw/update-nudge {:big %})))
update-small (mf/use-fn #(st/emit! (dw/update-nudge {:small %})))
@ -43,7 +41,6 @@
(->> (events/listen js/document EventType.KEYDOWN on-keydown)
(partial events/unlistenByKey)))
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
@ -64,24 +61,4 @@
[:> numeric-input* {:min 0.01
:id "nudge-big"
:value (:big nudge)
:on-change update-big}]]]]]
[:div.nudge-modal-overlay
[:div.nudge-modal-container
[:div.nudge-modal-header
[:p.nudge-modal-title (tr "modals.nudge-title")]
[:button.modal-close-button {:on-click on-close} i/close]]
[:div.nudge-modal-body
[:div.input-wrapper
[:span
[:p.nudge-subtitle (tr "modals.small-nudge")]
[:> numeric-input* {:min 0.01
:value (:small nudge)
:on-change update-small}]]]
[:div.input-wrapper
[:span
[:p.nudge-subtitle (tr "modals.big-nudge")]
[:> numeric-input* {:min 0.01
:value (:big nudge)
:on-change update-big}]]]]]])))
:on-change update-big}]]]]]))

View file

@ -8,34 +8,38 @@
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
}
.modal-container {
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
.modal-content {
@include flexColumn;
gap: $s-24;
@include titleTipography;
margin-bottom: $s-24;
.input-wrapper {
}
.input-wrapper {
@extend .input-with-label;
label {
text-transform: none;
}
}
}
}
}
.modal-msg {

View file

@ -12,10 +12,7 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
[app.main.ui.context :as ctx]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.icons :as i]
[app.main.ui.workspace.comments :refer [comments-sidebar]]
[app.main.ui.workspace.left-header :refer [left-header]]
[app.main.ui.workspace.right-header :refer [right-header]]
@ -26,7 +23,6 @@
[app.main.ui.workspace.sidebar.options :refer [options-toolbox]]
[app.main.ui.workspace.sidebar.shortcuts :refer [shortcuts-container]]
[app.main.ui.workspace.sidebar.sitemap :refer [sitemap]]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
[app.util.object :as obj]
[rumext.v2 :as mf]))
@ -47,7 +43,6 @@
(contains? layout :assets) :assets)
shortcuts? (contains? layout :shortcuts)
show-debug? (contains? layout :debug-panel)
new-css-system (mf/use-ctx ctx/new-css-system)
{on-pointer-down :on-pointer-down on-lost-pointer-capture :on-lost-pointer-capture on-pointer-move :on-pointer-move parent-ref :parent-ref size :size}
(use-resize-hook :left-sidebar 275 275 500 :x false :left)
@ -65,25 +60,17 @@
[:aside {:ref parent-ref
:id "left-sidebar-aside"
:data-size size
:class (stl/css-case new-css-system
:global/settings-bar (not new-css-system)
:global/settings-bar-left (not new-css-system)
:left-settings-bar true
:class (stl/css-case :left-settings-bar true
:global/two-row (<= size 300)
:global/three-row (and (> size 300) (<= size 400))
:global/four-row (> size 400))
:style #js {"--width" (dm/str size "px")}}
(when new-css-system
[:& left-header {:file file :layout layout :project project :page-id page-id}])
[:& left-header {:file file :layout layout :project project :page-id page-id}]
[:div {:on-pointer-down on-pointer-down
:on-lost-pointer-capture on-lost-pointer-capture
:on-pointer-move on-pointer-move
:class (if ^boolean new-css-system
(stl/css :resize-area)
(dom/classnames :resize-area true))}]
[:div {:class (if ^boolean new-css-system
(stl/css :settings-bar-inside)
(dom/classnames :settings-bar-inside true))}
:class (stl/css :resize-area)}]
[:div {:class (stl/css :settings-bar-inside)}
(cond
(true? shortcuts?)
[:& shortcuts-container]
@ -92,7 +79,6 @@
[:& debug-panel]
:else
(if ^boolean new-css-system
[:div {:class (stl/css :tabs-wrapper)}
[:& tab-container
{:on-change-tab on-tab-change
@ -118,38 +104,7 @@
(when-not ^boolean mode-inspect?
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
[:& assets-toolbox]])]]
[:*
[:button.collapse-sidebar
{:on-click handle-collapse
:aria-label (tr "workspace.sidebar.collapse")}
i/arrow-slide]
[:& tabs-container
{:on-change-tab on-tab-change
:selected section
:shortcuts? shortcuts?
:collapsable? true
:handle-collapse handle-collapse}
[:& tabs-element {:id :layers :title (tr "workspace.sidebar.layers")}
[:div {:class :layers-tab
:style #js {"--height" (str size-pages "px")}}
[:& sitemap {:layout layout
:toggle-pages toggle-pages
:show-pages? @show-pages?
:size size-pages}]
(when @show-pages?
[:div.resize-area-horiz
{:on-pointer-down on-pointer-down-pages
:on-lost-pointer-capture on-lost-pointer-capture-pages
:on-pointer-move on-pointer-move-pages}])
[:& layers-toolbox {:size-parent size}]]]
(when-not ^boolean mode-inspect?
[:& tabs-element {:id :assets :title (tr "workspace.toolbar.assets")}
[:& assets-toolbox]])]]))]]))
[:& assets-toolbox]])]])]]))
;; --- Right Sidebar (Component)

View file

@ -64,8 +64,8 @@
(mf/html [:div {:class (stl/css :special-title)}
file-name]))}
(when-not local?
[:span.tool-link.tooltip.tooltip-left {:alt "Open library file"}
[:a {:class (dom/classnames true)
[:span {:title "Open library file"}
[:a {:class (stl/css :file-link)
:href (str "#" url)
:target "_blank"
:on-click dom/stop-propagation}