♻️ 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 (:require
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -27,8 +26,8 @@
hint hint
accept-label accept-label
accept-style] :as props}] 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")) message (or message (tr "ds.alert-title"))
accept-label (or accept-label (tr "ds.alert-ok")) accept-label (or accept-label (tr "ds.alert-ok"))
accept-style (or accept-style :danger) accept-style (or accept-style :danger)
@ -50,54 +49,26 @@
(on-accept props)))] (on-accept props)))]
(->> (events/listen js/document "keydown" on-keydown) (->> (events/listen js/document "keydown" on-keydown)
(partial events/unlistenByKey)))) (partial events/unlistenByKey))))
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)} title]
[:h2 {:class (stl/css :modal-title)} title] [:button {:class (stl/css :modal-close-btn)
[:button {:class (stl/css :modal-close-btn) :on-click accept-fn} i/close-refactor]]
:on-click accept-fn} i/close-refactor]]
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
(when (and (string? message) (not= message "")) (when (and (string? message) (not= message ""))
[:h3 {:class (stl/css :modal-msg)} message]) [:h3 {:class (stl/css :modal-msg)} message])
(when (and (string? scd-message) (not= scd-message "")) (when (and (string? scd-message) (not= scd-message ""))
[:h3 {:class (stl/css :modal-scd-msg)} scd-message]) [:h3 {:class (stl/css :modal-scd-msg)} scd-message])
(when (string? hint) (when (string? hint)
[:p {:class (stl/css :modal-hint)} hint])] [:p {:class (stl/css :modal-hint)} hint])]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)} [:div {:class (stl/css :action-buttons)}
[:input {:class (stl/css-case :accept-btn true [:input {:class (stl/css-case :accept-btn true
:danger (= accept-style :danger) :danger (= accept-style :danger)
:primary (= accept-style :primary)) :primary (= accept-style :primary))
:type "button" :type "button"
:value accept-label :value accept-label
:on-click accept-fn}]]]]] :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}]]]]])))

View file

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

View file

@ -12,7 +12,6 @@
[app.main.ui.auth.recovery :refer [recovery-page]] [app.main.ui.auth.recovery :refer [recovery-page]]
[app.main.ui.auth.recovery-request :refer [recovery-request-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.auth.register :refer [register-page register-success-page register-validate-page]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -20,102 +19,57 @@
(mf/defc terms-login (mf/defc terms-login
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
show-all? (and cf/terms-of-service-uri cf/privacy-policy-uri)
show-terms? (some? cf/terms-of-service-uri) show-terms? (some? cf/terms-of-service-uri)
show-privacy? (some? cf/privacy-policy-uri)] show-privacy? (some? cf/privacy-policy-uri)]
(if new-css-system (when show-all?
(when show-all? [:div {:class (stl/css :terms-login)}
[:div {:class (stl/css :terms-login)} (when show-terms?
(when show-terms? [:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
[:a {:href cf/terms-of-service-uri :target "_blank"} (tr "auth.terms-of-service")])
(when show-all? (when show-all?
[:span (tr "labels.and")]) [:span (tr "labels.and")])
(when show-privacy? (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")])])))
(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")])]))))
(mf/defc auth (mf/defc auth
[{:keys [route] :as props}] [{:keys [route] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [section (get-in route [:data :name])
section (get-in route [:data :name])
params (:query-params route) params (:query-params route)
show-illustration? (contains? cf/flags :login-illustration)] show-illustration? (contains? cf/flags :login-illustration)]
(mf/use-effect (mf/use-effect
#(dom/set-html-title (tr "title.default"))) #(dom/set-html-title (tr "title.default")))
(if new-css-system [:main {:class (stl/css-case :auth-section true
[:main {:class (stl/css-case :auth-section true :no-illustration (not show-illustration?))}
:no-illustration (not show-illustration?))} (when show-illustration?
(when show-illustration? [:div {:class (stl/css :login-illustration)}
[:div {:class (stl/css :login-illustration)} i/login-illustration])
i/login-illustration])
[:section {:class (stl/css :auth-content)} [: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 (case section
:auth-register :auth-register
[:& register-page {:params params}] [:& register-page {:params params}]
:auth-register-validate :auth-register-validate
[:& register-validate-page {:params params}] [:& register-validate-page {:params params}]
:auth-register-success :auth-register-success
[:& register-success-page {:params params}] [:& register-success-page {:params params}]
:auth-login :auth-login
[:& login-page {:params params}] [:& login-page {:params params}]
:auth-recovery-request :auth-recovery-request
[:& recovery-request-page] [:& recovery-request-page]
:auth-recovery :auth-recovery
[:& recovery-page {:params params}])] [:& recovery-page {:params params}])]
(when (contains? #{:auth-login :auth-register} section) (when (contains? #{:auth-login :auth-register} section)
[:& terms-login])]] [:& 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 {}]]])))

View file

@ -18,7 +18,6 @@
[app.main.ui.components.button-link :as bl] [app.main.ui.components.button-link :as bl]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk] [app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.messages :as msgs] [app.main.ui.messages :as msgs]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -94,8 +93,7 @@
(mf/defc login-form (mf/defc login-form
[{:keys [params on-success-callback origin] :as props}] [{:keys [params on-success-callback origin] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [initial (mf/use-memo (mf/deps params) (constantly params))
initial (mf/use-memo (mf/deps params) (constantly params))
error (mf/use-state false) error (mf/use-state false)
form (fm/use-form :spec ::login-form form (fm/use-form :spec ::login-form
:validators [handle-error-messages] :validators [handle-error-messages]
@ -157,156 +155,86 @@
(mf/use-fn (mf/use-fn
#(st/emit! (rt/nav :auth-recovery-request)))] #(st/emit! (rt/nav :auth-recovery-request)))]
(if new-css-system [:*
[:* (when-let [message @error]
(when-let [message @error] [:& msgs/inline-banner
[:& msgs/inline-banner {:type :warning
{:type :warning :content message
:content message :on-close #(reset! error nil)
:on-close #(reset! error nil) :data-test "login-banner"
:data-test "login-banner" :role "alert"}])
:role "alert"}])
[:& fm/form {:on-submit on-submit :form form} [:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)} [:div {:class (stl/css :fields-row)}
[:& fm/input [:& fm/input
{:name :email {:name :email
:type "email" :type "email"
:label (tr "auth.email") :label (tr "auth.email")
:class (stl/css :form-field)}]] :class (stl/css :form-field)}]]
[:div {:class (stl/css :fields-row)} [:div {:class (stl/css :fields-row)}
[:& fm/input [:& fm/input
{:type "password" {:type "password"
:name :password :name :password
:label (tr "auth.password") :label (tr "auth.password")
:class (stl/css :form-field)}]] :class (stl/css :form-field)}]]
(when (and (not= origin :viewer) (when (and (not= origin :viewer)
(or (contains? cf/flags :login) (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))) (contains? cf/flags :login-with-password)))
[:div {:class (stl/css :fields-row :forgot-password)} [:div {:class (stl/css :fields-row :forgot-password)}
[:& lk/link {:action on-recovery-request [:& lk/link {:action on-recovery-request
:data-test "forgot-password"} :data-test "forgot-password"}
(tr "auth.forgot-password")]]) (tr "auth.forgot-password")]])
[:div {:class (stl/css :buttons-stack)} [:div {:class (stl/css :buttons-stack)}
(when (or (contains? cf/flags :login) (when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)) (contains? cf/flags :login-with-password))
[:> fm/submit-button* [:> fm/submit-button*
{:label (tr "auth.login-submit") {:label (tr "auth.login-submit")
:data-test "login-submit" :data-test "login-submit"
:class (stl/css :login-button)}]) :class (stl/css :login-button)}])
(when (contains? cf/flags :login-with-ldap) (when (contains? cf/flags :login-with-ldap)
[:> fm/submit-button* [:> fm/submit-button*
{:label (tr "auth.login-with-ldap-submit") {:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]] :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}])]]])))
(mf/defc login-buttons (mf/defc login-buttons
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [login-with-google (mf/use-fn (mf/deps params) #(login-with-oidc % :google params))
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-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-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))] login-with-oidc (mf/use-fn (mf/deps params) #(login-with-oidc % :oidc params))]
(if new-css-system [:div {:class (stl/css :auth-buttons)}
[:div {:class (stl/css :auth-buttons)} (when (contains? cf/flags :login-with-google)
(when (contains? cf/flags :login-with-google) [:& bl/button-link {:on-click login-with-google
[:& bl/button-link {:on-click login-with-google :icon i/brand-google
:icon i/brand-google :label (tr "auth.login-with-google-submit")
:label (tr "auth.login-with-google-submit") :class (stl/css :login-btn :btn-google-auth)}])
:class (stl/css :login-btn :btn-google-auth)}])
(when (contains? cf/flags :login-with-github) (when (contains? cf/flags :login-with-github)
[:& bl/button-link {:on-click login-with-github [:& bl/button-link {:on-click login-with-github
:icon i/brand-github :icon i/brand-github
:label (tr "auth.login-with-github-submit") :label (tr "auth.login-with-github-submit")
:class (stl/css :login-btn :btn-github-auth)}]) :class (stl/css :login-btn :btn-github-auth)}])
(when (contains? cf/flags :login-with-gitlab) (when (contains? cf/flags :login-with-gitlab)
[:& bl/button-link {:on-click login-with-gitlab [:& bl/button-link {:on-click login-with-gitlab
:icon i/brand-gitlab :icon i/brand-gitlab
:label (tr "auth.login-with-gitlab-submit") :label (tr "auth.login-with-gitlab-submit")
:class (stl/css :login-btn :btn-gitlab-auth)}]) :class (stl/css :login-btn :btn-gitlab-auth)}])
(when (contains? cf/flags :login-with-oidc) (when (contains? cf/flags :login-with-oidc)
[:& bl/button-link {:on-click login-with-oidc [:& bl/button-link {:on-click login-with-oidc
:icon i/brand-openid :icon i/brand-openid
:label (tr "auth.login-with-oidc-submit") :label (tr "auth.login-with-oidc-submit")
:class (stl/css :login-btn :btn-oidc-auth)}])] :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"}])])))
(mf/defc login-button-oidc (mf/defc login-button-oidc
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [login-oidc
login-oidc
(mf/use-fn (mf/use-fn
(mf/deps params) (mf/deps params)
(fn [event] (fn [event]
@ -317,69 +245,33 @@
(fn [event] (fn [event]
(when (k/enter? event) (when (k/enter? event)
(login-oidc event))))] (login-oidc event))))]
(if new-css-system (when (contains? cf/flags :login-with-oidc)
(when (contains? cf/flags :login-with-oidc) [:div {:class (stl/css :link-entry :link-oidc)}
[:div {:class (stl/css :link-entry :link-oidc)} [:a {:tab-index "0"
[:a {:tab-index "0" :on-key-down handle-key-down
:on-key-down handle-key-down :on-click login-oidc}
:on-click login-oidc} (tr "auth.login-with-oidc-submit")]])))
(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")]]))))
(mf/defc login-methods (mf/defc login-methods
[{:keys [params on-success-callback origin] :as props}] [{: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?
[:* [:*
(when show-alt-login-buttons? [:& login-buttons {:params params}]
[:*
[:& login-buttons {:params params}]
(when (or (contains? cf/flags :login) (when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password) (contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap)) (contains? cf/flags :login-with-ldap))
[:hr {:class (stl/css :separator)}])]) [:hr {:class (stl/css :separator)}])])
(when (or (contains? cf/flags :login) (when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password) (contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap)) (contains? cf/flags :login-with-ldap))
[:& login-form {:params params :on-success-callback on-success-callback :origin origin}])] [:& 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}])])))
(mf/defc login-page (mf/defc login-page
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [go-register
go-register
(mf/use-fn (mf/use-fn
#(st/emit! (rt/nav :auth-register {} params))) #(st/emit! (rt/nav :auth-register {} params)))
@ -391,64 +283,33 @@
(mf/use-fn (mf/use-fn
#(st/emit! (du/create-demo-profile)))] #(st/emit! (du/create-demo-profile)))]
(if new-css-system [:div {:class (stl/css :auth-form)}
[:div {:class (stl/css :auth-form)} [:h1 {:class (stl/css :auth-title)
[:h1 {:class (stl/css :auth-title) :data-test "login-title"} (tr "auth.login-title")]
:data-test "login-title"} (tr "auth.login-title")]
[:hr {:class (stl/css :separator)}] [:hr {:class (stl/css :separator)}]
[:& login-methods {:params params}] [:& login-methods {:params params}]
[:div {:class (stl/css :links)} [:div {:class (stl/css :links)}
(when (or (contains? cf/flags :login) (when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)) (contains? cf/flags :login-with-password))
[:div {:class (stl/css :link-entry :register)} [:div {:class (stl/css :link-entry :register)}
[:& lk/link {:action on-pass-recovery [:& lk/link {:action on-pass-recovery
:data-test "forgot-password"} :data-test "forgot-password"}
(tr "auth.forgot-password")]]) (tr "auth.forgot-password")]])
(when (contains? cf/flags :registration) (when (contains? cf/flags :registration)
[:div {:class (stl/css :link-entry :register)} [:div {:class (stl/css :link-entry :register)}
[:span (tr "auth.register") " "] [:span (tr "auth.register") " "]
[:& lk/link {:action go-register [:& lk/link {:action go-register
:data-test "register-submit"} :data-test "register-submit"}
(tr "auth.register-submit")]])] (tr "auth.register-submit")]])]
(when (contains? cf/flags :demo-users) (when (contains? cf/flags :demo-users)
[:div {:class (stl/css :link-entry :demo-account)} [:div {:class (stl/css :link-entry :demo-account)}
[:span (tr "auth.create-demo-profile") " "] [:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action on-create-demo-profile [:& lk/link {:action on-create-demo-profile
:data-test "demo-account-link"} :data-test "demo-account-link"}
(tr "auth.create-demo-account")]])] (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")]]])]])))

View file

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

View file

@ -17,7 +17,6 @@
[app.main.ui.auth.login :as login] [app.main.ui.auth.login :as login]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.main.ui.components.link :as lk] [app.main.ui.components.link :as lk]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.messages :as msgs] [app.main.ui.messages :as msgs]
[app.util.i18n :refer [tr tr-html]] [app.util.i18n :refer [tr tr-html]]
@ -88,8 +87,7 @@
(mf/defc register-form (mf/defc register-form
[{:keys [params on-success-callback] :as props}] [{:keys [params on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [initial (mf/use-memo (mf/deps params) (constantly params))
initial (mf/use-memo (mf/deps params) (constantly params))
form (fm/use-form :spec ::register-form form (fm/use-form :spec ::register-form
:validators [validate :validators [validate
(fm/validate-not-empty :password (tr "auth.password-not-empty"))] (fm/validate-not-empty :password (tr "auth.password-not-empty"))]
@ -114,133 +112,64 @@
(partial handle-prepare-register-error form))))))] (partial handle-prepare-register-error form))))))]
(if new-css-system [:& fm/form {:on-submit on-submit :form form}
[:& fm/form {:on-submit on-submit :form form} [:div {:class (stl/css :fields-row)}
[:div {:class (stl/css :fields-row)} [:& fm/input {:type "email"
[:& fm/input {:type "email" :name :email
:name :email :label (tr "auth.email")
:label (tr "auth.email") :data-test "email-input"
:data-test "email-input" :show-success? true
:show-success? true :class (stl/css :form-field)}]]
:class (stl/css :form-field)}]] [:div {:class (stl/css :fields-row)}
[:div {:class (stl/css :fields-row)} [:& fm/input {:name :password
[:& fm/input {:name :password :hint (tr "auth.password-length-hint")
:hint (tr "auth.password-length-hint") :label (tr "auth.password")
:label (tr "auth.password") :show-success? true
:show-success? true :type "password"
:type "password" :class (stl/css :form-field)}]]
:class (stl/css :form-field)}]]
[:> fm/submit-button* [:> fm/submit-button*
{:label (tr "auth.register-submit") {:label (tr "auth.register-submit")
:disabled @submitted? :disabled @submitted?
:data-test "register-form-submit" :data-test "register-form-submit"
:class (stl/css :register-btn)}]] :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"}]])))
(mf/defc register-methods (mf/defc register-methods
[{:keys [params on-success-callback] :as props}] [{: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?
[:* [:*
(when login/show-alt-login-buttons? [:hr {:class (stl/css :separator)}]
[:* [:& login/login-buttons {:params params}]])
[:hr {:class (stl/css :separator)}] [:hr {:class (stl/css :separator)}]
[:& login/login-buttons {:params params}]]) [:& register-form {:params params :on-success-callback on-success-callback}]])
[: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}]])))
(mf/defc register-page (mf/defc register-page
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)] [:div {:class (stl/css :auth-form)}
(if new-css-system [:h1 {:class (stl/css :auth-title)
[:div {:class (stl/css :auth-form)} :data-test "registration-title"} (tr "auth.register-title")]
[:h1 {:class (stl/css :auth-title) [:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
:data-test "registration-title"} (tr "auth.register-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
(when (contains? cf/flags :demo-warning) (when (contains? cf/flags :demo-warning)
[:& demo-warning]) [:& demo-warning])
[:& register-methods {:params params}] [:& register-methods {:params params}]
[:div {:class (stl/css :links)} [:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry :account)} [:div {:class (stl/css :link-entry :account)}
[:span (tr "auth.already-have-account") " "] [:span (tr "auth.already-have-account") " "]
[:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params)) [:& lk/link {:action #(st/emit! (rt/nav :auth-login {} params))
:data-test "login-here-link"} :data-test "login-here-link"}
(tr "auth.login-here")]] (tr "auth.login-here")]]
(when (contains? cf/flags :demo-users) (when (contains? cf/flags :demo-users)
[:div {:class (stl/css :link-entry :demo-users)} [:div {:class (stl/css :link-entry :demo-users)}
[:span (tr "auth.create-demo-profile") " "] [:span (tr "auth.create-demo-profile") " "]
[:& lk/link {:action #(st/emit! (du/create-demo-profile))} [:& lk/link {:action #(st/emit! (du/create-demo-profile))}
(tr "auth.create-demo-account")]])]] (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")]])]])))
;; --- PAGE: register validation ;; --- PAGE: register validation
@ -284,8 +213,7 @@
(mf/defc register-validate-form (mf/defc register-validate-form
[{:keys [params on-success-callback] :as props}] [{:keys [params on-success-callback] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [form (fm/use-form :spec ::register-validate-form
form (fm/use-form :spec ::register-validate-form
:validators [(fm/validate-not-empty :fullname (tr "auth.name.not-all-space")) :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"))] (fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))]
:initial params) :initial params)
@ -306,103 +234,55 @@
(rx/subs! on-success (rx/subs! on-success
(partial handle-register-error form))))))] (partial handle-register-error form))))))]
(if new-css-system [:& fm/form {:on-submit on-submit :form form}
[:& fm/form {:on-submit on-submit :form form} [:div {:class (stl/css :fields-row)}
[:div {:class (stl/css :fields-row)} [:& fm/input {:name :fullname
[:& fm/input {:name :fullname :label (tr "auth.fullname")
:label (tr "auth.fullname") :type "text"
:type "text" :show-success? true
:show-success? true :class (stl/css :form-field)}]]
:class (stl/css :form-field)}]]
(when (contains? cf/flags :terms-and-privacy-checkbox) (when (contains? cf/flags :terms-and-privacy-checkbox)
(let [terms-label (let [terms-label
(mf/html (mf/html
[:& tr-html [:& tr-html
{:tag-name "div" {:tag-name "div"
:label "auth.terms-privacy-agreement-md" :label "auth.terms-privacy-agreement-md"
:params [cf/terms-of-service-uri cf/privacy-policy-uri]}])] :params [cf/terms-of-service-uri cf/privacy-policy-uri]}])]
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)} [:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
[:& fm/input {:name :accept-terms-and-privacy
:class "check-primary"
:type "checkbox"
:label terms-label}]]))
[:> 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 [:& fm/input {:name :accept-terms-and-privacy
:class "check-primary" :class "check-primary"
:type "checkbox"} :type "checkbox"
[:span :label terms-label}]]))
(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* [:> fm/submit-button*
{:label (tr "auth.register-submit") {:label (tr "auth.register-submit")
:disabled @submitted?}]]))) :disabled @submitted?
:class (stl/css :register-btn)}]]))
(mf/defc register-validate-page (mf/defc register-validate-page
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)] [:div {:class (stl/css :auth-form)}
(if new-css-system [:h1 {:class (stl/css :auth-title)
[:div {:class (stl/css :auth-form)} :data-test "register-title"} (tr "auth.register-title")]
[:h1 {:class (stl/css :auth-title) [:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
:data-test "register-title"} (tr "auth.register-title")]
[:div {:class (stl/css :auth-subtitle)} (tr "auth.register-subtitle")]
[:hr {:class (stl/css :separator)}] [:hr {:class (stl/css :separator)}]
[:& register-validate-form {:params params}] [:& register-validate-form {:params params}]
[:div {:class (stl/css :links)} [:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry :go-back)} [:div {:class (stl/css :link-entry :go-back)}
[:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))} [:& lk/link {:action #(st/emit! (rt/nav :auth-register {} {}))}
(tr "labels.go-back")]]]] (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")]]]])))
(mf/defc register-success-page (mf/defc register-success-page
[{:keys [params] :as props}] [{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)] [:div {:class (stl/css :auth-form :register-success)}
(if new-css-system [:div {:class (stl/css :notification-icon)} i/icon-verify]
[:div {:class (stl/css :auth-form :register-success)} [:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")]
[:div {:class (stl/css :notification-icon)} i/icon-verify] [:div {:class (stl/css :notification-text-email)} (:email params "")]
[:div {:class (stl/css :notification-text)} (tr "auth.verification-email-sent")] [:div {:class (stl/css :notification-text)} (tr "auth.check-your-email")]])
[: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")]])))

View file

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

View file

@ -13,96 +13,106 @@
border-radius: $br-8; border-radius: $br-8;
padding: $s-8 $s-16; padding: $s-8 $s-16;
.section-title {
@include titleTipography;
height: $s-32;
display: flex;
align-items: center;
margin-bottom: $s-8;
.file-name {
color: var(--comment-subtitle-color);
}
.page-name {
color: var(--comment-subtitle-color);
}
.icon {
display: flex;
align-items: center;
padding: 0 $s-6 0 $s-4;
width: $s-24;
height: $s-32;
margin-left: $s-6;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
}
.threads {
display: flex;
flex-direction: column;
gap: $s-24;
}
&:hover { &:hover {
background: $db-primary; background: $db-primary;
} }
} }
.section-title {
@include titleTipography;
height: $s-32;
display: flex;
align-items: center;
margin-bottom: $s-8;
}
.file-name {
color: var(--comment-subtitle-color);
}
.page-name {
color: var(--comment-subtitle-color);
}
.icon {
display: flex;
align-items: center;
padding: 0 $s-6 0 $s-4;
width: $s-24;
height: $s-32;
margin-left: $s-6;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
}
.threads {
display: flex;
flex-direction: column;
gap: $s-24;
}
// Comment-thread // Comment-thread
.comment { .comment {
@include titleTipography; @include titleTipography;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: $s-12; gap: $s-12;
.author { }
display: flex;
gap: $s-8; .author {
.thread-bubble { display: flex;
@extend .comment-bubbles; gap: $s-8;
&.resolved { }
@extend .resolved-comment-bubble;
} .thread-bubble {
&.unread { @extend .comment-bubbles;
@extend .unread-comment-bubble; &.resolved {
} @extend .resolved-comment-bubble;
}
.avatar {
height: $s-32;
width: $s-32;
border-radius: $br-circle;
img {
border-radius: $br-circle;
}
}
.name {
flex-grow: 1;
.fullname {
@include textEllipsis;
color: var(--comment-title-color);
}
.timeago {
@include textEllipsis;
color: var(--comment-subtitle-color);
}
}
} }
.content { &.unread {
@include titleTipography; @extend .unread-comment-bubble;
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);
}
} }
} }
.avatar {
height: $s-32;
width: $s-32;
border-radius: $br-circle;
img {
border-radius: $br-circle;
}
}
.name {
flex-grow: 1;
.fullname {
@include textEllipsis;
color: var(--comment-title-color);
}
.timeago {
@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);
}
// Thread-bubble // Thread-bubble
.floating-thread-bubble { .floating-thread-bubble {

View file

@ -30,15 +30,14 @@
(when label-text (when label-text
[:label {:for input-id :class-name label-class} label-text]) [:label {:for input-id :class-name label-class} label-text])
[:input [:input {:style {:display "none"
{:style {:display "none" :width 0}
:width 0} :id input-id
:id input-id :multiple multi
:multiple multi :accept accept
:accept accept :type "file"
:type "file" :ref input-ref
:ref input-ref :on-change on-files-selected
:on-change on-files-selected :data-test data-test
:data-test data-test :aria-label "uploader"}]]))
:aria-label "uploader"}]]))

View file

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

View file

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

View file

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

View file

@ -8,39 +8,46 @@
.modal-overlay { .modal-overlay {
@extend .modal-overlay-base; @extend .modal-overlay-base;
.modal-container { }
@extend .modal-container-base;
border: $s-1 solid var(--modal-border-color); .modal-container {
.modal-header { @extend .modal-container-base;
margin-bottom: $s-24; border: $s-1 solid var(--modal-border-color);
.modal-title { }
@include tabTitleTipography;
color: var(--modal-title-foreground-color); .modal-header {
} margin-bottom: $s-24;
.modal-close-btn { }
@extend .modal-close-btn-base;
} .modal-title {
} @include tabTitleTipography;
.modal-content { color: var(--modal-title-foreground-color);
@include titleTipography; }
margin-bottom: $s-24;
.input-wrapper { .modal-close-btn {
@extend .input-with-label; @extend .modal-close-btn-base;
} }
}
.modal-footer { .modal-content {
.action-buttons { @include titleTipography;
@extend .modal-action-btns; margin-bottom: $s-24;
.cancel-button { }
@extend .modal-cancel-btn;
} .input-wrapper {
.accept-btn { @extend .input-with-label;
@extend .modal-accept-btn; }
&.danger {
@extend .modal-danger-btn; .action-buttons {
} @extend .modal-action-btns;
} }
}
} .cancel-button {
@extend .modal-cancel-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.common.data.macros :as dm]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.worker :as uw] [app.main.worker :as uw]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -24,36 +23,19 @@
(mf/defc export-entry (mf/defc export-entry
{::mf/wrap-props false} {::mf/wrap-props false}
[{:keys [file]}] [{:keys [file]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)] [:div {:class (stl/css-case :file-entry true
:loading (:loading? file)
:success (:export-success? file)
:error (:export-error? file))}
(if new-css-system [:div {:class (stl/css :file-name)}
[:div {:class (stl/css-case :file-entry true [:span {:class (stl/css :file-icon)}
:loading (:loading? file) (cond (:export-success? file) i/tick-refactor
:success (:export-success? file) (:export-error? file) i/close-refactor
:error (:export-error? file))} (:loading? file) i/loader-pencil)]
[:div {:class (stl/css :file-name)} [:div {:class (stl/css :file-name-label)}
[:span {:class (stl/css :file-icon)} (:name file)]]])
(cond (:export-success? file) i/tick-refactor
(:export-error? file) i/close-refactor
(: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)]]])))
(defn- mark-file-error (defn- mark-file-error
[files file-id] [files file-id]
@ -79,8 +61,7 @@
::mf/register-as :export ::mf/register-as :export
::mf/wrap-props false} ::mf/wrap-props false}
[{:keys [team-id files has-libraries? binary? features]}] [{:keys [team-id files has-libraries? binary? features]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [state* (mf/use-state
state* (mf/use-state
#(let [files (mapv (fn [file] (assoc file :loading? true)) files)] #(let [files (mapv (fn [file] (assoc file :loading? true)) files)]
{:status :prepare {:status :prepare
:selected :all :selected :all
@ -140,136 +121,70 @@
(when-not has-libraries? (when-not has-libraries?
(start-export))) (start-export)))
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)}
[:h2 {:class (stl/css :modal-title)} (tr "dashboard.export.title")]
(tr "dashboard.export.title")] [:button {:class (stl/css :modal-close-btn)
[:button {:class (stl/css :modal-close-btn) :on-click on-cancel} i/close-refactor]]
:on-click on-cancel} i/close-refactor]]
(cond (cond
(= status :prepare) (= status :prepare)
[:* [:*
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
[:p {:class (stl/css :modal-msg)} (tr "dashboard.export.explain")] [:p {:class (stl/css :modal-msg)} (tr "dashboard.export.explain")]
[:p {:class (stl/css :modal-scd-msg)} (tr "dashboard.export.detail")] [:p {:class (stl/css :modal-scd-msg)} (tr "dashboard.export.detail")]
(for [type export-types] (for [type export-types]
[:div {:class (stl/css :export-option true) [:div {:class (stl/css :export-option true)
:key (name type)} :key (name type)}
[:label {:for (str "export-" type) [:label {:for (str "export-" type)
:class (stl/css-case :global/checked (= selected type))} :class (stl/css-case :global/checked (= selected type))}
;; Execution time translation strings: ;; Execution time translation strings:
;; dashboard.export.options.all.message ;; dashboard.export.options.all.message
;; dashboard.export.options.all.title ;; dashboard.export.options.all.title
;; dashboard.export.options.detach.message ;; dashboard.export.options.detach.message
;; dashboard.export.options.detach.title ;; dashboard.export.options.detach.title
;; dashboard.export.options.merge.message ;; dashboard.export.options.merge.message
;; dashboard.export.options.merge.title ;; dashboard.export.options.merge.title
[:span {:class (stl/css-case :global/checked (= selected type))} [:span {:class (stl/css-case :global/checked (= selected type))}
(when (= selected type) (when (= selected type)
i/status-tick-refactor)] i/status-tick-refactor)]
[:div {:class (stl/css :option-content)} [:div {:class (stl/css :option-content)}
[:h3 {:class (stl/css :modal-subtitle)} (tr (dm/str "dashboard.export.options." (d/name type) ".title"))] [:h3 {:class (stl/css :modal-subtitle)} (tr (dm/str "dashboard.export.options." (d/name type) ".title"))]
[:p {:class (stl/css :modal-msg)} (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]] [:p {:class (stl/css :modal-msg)} (tr (dm/str "dashboard.export.options." (d/name type) ".message"))]]
[:input {:type "radio" [:input {:type "radio"
:class (stl/css :option-input) :class (stl/css :option-input)
:id (str "export-" type) :id (str "export-" type)
:checked (= selected type) :checked (= selected type)
:name "export-option" :name "export-option"
:data-type (name type) :data-type (name type)
:on-change on-change}]]])] :on-change on-change}]]])]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)} [:div {:class (stl/css :action-buttons)}
[:input {:class (stl/css :cancel-button) [:input {:class (stl/css :cancel-button)
:type "button" :type "button"
:value (tr "labels.cancel") :value (tr "labels.cancel")
:on-click on-cancel}] :on-click on-cancel}]
[:input {:class (stl/css :accept-btn) [:input {:class (stl/css :accept-btn)
:type "button" :type "button"
:value (tr "labels.continue") :value (tr "labels.continue")
:on-click on-accept}]]]] :on-click on-accept}]]]]
(= status :exporting) (= status :exporting)
[:* [:*
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
(for [file (:files state)] (for [file (:files state)]
[:& export-entry {:file file :key (dm/str (:id file))}])] [:& export-entry {:file file :key (dm/str (:id file))}])]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)} [:div {:class (stl/css :action-buttons)}
[:input {:class (stl/css :accept-btn) [:input {:class (stl/css :accept-btn)
:type "button" :type "button"
:value (tr "labels.close") :value (tr "labels.close")
:disabled (->> state :files (some :loading?)) :disabled (->> state :files (some :loading?))
:on-click on-cancel}]]]])]] :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}]]]])]])))

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,7 +13,6 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.users :as du] [app.main.data.users :as du]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.onboarding.newsletter] [app.main.ui.onboarding.newsletter]
[app.main.ui.onboarding.questions] [app.main.ui.onboarding.questions]
[app.main.ui.onboarding.team-choice] [app.main.ui.onboarding.team-choice]
@ -33,178 +32,113 @@
(mf/defc onboarding-welcome (mf/defc onboarding-welcome
[{:keys [next] :as props}] [{:keys [next] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [go-next
go-next
(fn [] (fn []
(send-event "onboarding-step1-continue") (send-event "onboarding-step1-continue")
(next))] (next))]
(if new-css-system [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-left)}
[:div {:class (stl/css :modal-left)} [:img {:src "images/onboarding-welcome.png"
[:img {:src "images/onboarding-welcome.png" :border "0"
:border "0" :alt (tr "onboarding.welcome.alt")}]]
:alt (tr "onboarding.welcome.alt")}]] [:div {:class (stl/css :modal-right)}
[:div {:class (stl/css :modal-right)} [:div {:class (stl/css :release)}
[:div {:class (stl/css :release)} "Version " (:main cf/version)]
"Version " (:main cf/version)] [:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)
[:h2 {:class (stl/css :modal-title) :data-test "onboarding-welcome"}
:data-test "onboarding-welcome"} (tr "onboarding-v2.welcome.title")]]
(tr "onboarding-v2.welcome.title")]]
[:div {:class (stl/css :modal-info)} [:div {:class (stl/css :modal-info)}
[:p {:class (stl/css :modal-text)} [:p {:class (stl/css :modal-text)}
(tr "onboarding-v2.welcome.desc1")] (tr "onboarding-v2.welcome.desc1")]
[:div {:class (stl/css :property-block)} [:div {:class (stl/css :property-block)}
[:img {:src "images/community.svg" [:img {:src "images/community.svg"
:border "0"}] :border "0"}]
[:div {:class (stl/css :text-wrapper)} [:div {:class (stl/css :text-wrapper)}
[:div {:class (stl/css :property-title)} [:div {:class (stl/css :property-title)}
[:a {:href "https://community.penpot.app/" [:a {:href "https://community.penpot.app/"
:target "_blank" :target "_blank"
:on-click #(send-event "onboarding-community-link")} :on-click #(send-event "onboarding-community-link")}
(tr "onboarding-v2.welcome.desc2.title")]] (tr "onboarding-v2.welcome.desc2.title")]]
[:div {:class (stl/css :property-description)} [:div {:class (stl/css :property-description)}
(tr "onboarding-v2.welcome.desc2")]]] (tr "onboarding-v2.welcome.desc2")]]]
[:div {:class (stl/css :property-block)} [:div {:class (stl/css :property-block)}
[:img {:src "images/contributing.svg" [:img {:src "images/contributing.svg"
:border "0"}] :border "0"}]
[:div {:class (stl/css :text-wrapper)} [:div {:class (stl/css :text-wrapper)}
[:div {:class (stl/css :property-title)} [:div {:class (stl/css :property-title)}
[:a {:href "https://help.penpot.app/contributing-guide/" [:a {:href "https://help.penpot.app/contributing-guide/"
:target "_blank" :on-click #(send-event "onboarding-contributing-link")} :target "_blank" :on-click #(send-event "onboarding-contributing-link")}
(tr "onboarding-v2.welcome.desc3.title")]] (tr "onboarding-v2.welcome.desc3.title")]]
[:div {:class (stl/css :property-description)} [:div {:class (stl/css :property-description)}
(tr "onboarding-v2.welcome.desc3")]]]]] (tr "onboarding-v2.welcome.desc3")]]]]]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:button {:on-click go-next [:button {:on-click go-next
:data-test "onboarding-next-btn"} :data-test "onboarding-next-btn"}
(tr "labels.continue")]]]] (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"}]]])))
(mf/defc onboarding-before-start (mf/defc onboarding-before-start
[{:keys [next] :as props}] [{:keys [next] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [go-next
go-next
(fn [] (fn []
(send-event "onboarding-step2-continue") (send-event "onboarding-step2-continue")
(next))] (next))]
(if new-css-system [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-left)}
[:div {:class (stl/css :modal-left)} [:img {:src "images/onboarding-people.png"
[:img {:src "images/onboarding-people.png" :border "0"
:border "0" :alt (tr "onboarding.welcome.alt")}]]
:alt (tr "onboarding.welcome.alt")}]] [:div {:class (stl/css :modal-right)}
[:div {:class (stl/css :modal-right)} [:div {:class (stl/css :release)}
[:div {:class (stl/css :release)} "Version " (:main cf/version)]
"Version " (:main cf/version)] [:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)
[:h2 {:class (stl/css :modal-title) :data-test "onboarding-welcome"}
:data-test "onboarding-welcome"} (tr "onboarding-v2.before-start.title")]]
(tr "onboarding-v2.before-start.title")]]
[:div {:class (stl/css :modal-info)} [:div {:class (stl/css :modal-info)}
[:p {:class (stl/css :modal-text)} [:p {:class (stl/css :modal-text)}
(tr "onboarding-v2.before-start.desc1")] (tr "onboarding-v2.before-start.desc1")]
[:div {:class (stl/css :property-block)} [:div {:class (stl/css :property-block)}
[:img {:src "images/user-guide.svg" :border "0"}] [:img {:src "images/user-guide.svg" :border "0"}]
[:div {:class (stl/css :text-wrapper)} [:div {:class (stl/css :text-wrapper)}
[:div {:class (stl/css :property-title)} [:div {:class (stl/css :property-title)}
[:a {:class (stl/css :modal-link) [:a {:class (stl/css :modal-link)
:href "https://help.penpot.app/user-guide/" :href "https://help.penpot.app/user-guide/"
:target "_blank" :target "_blank"
:on-click #(send-event "onboarding-user-guide-link")} :on-click #(send-event "onboarding-user-guide-link")}
(tr "onboarding-v2.before-start.desc2.title")]] (tr "onboarding-v2.before-start.desc2.title")]]
[:div {:class (stl/css :property-description)} [:div {:class (stl/css :property-description)}
(tr "onboarding-v2.before-start.desc2")]]] (tr "onboarding-v2.before-start.desc2")]]]
[:div {:class (stl/css :property-block)} [:div {:class (stl/css :property-block)}
[:img {:src "images/video-tutorials.svg" :border "0"}] [:img {:src "images/video-tutorials.svg" :border "0"}]
[:div {:class (stl/css :text-wrapper)} [:div {:class (stl/css :text-wrapper)}
[:div {:class (stl/css :property-title)} [:div {:class (stl/css :property-title)}
[:a {:class (stl/css :modal-link) [:a {:class (stl/css :modal-link)
:href "https://www.youtube.com/c/Penpot" :href "https://www.youtube.com/c/Penpot"
:target "_blank" :target "_blank"
:on-click #(send-event "onboarding-video-tutorials-link")} :on-click #(send-event "onboarding-video-tutorials-link")}
(tr "onboarding-v2.before-start.desc3.title")]] (tr "onboarding-v2.before-start.desc3.title")]]
[:div {:class (stl/css :property-description)} [:div {:class (stl/css :property-description)}
(tr "onboarding-v2.before-start.desc3")]]]]] (tr "onboarding-v2.before-start.desc3")]]]]]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:button {:on-click go-next [:button {:on-click go-next
:data-test "onboarding-next-btn"} :data-test "onboarding-next-btn"}
(tr "labels.continue")]]]] (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"}]]])))
(mf/defc onboarding-modal (mf/defc onboarding-modal
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :onboarding} ::mf/register-as :onboarding}
[_] [_]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [slide (mf/use-state :start)
slide (mf/use-state :start)
klass (mf/use-state "fadeInDown") klass (mf/use-state "fadeInDown")
navigate navigate
@ -230,15 +164,8 @@
(reset! klass nil) (reset! klass nil)
(tm/dispose! sem)))) (tm/dispose! sem))))
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[: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
(case @slide :start [:& onboarding-welcome {:next #(navigate :opensource)}]
:start [:& onboarding-welcome {:next #(navigate :opensource)}] :opensource [:& onboarding-before-start {:next skip}])]]))
: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}])]])))

View file

@ -11,7 +11,6 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.users :as du] [app.main.data.users :as du]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -20,8 +19,7 @@
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :onboarding-newsletter-modal} ::mf/register-as :onboarding-newsletter-modal}
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [message (tr "onboarding.newsletter.acceptance-message")
message (tr "onboarding.newsletter.acceptance-message")
newsletter-updates (mf/use-state false) newsletter-updates (mf/use-state false)
newsletter-news (mf/use-state false) newsletter-news (mf/use-state false)
toggle toggle
@ -39,78 +37,49 @@
(modal/show {:type :onboarding-team}) (modal/show {:type :onboarding-team})
(du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))] (du/update-profile-props {:newsletter-updates @newsletter-updates :newsletter-news @newsletter-news}))))]
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div.animated.fadeInDown {:class (stl/css :modal-container)}
[:div.animated.fadeInDown {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)
[:h2 {:class (stl/css :modal-title) :data-test "onboarding-newsletter-title"}
:data-test "onboarding-newsletter-title"} (tr "onboarding.newsletter.title")]
(tr "onboarding.newsletter.title")] [:p {:class (stl/css :modal-text)}
[:p {:class (stl/css :modal-text)} (tr "onboarding-v2.newsletter.desc")]]
(tr "onboarding-v2.newsletter.desc")]] [:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :newsletter-options)}
[:div {:class (stl/css :newsletter-options)} [:div {:class (stl/css :input-wrapper)}
[:div {:class (stl/css :input-wrapper)} [:label {:for "newsletter-updates"}
[:label {:for "newsletter-updates"} [:span {:class (stl/css-case :global/checked @newsletter-updates)}
[:span {:class (stl/css-case :global/checked @newsletter-updates)} (when @newsletter-updates
(when @newsletter-updates i/status-tick-refactor)]
i/status-tick-refactor)] (tr "onboarding-v2.newsletter.updates")
(tr "onboarding-v2.newsletter.updates") [:input {:type "checkbox"
[:input {:type "checkbox" :id "newsletter-updates"
:id "newsletter-updates" :on-change #(toggle newsletter-updates)}]]]
:on-change #(toggle newsletter-updates)}]]]
[:div {:class (stl/css :input-wrapper)} [:div {:class (stl/css :input-wrapper)}
[:label {:for "newsletter-news"} [:label {:for "newsletter-news"}
[:span {:class (stl/css-case :global/checked @newsletter-news)} [:span {:class (stl/css-case :global/checked @newsletter-news)}
(when @newsletter-news (when @newsletter-news
i/status-tick-refactor)] i/status-tick-refactor)]
(tr "onboarding-v2.newsletter.news") (tr "onboarding-v2.newsletter.news")
[:input {:type "checkbox" [:input {:type "checkbox"
:id "newsletter-news" :id "newsletter-news"
:on-change #(toggle newsletter-news)}]]]] :on-change #(toggle newsletter-news)}]]]]
[:div {:class (stl/css :modal-info)} [:div {:class (stl/css :modal-info)}
[:p {:class (stl/css :modal-text)} [:p {:class (stl/css :modal-text)}
(tr "onboarding-v2.newsletter.privacy1") (tr "onboarding-v2.newsletter.privacy1")
[:a {:class (stl/css :modal-link) [:a {:class (stl/css :modal-link)
:target "_blank" :target "_blank"
:href "https://penpot.app/privacy"} :href "https://penpot.app/privacy"}
(tr "onboarding.newsletter.policy")]] (tr "onboarding.newsletter.policy")]]
[:p {:class (stl/css :modal-text)} [:p {:class (stl/css :modal-text)}
(tr "onboarding-v2.newsletter.privacy2")]]] (tr "onboarding-v2.newsletter.privacy2")]]]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:button {:on-click accept} (tr "labels.continue")]] [:button {:on-click accept} (tr "labels.continue")]]
[:img {:class (stl/css-case :deco true [:img {:class (stl/css-case :deco true
:top true) :top true)
:src "images/deco-newsletter.png" :border "0"}]]] :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"}]]])
))

View file

@ -15,7 +15,6 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt] [app.util.router :as rt]
@ -30,64 +29,38 @@
(mf/defc team-modal-right (mf/defc team-modal-right
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system)] [:div {:class (stl/css :modal-right)}
(if new-css-system [:h2 {:class (stl/css :modal-subtitle)}
(tr "onboarding.team-modal.create-team")]
[:div {:class (stl/css :modal-right)} [:p {:class (stl/css :modal-text)}
[:h2 {:class (stl/css :modal-subtitle)} (tr "onboarding.team-modal.create-team-desc")]
(tr "onboarding.team-modal.create-team")] [:ul {:class (stl/css :team-features)}
[:p {:class (stl/css :modal-text)} [:li {:class (stl/css :feature)}
(tr "onboarding.team-modal.create-team-desc")] [:span {:class (stl/css :icon)} i/document-refactor]
[:ul {:class (stl/css :team-features)} [:p {:class (stl/css :modal-text)}
[:li {:class (stl/css :feature)} (tr "onboarding.team-modal.create-team-feature-1")]]
[:span {:class (stl/css :icon)} i/document-refactor] [:li {:class (stl/css :feature)}
[:p {:class (stl/css :modal-text)} [:span {:class (stl/css :icon)} i/move-refactor]
(tr "onboarding.team-modal.create-team-feature-1")]] [:p {:class (stl/css :modal-text)}
[:li {:class (stl/css :feature)} (tr "onboarding.team-modal.create-team-feature-2")]]
[:span {:class (stl/css :icon)} i/move-refactor] [:li {:class (stl/css :feature)}
[:p {:class (stl/css :modal-text)} [:span {:class (stl/css :icon)} i/tree-refactor]
(tr "onboarding.team-modal.create-team-feature-2")]] [:p {:class (stl/css :modal-text)}
[:li {:class (stl/css :feature)} (tr "onboarding.team-modal.create-team-feature-3")]]
[:span {:class (stl/css :icon)} i/tree-refactor] [:li {:class (stl/css :feature)}
[:p {:class (stl/css :modal-text)} [:span {:class (stl/css :icon)} i/user-refactor]
(tr "onboarding.team-modal.create-team-feature-3")]] [:p {:class (stl/css :modal-text)}
[:li {:class (stl/css :feature)} (tr "onboarding.team-modal.create-team-feature-4")]]
[:span {:class (stl/css :icon)} i/user-refactor] [:li {:class (stl/css :feature)}
[:p {:class (stl/css :modal-text)} [:span {:class (stl/css :icon)} i/tick-refactor]
(tr "onboarding.team-modal.create-team-feature-4")]] [:p {:class (stl/css :modal-text)}
[:li {:class (stl/css :feature)} (tr "onboarding.team-modal.create-team-feature-5")]]]])
[: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")]]]])))
(mf/defc onboarding-team-modal (mf/defc onboarding-team-modal
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :onboarding-team} ::mf/register-as :onboarding-team}
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [form (fm/use-form :spec ::team-form
form (fm/use-form :spec ::team-form
:initial {} :initial {}
:validators [(fm/validate-not-empty :name (tr "auth.name.not-all-space")) :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"))]) (fm/validate-length :name fm/max-length-allowed (tr "auth.name.too-long"))])
@ -109,76 +82,43 @@
teams (mf/deref refs/teams)] teams (mf/deref refs/teams)]
(if new-css-system (if (< (count teams) 2)
(if (< (count teams) 2) [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div.animated.fadeIn {:class (stl/css :modal-container)}
[:div.animated.fadeIn {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-left)}
[:div {:class (stl/css :modal-left)} [:div {:class (stl/css :first-block)}
[:div {:class (stl/css :first-block)} [:h2 {:class (stl/css :modal-title)}
[:h2 {:class (stl/css :modal-title)} (tr "onboarding.team-modal.create-team")]
(tr "onboarding.team-modal.create-team")] [:p {:class (stl/css :modal-text)}
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.create-team-desc")]
(tr "onboarding.choice.team-up.create-team-desc")] [:& fm/form {:form form
[:& fm/form {:form form :class (stl/css :modal-form)
:class (stl/css :modal-form) :on-submit on-submit}
:on-submit on-submit}
[:& fm/input {:type "text" [:& fm/input {:type "text"
:class (stl/css :team-name-input) :class (stl/css :team-name-input)
:name :name :name :name
:placeholder "Team name" :placeholder "Team name"
:label (tr "onboarding.choice.team-up.create-team-placeholder")}] :label (tr "onboarding.choice.team-up.create-team-placeholder")}]
[:div {:class (stl/css :action-buttons)}
[:& fm/submit-button*
{:className (stl/css :accept-button)
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
[:div {:class (stl/css :second-block)}
[:h2 {:class (stl/css :modal-title)}
(tr "onboarding.choice.team-up.start-without-a-team")]
[:p {:class (stl/css :modal-text)}
(tr "onboarding.choice.team-up.start-without-a-team-description")]
[:div {:class (stl/css :action-buttons)}
[:button {:class (stl/css :accept-button)
:on-click on-skip}
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
[:& 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")}]
[:div {:class (stl/css :action-buttons)}
[:& fm/submit-button* [:& fm/submit-button*
{:label (tr "onboarding.choice.team-up.continue-creating-team")}]] {:className (stl/css :accept-button)
:label (tr "onboarding.choice.team-up.continue-creating-team")}]]]]
[:div {:class (stl/css :second-block)}
[:h2 {:class (stl/css :modal-title)}
(tr "onboarding.choice.team-up.start-without-a-team")]
[:p {:class (stl/css :modal-text)}
(tr "onboarding.choice.team-up.start-without-a-team-description")]
[:h2.title (tr "onboarding.choice.team-up.start-without-a-team")] [:div {:class (stl/css :action-buttons)}
[:p.info (tr "onboarding.choice.team-up.start-without-a-team-description")] [:button {:class (stl/css :accept-button)
:on-click on-skip}
(tr "onboarding.choice.team-up.continue-without-a-team")]]]]
[:& team-modal-right]
[:div {:class (stl/css :paginator)} "1/2"]]]
[:div (st/emit! (modal/hide)))))
[: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))))))
(defn get-available-roles (defn get-available-roles
[] []
@ -197,8 +137,7 @@
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :onboarding-team-invitations} ::mf/register-as :onboarding-team-invitations}
[{:keys [name] :as props}] [{:keys [name] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [initial (mf/use-memo (constantly
initial (mf/use-memo (constantly
{:role "editor" {:role "editor"
:name name})) :name name}))
form (fm/use-form :spec ::invite-form form (fm/use-form :spec ::invite-form
@ -265,96 +204,48 @@
(on-invite-now form) (on-invite-now form)
(on-invite-later form)))))] (on-invite-later form)))))]
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div.animated.fadeIn {:class (stl/css :modal-container)}
[:div.animated.fadeIn {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-left)}
[:div {:class (stl/css :modal-left)} [:h2 {:class (stl/css :modal-title)} (tr "onboarding.choice.team-up.invite-members")]
[:h2 {:class (stl/css :modal-title)} (tr "onboarding.choice.team-up.invite-members")] [:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
[:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")]
[:div {:class (stl/css :modal-form)} [:div {:class (stl/css :modal-form)}
[:& fm/form {:form form [:& fm/form {:form form
:on-submit on-submit} :on-submit on-submit}
[:div {:class (stl/css :role-select)} [:div {:class (stl/css :role-select)}
[:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")] [:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")]
[:& fm/select {:name :role :options roles}]] [:& fm/select {:name :role :options roles}]]
[:div {:class (stl/css :invitation-row)} [:div {:class (stl/css :invitation-row)}
[:& fm/multi-input {:type "email" [:& fm/multi-input {:type "email"
:name :emails :name :emails
:auto-focus? true :auto-focus? true
:trim true :trim true
:valid-item-fn us/parse-email :valid-item-fn us/parse-email
:caution-item-fn #{} :caution-item-fn #{}
:label (tr "modals.invite-member.emails") :label (tr "modals.invite-member.emails")
:on-submit on-submit}]]] :on-submit on-submit}]]]
[:div {:class (stl/css :action-buttons)} [:div {:class (stl/css :action-buttons)}
[:button {:class (stl/css :back-button) [:button {:class (stl/css :back-button)
:on-click #(st/emit! (modal/show {:type :onboarding-team}) :on-click #(st/emit! (modal/show {:type :onboarding-team})
(ptk/event ::ev/event {::ev/name "invite-members-back" (ptk/event ::ev/event {::ev/name "invite-members-back"
::ev/origin "onboarding" ::ev/origin "onboarding"
:name name :name name
:step 2}))} :step 2}))}
(tr "labels.back")] (tr "labels.back")]
[:& fm/submit-button* [:& fm/submit-button*
{:className (stl/css :accept-button) {:className (stl/css :accept-button)
:label :label
(if (> (count emails) 0) (if (> (count emails) 0)
(tr "onboarding.choice.team-up.create-team-and-invite") (tr "onboarding.choice.team-up.create-team-and-invite")
(tr "onboarding.choice.team-up.create-team-without-invite"))}]] (tr "onboarding.choice.team-up.create-team-without-invite"))}]]
[:div {:class (stl/css :modal-hint)} [:div {:class (stl/css :modal-hint)}
(tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]] (tr "onboarding.choice.team-up.create-team-and-send-invites-description")]]]
[:& team-modal-right] [:& team-modal-right]
[:div {:class (stl/css :paginator)} "2/2"]]] [: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"}]]])))

View file

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

View file

@ -12,95 +12,95 @@
font-size: $fs-16; font-size: $fs-16;
margin-top: $s-20; margin-top: $s-20;
width: $s-800; width: $s-800;
}
.table-header { .table-header {
color: $df-secondary; color: $df-secondary;
display: grid; display: grid;
font-size: $fs-12; font-size: $fs-12;
grid-template-columns: 43% 1fr $s-108 $s-12; grid-template-columns: 43% 1fr $s-108 $s-12;
height: $s-40; height: $s-40;
max-width: $s-1000; max-width: $s-1000;
padding: 0 $s-16; padding: 0 $s-16;
text-transform: uppercase; text-transform: uppercase;
width: 100%; width: 100%;
}
.table-rows {
color: $db-secondary;
display: flex;
flex-direction: column;
margin-top: $s-16;
max-width: $s-1000;
padding-top: 0;
width: 100%;
}
.table-row {
align-items: center;
background-color: $db-tertiary;
border-radius: $br-8;
color: $df-primary;
display: grid;
font-size: $fs-14;
grid-template-columns: 1fr 43% $s-12;
height: fit-content;
min-height: $s-40;
padding: 0 $s-16;
width: 100%;
&:not(:first-child) {
margin-top: $s-8;
}
}
.table-field {
display: flex;
align-items: center;
.icon {
padding-left: $s-12;
cursor: pointer;
} }
.table-rows { &.name {
color: $db-secondary; -webkit-box-orient: vertical;
display: flex; -webkit-line-clamp: 2;
flex-direction: column;
margin-top: $s-16;
max-width: $s-1000;
padding-top: 0;
width: 100%;
}
.table-row {
align-items: center;
background-color: $db-tertiary;
border-radius: $br-8;
color: $df-primary; color: $df-primary;
display: grid; display: -webkit-box;
font-size: $fs-14; max-width: $s-480;
grid-template-columns: 1fr 43% $s-12; overflow: hidden;
height: fit-content; text-overflow: ellipsis;
min-height: $s-40;
padding: 0 $s-16;
width: 100%;
&:not(:first-child) {
margin-top: $s-8;
}
} }
.table-field { &.expiration-date {
display: flex; color: $df-secondary;
align-items: center; font-size: $fs-14;
.icon { .content {
padding-left: $s-12; padding: $s-2 $s-6;
cursor: pointer; &.expired {
} background-color: var(--warning-color);
border-radius: $br-4;
&.name { color: $db-secondary;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
color: $df-primary;
display: -webkit-box;
max-width: $s-480;
overflow: hidden;
text-overflow: ellipsis;
}
&.expiration-date {
color: $df-secondary;
font-size: $fs-14;
.content {
padding: $s-2 $s-6;
&.expired {
background-color: var(--warning-color);
border-radius: $br-4;
color: $db-secondary;
}
} }
} }
&.access-token-created { }
word-break: break-all; &.access-token-created {
} word-break: break-all;
&.actions {
position: relative;
}
} }
svg { &.actions {
width: $s-12; position: relative;
height: $s-12;
fill: $df-primary;
} }
} }
svg {
width: $s-12;
height: $s-12;
fill: $df-primary;
}
.dashboard-access-tokens { .dashboard-access-tokens {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -16,7 +16,6 @@
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.forms :as fm] [app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.messages :as msgs] [app.main.ui.messages :as msgs]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -76,8 +75,7 @@
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :change-email} ::mf/register-as :change-email}
[] []
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [profile (mf/deref refs/profile)
profile (mf/deref refs/profile)
form (fm/use-form :spec ::email-change-form form (fm/use-form :spec ::email-change-form
:validators [email-equality] :validators [email-equality]
:initial profile) :initial profile)
@ -99,82 +97,44 @@
(when (and different-emails-error? (= email-1 email-2)) (when (and different-emails-error? (= email-1 email-2))
(swap! form d/dissoc-in [:errors :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-overlay)} [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:& fm/form {:form form
[:& fm/form {:form form :on-submit on-submit}
:on-submit on-submit}
[:div {:class (stl/css :modal-header)} [:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title) [:h2 {:class (stl/css :modal-title)
:data-test "change-email-title"} :data-test "change-email-title"}
(tr "modals.change-email.title")] (tr "modals.change-email.title")]
[:button {:class (stl/css :modal-close-btn) [:button {:class (stl/css :modal-close-btn)
:on-click on-close} i/close-refactor]] :on-click on-close} i/close-refactor]]
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
[:& msgs/inline-banner [:& msgs/inline-banner
{:type :info {:type :info
:content (tr "modals.change-email.info" (:email profile))}] :content (tr "modals.change-email.info" (:email profile))}]
[:div {:class (stl/css :fields-row)} [:div {:class (stl/css :fields-row)}
[:& fm/input {:type "email" [:& fm/input {:type "email"
:name :email-1 :name :email-1
:label (tr "modals.change-email.new-email") :label (tr "modals.change-email.new-email")
:trim true :trim true
:show-success? true :show-success? true
:on-change-value on-email-change}]] :on-change-value on-email-change}]]
[:div {:class (stl/css :fields-row)} [:div {:class (stl/css :fields-row)}
[:& fm/input {:type "email" [:& fm/input {:type "email"
:name :email-2 :name :email-2
:label (tr "modals.change-email.confirm-email") :label (tr "modals.change-email.confirm-email")
:trim true :trim true
:show-success? true :show-success? true
:on-change-value on-email-change}]]] :on-change-value on-email-change}]]]
[:div {:class (stl/css :modal-footer)} [:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons) [:div {:class (stl/css :action-buttons)
:data-test "change-email-submit"} :data-test "change-email-submit"}
[:> fm/submit-button* [:> fm/submit-button*
{:label (tr "modals.change-email.submit")}]]]]]] {: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 { .modal-overlay {
@extend .modal-overlay-base; @extend .modal-overlay-base;
.modal-container { }
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
margin-bottom: $s-24;
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content { .modal-container {
@include flexColumn; @extend .modal-container-base;
@include titleTipography; min-width: $s-408;
gap: $s-24; border: $s-1 solid var(--modal-border-color);
margin-bottom: $s-24; }
.fields-row { .modal-header {
@include flexColumn; margin-bottom: $s-24;
.select-title { }
@include titleTipography;
color: var(--modal-title-foreground-color);
}
}
}
.modal-footer { .modal-title {
.action-buttons { @include tabTitleTipography;
@extend .modal-action-btns; color: var(--modal-title-foreground-color);
button { }
@extend .modal-accept-btn;
} .modal-close-btn {
.cancel-button { @extend .modal-close-btn-base;
@extend .modal-cancel-btn; }
}
} .modal-content {
} @include flexColumn;
@include titleTipography;
gap: $s-24;
margin-bottom: $s-24;
}
.fields-row {
@include flexColumn;
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
} }
} }
.cancel-button {
@extend .modal-cancel-btn;
}

View file

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

View file

@ -8,50 +8,54 @@
.modal-overlay { .modal-overlay {
@extend .modal-overlay-base; @extend .modal-overlay-base;
.modal-container { }
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
margin-bottom: $s-24;
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content { .modal-container {
@include flexColumn; @extend .modal-container-base;
@include titleTipography; min-width: $s-408;
gap: $s-24; border: $s-1 solid var(--modal-border-color);
margin-bottom: $s-24; }
.fields-row { .modal-header {
@include flexColumn; margin-bottom: $s-24;
.select-title { }
@include titleTipography;
color: var(--modal-title-foreground-color);
}
}
}
.modal-footer { .modal-title {
.action-buttons { @include tabTitleTipography;
@extend .modal-action-btns; color: var(--modal-title-foreground-color);
}
.cancel-button { .modal-close-btn {
@extend .modal-cancel-btn; @extend .modal-close-btn-base;
} }
.accept-button {
@extend .modal-accept-btn; .modal-content {
&.danger { @include flexColumn;
@extend .modal-danger-btn; @include titleTipography;
} gap: $s-24;
} margin-bottom: $s-24;
} }
}
.fields-row {
@include flexColumn;
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.action-buttons {
@extend .modal-action-btns;
}
.cancel-button {
@extend .modal-cancel-btn;
}
.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.login :refer [login-methods]]
[app.main.ui.auth.recovery-request :refer [recovery-request-page]] [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.auth.register :refer [register-methods register-validate-form register-success-page]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
@ -27,8 +26,7 @@
{::mf/register modal/components {::mf/register modal/components
::mf/register-as :login-register} ::mf/register-as :login-register}
[_] [_]
(let [new-css-system (mf/use-ctx ctx/new-css-system) (let [uri (. (. js/document -location) -href)
uri (. (. js/document -location) -href)
user-email (mf/use-state "") user-email (mf/use-state "")
register-token (mf/use-state "") register-token (mf/use-state "")
@ -71,114 +69,58 @@
(mf/with-effect [] (mf/with-effect []
(swap! storage assoc :redirect-url uri)) (swap! storage assoc :redirect-url uri))
(if new-css-system [:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-overlay)} [:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-container)} [:div {:class (stl/css :modal-header)}
[:div {:class (stl/css :modal-header)} [:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")]
[:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")] [:button {:class (stl/css :modal-close-btn)
[:button {:class (stl/css :modal-close-btn) :title (tr "labels.close")
:title (tr "labels.close") :on-click close} i/close-refactor]]
:on-click close} i/close-refactor]]
[:div {:class (stl/css :modal-content)} [:div {:class (stl/css :modal-content)}
(case current-section (case current-section
:login :login
[:div {:class (stl/css :form-container)} [:div {:class (stl/css :form-container)}
[:& login-methods {:on-success-callback success-login :origin :viewer}] [:& login-methods {:on-success-callback success-login :origin :viewer}]
[:div {:class (stl/css :links)} [:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)} [:div {:class (stl/css :link-entry)}
[:a {:on-click set-section [:a {:on-click set-section
:data-value :recovery-request} :data-value :recovery-request}
(tr "auth.forgot-password")]] (tr "auth.forgot-password")]]
[:div {:class (stl/css :link-entry)} [:div {:class (stl/css :link-entry)}
[:span (tr "auth.register") " "] [:span (tr "auth.register") " "]
[:a {:on-click set-section [:a {:on-click set-section
:data-value :register} :data-value :register}
(tr "auth.register-submit")]]]] (tr "auth.register-submit")]]]]
:register :register
[:div {:class (stl/css :form-container)} [:div {:class (stl/css :form-container)}
[:& register-methods {:on-success-callback success-register}] [:& register-methods {:on-success-callback success-register}]
[:div {:class (stl/css :links)} [:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)} [:div {:class (stl/css :link-entry)}
[:span (tr "auth.already-have-account") " "] [:span (tr "auth.already-have-account") " "]
[:a {:on-click set-section [:a {:on-click set-section
:data-value :login} :data-value :login}
(tr "auth.login-here")]]]] (tr "auth.login-here")]]]]
:register-validate :register-validate
[:div {:class (stl/css :form-container)} [:div {:class (stl/css :form-container)}
[:& register-validate-form {:params {:token @register-token} [:& register-validate-form {:params {:token @register-token}
:on-success-callback success-email-sent}]
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)}
[:a {:on-click set-section
:data-value :register}
(tr "labels.go-back")]]]]
:recovery-request
[:& recovery-request-page {:go-back-callback go-back-to-login
:on-success-callback success-email-sent}] :on-success-callback success-email-sent}]
:email-sent [:div {:class (stl/css :links)}
[:div {:class (stl/css :form-container)} [:div {:class (stl/css :link-entry)}
[:& register-success-page {:params {:email @user-email}}]]) [:a {:on-click set-section
:data-value :register}
(tr "labels.go-back")]]]]
(when main-section :recovery-request
[:div {:class (stl/css :links)} [:& recovery-request-page {:go-back-callback go-back-to-login
[:& terms-login]])]]] :on-success-callback success-email-sent}]
:email-sent
[:div {:class (stl/css :form-container)}
[:& register-success-page {:params {:email @user-email}}]])
(when main-section
;;OLD [:div {:class (stl/css :links)}
[:div.modal-overlay [:& terms-login]])]]]))
[: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]])]])))

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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