diff --git a/frontend/resources/images/icons/expand-refactor.svg b/frontend/resources/images/icons/expand-refactor.svg
new file mode 100644
index 000000000..e63fd74c8
--- /dev/null
+++ b/frontend/resources/images/icons/expand-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/images/icons/reload-refactor.svg b/frontend/resources/images/icons/reload-refactor.svg
new file mode 100644
index 000000000..e1ac593b7
--- /dev/null
+++ b/frontend/resources/images/icons/reload-refactor.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss
index cd3b86762..944fa8e52 100644
--- a/frontend/resources/styles/common/refactor/basic-rules.scss
+++ b/frontend/resources/styles/common/refactor/basic-rules.scss
@@ -148,6 +148,7 @@
stroke: var(--button-tertiary-foreground-color-active);
}
}
+
&:global(.disabled),
&[disabled],
&:disabled {
diff --git a/frontend/resources/styles/common/refactor/design-tokens.scss b/frontend/resources/styles/common/refactor/design-tokens.scss
index c1d86f5ea..559d779c9 100644
--- a/frontend/resources/styles/common/refactor/design-tokens.scss
+++ b/frontend/resources/styles/common/refactor/design-tokens.scss
@@ -297,4 +297,13 @@
--tag-background-color: var(--color-accent-primary);
--link-foreground-color: var(--color-accent-primary);
+
+ // VIEWER
+ --viewer-background-color: var(--color-background-secondary);
+ --viewer-paginator-background-color: var(--color-background-tertiary);
+ --viewer-controls-background-color: var(--color-background-primary);
+ --viewer-inspect-border-color: var(--color-background-tertiary);
+ --viewer-thumbnails-control-foreground-color: var(--color-foreground-secondary);
+ --viewer-thumbnail-border-color: var(--color-accent-primary);
+ --viewer-thumbnail-background-color-selected: var(--color-accent-primary-muted);
}
diff --git a/frontend/src/app/main/ui/auth/login.cljs b/frontend/src/app/main/ui/auth/login.cljs
index bc64bdf75..2092a2fb5 100644
--- a/frontend/src/app/main/ui/auth/login.cljs
+++ b/frontend/src/app/main/ui/auth/login.cljs
@@ -93,10 +93,9 @@
(assoc :message (tr "errors.email-invalid"))))))
(mf/defc login-form
- [{:keys [params on-success-callback] :as props}]
+ [{:keys [params on-success-callback origin] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (mf/deps params) (constantly params))
-
error (mf/use-state false)
form (fm/use-form :spec ::login-form
:validators [handle-error-messages]
@@ -152,7 +151,12 @@
(let [params (:clean-data @form)]
(login-with-ldap event (with-meta params
{:on-error on-error
- :on-success on-success})))))]
+ :on-success on-success})))))
+
+ on-recovery-request
+ (mf/use-fn
+ #(st/emit! (rt/nav :auth-recovery-request)))]
+
(if new-css-system
[:*
(when-let [message @error]
@@ -178,10 +182,11 @@
:label (tr "auth.password")
:class (stl/css :form-field)}]]
- (when (or (contains? cf/flags :login)
- (contains? cf/flags :login-with-password))
+ (when (and (not= origin :viewer)
+ (or (contains? cf/flags :login)
+ (contains? cf/flags :login-with-password)))
[:div {:class (stl/css :fields-row :forgot-password)}
- [:& lk/link {:action #(st/emit! (rt/nav :auth-recovery-request))
+ [:& lk/link {:action on-recovery-request
:data-test "forgot-password"}
(tr "auth.forgot-password")]])
@@ -198,6 +203,7 @@
{:label (tr "auth.login-with-ldap-submit")
:on-click on-submit-ldap}])]]]
+
;; OLD
[:*
(when-let [message @error]
@@ -271,7 +277,7 @@
:icon i/brand-openid
:label (tr "auth.login-with-oidc-submit")
:class (stl/css :login-btn :btn-oidc-auth)}])]
-
+
[:div.auth-buttons
(when (contains? cf/flags :login-with-google)
[:& bl/button-link {:on-click login-with-google
@@ -299,28 +305,36 @@
(mf/defc login-button-oidc
[{:keys [params] :as props}]
- (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ login-oidc
+ (mf/use-fn
+ (mf/deps params)
+ (fn [event]
+ (login-with-oidc event :oidc params)))
+
+ handle-key-down
+ (mf/use-fn
+ (fn [event]
+ (when (k/enter? event)
+ (login-oidc event))))]
(if new-css-system
(when (contains? cf/flags :login-with-oidc)
[:div {:class (stl/css :link-entry :link-oidc)}
[:a {:tab-index "0"
- :on-key-down (fn [event]
- (when (k/enter? event)
- (login-with-oidc event :oidc params)))
- :on-click #(login-with-oidc % :oidc params)}
+ :on-key-down handle-key-down
+ :on-click login-oidc}
(tr "auth.login-with-oidc-submit")]])
-
+
+ ;; OLD
(when (contains? cf/flags :login-with-oidc)
[:div.link-entry.link-oidc
[:a {:tab-index "0"
- :on-key-down (fn [event]
- (when (k/enter? event)
- (login-with-oidc event :oidc params)))
- :on-click #(login-with-oidc % :oidc params)}
+ :on-key-down handle-key-down
+ :on-click login-oidc}
(tr "auth.login-with-oidc-submit")]]))))
(mf/defc login-methods
- [{:keys [params on-success-callback] :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
[:*
@@ -336,7 +350,7 @@
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password)
(contains? cf/flags :login-with-ldap))
- [:& login-form {:params params :on-success-callback on-success-callback}])]
+ [:& login-form {:params params :on-success-callback on-success-callback :origin origin}])]
;; OLD
[:*
@@ -364,7 +378,19 @@
(mf/defc login-page
[{:keys [params] :as props}]
- (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ go-register
+ (mf/use-fn
+ #(st/emit! (rt/nav :auth-register {} params)))
+
+ on-pass-recovery
+ (mf/use-fn
+ #(st/emit! (rt/nav :auth-recovery-request)))
+
+ on-create-demo-profile
+ (mf/use-fn
+ #(st/emit! (du/create-demo-profile)))]
+
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)
@@ -375,17 +401,24 @@
[:& login-methods {:params params}]
[:div {:class (stl/css :links)}
+ (when (or (contains? cf/flags :login)
+ (contains? cf/flags :login-with-password))
+ [:div {:class (stl/css :link-entry :register)}
+ [:& lk/link {:action on-pass-recovery
+ :data-test "forgot-password"}
+ (tr "auth.forgot-password")]])
+
(when (contains? cf/flags :registration)
[:div {:class (stl/css :link-entry :register)}
[:span (tr "auth.register") " "]
- [:& lk/link {:action #(st/emit! (rt/nav :auth-register {} params))
+ [:& lk/link {:action go-register
:data-test "register-submit"}
(tr "auth.register-submit")]])]
(when (contains? cf/flags :demo-users)
[:div {:class (stl/css :link-entry :demo-account)}
[:span (tr "auth.create-demo-profile") " "]
- [:& lk/link {:action #(st/emit! (du/create-demo-profile))
+ [:& lk/link {:action on-create-demo-profile
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]])]
@@ -400,14 +433,14 @@
(when (or (contains? cf/flags :login)
(contains? cf/flags :login-with-password))
[:div.link-entry
- [:& lk/link {:action #(st/emit! (rt/nav :auth-recovery-request))
+ [:& 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 #(st/emit! (rt/nav :auth-register {} params))
+ [:& lk/link {:action go-register
:data-test "register-submit"}
(tr "auth.register-submit")]])]
@@ -415,7 +448,7 @@
[:div.links.demo
[:div.link-entry
[:span (tr "auth.create-demo-profile") " "]
- [:& lk/link {:action #(st/emit! (du/create-demo-profile))
+ [:& lk/link {:action on-create-demo-profile
:data-test "demo-account-link"}
(tr "auth.create-demo-account")]]])]])))
diff --git a/frontend/src/app/main/ui/export.cljs b/frontend/src/app/main/ui/export.cljs
index 710e5efc5..436265499 100644
--- a/frontend/src/app/main/ui/export.cljs
+++ b/frontend/src/app/main/ui/export.cljs
@@ -55,8 +55,12 @@
:cmd cmd})))
on-toggle-enabled
- (fn [index]
- (swap! exports update-in [index :enabled] not))
+ (mf/use-fn
+ (mf/deps exports)
+ (fn [event]
+ (let [index (-> (dom/get-current-target event)
+ (dom/get-data "value"))]
+ (swap! exports update-in [index :enabled] not))))
change-all
(fn [_]
@@ -65,9 +69,8 @@
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
- [:div.modal-container.export-multiple-dialog
- {:class (stl/css-case :modal-container true
- :empty (empty? all-exports))}
+ [:div {:class (stl/css-case :modal-container true
+ :empty (empty? all-exports))}
[:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title)} title]
@@ -84,55 +87,58 @@
:on-click change-all}
[:span {:class (stl/css :checkbox-wrapper)}
(cond
- all-checked? [:span {:class (stl/css-case :checkbox-icon2 true
+ all-checked? [:span {:class (stl/css-case :checkobox-tick true
:global/checked true)} i/tick-refactor]
- all-unchecked? [:span {:class (stl/css-case :checkbox-icon2 true
+ all-unchecked? [:span {:class (stl/css-case :checkobox-tick true
:global/uncheked true)}]
- :else [:span {:class (stl/css-case :checkbox-icon2 true
+ :else [:span {:class (stl/css-case :checkobox-tick true
:global/intermediate true)} i/remove-refactor])]]
- [:div {:class (stl/css :selection-title)} (tr "dashboard.export-multiple.selected"
- (c (count enabled-exports))
- (c (count all-exports)))]]
+ [:div {:class (stl/css :selection-title)}
+ (tr "dashboard.export-multiple.selected"
+ (c (count enabled-exports))
+ (c (count all-exports)))]]
[:div {:class (stl/css :selection-wrapper)}
[:div {:class (stl/css-case :selection-list true
:selection-shadow (> (count all-exports) 8))}
- (for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
- (let [{:keys [x y width height]} (:selrect shape)]
- [:div {:class (stl/css :selection-row)}
- [:button {:class (stl/css :selection-btn)
- :on-click #(on-toggle-enabled index)}
- [:span {:class (stl/css :checkbox-wrapper)}
- (if (:enabled export)
- [:span {:class (stl/css-case :checkbox-icon2 true
- :global/checked true)} i/tick-refactor]
- [:span {:class (stl/css-case :checkbox-icon2 true
- :global/uncheked true)}])]
+ (for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
+ (let [{:keys [x y width height]} (:selrect shape)]
+ [:div {:class (stl/css :selection-row)
+ :key (:id shape)}
+ [:button {:class (stl/css :selection-btn)
+ :data-value index
+ :on-click on-toggle-enabled}
+ [:span {:class (stl/css :checkbox-wrapper)}
+ (if (:enabled export)
+ [:span {:class (stl/css-case :checkobox-tick true
+ :global/checked true)} i/tick-refactor]
+ [:span {:class (stl/css-case :checkobox-tick true
+ :global/uncheked true)}])]
- [:div {:class (stl/css :image-wrapper)}
- (if (some? (:thumbnail shape))
- [:img {:src (:thumbnail shape)}]
- [:svg {:view-box (dm/str x " " y " " width " " height)
- :width 24
- :height 20
- :version "1.1"
- :xmlns "http://www.w3.org/2000/svg"
- :xmlnsXlink "http://www.w3.org/1999/xlink"
+ [:div {:class (stl/css :image-wrapper)}
+ (if (some? (:thumbnail shape))
+ [:img {:src (:thumbnail shape)}]
+ [:svg {:view-box (dm/str x " " y " " width " " height)
+ :width 24
+ :height 20
+ :version "1.1"
+ :xmlns "http://www.w3.org/2000/svg"
+ :xmlnsXlink "http://www.w3.org/1999/xlink"
;; Fix Chromium bug about color of html texts
;; https://bugs.chromium.org/p/chromium/issues/detail?id=1244560#c5
- :style {:-webkit-print-color-adjust :exact}
- :fill "none"}
+ :style {:-webkit-print-color-adjust :exact}
+ :fill "none"}
- [:& shape-wrapper {:shape shape}]])]
+ [:& shape-wrapper {:shape shape}]])]
- [:div {:class (stl/css :selection-name)} (cond-> (:name shape) suffix (str suffix))]
- (when (:scale export)
- [:div {:class (stl/css :selection-scale)}
- (dm/str (ust/format-precision (* width (:scale export)) 2) "x"
- (ust/format-precision (* height (:scale export)) 2) "px ")])
+ [:div {:class (stl/css :selection-name)} (cond-> (:name shape) suffix (str suffix))]
+ (when (:scale export)
+ [:div {:class (stl/css :selection-scale)}
+ (dm/str (ust/format-precision (* width (:scale export)) 2) "px"
+ (ust/format-precision (* height (:scale export)) 2) "px")])
- (when (:type export)
- [:div {:class (stl/css :selection-extension)}
- (-> export :type d/name str/upper)])]]))]]]
+ (when (:type export)
+ [:div {:class (stl/css :selection-extension)}
+ (-> export :type d/name str/upper)])]]))]]]
[:& no-selection])]
@@ -187,7 +193,8 @@
(for [[index {:keys [shape suffix] :as export}] (d/enumerate @exports)]
(let [{:keys [x y width height]} (:selrect shape)]
[:div.row
- [:div.field.check {:on-click #(on-toggle-enabled index)}
+ [:div.field.check {:data-value index
+ :on-click on-toggle-enabled}
(if (:enabled export)
[:span.checked i/checkbox-checked]
[:span.unchecked i/checkbox-unchecked])]
@@ -210,7 +217,7 @@
[:div.field.name (cond-> (:name shape) suffix (str suffix))]
(when (:scale export)
- [:div.field.scale (dm/str (ust/format-precision (* width (:scale export)) 2) "x"
+ [:div.field.scale (dm/str (ust/format-precision (* width (:scale export)) 2) "px"
(ust/format-precision (* height (:scale export)) 2) "px ")])
(when (:type export)
diff --git a/frontend/src/app/main/ui/export.scss b/frontend/src/app/main/ui/export.scss
index a14f40908..a958a0dc8 100644
--- a/frontend/src/app/main/ui/export.scss
+++ b/frontend/src/app/main/ui/export.scss
@@ -161,7 +161,7 @@
height: $s-24;
width: $s-24;
padding: 0;
- .checkbox-icon2 {
+ .checkobox-tick {
@extend .checkbox-icon;
}
}
diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs
index 610eec75e..96ebebf05 100644
--- a/frontend/src/app/main/ui/icons.cljs
+++ b/frontend/src/app/main/ui/icons.cljs
@@ -339,6 +339,7 @@
(def easing-ease-in-out-refactor (icon-xref :easing-ease-in-out-refactor))
(def effects-refactor (icon-xref :effects-refactor))
(def elipse-refactor (icon-xref :elipse-refactor))
+(def expand-refactor (icon-xref :expand-refactor))
(def fill-content-refactor (icon-xref :fill-content-refactor))
(def filter-refactor (icon-xref :filter-refactor))
(def fixed-width-refactor (icon-xref :fixed-width-refactor))
@@ -414,6 +415,7 @@
(def picker-refactor (icon-xref :picker-refactor))
(def play-refactor (icon-xref :play-refactor))
(def rectangle-refactor (icon-xref :rectangle-refactor))
+(def reload-refactor (icon-xref :reload-refactor))
(def remove-refactor (icon-xref :remove-refactor))
(def rgba-refactor (icon-xref :rgba-refactor))
(def rgba-complementary-refactor (icon-xref :rgba-complementary-refactor))
diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs
index 366453dd0..37577d56f 100644
--- a/frontend/src/app/main/ui/viewer.cljs
+++ b/frontend/src/app/main/ui/viewer.cljs
@@ -6,6 +6,7 @@
(ns app.main.ui.viewer
(:import goog.events.EventType)
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -91,29 +92,57 @@
:vbox (str "0 0 " width " " height)})))
(mf/defc viewer-pagination
- [{:keys [index num-frames left-bar right-bar] :as props}]
- [:*
- (when (pos? index)
- [:div.viewer-go-prev {:class (when left-bar "left-bar")}
- [:div.arrow {:on-click #(st/emit! dv/select-prev-frame)} i/go-prev]])
- (when (< (+ index 1) num-frames)
- [:div.viewer-go-next {:class (when right-bar "right-bar")}
- [:div.arrow {:on-click #(st/emit! dv/select-next-frame)} i/go-next]])
- [:div.viewer-bottom {:class (when left-bar "left-bar")}
- [:div.reset {:on-click #(st/emit! dv/select-first-frame)} i/reset]
- [:div.counter (str/join " / " [(+ index 1) num-frames])]
- [:span]]])
+ [{:keys [index num-frames left-bar right-bar comment-sidebar] :as props}]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ go-prev-frame (mf/use-fn #(st/emit! dv/select-prev-frame))
+ go-next-frame (mf/use-fn #(st/emit! dv/select-next-frame))
+ go-first-frame (mf/use-fn #(st/emit! dv/select-first-frame))]
+ (if new-css-system
+ [:*
+ (when (pos? index)
+ [:button {:class (stl/css-case :viewer-go-prev true
+ :left-bar left-bar)
+ :on-click go-prev-frame}
+ i/arrow-refactor])
+ (when (< (+ index 1) num-frames)
+ [:button {:class (stl/css-case :viewer-go-next true
+ :comment-sidebar comment-sidebar
+ :right-bar right-bar)
+ :on-click go-next-frame}
+ i/arrow-refactor])
+ [:div {:class (stl/css-case :viewer-bottom true
+ :left-bar left-bar)}
+ [:button {:on-click go-first-frame
+ :class (stl/css :reset-button)}
+ i/reload-refactor]
+ [:span {:class (stl/css :counter)}
+ (str/join " / " [(+ index 1) num-frames])]
+ [:span]]]
+
+
+ ;; OLD
+ [:*
+ (when (pos? index)
+ [:div.viewer-go-prev {:class (when left-bar "left-bar")}
+ [:div.arrow {:on-click go-prev-frame} i/go-prev]])
+ (when (< (+ index 1) num-frames)
+ [:div.viewer-go-next {:class (when right-bar "right-bar")}
+ [:div.arrow {:on-click go-next-frame} i/go-next]])
+ [:div.viewer-bottom {:class (when left-bar "left-bar")}
+ [:div.reset {:on-click go-first-frame} i/reset]
+ [:div.counter (str/join " / " [(+ index 1) num-frames])]
+ [:span]]])))
(mf/defc viewer-pagination-and-sidebar
{::mf/wrap [mf/memo]}
[{:keys [section index users frame page]}]
(let [comments-local (mf/deref refs/comments-local)
show-sidebar? (and (= section :comments) (:show-sidebar? comments-local))]
- [:*
+ [:*
[:& viewer-pagination
{:index index
:num-frames (count (:frames page))
- :right-bar show-sidebar?}]
+ :comment-sidebar show-sidebar?}]
(when show-sidebar?
[:& comments-sidebar
@@ -172,72 +201,138 @@
:page page
:interactions-mode interactions-mode}]]]))
-
(mf/defc viewer-wrapper
{::mf/wrap-props false}
[{:keys [wrapper-size orig-frame orig-viewport-ref orig-size page file users current-viewport-ref
size frame interactions-mode overlays zoom section index]}]
- [:*
- [:& viewer-pagination-and-sidebar
- {:section section
- :index index
- :page page
- :users users
- :frame frame
- :interactions-mode interactions-mode}]
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (if new-css-system
+ [:*
+ [:& viewer-pagination-and-sidebar
+ {:section section
+ :index index
+ :page page
+ :users users
+ :frame frame
+ :interactions-mode interactions-mode}]
- [:div.viewer-wrapper
- {:style {:width (:width wrapper-size)
- :height (:height wrapper-size)}}
- [:div.viewer-clipper
- (when orig-frame
- [:div.viewport-container
- {:ref orig-viewport-ref
- :style {:width (:width orig-size)
- :height (:height orig-size)
- :position "relative"}}
+ [:div {:class (stl/css :viewer-wrapper)
+ :style {:width (:width wrapper-size)
+ :height (:height wrapper-size)}}
+ [:div {:class (stl/css :viewer-clipper)}
- [:& interactions/viewport
- {:frame orig-frame
- :base-frame orig-frame
- :frame-offset (gpt/point 0 0)
- :size orig-size
- :page page
- :users users
- :interactions-mode interactions-mode}]])
+ (when orig-frame
+ [:div {:class (stl/css :viewport-container)
+ :ref orig-viewport-ref
+ :style {:width (:width orig-size)
+ :height (:height orig-size)
+ :position "relative"}}
- [:div.viewport-container
- {:ref current-viewport-ref
- :style {:width (:width size)
- :height (:height size)
- :position "relative"}}
+ [:& interactions/viewport
+ {:frame orig-frame
+ :base-frame orig-frame
+ :frame-offset (gpt/point 0 0)
+ :size orig-size
+ :page page
+ :users users
+ :interactions-mode interactions-mode}]])
- [:& interactions/viewport
- {:frame frame
- :base-frame frame
- :frame-offset (gpt/point 0 0)
- :size size
- :page page
- :interactions-mode interactions-mode}]
+ [:div {:class (stl/css :viewport-container)
+ :ref current-viewport-ref
+ :style {:width (:width size)
+ :height (:height size)
+ :position "relative"}}
- (for [overlay overlays]
- [:& viewer-overlay
- {:overlay overlay
- :key (dm/str (:id overlay))
- :page page
- :frame frame
- :zoom zoom
- :wrapper-size wrapper-size
- :interactions-mode interactions-mode}])]]
+ [:& interactions/viewport
+ {:frame frame
+ :base-frame frame
+ :frame-offset (gpt/point 0 0)
+ :size size
+ :page page
+ :interactions-mode interactions-mode}]
+
+ (for [overlay overlays]
+ [:& viewer-overlay
+ {:overlay overlay
+ :key (dm/str (:id overlay))
+ :page page
+ :frame frame
+ :zoom zoom
+ :wrapper-size wrapper-size
+ :interactions-mode interactions-mode}])]]
- (when (= section :comments)
- [:& comments-layer {:file file
- :users users
- :frame frame
- :page page
- :zoom zoom}])]])
+ (when (= section :comments)
+ [:& comments-layer {:file file
+ :users users
+ :frame frame
+ :page page
+ :zoom zoom}])]]
+
+
+
+ ;; OLD
+ [:*
+ [:& viewer-pagination-and-sidebar
+ {:section section
+ :index index
+ :page page
+ :users users
+ :frame frame
+ :interactions-mode interactions-mode}]
+
+ [:div.viewer-wrapper
+ {:style {:width (:width wrapper-size)
+ :height (:height wrapper-size)}}
+ [:div.viewer-clipper
+ (when orig-frame
+ [:div.viewport-container
+ {:ref orig-viewport-ref
+ :style {:width (:width orig-size)
+ :height (:height orig-size)
+ :position "relative"}}
+
+ [:& interactions/viewport
+ {:frame orig-frame
+ :base-frame orig-frame
+ :frame-offset (gpt/point 0 0)
+ :size orig-size
+ :page page
+ :users users
+ :interactions-mode interactions-mode}]])
+
+ [:div.viewport-container
+ {:ref current-viewport-ref
+ :style {:width (:width size)
+ :height (:height size)
+ :position "relative"}}
+
+ [:& interactions/viewport
+ {:frame frame
+ :base-frame frame
+ :frame-offset (gpt/point 0 0)
+ :size size
+ :page page
+ :interactions-mode interactions-mode}]
+
+ (for [overlay overlays]
+ [:& viewer-overlay
+ {:overlay overlay
+ :key (dm/str (:id overlay))
+ :page page
+ :frame frame
+ :zoom zoom
+ :wrapper-size wrapper-size
+ :interactions-mode interactions-mode}])]]
+
+
+ (when (= section :comments)
+ [:& comments-layer {:file file
+ :users users
+ :frame frame
+ :page page
+ :zoom zoom}])]])))
(mf/defc viewer
[{:keys [params data]}]
@@ -245,6 +340,8 @@
(let [{:keys [page-id share-id section index interactions-mode]} params
{:keys [file users project permissions]} data
+ new-css-system (mf/use-ctx ctx/new-css-system)
+
allowed (or
(= section :interactions)
(and (= section :comments)
@@ -311,7 +408,7 @@
(calculate-wrapper size orig-size zoom))
click-on-screen
- (mf/use-callback
+ (mf/use-fn
(fn [event]
(let [origin (dom/get-target event)
over-section? (dom/class? origin "viewer-section")
@@ -360,9 +457,13 @@
(if shift?
(dom/set-h-scroll-pos! section new-scroll-pos)
(dom/set-scroll-pos! section new-scroll-pos)))))))))
+ on-thumbnails-close
+ (mf/use-fn
+ #(st/emit! dv/close-thumbnails-panel))
+
on-exit-fullscreen
- (mf/use-callback
+ (mf/use-fn
(fn []
(when (not (dom/fullscreen?))
(st/emit! (dv/exit-fullscreen)))))]
@@ -441,7 +542,7 @@
nil)
;; Navigate animation needs to be started after navigation
;; is complete, and we have the next page index.
- (let [nav-animation (d/seek #(= (:kind %) :go-to-frame) (vals current-animations))]
+ (let [nav-animation (d/seek #(= (:kind %) :go-to-frame) (vals current-animations))]
(when nav-animation
(let [orig-viewport (mf/ref-val orig-viewport-ref)
current-viewport (mf/ref-val current-viewport-ref)]
@@ -498,76 +599,153 @@
fonts (into #{} (keep :font-id) text-nodes)]
(run! fonts/ensure-loaded! fonts))))
- [:div#viewer-layout
- {:class (dom/classnames
- :force-visible (:show-thumbnails local)
- :viewer-layout (not= section :inspect)
- :inspect-layout (= section :inspect)
- :fullscreen fullscreen?)}
+ (if new-css-system
+ [:div#viewer-layout
+ {:class (stl/css-case
+ :force-visible (:show-thumbnails local)
+ :viewer-layout (not= section :inspect)
+ :inspect-layout (= section :inspect)
+ :fullscreen fullscreen?)}
- [:div.viewer-content
- [:& header/header {:project project
- :index index
- :file file
- :page page
- :frame frame
- :permissions permissions
- :zoom zoom
- :section section
- :interactions-mode interactions-mode}]
- [:div.thumbnail-close {:on-click #(st/emit! dv/close-thumbnails-panel)
- :class (dom/classnames :invisible (not (:show-thumbnails local false)))}]
- [:& thumbnails-panel {:frames frames
- :show? (:show-thumbnails local false)
- :page page
- :index index
- :thumbnail-data (:thumbnails file)}]
- [:section.viewer-section {:id "viewer-section"
- :ref viewer-section-ref
- :class (if fullscreen? "fullscreen" "")
- :on-click click-on-screen}
- (cond
- (empty? frames)
- [:section.empty-state
- [:span (tr "viewer.empty-state")]]
+ [:div {:class (stl/css :viewer-content)}
+ [:& header/header {:project project
+ :index index
+ :file file
+ :page page
+ :frame frame
+ :permissions permissions
+ :zoom zoom
+ :section section
+ :interactions-mode interactions-mode}]
- (nil? frame)
- [:section.empty-state
- (when (some? index)
- [:span (tr "viewer.frame-not-found")])]
+ [:button {:on-click on-thumbnails-close
+ :class (stl/css-case :thumbnails-close true
+ :invisible (not (:show-thumbnails local false)))}]
- (some? frame)
- (if (= :inspect section)
- [:& inspect/viewport
- {:frame frame
- :page page
- :file file
- :section section
- :local local
- :size size
- :index index
- :viewer-pagination viewer-pagination
- :interactions-mode interactions-mode
- :share-id share-id}]
+ [:& thumbnails-panel {:frames frames
+ :show? (:show-thumbnails local false)
+ :page page
+ :index index
+ :thumbnail-data (:thumbnails file)}]
+
+ [:section {:id "viewer-section"
+ :ref viewer-section-ref
+ :class (stl/css-case :viewer-section true
+ :fulscreen fullscreen?)
+ :on-click click-on-screen}
+ (cond
+ (empty? frames)
+ [:section {:class (stl/css :empty-state)}
+ [:span (tr "viewer.empty-state")]]
+
+ (nil? frame)
+ [:section {:class (stl/css :empty-state)}
+ (when (some? index)
+ [:span (tr "viewer.frame-not-found")])]
+
+ (some? frame)
+ (if (= :inspect section)
+ [:& inspect/viewport
+ {:frame frame
+ :page page
+ :file file
+ :section section
+ :local local
+ :size size
+ :index index
+ :viewer-pagination viewer-pagination
+ :interactions-mode interactions-mode
+ :share-id share-id}]
+
+ [:& (mf/provider ctx/current-zoom) {:value zoom}
+ [:& viewer-wrapper
+ {:wrapper-size wrapper-size
+ :orig-frame orig-frame
+ :orig-viewport-ref orig-viewport-ref
+ :orig-size orig-size
+ :page page
+ :file file
+ :users users
+ :current-viewport-ref current-viewport-ref
+ :size size
+ :frame frame
+ :interactions-mode interactions-mode
+ :overlays overlays
+ :zoom zoom
+ :section section
+ :index index}]]))]]]
+
+ ;; OLD
+ [:div#viewer-layout
+ {:class (dom/classnames
+ :force-visible (:show-thumbnails local)
+ :viewer-layout (not= section :inspect)
+ :inspect-layout (= section :inspect)
+ :fullscreen fullscreen?)}
+
+ [:div.viewer-content
+ [:& header/header {:project project
+ :index index
+ :file file
+ :page page
+ :frame frame
+ :permissions permissions
+ :zoom zoom
+ :section section
+ :interactions-mode interactions-mode}]
+ [:div.thumbnail-close {:on-click on-thumbnails-close
+ :class (dom/classnames :invisible (not (:show-thumbnails local false)))}]
+ [:& thumbnails-panel {:frames frames
+ :show? (:show-thumbnails local false)
+ :page page
+ :index index
+ :thumbnail-data (:thumbnails file)}]
+ [:section.viewer-section {:id "viewer-section"
+ :ref viewer-section-ref
+ :class (if fullscreen? "fullscreen" "")
+ :on-click click-on-screen}
+ (cond
+ (empty? frames)
+ [:section.empty-state
+ [:span (tr "viewer.empty-state")]]
+
+ (nil? frame)
+ [:section.empty-state
+ (when (some? index)
+ [:span (tr "viewer.frame-not-found")])]
+
+ (some? frame)
+ (if (= :inspect section)
+ [:& inspect/viewport
+ {:frame frame
+ :page page
+ :file file
+ :section section
+ :local local
+ :size size
+ :index index
+ :viewer-pagination viewer-pagination
+ :interactions-mode interactions-mode
+ :share-id share-id}]
- [:& (mf/provider ctx/current-zoom) {:value zoom}
- [:& viewer-wrapper
- {:wrapper-size wrapper-size
- :orig-frame orig-frame
- :orig-viewport-ref orig-viewport-ref
- :orig-size orig-size
- :page page
- :file file
- :users users
- :current-viewport-ref current-viewport-ref
- :size size
- :frame frame
- :interactions-mode interactions-mode
- :overlays overlays
- :zoom zoom
- :section section
- :index index}]]))]]]))
+ [:& (mf/provider ctx/current-zoom) {:value zoom}
+ [:& viewer-wrapper
+ {:wrapper-size wrapper-size
+ :orig-frame orig-frame
+ :orig-viewport-ref orig-viewport-ref
+ :orig-size orig-size
+ :page page
+ :file file
+ :users users
+ :current-viewport-ref current-viewport-ref
+ :size size
+ :frame frame
+ :interactions-mode interactions-mode
+ :overlays overlays
+ :zoom zoom
+ :section section
+ :index index}]]))]]])))
;; --- Component: Viewer Page
diff --git a/frontend/src/app/main/ui/viewer.scss b/frontend/src/app/main/ui/viewer.scss
new file mode 100644
index 000000000..7825fe3a4
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer.scss
@@ -0,0 +1,142 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+.viewer-layout {
+ height: 100vh;
+ display: grid;
+ grid-template-rows: $s-48 auto;
+ grid-template-columns: 1fr;
+ user-select: none;
+}
+
+.viewer-content {
+ grid-row: 2 / span 1;
+ display: grid;
+ grid-template-rows: $s-252 auto;
+ grid-template-columns: 1fr;
+ background-color: var(--viewer-background-color);
+}
+
+.viewer-header {
+ grid-row: 1 / span 1;
+}
+
+.inspect-layout {
+ display: grid;
+ grid-template-rows: $s-48 auto;
+ grid-template-columns: 1fr;
+ height: 100vh;
+ margin-top: 0;
+ user-select: none;
+}
+
+.thumbnails-close {
+ @include buttonStyle;
+ grid-row: 1 / span 2;
+ grid-column: 1 / span 1;
+ z-index: $z-index-10;
+ background-color: var(--overlay-color);
+}
+
+.thumbnails-close.invisible {
+ display: none;
+}
+
+.viewer-section {
+ grid-row: 1 / span 2;
+ grid-column: 1 / span 1;
+ display: flex;
+ align-items: center;
+ flex-wrap: nowrap;
+ height: calc(100vh - $s-48);
+ flex-flow: wrap;
+ overflow: auto;
+}
+.inspect-layout .viewer-section {
+ flex-wrap: nowrap;
+ margin-top: 0;
+ height: 100%;
+}
+
+.viewer-go-prev,
+.viewer-go-next {
+ @extend .button-secondary;
+ @include flexCenter;
+ position: absolute;
+ right: $s-8;
+ height: $s-64;
+ width: $s-32;
+ top: calc(50vh - $s-32);
+ z-index: $z-index-2;
+ background-color: var(--viewer-controls-background-color);
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.viewer-go-next.comment-sidebar {
+ right: $s-264;
+}
+
+.viewer-go-prev {
+ left: $s-8;
+ right: unset;
+ svg {
+ transform: rotate(180deg);
+ }
+}
+
+.viewer-bottom {
+ position: fixed;
+ bottom: 0;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ width: 100%;
+ height: $s-40;
+ padding-right: 0 $s-8 $s-40 $s-8;
+ transition: bottom 400ms ease 300ms;
+ z-index: $z-index-2;
+}
+
+.reset-button {
+ @extend .button-secondary;
+ @include flexCenter;
+ height: $s-32;
+ width: $s-28;
+ margin-left: $s-8;
+ background-color: var(--viewer-controls-background-color);
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.counter {
+ @include flexCenter;
+ @include titleTipography;
+ border-radius: $br-8;
+ width: $s-64;
+ height: $s-32;
+ background-color: var(--viewer-controls-background-color);
+}
+
+.viewer-wrapper {
+ position: relative;
+ margin: 0 auto;
+}
+
+.viewer-clipper {
+ display: grid;
+ grid-template-rows: 1fr;
+ grid-template-columns: 1fr;
+ justify-items: center;
+ align-items: center;
+ overflow: hidden;
+}
diff --git a/frontend/src/app/main/ui/viewer/comments.cljs b/frontend/src/app/main/ui/viewer/comments.cljs
index 242da7cba..b9eed98bf 100644
--- a/frontend/src/app/main/ui/viewer/comments.cljs
+++ b/frontend/src/app/main/ui/viewer/comments.cljs
@@ -5,7 +5,9 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.comments
+ (:require-macros [app.main.style :as stl])
(:require
+ [app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.rect :as grc]
@@ -16,6 +18,7 @@
[app.main.store :as st]
[app.main.ui.comments :as cmt]
[app.main.ui.components.dropdown :refer [dropdown]]
+ [app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.workspace.comments :as wc]
[app.util.dom :as dom]
@@ -28,55 +31,126 @@
::mf/wrap-props false}
[]
(let [{cmode :mode cshow :show show-sidebar? :show-sidebar?} (mf/deref refs/comments-local)
-
+ new-css-system (mf/use-ctx ctx/new-css-system)
show-dropdown? (mf/use-state false)
toggle-dropdown (mf/use-fn #(swap! show-dropdown? not))
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
update-mode
(mf/use-callback
- (fn [mode]
- (st/emit! (dcm/update-filters {:mode mode}))))
+ (fn [event]
+ (let [mode (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (keyword))]
+ (st/emit! (dcm/update-filters {:mode mode})))))
update-show
(mf/use-callback
- (fn [mode]
- (st/emit! (dcm/update-filters {:show mode}))))
+ (fn [event]
+ (let [mode (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (d/read-string))]
+ (st/emit! (dcm/update-filters {:show mode})))))
update-options
(mf/use-callback
- (fn [mode]
- (st/emit! (dcm/update-options {:show-sidebar? mode}))))]
+ (fn [event]
+ (let [mode (-> (dom/get-target event)
+ (dom/get-data "value")
+ (boolean))]
+ (st/emit! (dcm/update-options {:show-sidebar? mode})))))]
- [:div.view-options {:on-click toggle-dropdown}
- [:span.label (tr "labels.comments")]
- [:span.icon i/arrow-down]
- [:& dropdown {:show @show-dropdown?
- :on-close hide-dropdown}
+ (if new-css-system
+ [:div {:class (stl/css :view-options)
+ :on-click toggle-dropdown}
+ [:span {:class (stl/css :dropdown-title)}
+ (tr "labels.comments")]
+ [:span {:class (stl/css :icon-dropdown)}
+ i/arrow-refactor]
+ [:& dropdown {:show @show-dropdown?
+ :on-close hide-dropdown}
+ [:ul {:class (stl/css :dropdown)}
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (or (= :all cmode) (nil? cmode)))
+ :data-value :all
+ :on-click update-mode}
- [:ul.dropdown.with-check
- [:li {:class (dom/classnames :selected (or (= :all cmode) (nil? cmode)))
- :on-click #(update-mode :all)}
- [:span.icon i/tick]
- [:span.label (tr "labels.show-all-comments")]]
+ [:span {:class (stl/css :label)} (tr "labels.show-all-comments")]
+ (when (or (= :all cmode) (nil? cmode))
+ [:span {:class (stl/css :icon)} i/tick-refactor])]
- [:li {:class (dom/classnames :selected (= :yours cmode))
- :on-click #(update-mode :yours)}
- [:span.icon i/tick]
- [:span.label (tr "labels.show-your-comments")]]
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= :yours cmode))
+ :data-value :yours
+ :on-click update-mode}
- [:hr]
+ [:span {:class (stl/css :label)}
+ (tr "labels.show-your-comments")]
- [:li {:class (dom/classnames :selected (= :pending cshow))
- :on-click #(update-show (if (= :pending cshow) :all :pending))}
- [:span.icon i/tick]
- [:span.label (tr "labels.hide-resolved-comments")]]
+ (when (= :yours cmode)
+ [:span {:class (stl/css :icon)}
+ i/tick-refactor])]
- [:hr]
- [:li {:class (dom/classnames :selected show-sidebar?)
- :on-click #(update-options (not show-sidebar?))}
- [:span.icon i/tick]
- [:span.label (tr "labels.show-comments-list")]]]]]))
+ [:li {:class (stl/css :separator)}]
+
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= :pending cshow))
+ :data-value (if (= :pending cshow) :all :pending)
+ :on-click update-show}
+
+ [:span {:class (stl/css :label)}
+ (tr "labels.hide-resolved-comments")]
+ (when (= :pending cshow)
+ [:span {:class (stl/css :icon)}
+ i/tick-refactor])]
+
+ [:li {:class (stl/css :separator)}]
+
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected show-sidebar?)
+ :data-value (not show-sidebar?)
+ :on-click update-options}
+
+ [:span {:class (stl/css :label)} (tr "labels.show-comments-list")]
+ (when show-sidebar?
+ [:span {:class (stl/css :icon)} i/tick-refactor])]]]]
+
+
+
+ ; OLD
+ [:div.view-options {:on-click toggle-dropdown}
+ [:span.label (tr "labels.comments")]
+ [:span.icon i/arrow-down]
+ [:& dropdown {:show @show-dropdown?
+ :on-close hide-dropdown}
+
+ [:ul.dropdown.with-check
+ [:li {:class (dom/classnames :selected (or (= :all cmode) (nil? cmode)))
+ :data-value :all
+ :on-click update-mode}
+ [:span.icon i/tick]
+ [:span.label (tr "labels.show-all-comments")]]
+
+ [:li {:class (dom/classnames :selected (= :yours cmode))
+ :data-value :yours
+ :on-click update-mode}
+ [:span.icon i/tick]
+ [:span.label (tr "labels.show-your-comments")]]
+
+ [:hr]
+
+ [:li {:class (dom/classnames :selected (= :pending cshow))
+ :data-value (if (= :pending cshow) :all :pending)
+ :on-click update-show}
+ [:span.icon i/tick]
+ [:span.label (tr "labels.hide-resolved-comments")]]
+
+ [:hr]
+ [:li {:class (dom/classnames :selected show-sidebar?)
+ :data-value (not show-sidebar?)
+ :on-click update-options}
+ [:span.icon i/tick]
+ [:span.label (tr "labels.show-comments-list")]]]]])))
(defn- update-thread-position [positions {:keys [id] :as thread}]
@@ -88,7 +162,8 @@
(mf/defc comments-layer
[{:keys [zoom file users frame page] :as props}]
- (let [profile (mf/deref refs/profile)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ profile (mf/deref refs/profile)
local (mf/deref refs/comments-local)
open-thread-id (:open local)
@@ -159,43 +234,81 @@
(st/emit! (dcm/create-thread-on-viewer params)
(dcm/close-thread)))))]
- [:div.comments-section {:on-click on-click}
- [:div.viewer-comments-container
- [:div.threads
- (for [item threads]
- [:& cmt/thread-bubble
- {:thread item
- :position-modifier modifier1
- :zoom zoom
- :on-click on-bubble-click
- :open? (= (:id item) (:open local))
- :key (:seqn item)
- :origin :viewer}])
+ (if new-css-system
+ [:div {:class (stl/css :comments-section)
+ :on-click on-click}
+ [:div {:class (stl/css :viewer-comments-container)}
+ [:div {:class (stl/css :threads)}
+ (for [item threads]
+ [:& cmt/thread-bubble
+ {:thread item
+ :position-modifier modifier1
+ :zoom zoom
+ :on-click on-bubble-click
+ :open? (= (:id item) (:open local))
+ :key (:seqn item)
+ :origin :viewer}])
- (when-let [thread (get threads-map open-thread-id)]
- [:& cmt/thread-comments
- {:thread thread
- :position-modifier modifier1
- :users users
- :zoom zoom}])
+ (when-let [thread (get threads-map open-thread-id)]
+ [:& cmt/thread-comments
+ {:thread thread
+ :position-modifier modifier1
+ :users users
+ :zoom zoom}])
- (when-let [draft (:draft local)]
- [:& cmt/draft-thread
- {:draft draft
- :position-modifier modifier1
- :on-cancel on-draft-cancel
- :on-submit on-draft-submit
- :zoom zoom}])]]]))
+ (when-let [draft (:draft local)]
+ [:& cmt/draft-thread
+ {:draft draft
+ :position-modifier modifier1
+ :on-cancel on-draft-cancel
+ :on-submit on-draft-submit
+ :zoom zoom}])]]]
+
+
+ [:div.comments-section {:on-click on-click}
+ [:div.viewer-comments-container
+ [:div.threads
+ (for [item threads]
+ [:& cmt/thread-bubble
+ {:thread item
+ :position-modifier modifier1
+ :zoom zoom
+ :on-click on-bubble-click
+ :open? (= (:id item) (:open local))
+ :key (:seqn item)
+ :origin :viewer}])
+
+ (when-let [thread (get threads-map open-thread-id)]
+ [:& cmt/thread-comments
+ {:thread thread
+ :position-modifier modifier1
+ :users users
+ :zoom zoom}])
+
+ (when-let [draft (:draft local)]
+ [:& cmt/draft-thread
+ {:draft draft
+ :position-modifier modifier1
+ :on-cancel on-draft-cancel
+ :on-submit on-draft-submit
+ :zoom zoom}])]]])))
(mf/defc comments-sidebar
[{:keys [users frame page]}]
- (let [profile (mf/deref refs/profile)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ profile (mf/deref refs/profile)
local (mf/deref refs/comments-local)
threads-map (mf/deref refs/comment-threads)
threads (->> (vals threads-map)
(dcm/apply-filters local profile)
(filter (fn [{:keys [position]}]
(gsh/has-point? frame position))))]
- [:aside.settings-bar.settings-bar-right.comments-right-sidebar
- [:div.settings-bar-inside
- [:& wc/comments-sidebar {:users users :threads threads :page-id (:id page)}]]]))
+ (if new-css-system
+ [:aside {:class (stl/css :comments-sidebar)}
+ [:div {:class (stl/css :settings-bar-inside)}
+ [:& wc/comments-sidebar {:from-viewer true :users users :threads threads :page-id (:id page)}]]]
+
+
+ [:aside.settings-bar.settings-bar-right.comments-right-sidebar
+ [:div.settings-bar-inside
+ [:& wc/comments-sidebar {:users users :threads threads :page-id (:id page)}]]])))
diff --git a/frontend/src/app/main/ui/viewer/comments.scss b/frontend/src/app/main/ui/viewer/comments.scss
new file mode 100644
index 000000000..7dbbfcc83
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/comments.scss
@@ -0,0 +1,119 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+// COMMENT DROPDOWN ON HEADER
+.view-options {
+ @include titleTipography;
+ display: flex;
+ align-items: center;
+ position: relative;
+ gap: $s-4;
+ height: $s-32;
+ padding: $s-8;
+ border-radius: $br-8;
+ background-color: var(--input-background-color);
+ cursor: pointer;
+}
+
+.dropdown {
+ @extend .menu-dropdown;
+ right: $s-2;
+ top: calc($s-2 + $s-48);
+ width: $s-272;
+ padding: $s-6;
+}
+
+.dropdown-title {
+ @include titleTipography;
+ flex-grow: 1;
+ color: var(--input-foreground-color-active);
+}
+
+.label {
+ flex-grow: 1;
+ color: var(--input-foreground-color);
+}
+
+.icon,
+.icon-dropdown {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.icon-dropdown svg {
+ transform: rotate(90deg);
+}
+
+.dropdown-element {
+ @extend .dropdown-element-base;
+ .icon {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+ }
+ &:hover .label {
+ color: var(--input-foreground-color-active);
+ }
+}
+
+.dropdown-element.selected {
+ .label {
+ color: var(--input-foreground-color-active);
+ }
+ .icon svg {
+ stroke: var(--input-foreground-color);
+ }
+}
+
+.separator {
+ height: $s-8;
+}
+
+// FLOATING COMMENT
+.viewer-comments-container {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ z-index: $z-index-1;
+}
+
+.threads {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+}
+
+//COMMENT SIDEBAR
+.comments-sidebar {
+ position: absolute;
+ right: 0;
+ top: $s-44;
+ width: $s-256;
+ height: calc(100vh - $s-48);
+ z-index: $z-index-10;
+ background-color: var(--panel-background-color);
+}
+
+.settings-bar-inside {
+ overflow-y: auto;
+}
+
+.comments-section {
+ background-color: var(--panel-background-color);
+}
diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs
index 156e21d95..83bf05914 100644
--- a/frontend/src/app/main/ui/viewer/header.cljs
+++ b/frontend/src/app/main/ui/viewer/header.cljs
@@ -5,13 +5,16 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.header
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.data.modal :as modal]
+ [app.main.data.shortcuts :as scd]
[app.main.data.viewer :as dv]
[app.main.data.viewer.shortcuts :as sc]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
+ [app.main.ui.context :as ctx]
[app.main.ui.export :refer [export-progress-widget]]
[app.main.ui.formats :as fmt]
[app.main.ui.icons :as i]
@@ -41,40 +44,120 @@
on-zoom-fit
on-zoom-fill]
:as props}]
- (let [show-dropdown? (mf/use-state false)]
- [:div.zoom-widget {:on-click
- (fn [event]
- (dom/stop-propagation event)
- (reset! show-dropdown? true))}
- [:span.label (fmt/format-percent zoom)]
- [:span.icon i/arrow-down]
- [:& dropdown {:show @show-dropdown?
- :on-close #(reset! show-dropdown? false)}
- [:ul.dropdown
- [:li.basic-zoom-bar
- [:span.zoom-btns
- [:button {:on-click (fn [event]
- (dom/stop-propagation event)
- (dom/prevent-default event)
- (on-decrease))} "-"]
- [:p.zoom-size (fmt/format-percent zoom)]
- [:button {:on-click (fn [event]
- (dom/stop-propagation event)
- (dom/prevent-default event)
- (on-increase))} "+"]]
- [:button.reset-btn {:on-click on-zoom-reset} (tr "workspace.header.reset-zoom")]]
- [:li.separator]
- [:li {:on-click on-zoom-fit}
- (tr "workspace.header.zoom-fit") [:span (sc/get-tooltip :toggle-zoom-style)]]
- [:li {:on-click on-zoom-fill}
- (tr "workspace.header.zoom-fill") [:span (sc/get-tooltip :toggle-zoom-style)]]
- [:li {:on-click on-fullscreen}
- (tr "workspace.header.zoom-full-screen") [:span (sc/get-tooltip :toggle-fullscreen)]]]]]))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ open* (mf/use-state false)
+ open? (deref open*)
+ open-dropdown
+ (mf/use-fn
+ (fn [event]
+ (dom/stop-propagation event)
+ (reset! open* true)))
+
+ close-dropdown
+ (mf/use-fn
+ (fn [event]
+ (dom/stop-propagation event)
+ (reset! open* false)))
+
+ on-increase
+ (mf/use-fn
+ (mf/deps on-increase)
+ (fn [event]
+ (dom/stop-propagation event)
+ (on-increase)))
+
+ on-decrease
+ (mf/use-fn
+ (mf/deps on-decrease)
+ (fn [event]
+ (dom/stop-propagation event)
+ (on-decrease)))
+
+ show-dropdown? (mf/use-state false)]
+
+ (if new-css-system
+ [:div {:class (stl/css-case :zoom-widget true
+ :selected open?)
+ :on-click open-dropdown
+ :title (tr "workspace.header.zoom")}
+ [:span {:class (stl/css :label)} (fmt/format-percent zoom)]
+ [:& dropdown {:show open?
+ :on-close close-dropdown}
+ [:ul {:class (stl/css :dropdown)}
+ [:li {:class (stl/css :basic-zoom-bar)}
+ [:span {:class (stl/css :zoom-btns)}
+ [:button {:class (stl/css :zoom-btn)
+ :on-click on-decrease}
+ [:span {:class (stl/css :zoom-icon)}
+ i/remove-refactor]]
+ [:p {:class (stl/css :zoom-text)}
+ (fmt/format-percent zoom)]
+ [:button {:class (stl/css :zoom-btn)
+ :on-click on-increase}
+ [:span {:class (stl/css :zoom-icon)}
+ i/add-refactor]]]
+ [:button {:class (stl/css :reset-btn)
+ :on-click on-zoom-reset}
+ (tr "workspace.header.reset-zoom")]]
+
+ [:li {:class (stl/css :zoom-option)
+ :on-click on-zoom-fit}
+ (tr "workspace.header.zoom-fit")
+ [:span {:class (stl/css :shortcuts)}
+ (for [sc (scd/split-sc (sc/get-tooltip :toggle-zoom-style))]
+ [:span {:class (stl/css :shortcut-key)
+ :key (str "zoom-fit-" sc)} sc])]]
+ [:li {:class (stl/css :zoom-option)
+ :on-click on-zoom-fill}
+ (tr "workspace.header.zoom-fill")
+ [:span {:class (stl/css :shortcuts)}
+ (for [sc (scd/split-sc (sc/get-tooltip :toggle-zoom-style))]
+ [:span {:class (stl/css :shortcut-key)
+ :key (str "zoom-fill-" sc)} sc])]]
+ [:li {:class (stl/css :zoom-option)
+ :on-click on-fullscreen}
+ (tr "workspace.header.zoom-full-screen")
+ [:span {:class (stl/css :shortcuts)}
+ (for [sc (scd/split-sc (sc/get-tooltip :toggle-fullscreen))]
+ [:span {:class (stl/css :shortcut-key)
+ :key (str "zoom-fullscreen-" sc)} sc])]]]]]
+
+
+ ;; OLD
+ [:div.zoom-widget {:on-click
+ (fn [event]
+ (dom/stop-propagation event)
+ (reset! show-dropdown? true))}
+ [:span.label (fmt/format-percent zoom)]
+ [:span.icon i/arrow-down]
+ [:& dropdown {:show @show-dropdown?
+ :on-close #(reset! show-dropdown? false)}
+ [:ul.dropdown
+ [:li.basic-zoom-bar
+ [:span.zoom-btns
+ [:button {:on-click (fn [event]
+ (dom/stop-propagation event)
+ (dom/prevent-default event)
+ (on-decrease))} "-"]
+ [:p.zoom-size (fmt/format-percent zoom)]
+ [:button {:on-click (fn [event]
+ (dom/stop-propagation event)
+ (dom/prevent-default event)
+ (on-increase))} "+"]]
+ [:button.reset-btn {:on-click on-zoom-reset} (tr "workspace.header.reset-zoom")]]
+ [:li.separator]
+ [:li {:on-click on-zoom-fit}
+ (tr "workspace.header.zoom-fit") [:span (sc/get-tooltip :toggle-zoom-style)]]
+ [:li {:on-click on-zoom-fill}
+ (tr "workspace.header.zoom-fill") [:span (sc/get-tooltip :toggle-zoom-style)]]
+ [:li {:on-click on-fullscreen}
+ (tr "workspace.header.zoom-full-screen") [:span (sc/get-tooltip :toggle-fullscreen)]]]]])))
(mf/defc header-options
[{:keys [section zoom page file index permissions interactions-mode]}]
- (let [fullscreen? (mf/deref fullscreen-ref)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ fullscreen? (mf/deref fullscreen-ref)
toggle-fullscreen
(mf/use-callback
@@ -91,49 +174,114 @@
(mf/deps page)
(fn []
(modal/show! :share-link {:page page :file file})
- (modal/allow-click-outside!)))]
+ (modal/allow-click-outside!)))
- [:div.options-zone
- (case section
- :interactions [:*
- (when index
- [:& flows-menu {:page page :index index}])
- [:& interactions-menu {:interactions-mode interactions-mode}]]
- :comments [:& comments-menu]
+ handle-increase
+ (mf/use-fn
+ #(st/emit! dv/increase-zoom))
- [:div.view-options])
+ handle-decrease
+ (mf/use-fn
+ #(st/emit! dv/decrease-zoom))
- [:& export-progress-widget]
- [:& zoom-widget
- {:zoom zoom
- :on-increase #(st/emit! dv/increase-zoom)
- :on-decrease #(st/emit! dv/decrease-zoom)
- :on-zoom-reset #(st/emit! dv/reset-zoom)
- :on-zoom-fill #(st/emit! dv/zoom-to-fill)
- :on-zoom-fit #(st/emit! dv/zoom-to-fit)
- :on-fullscreen toggle-fullscreen}]
+ handle-zoom-reset
+ (mf/use-fn
+ #(st/emit! dv/reset-zoom))
- [:span.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left
- {:alt (tr "viewer.header.fullscreen")
- :on-click toggle-fullscreen}
- (if fullscreen?
- i/full-screen-off
- i/full-screen)]
+ handle-zoom-fill
+ (mf/use-fn
+ #(st/emit! dv/zoom-to-fill))
- (when (:is-admin permissions)
- [:span.btn-primary.tooltip.tooltip-bottom-left {:on-click open-share-dialog :alt (tr "labels.share-prototype")} i/export [:span (tr "labels.share-prototype")]])
+ handle-zoom-fit
+ (mf/use-fn
+ #(st/emit! dv/zoom-to-fit))]
- (when (:can-edit permissions)
- [:span.btn-text-dark {:on-click go-to-workspace} (tr "labels.edit-file")])
+ (if new-css-system
+ [:div {:class (stl/css :options-zone)}
+ (case section
+ :interactions [:*
+ (when index
+ [:& flows-menu {:page page :index index}])
+ [:& interactions-menu {:interactions-mode interactions-mode}]]
+ :comments [:& comments-menu]
+ [:div {:class (stl/css :view-options)}])
- (when-not (:is-logged permissions)
- [:span.btn-text-dark {:on-click open-login-dialog} (tr "labels.log-or-sign")])]))
+ [:& export-progress-widget]
+
+ [:& zoom-widget
+ {:zoom zoom
+ :on-increase handle-increase
+ :on-decrease handle-decrease
+ :on-zoom-reset handle-zoom-reset
+ :on-zoom-fill handle-zoom-fill
+ :on-zoom-fit handle-zoom-fit
+ :on-fullscreen toggle-fullscreen}]
+
+ (when (:can-edit permissions)
+ [:span {:on-click go-to-workspace
+ :class (stl/css :edit-btn)}
+ i/curve-refactor])
+
+ [:span {:title (tr "viewer.header.fullscreen")
+ :class (stl/css-case :fullscreen-btn true
+ :selected fullscreen?)
+ :on-click toggle-fullscreen}
+ i/expand-refactor]
+
+ (when (:is-admin permissions)
+ [:button {:on-click open-share-dialog
+ :class (stl/css :share-btn)}
+ (tr "labels.share")])
+
+ (when-not (:is-logged permissions)
+ [:span {:on-click open-login-dialog
+ :class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])]
+
+
+ ;; OLD
+ [:div.options-zone
+ (case section
+ :interactions [:*
+ (when index
+ [:& flows-menu {:page page :index index}])
+ [:& interactions-menu {:interactions-mode interactions-mode}]]
+ :comments [:& comments-menu]
+
+ [:div.view-options])
+
+ [:& export-progress-widget]
+ [:& zoom-widget
+ {:zoom zoom
+ :on-increase handle-increase
+ :on-decrease handle-decrease
+ :on-zoom-reset handle-zoom-reset
+ :on-zoom-fill handle-zoom-fill
+ :on-zoom-fit handle-zoom-fit
+ :on-fullscreen toggle-fullscreen}]
+
+ [:span.btn-icon-dark.btn-small.tooltip.tooltip-bottom-left
+ {:alt (tr "viewer.header.fullscreen")
+ :on-click toggle-fullscreen}
+ (if fullscreen?
+ i/full-screen-off
+ i/full-screen)]
+
+ (when (:is-admin permissions)
+ [:span.btn-primary.tooltip.tooltip-bottom-left {:on-click open-share-dialog :alt (tr "labels.share-prototype")} i/export [:span (tr "labels.share-prototype")]])
+
+ (when (:can-edit permissions)
+ [:span.btn-text-dark {:on-click go-to-workspace} (tr "labels.edit-file")])
+
+ (when-not (:is-logged permissions)
+ [:span.btn-text-dark {:on-click open-login-dialog} (tr "labels.log-or-sign")])])))
(mf/defc header-sitemap
[{:keys [project file page frame] :as props}]
- (let [project-name (:name project)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ project-name (:name project)
file-name (:name file)
page-name (:name page)
+ page-id (:id page)
frame-name (:name frame)
show-dropdown? (mf/use-state false)
@@ -158,88 +306,181 @@
(st/emit! (dv/go-to-page page-id))
(reset! show-dropdown? false)))]
- [:div.sitemap-zone {:alt (tr "viewer.header.sitemap")}
- [:div.breadcrumb
- {:on-click open-dropdown}
- [:span.project-name project-name]
- [:span "/"]
- [:span.file-name file-name]
- [:span "/"]
-
- [:span.page-name page-name]
+ (if new-css-system
+ [:div {:class (stl/css :sitemap-zone)
+ :title (tr "viewer.header.sitemap")}
+ [:span {:class (stl/css :project-name)} project-name]
+ [:div {:class (stl/css :sitemap-text)}
+ [:div {:class (stl/css :breadcrumb)
+ :on-click open-dropdown}
+ [:span {:class (stl/css :breadcrumb-text)}
+ (dm/str file-name " / " page-name)]
+ [:span {:class (stl/css :icon)} i/arrow-refactor]
+ [:span "/"]
+ [:& dropdown {:show @show-dropdown?
+ :on-close close-dropdown}
+ [:ul {:class (stl/css :dropdown-sitemap)}
+ (for [id (get-in file [:data :pages])]
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= page-id id))
+ :id (str id)
+ :key (str id)
+ :on-click (partial navigate-to id)}
+ [:span {:class (stl/css :label)}
+ (get-in file [:data :pages-index id :name])]
+ (when (= page-id id)
+ [:span {:class (stl/css :icon-check)} i/tick-refactor])])]]]
+ [:div {:class (stl/css :current-frame)
+ :on-click toggle-thumbnails}
+ [:span {:class (stl/css :frame-name)} frame-name]
+ [:span {:class (stl/css :icon)} i/arrow-refactor]]]]
- [:& dropdown {:show @show-dropdown?
- :on-close close-dropdown}
- [:ul.dropdown
- (for [id (get-in file [:data :pages])]
- [:li {:id (str id)
- :key (str id)
- :on-click (partial navigate-to id)}
- (get-in file [:data :pages-index id :name])])]]]
+ ;; OLD
+ [:div.sitemap-zone {:alt (tr "viewer.header.sitemap")}
+ [:div.breadcrumb
+ {:on-click open-dropdown}
+ [:span.project-name project-name]
+ [:span "/"]
+ [:span.file-name file-name]
+ [:span "/"]
- [:span.icon {:on-click open-dropdown} i/arrow-down]
- [:div.current-frame
- {:on-click toggle-thumbnails}
- [:span.label "/"]
- [:span.label frame-name]]
- [:span.icon {:on-click toggle-thumbnails} i/arrow-down]]))
+ [:span.page-name page-name]
+ [:& dropdown {:show @show-dropdown?
+ :on-close close-dropdown}
+ [:ul.dropdown
+ (for [id (get-in file [:data :pages])]
+ [:li {:id (str id)
+ :key (str id)
+ :on-click (partial navigate-to id)}
+ (get-in file [:data :pages-index id :name])])]]]
+ [:span.icon {:on-click open-dropdown} i/arrow-down]
+ [:div.current-frame
+ {:on-click toggle-thumbnails}
+ [:span.label "/"]
+ [:span.label frame-name]]
+ [:span.icon {:on-click toggle-thumbnails} i/arrow-down]])))
(mf/defc header
[{:keys [project file page frame zoom section permissions index interactions-mode]}]
- (let [go-to-dashboard
- #(st/emit! (dv/go-to-dashboard))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ go-to-dashboard
+ (mf/use-fn
+ #(st/emit! (dv/go-to-dashboard)))
go-to-inspect
- (fn[]
- (if (:is-logged permissions)
- (st/emit! dv/close-thumbnails-panel (dv/go-to-section :inspect))
- (open-login-dialog)))
+ (mf/use-fn
+ (mf/deps permissions)
+ (fn []
+ (if (:is-logged permissions)
+ (st/emit! dv/close-thumbnails-panel (dv/go-to-section :inspect))
+ (open-login-dialog))))
navigate
- (fn [section]
- (if (or (= section :interactions) (:is-logged permissions))
- (st/emit! (dv/go-to-section section))
- (open-login-dialog)))]
+ (mf/use-fn
+ (mf/deps permissions)
+ (fn [event]
+ (let [section (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (keyword))]
- [:header.viewer-header
- [:div.nav-zone
- ;; If the user doesn't have permission we disable the link
- [:div.main-icon {:style {:cursor (when-not (:can-edit permissions) "auto")}}
- [:a {:on-click go-to-dashboard
- :style {:pointer-events (when-not (:can-edit permissions) "none")}} i/logo-icon]]
+ (if (or (= section :interactions) (:is-logged permissions))
+ (st/emit! (dv/go-to-section section))
+ (open-login-dialog)))))]
- [:& header-sitemap {:project project :file file :page page :frame frame :index index}]]
+ (if new-css-system
+ [:header {:class (stl/css :viewer-header)}
+ [:div {:class (stl/css :nav-zone)}
+ ;; If the user doesn't have permission we disable the link
+ [:a {:class (stl/css :home-link)
+ :on-click go-to-dashboard
+ :style {:cursor (when-not (:can-edit permissions) "auto")
+ :pointer-events (when-not (:can-edit permissions) "none")}}
+ [:span {:class (stl/css :logo-icon)}
+ i/logo-icon]]
- [:div.mode-zone
- [:button.mode-zone-button.tooltip.tooltip-bottom
- {:on-click #(navigate :interactions)
- :class (dom/classnames :active (= section :interactions))
- :alt (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
- i/play]
+ [:& header-sitemap {:project project
+ :file file
+ :page page
+ :frame frame
+ :index index}]]
- (when (or (:can-edit permissions)
- (= (:who-comment permissions) "all"))
+ [:div {:class (stl/css :mode-zone)}
+ [:button {:on-click navigate
+ :data-value :interactions
+ :class (stl/css-case :mode-zone-btn true
+ :selected (= section :interactions))
+ :title (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
+ i/play-refactor]
+
+ (when (or (:can-edit permissions)
+ (= (:who-comment permissions) "all"))
+ [:button {:on-click navigate
+ :data-value :comments
+ :class (stl/css-case :mode-zone-btn true
+ :selected (= section :comments))
+ :title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
+ i/comments-refactor])
+
+ (when (or (= (:type permissions) :membership)
+ (and (= (:type permissions) :share-link)
+ (= (:who-inspect permissions) "all")))
+ [:button {:on-click go-to-inspect
+ :class (stl/css-case :mode-zone-btn true
+ :selected (= section :inspect))
+ :title (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
+ i/code-refactor])]
+
+ [:& header-options {:section section
+ :permissions permissions
+ :page page
+ :file file
+ :index index
+ :zoom zoom
+ :interactions-mode interactions-mode}]]
+
+
+ ;; OLD
+ [:header.viewer-header
+ [:div.nav-zone
+ ;; If the user doesn't have permission we disable the link
+ [:div.main-icon {:style {:cursor (when-not (:can-edit permissions) "auto")}}
+ [:a {:on-click go-to-dashboard
+ :style {:pointer-events (when-not (:can-edit permissions) "none")}} i/logo-icon]]
+
+ [:& header-sitemap {:project project :file file :page page :frame frame :index index}]]
+
+ [:div.mode-zone
[:button.mode-zone-button.tooltip.tooltip-bottom
- {:on-click #(navigate :comments)
- :class (dom/classnames :active (= section :comments))
- :alt (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
- i/chat])
+ {:on-click navigate
+ :data-value :interactions
+ :class (dom/classnames :active (= section :interactions))
+ :alt (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
+ i/play]
- (when (or (= (:type permissions) :membership)
- (and (= (:type permissions) :share-link)
- (= (:who-inspect permissions) "all")))
- [:button.mode-zone-button.tooltip.tooltip-bottom
- {:on-click go-to-inspect
- :class (dom/classnames :active (= section :inspect))
- :alt (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
- i/code])]
+ (when (or (:can-edit permissions)
+ (= (:who-comment permissions) "all"))
+ [:button.mode-zone-button.tooltip.tooltip-bottom
+ {:on-click navigate
+ :data-value :comments
+ :class (dom/classnames :active (= section :comments))
+ :alt (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
+ i/chat])
- [:& header-options {:section section
- :permissions permissions
- :page page
- :file file
- :index index
- :zoom zoom
- :interactions-mode interactions-mode}]]))
+ (when (or (= (:type permissions) :membership)
+ (and (= (:type permissions) :share-link)
+ (= (:who-inspect permissions) "all")))
+ [:button.mode-zone-button.tooltip.tooltip-bottom
+ {:on-click go-to-inspect
+ :class (dom/classnames :active (= section :inspect))
+ :alt (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
+ i/code])]
+
+ [:& header-options {:section section
+ :permissions permissions
+ :page page
+ :file file
+ :index index
+ :zoom zoom
+ :interactions-mode interactions-mode}]])))
diff --git a/frontend/src/app/main/ui/viewer/header.scss b/frontend/src/app/main/ui/viewer/header.scss
new file mode 100644
index 000000000..a0dde598d
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/header.scss
@@ -0,0 +1,301 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+.viewer-header {
+ position: absolute;
+ top: 0;
+ grid-column: 1 / span 1;
+ grid-row: 1 / span 1;
+ display: grid;
+ grid-template-columns: 1fr $s-92 1fr;
+ justify-content: space-between;
+ align-items: center;
+ height: $s-48;
+ width: 100vw;
+ padding: $s-8 $s-12;
+ background-color: var(--panel-background-color);
+}
+
+// FILE NAVIGATION
+
+.nav-zone {
+ display: flex;
+ justify-content: flex-start;
+ flex-basis: min-content;
+ width: 100%;
+ gap: $s-12;
+}
+
+.home-link {
+ padding: 0;
+}
+
+.logo-icon {
+ @include flexCenter;
+ width: $s-32;
+ height: $s-32;
+ svg {
+ width: $s-28;
+ fill: var(--icon-foreground-hover);
+ }
+}
+
+.sitemap-zone {
+ @include flexColumn;
+ position: relative;
+ width: 100%;
+}
+
+.project-name {
+ @include tabTitleTipography;
+}
+
+.sitemap-text {
+ @include flexRow;
+}
+
+.breadcrumb {
+ @include titleTipography;
+ @include flexRow;
+ color: var(--title-foreground-color);
+ cursor: pointer;
+}
+
+.breadcrumb-text {
+ @include textEllipsis;
+ max-width: 12vw; // This is a fallback
+ max-width: 12cqw; // This is a unit refered to container
+}
+
+.icon {
+ @include flexCenter;
+ height: $s-16;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ transform: rotate(90deg);
+ stroke: var(--icon-foreground);
+ }
+}
+
+.dropdown {
+ position: absolute;
+}
+
+.dropdown-sitemap {
+ @extend .menu-dropdown;
+ left: 0;
+ top: calc($s-2 + $s-48);
+ width: $s-272;
+ padding: $s-6;
+}
+
+.dropdown-element {
+ @extend .dropdown-element-base;
+ .icon-check {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+ }
+ &:hover .label {
+ color: var(--input-foreground-color-active);
+ }
+}
+
+.current-frame {
+ @include titleTipography;
+ @include flexRow;
+ flex-grow: 1;
+ color: var(--title-foreground-color-hover);
+ cursor: pointer;
+ .icon svg {
+ stroke: var(--title-foreground-color-hover);
+ }
+}
+
+.frame-name {
+ @include textEllipsis;
+ max-width: 17vw; // This is a fallback
+ max-width: 17cqw; // This is a unit refered to container
+}
+
+// SECTION BUTTONS
+.mode-zone {
+ @include flexRow;
+ height: 100%;
+}
+
+.mode-zone-btn {
+ @extend .button-tertiary;
+ @include flexCenter;
+ height: $s-32;
+ width: $s-28;
+ padding: 0;
+ svg {
+ @extend .button-icon;
+ }
+}
+
+.selected {
+ @extend .button-icon-selected;
+}
+
+// OPTION AREA
+.options-zone {
+ @include flexRow;
+ position: relative;
+ justify-content: flex-end;
+ gap: $s-8;
+ z-index: $z-index-10;
+}
+
+.view-options {
+ position: relative;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+}
+
+.fullscreen-btn {
+ @extend .button-tertiary;
+ @include flexCenter;
+ height: $s-32;
+ width: $s-28;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.share-btn {
+ @extend .button-primary;
+ height: $s-32;
+ min-width: $s-72;
+ margin-left: $s-4;
+}
+
+.edit-btn {
+ @extend .button-tertiary;
+ @include flexCenter;
+ height: $s-32;
+ width: $s-28;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.go-log-btn {
+ @extend .button-tertiary;
+ @include titleTipography;
+ height: $s-32;
+ padding: 0 $s-8;
+ border-radius: $br-8;
+ color: var(--button-tertiary-foreground-color-rest);
+}
+
+// ZOOM WIDGET
+.zoom-widget {
+ @include buttonStyle;
+ @include flexCenter;
+ height: $s-28;
+ min-width: $s-64;
+ border-radius: $br-8;
+ .label {
+ @include titleTipography;
+ color: var(--button-tertiary-foreground-color-rest);
+ }
+
+ &:hover {
+ .label {
+ color: var(--button-tertiary-foreground-color-focus);
+ }
+ }
+ &.selected {
+ .label {
+ color: var(--button-tertiary-foreground-color-focus);
+ }
+ }
+}
+
+.dropdown {
+ @extend .menu-dropdown;
+ right: $s-2;
+ top: calc($s-2 + $s-48);
+ width: $s-272;
+}
+
+.basic-zoom-bar {
+ display: flex;
+ justify-content: space-between;
+ padding: $s-6;
+ cursor: auto;
+}
+
+.zoom-btns {
+ display: flex;
+}
+
+.zoom-btn {
+ @extend .button-tertiary;
+ height: $s-28;
+ width: $s-28;
+ border-radius: $br-8;
+ .zoom-icon {
+ @include flexCenter;
+ width: $s-24;
+ height: $s-32;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+ }
+ &:hover {
+ .zoom-icon svg {
+ stroke: var(--button-tertiary-foreground-color-hover);
+ }
+ }
+}
+
+.zoom-text {
+ @include flexCenter;
+ height: 100%;
+ min-width: $s-64;
+ padding: 0;
+ margin: 0 $s-2;
+ color: var(--modal-title-foreground-color);
+}
+
+.reset-btn {
+ @extend .button-tertiary;
+ color: var(--button-tertiary-foreground-color-hover);
+ height: $s-28;
+ border-radius: $br-8;
+}
+
+.zoom-option {
+ @extend .menu-item;
+ .shortcuts {
+ @extend .shortcut;
+ .shortcut-key {
+ @extend .shortcut-key;
+ }
+ }
+ &:hover {
+ color: var(--menu-foreground-color-hover);
+ .shortcuts {
+ .shortcut-key {
+ color: var(--menu-foreground-color-hover);
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/main/ui/viewer/inspect.cljs b/frontend/src/app/main/ui/viewer/inspect.cljs
index 576cbe06b..9624d480d 100644
--- a/frontend/src/app/main/ui/viewer/inspect.cljs
+++ b/frontend/src/app/main/ui/viewer/inspect.cljs
@@ -5,10 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.inspect
+ (:require-macros [app.main.style :as stl])
(:require
+ [app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.data.viewer :as dv]
[app.main.store :as st]
+ [app.main.ui.context :as ctx]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.viewer.inspect.left-sidebar :refer [left-sidebar]]
[app.main.ui.viewer.inspect.render :refer [render-frame-svg]]
@@ -20,25 +23,27 @@
(:import goog.events.EventType))
(defn handle-select-frame
- [frame]
- (fn [event]
+ [event]
+ (let [frame-id (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (d/read-string))
+ origin (dom/get-target event)
+ over-section? (dom/class? origin "inspect-svg-container")
+ layout (dom/get-element "viewer-layout")
+ has-force? (dom/class? layout "force-visible")]
+
(dom/prevent-default event)
(dom/stop-propagation event)
- (st/emit! (dv/select-shape (:id frame)))
-
- (let [origin (dom/get-target event)
- over-section? (dom/class? origin "inspect-svg-container")
- layout (dom/get-element "viewer-layout")
- has-force? (dom/class? layout "force-visible")]
-
- (when over-section?
- (if has-force?
- (dom/remove-class! layout "force-visible")
- (dom/add-class! layout "force-visible"))))))
+ (st/emit! (dv/select-shape frame-id))
+ (when over-section?
+ (if has-force?
+ (dom/remove-class! layout "force-visible")
+ (dom/add-class! layout "force-visible")))))
(mf/defc viewport
[{:keys [local file page frame index viewer-pagination size share-id]}]
- (let [inspect-svg-container-ref (mf/use-ref nil)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ inspect-svg-container-ref (mf/use-ref nil)
current-section* (mf/use-state :info)
current-section (deref current-section*)
@@ -77,7 +82,8 @@
handle-expand
(mf/use-callback
(mf/deps right-size)
- #(set-right-size (if (> right-size 276) 276 768)))]
+ (fn[]
+ (set-right-size (if (> right-size 276) 276 768))))]
(mf/use-effect on-mount)
@@ -86,26 +92,60 @@
(fn []
(st/emit! (dv/select-shape (:id frame)))))
- [:*
- [:& left-sidebar {:frame frame
- :local local
- :page page}]
- [:div.inspect-svg-wrapper {:on-click (handle-select-frame frame)}
- [:& viewer-pagination {:index index :num-frames (count (:frames page)) :left-bar true :right-bar true}]
- [:div.inspect-svg-container {:ref inspect-svg-container-ref}
- [:& render-frame-svg {:frame frame :page page :local local :size size}]]]
+ (if new-css-system
+ [:*
+ [:& left-sidebar {:frame frame
+ :local local
+ :page page}]
+ [:div {:class (stl/css :inspect-svg-wrapper)
+ :data-value (pr-str (:id frame))
+ :on-click handle-select-frame}
+ [:& viewer-pagination {:index index :num-frames (count (:frames page)) :left-bar true :right-bar true}]
+ [:div {:class (stl/css :inspect-svg-container)
+ :ref inspect-svg-container-ref}
+ [:& render-frame-svg {:frame frame :page page :local local :size size}]]]
- [:div.sidebar-container
- {:class (when (not can-be-expanded?) "not-expand")
- :style #js {"--width" (when can-be-expanded? (dm/str right-size "px"))}}
- [:div.resize-area
- {:on-pointer-down on-pointer-down
- :on-lost-pointer-capture on-lost-pointer-capture
- :on-pointer-move on-pointer-move}]
- [:& right-sidebar {:frame frame
- :selected (:selected local)
- :page page
- :file file
- :on-change-section handle-change-section
- :on-expand handle-expand
- :share-id share-id}]]]))
+ [:div {:class (stl/css-case :sidebar-container true
+ :not-expand (not can-be-expanded?)
+ :expanded can-be-expanded?)
+
+ :style #js {"--width" (when can-be-expanded? (dm/str right-size "px"))}}
+ (when can-be-expanded?
+ [:div {:class (stl/css :resize-area)
+ :on-pointer-down on-pointer-down
+ :on-lost-pointer-capture on-lost-pointer-capture
+ :on-pointer-move on-pointer-move}])
+ [:& right-sidebar {:frame frame
+ :selected (:selected local)
+ :page page
+ :file file
+ :on-change-section handle-change-section
+ :on-expand handle-expand
+ :share-id share-id}]]]
+
+
+ ;;OLD
+ [:*
+ [:& left-sidebar {:frame frame
+ :local local
+ :page page}]
+ [:div.inspect-svg-wrapper {:data-value (pr-str (:id frame))
+ :on-click handle-select-frame}
+ [:& viewer-pagination {:index index :num-frames (count (:frames page)) :left-bar true :right-bar true}]
+ [:div.inspect-svg-container {:ref inspect-svg-container-ref}
+ [:& render-frame-svg {:frame frame :page page :local local :size size}]]]
+
+ [:div.sidebar-container
+ {:class (when (not can-be-expanded?) "not-expand")
+ :style #js {"--width" (when can-be-expanded? (dm/str right-size "px"))}}
+ [:div.resize-area
+ {:on-pointer-down on-pointer-down
+ :on-lost-pointer-capture on-lost-pointer-capture
+ :on-pointer-move on-pointer-move}]
+ [:& right-sidebar {:frame frame
+ :selected (:selected local)
+ :page page
+ :file file
+ :on-change-section handle-change-section
+ :on-expand handle-expand
+ :share-id share-id}]]])))
diff --git a/frontend/src/app/main/ui/viewer/inspect.scss b/frontend/src/app/main/ui/viewer/inspect.scss
new file mode 100644
index 000000000..340003ce9
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/inspect.scss
@@ -0,0 +1,56 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+$width-settings-bar: $s-276;
+$width-settings-bar-max: $s-500;
+
+.inspect-svg-wrapper {
+ @include flexCenter;
+ position: relative;
+ flex-direction: column;
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+.inspect-svg-container {
+ display: grid;
+ align-items: center;
+ justify-content: safe center;
+ width: 100%;
+ height: 100%;
+ margin: 0 auto;
+ overflow: auto;
+}
+
+.sidebar-container {
+ position: relative;
+ align-self: flex-start;
+ width: $width-settings-bar;
+
+ background-color: var(--panel-background-color);
+ border-top: $s-1 solid var(--search-bar-input-border-color);
+}
+
+.not-expand {
+ max-width: $width-settings-bar;
+}
+
+.expanded {
+ width: var(--width, $width-settings-bar);
+}
+
+.resize-area {
+ position: absolute;
+ left: 0;
+ width: $s-8;
+ height: 100%;
+ z-index: $z-index-10;
+ cursor: ew-resize;
+}
diff --git a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.cljs b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.cljs
index bf42b3e7b..d5fe584b7 100644
--- a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.cljs
+++ b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.cljs
@@ -87,8 +87,8 @@
(handle-change-tab :info))))
(if new-css-system
- [:aside {:class (stl/css :settings-bar-right)}
-
+ [:aside {:class (stl/css-case :settings-bar-right true
+ :viewer-code (= from :inspect))}
(if (seq shapes)
[:div {:class (stl/css :tool-windows)}
[:div {:class (stl/css :shape-row)}
diff --git a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss
index de3e6d54c..13bf37fac 100644
--- a/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss
+++ b/frontend/src/app/main/ui/viewer/inspect/right_sidebar.scss
@@ -9,11 +9,13 @@
.settings-bar-right {
min-width: $s-252;
width: 100%;
- height: 100%;
+ height: 100vh;
position: relative;
left: unset;
right: unset;
grid-area: right-sidebar;
+ padding-top: $s-8;
+ padding-left: $s-12;
.tool-windows {
height: 100%;
display: flex;
@@ -64,9 +66,11 @@
padding: $s-8 $s-24;
}
}
-
.inspect-content {
flex: 1;
overflow: hidden;
}
+ &.viewer-code {
+ height: calc(100vh - $s-48);
+ }
}
diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs
index 6e5645538..c570f091a 100644
--- a/frontend/src/app/main/ui/viewer/interactions.cljs
+++ b/frontend/src/app/main/ui/viewer/interactions.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.interactions
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -18,6 +19,7 @@
[app.main.data.viewer :as dv]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
+ [app.main.ui.context :as ctx]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.viewer.shapes :as shapes]
@@ -191,77 +193,144 @@
(mf/defc flows-menu
{::mf/wrap [mf/memo]}
[{:keys [page index]}]
- (let [flows (dm/get-in page [:options :flows])
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ flows (dm/get-in page [:options :flows])
frames (:frames page)
frame (get frames index)
- current-flow (mf/use-state
- (ctp/get-frame-flow flows (:id frame)))
+ current-flow* (mf/use-state
+ #(ctp/get-frame-flow flows (:id frame)))
- show-dropdown? (mf/use-state false)
- toggle-dropdown (mf/use-fn #(swap! show-dropdown? not))
- hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
+ current-flow (deref current-flow*)
+
+ show-dropdown?* (mf/use-state false)
+ show-dropdown? (deref show-dropdown?*)
+ toggle-dropdown (mf/use-fn #(swap! show-dropdown?* not))
+ hide-dropdown (mf/use-fn #(reset! show-dropdown?* false))
select-flow
(mf/use-callback
- (fn [flow]
- (reset! current-flow flow)
- (st/emit! (dv/go-to-frame (:starting-frame flow)))))]
+ (fn [event]
+ (let [flow (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (d/read-string))]
+ (reset! current-flow* flow)
+ (st/emit! (dv/go-to-frame (:starting-frame flow))))))]
(when (seq flows)
- [:div.view-options {:on-click toggle-dropdown}
- [:span.icon i/play]
- [:span.label (:name @current-flow)]
- [:span.icon i/arrow-down]
- [:& dropdown {:show @show-dropdown?
- :on-close hide-dropdown}
- [:ul.dropdown.with-check
- (for [[index flow] (d/enumerate flows)]
- [:li {:key (dm/str "flow-" (:id flow) "-" index)
- :class (dom/classnames :selected (= (:id flow) (:id @current-flow)))
- :on-click #(select-flow flow)}
- [:span.icon i/tick]
- [:span.label (:name flow)]])]]])))
+ (if new-css-system
+ [:div {:on-click toggle-dropdown
+ :class (stl/css :view-options)}
+ [:span {:class (stl/css :icon)} i/play-refactor]
+ [:span {:class (stl/css :dropdown-title)} (:name current-flow)]
+ [:span {:class (stl/css :icon-dropdown)} i/arrow-refactor]
+ [:& dropdown {:show show-dropdown?
+ :on-close hide-dropdown}
+ [:ul {:class (stl/css :dropdown)}
+ (for [[index flow] (d/enumerate flows)]
+ [:li {:key (dm/str "flow-" (:id flow) "-" index)
+ :class (stl/css-case :dropdown-element true
+ :selected (= (:id flow) (:id current-flow)))
+ ;; This is not a best practise, is not very performant Do not reproduce
+ :data-value (pr-str flow)
+ :on-click select-flow}
+ [:span {:class (stl/css :label)} (:name flow)]
+ (when (= (:id flow) (:id current-flow))
+ [:span {:class (stl/css :icon)} i/tick-refactor])])]]]
+
+ ;; OLD
+ [:div.view-options {:on-click toggle-dropdown}
+ [:span.icon i/play]
+ [:span.label (:name current-flow)]
+ [:span.icon i/arrow-down]
+ [:& dropdown {:show show-dropdown?
+ :on-close hide-dropdown}
+ [:ul.dropdown.with-check
+ (for [[index flow] (d/enumerate flows)]
+ [:li {:key (dm/str "flow-" (:id flow) "-" index)
+ :class (dom/classnames :selected (= (:id flow) (:id current-flow)))
+ ;; This is not a best practise, is not very performant Do not reproduce
+ :data-value (pr-str flow)
+ :on-click select-flow}
+ [:span.icon i/tick]
+ [:span.label (:name flow)]])]]]))))
(mf/defc interactions-menu
[{:keys [interactions-mode]}]
- (let [show-dropdown? (mf/use-state false)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ show-dropdown? (mf/use-state false)
toggle-dropdown (mf/use-fn #(swap! show-dropdown? not))
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
select-mode
(mf/use-fn
- (fn [event]
- (let [mode (some-> (dom/get-current-target event)
- (dom/get-data "mode")
- (keyword))]
- (dom/stop-propagation event)
- (st/emit! (dv/set-interactions-mode mode)))))]
+ (fn [event]
+ (let [mode (some-> (dom/get-current-target event)
+ (dom/get-data "mode")
+ (keyword))]
+ (dom/stop-propagation event)
+ (st/emit! (dv/set-interactions-mode mode)))))]
+ (if new-css-system
+ [:div {:on-click toggle-dropdown
+ :class (stl/css :view-options)}
+ [:span {:class (stl/css :dropdown-title)} (tr "viewer.header.interactions")]
+ [:span {:class (stl/css :icon-dropdown)} i/arrow-refactor]
+ [:& dropdown {:show @show-dropdown?
+ :on-close hide-dropdown}
+ [:ul {:class (stl/css :dropdown)}
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= interactions-mode :hide))
+ :on-click select-mode
+ :data-mode :hide}
- [:div.view-options {:on-click toggle-dropdown}
- [:span.label (tr "viewer.header.interactions")]
- [:span.icon i/arrow-down]
- [:& dropdown {:show @show-dropdown?
- :on-close hide-dropdown}
- [:ul.dropdown.with-check
- [:li {:class (dom/classnames :selected (= interactions-mode :hide))
- :on-click select-mode
- :data-mode :hide}
- [:span.icon i/tick]
- [:span.label (tr "viewer.header.dont-show-interactions")]]
+ [:span {:class (stl/css :label)} (tr "viewer.header.dont-show-interactions")]
+ (when (= interactions-mode :hide)
+ [:span {:class (stl/css :icon)} i/tick-refactor])]
- [:li {:class (dom/classnames :selected (= interactions-mode :show))
- :on-click select-mode
- :data-mode :show}
- [:span.icon i/tick]
- [:span.label (tr "viewer.header.show-interactions")]]
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= interactions-mode :show))
+ :on-click select-mode
+ :data-mode :show}
+ [:span {:class (stl/css :label)} (tr "viewer.header.show-interactions")]
+ (when (= interactions-mode :show)
+ [:span {:class (stl/css :icon)} i/tick-refactor])]
- [:li {:class (dom/classnames :selected (= interactions-mode :show-on-click))
- :on-click select-mode
- :data-mode :show-on-click}
- [:span.icon i/tick]
- [:span.label (tr "viewer.header.show-interactions-on-click")]]]]]))
+ [:li {:class (stl/css-case :dropdown-element true
+ :selected (= interactions-mode :show-on-click))
+ :on-click select-mode
+ :data-mode :show-on-click}
+
+ [:span {:class (stl/css :label)} (tr "viewer.header.show-interactions-on-click")]
+ (when (= interactions-mode :show-on-click)
+ [:span {:class (stl/css :icon)} i/tick-refactor])]]]]
+
+
+
+ [:div.view-options {:on-click toggle-dropdown}
+ [:span.label (tr "viewer.header.interactions")]
+ [:span.icon i/arrow-down]
+ [:& dropdown {:show @show-dropdown?
+ :on-close hide-dropdown}
+ [:ul.dropdown.with-check
+ [:li {:class (dom/classnames :selected (= interactions-mode :hide))
+ :on-click select-mode
+ :data-mode :hide}
+ [:span.icon i/tick]
+ [:span.label (tr "viewer.header.dont-show-interactions")]]
+
+ [:li {:class (dom/classnames :selected (= interactions-mode :show))
+ :on-click select-mode
+ :data-mode :show}
+ [:span.icon i/tick]
+ [:span.label (tr "viewer.header.show-interactions")]]
+
+ [:li {:class (dom/classnames :selected (= interactions-mode :show-on-click))
+ :on-click select-mode
+ :data-mode :show-on-click}
+ [:span.icon i/tick]
+ [:span.label (tr "viewer.header.show-interactions-on-click")]]]]])))
+
(defn animate-go-to-frame
[animation current-viewport orig-viewport current-size orig-size wrapper-size]
(case (:animation-type animation)
diff --git a/frontend/src/app/main/ui/viewer/interactions.scss b/frontend/src/app/main/ui/viewer/interactions.scss
new file mode 100644
index 000000000..07b12e3af
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/interactions.scss
@@ -0,0 +1,80 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+.view-options {
+ @include titleTipography;
+ display: flex;
+ align-items: center;
+ position: relative;
+ gap: $s-4;
+ height: $s-32;
+ border-radius: $br-8;
+ background-color: var(--input-background-color);
+ padding: $s-8;
+ cursor: pointer;
+}
+.dropdown-title {
+ @include titleTipography;
+ flex-grow: 1;
+ color: var(--input-foreground-color-active);
+}
+
+.label {
+ flex-grow: 1;
+ color: var(--input-foreground-color);
+}
+
+.dropdown {
+ @extend .menu-dropdown;
+ right: $s-2;
+ top: calc($s-2 + $s-48);
+ width: $s-272;
+ padding: $s-6;
+}
+
+.dropdown-element {
+ @extend .dropdown-element-base;
+ .icon {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+ }
+ &:hover .label {
+ color: var(--input-foreground-color-active);
+ }
+}
+
+.dropdown-element.selected {
+ .label {
+ color: var(--input-foreground-color-active);
+ }
+ .icon svg {
+ stroke: var(--input-foreground-color);
+ }
+}
+
+.icon,
+.icon-dropdown {
+ @include flexCenter;
+ height: 100%;
+ width: $s-16;
+ svg {
+ @extend .button-icon-small;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.icon-dropdown svg {
+ transform: rotate(90deg);
+}
+
+// breakpoint 1013px
diff --git a/frontend/src/app/main/ui/viewer/login.cljs b/frontend/src/app/main/ui/viewer/login.cljs
index 46054f8f8..375066e13 100644
--- a/frontend/src/app/main/ui/viewer/login.cljs
+++ b/frontend/src/app/main/ui/viewer/login.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.login
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.logging :as log]
[app.main.data.modal :as modal]
@@ -13,6 +14,7 @@
[app.main.ui.auth.login :refer [login-methods]]
[app.main.ui.auth.recovery-request :refer [recovery-request-page]]
[app.main.ui.auth.register :refer [register-methods register-validate-form register-success-page]]
+ [app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@@ -25,15 +27,31 @@
{::mf/register modal/components
::mf/register-as :login-register}
[_]
- (let [uri (. (. js/document -location) -href)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ uri (. (. js/document -location) -href)
user-email (mf/use-state "")
register-token (mf/use-state "")
- current-section (mf/use-state :login)
- set-current-section (mf/use-fn #(reset! current-section %))
+
+ current-section* (mf/use-state :login)
+ current-section (deref current-section*)
+
+ set-current-section
+ (mf/use-fn #(reset! current-section* %))
+
+ set-section
+ (mf/use-fn
+ (fn [event]
+ (let [section (-> (dom/get-current-target event)
+ (dom/get-data "value")
+ (keyword))]
+ (set-current-section section))))
+
+ go-back-to-login (mf/use-fn #(set-current-section :login))
+
main-section (or
- (= @current-section :login)
- (= @current-section :register)
- (= @current-section :register-validate))
+ (= current-section :login)
+ (= current-section :register)
+ (= current-section :register-validate))
close
(fn [event]
(dom/prevent-default event)
@@ -49,57 +67,118 @@
(fn [data]
(reset! register-token (:token data))
(set-current-section :register-validate))]
+
(mf/with-effect []
(swap! storage assoc :redirect-url uri))
- [:div.modal-overlay
- [:div.modal-container.login-register
- [:div.title
- [:div.modal-close-button {:on-click close :title (tr "labels.close")}
- i/close]
- (when main-section
- [:h2 (tr "labels.continue-with-penpot")])]
- [:div.modal-bottom.auth-content
+ (if new-css-system
+ [:div {:class (stl/css :modal-overlay)}
+ [:div {:class (stl/css :modal-container)}
+ [:div {:class (stl/css :modal-header)}
+ [:h2 {:class (stl/css :modal-title)} (tr "labels.continue-with-penpot")]
+ [:button {:class (stl/css :modal-close-btn)
+ :title (tr "labels.close")
+ :on-click close} i/close-refactor]]
- (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")]]]]]
+ [:div {:class (stl/css :modal-content)}
- :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")]]]]
+ (case current-section
+ :login
+ [:div {:class (stl/css :form-container)}
+ [:& login-methods {:on-success-callback success-login :origin :viewer}]
+ [:div {:class (stl/css :links)}
+ [:div {:class (stl/css :link-entry)}
+ [:a {:on-click set-section
+ :data-value :recovery-request}
+ (tr "auth.forgot-password")]]
+ [:div {:class (stl/css :link-entry)}
+ [:span (tr "auth.register") " "]
+ [:a {:on-click set-section
+ :data-value :register}
+ (tr "auth.register-submit")]]]]
- :register-validate
- [:div.form-container
- [:& register-validate-form {:params {:token @register-token}
+ :register
+ [:div {:class (stl/css :form-container)}
+ [:& register-methods {:on-success-callback success-register}]
+ [:div {:class (stl/css :links)}
+ [:div {:class (stl/css :link-entry)}
+ [:span (tr "auth.already-have-account") " "]
+ [:a {:on-click set-section
+ :data-value :login}
+ (tr "auth.login-here")]]]]
+
+ :register-validate
+ [:div {:class (stl/css :form-container)}
+ [:& 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}]
- [:div.links
- [:div.link-entry
- [:a {:on-click #(set-current-section :register)}
- (tr "labels.go-back")]]]]
+ :email-sent
+ [:div {:class (stl/css :form-container)}
+ [:& register-success-page {:params {:email @user-email}}]])
- :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 {:class (stl/css :links)}
+ [:& terms-login]])]]]
- (when main-section
- [:div.modal-footer.links
- [:& terms-login]])]]))
+
+ ;;OLD
+ [:div.modal-overlay
+ [:div.modal-container.login-register
+ [:div.title
+ [:div.modal-close-button {:on-click close :title (tr "labels.close")}
+ i/close]
+ (when main-section
+ [:h2 (tr "labels.continue-with-penpot")])]
+
+ [:div.modal-bottom.auth-content
+
+ (case current-section
+ :login
+ [:div.generic-form.login-form
+ [:div.form-container
+ [:& login-methods {:on-success-callback success-login}]
+ [:div.links
+ [:div.link-entry
+ [:a {:on-click #(set-current-section :recovery-request)}
+ (tr "auth.forgot-password")]]
+ [:div.link-entry
+ [:span (tr "auth.register") " "]
+ [:a {:on-click #(set-current-section :register)}
+ (tr "auth.register-submit")]]]]]
+
+ :register
+ [:div.form-container
+ [:& register-methods {:on-success-callback success-register}]
+ [:div.links
+ [:div.link-entry
+ [:span (tr "auth.already-have-account") " "]
+ [:a {:on-click #(set-current-section :login)}
+ (tr "auth.login-here")]]]]
+
+ :register-validate
+ [:div.form-container
+ [:& register-validate-form {:params {:token @register-token}
+ :on-success-callback success-email-sent}]
+ [:div.links
+ [:div.link-entry
+ [:a {:on-click #(set-current-section :register)}
+ (tr "labels.go-back")]]]]
+
+ :recovery-request
+ [:& recovery-request-page {:go-back-callback #(set-current-section :login)
+ :on-success-callback success-email-sent}]
+ :email-sent
+ [:div.form-container
+ [:& register-success-page {:params {:email @user-email}}]])]
+
+ (when main-section
+ [:div.modal-footer.links
+ [:& terms-login]])]])))
diff --git a/frontend/src/app/main/ui/viewer/login.scss b/frontend/src/app/main/ui/viewer/login.scss
new file mode 100644
index 000000000..6e39b53f6
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/login.scss
@@ -0,0 +1,73 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@import "refactor/common-refactor.scss";
+
+.modal-overlay {
+ @extend .modal-overlay-base;
+}
+
+.modal-container {
+ @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 {
+ @include flexColumn;
+ @include titleTipography;
+ gap: $s-24;
+ max-height: $s-400;
+ width: $s-368;
+ overflow: hidden auto;
+ form {
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 1.5rem;
+ gap: 0.75rem;
+ }
+}
+
+.form-container {
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ max-width: $s-368;
+}
+
+.links {
+ position: relative;
+}
+
+.link-entry {
+ display: flex;
+ flex-direction: column;
+ gap: $s-12;
+
+ span {
+ text-align: center;
+ font-size: $fs-14;
+ color: var(--modal-text-foreground-color);
+ margin-top: $s-12;
+ }
+ a {
+ @extend .button-secondary;
+ height: $s-40;
+ text-transform: uppercase;
+ font-size: $fs-11;
+ }
+}
diff --git a/frontend/src/app/main/ui/viewer/share_link.cljs b/frontend/src/app/main/ui/viewer/share_link.cljs
index a6662fa16..a12e30da8 100644
--- a/frontend/src/app/main/ui/viewer/share_link.cljs
+++ b/frontend/src/app/main/ui/viewer/share_link.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.share-link
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -16,6 +17,8 @@
[app.main.data.modal :as modal]
[app.main.refs :as refs]
[app.main.store :as st]
+ [app.main.ui.components.select :refer [select]]
+ [app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@@ -37,7 +40,8 @@
::mf/register-as :share-link
::mf/wrap-props false}
[{:keys [file page]}]
- (let [current-page page
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ current-page page
current-page-id (:id page)
slinks (mf/deref refs/share-links)
router (mf/deref refs/router)
@@ -151,135 +155,284 @@
(fn [_]
(swap! perms-visible* not))
- on-who-change
- (fn [type event]
- (let [target (dom/get-target event)
- value (dom/get-value target)
- value (keyword value)]
- (reset! confirm* false)
- (if (= type :comment)
- (swap! options* assoc :who-comment (d/name value))
- (swap! options* assoc :who-inspect (d/name value)))))]
+ on-inspect-change
+ (fn [value]
+ (reset! confirm* false)
+ (swap! options* assoc :who-inspect value))
+
+ on-comment-change
+ (fn [value]
+ (reset! confirm* false)
+ (swap! options* assoc :who-comment value))]
+
+ (if new-css-system
+ [:div {:class (stl/css :share-modal)}
+ [:div {:class (stl/css :share-link-dialog)}
+ [:div {:class (stl/css :share-link-header)}
+ [:h2 {:class (stl/css :share-link-title)}
+ (tr "common.share-link.title")]
+ [:button {:class (stl/css :modal-close-button)
+ :on-click on-close
+ :title (tr "labels.close")}
+ i/close-refactor]]
+ [:div {:class (stl/css :modal-content)}
+ [:div {:class (stl/css :share-link-section)}
+ (when (and (not confirm?) (some? current-link))
+ [:div {:class (stl/css :custon-input-wrapper)}
+ [:input {:class (stl/css :input-text)
+ :type "text"
+ :value (or current-link "")
+ :placeholder (tr "common.share-link.placeholder")
+ :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")}])]]
+
- [: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
+ [: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")]
+
+ (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 {: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)}
+ [:input {:type "checkbox"
+ :id (dm/str "page-" current-page-id)
+ :data-page-id (dm/str current-page-id)
+ :on-change on-mark-checked-page
+ :checked true}]
+ [:label {:for (str "page-" current-page-id)} (:name current-page)]
+ [:span {: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)}
+ (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
+
+ [:ul {:class (stl/css :pages-selection)}
+ (for [{:keys [id name]} pages]
+ [:li {:class (stl/css :checkbox-wrapper)
+ :key (dm/str id)}
+ [:label {:for (dm/str "page-" id)}
+ [:span {:class (stl/css-case :global/checked (contains? selected id))}
+ (when (contains? selected id)
+ 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)}
+ (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"
- :on-click #(reset! confirm* false)
- :value (tr "labels.cancel")}]
- [:input.btn-danger
+ :class "primary"
+ :on-click try-delete-link
+ :value (tr "common.share-link.destroy-link")}]
+
+ :else
+ [:input.btn-primary
{:type "button"
- :on-click delete-link
- :value (tr "common.share-link.destroy-link")}]]]
-
- (some? current-link)
- [:input.btn-secondary
- {:type "button"
- :class "primary"
- :on-click try-delete-link
- :value (tr "common.share-link.destroy-link")}]
-
- :else
- [:input.btn-primary
- {:type "button"
- :class "primary"
- :on-click create-link
- :value (tr "common.share-link.get-link")}])]]]
- [:div.modal-content.ops-section
- [:div.manage-permissions
- {:on-click toggle-perms-visibility}
- [:span.icon i/picker-hsv]
- [:div.title (tr "common.share-link.manage-ops")]]
- (when ^boolean perms-visible?
- [:*
- (let [all-selected? (:all-pages options)
- pages (->> (get-in file [:data :pages])
- (map #(get-in file [:data :pages-index %])))
- selected (:pages options)]
- [:*
- [:div.view-mode
- [:div.subtitle
- [:span.icon i/play]
- (tr "common.share-link.permissions-pages")]
- [:div.items
- (if (= 1 (count pages))
- [:div.input-checkbox.check-primary
- [:input {:type "checkbox"
- :id (dm/str "page-" current-page-id)
- :data-page-id (dm/str current-page-id)
- :on-change on-mark-checked-page
- :checked true}]
- [:label {:for (str "page-" current-page-id)} (:name current-page)]
- [:span (str " " (tr "common.share-link.current-tag"))]]
-
- [:*
- [:div.row
+ :class "primary"
+ :on-click create-link
+ :value (tr "common.share-link.get-link")}])]]]
+ [:div.modal-content.ops-section
+ [:div.manage-permissions
+ {:on-click toggle-perms-visibility}
+ [:span.icon i/picker-hsv]
+ [:div.title (tr "common.share-link.manage-ops")]]
+ (when ^boolean perms-visible?
+ [:*
+ (let [all-selected? (:all-pages options)
+ pages (->> (get-in file [:data :pages])
+ (map #(get-in file [:data :pages-index %])))
+ selected (:pages options)]
+ [:*
+ [:div.view-mode
+ [:div.subtitle
+ [:span.icon i/play]
+ (tr "common.share-link.permissions-pages")]
+ [:div.items
+ (if (= 1 (count pages))
[:div.input-checkbox.check-primary
[:input {:type "checkbox"
- :id "view-all"
- :checked all-selected?
- :name "pages-mode"
- :on-change on-toggle-all}]
- [:label {:for "view-all"} (tr "common.share-link.view-all")]]
- [:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
+ :id (dm/str "page-" current-page-id)
+ :data-page-id (dm/str current-page-id)
+ :on-change on-mark-checked-page
+ :checked true}]
+ [:label {:for (str "page-" current-page-id)} (:name current-page)]
+ [:span (str " " (tr "common.share-link.current-tag"))]]
- [:ul.pages-selection
- (for [{:keys [id name]} pages]
- [:li.input-checkbox.check-primary {:key (dm/str id)}
+ [:*
+ [:div.row
+ [:div.input-checkbox.check-primary
[:input {:type "checkbox"
- :id (dm/str "page-" id)
- :data-page-id (dm/str id)
- :on-change on-mark-checked-page
- :checked (contains? selected id)}]
- (if (= current-page-id id)
- [:*
- [:label {:for (dm/str "page-" id)} name]
- [:span.current-tag (dm/str " " (tr "common.share-link.current-tag"))]]
- [:label {:for (dm/str "page-" id)} name])])]])]]])
- [:div.access-mode
- [:div.subtitle
- [:span.icon i/chat]
- (tr "common.share-link.permissions-can-comment")]
- [:div.items
- [:select.input-select {:on-change (partial on-who-change :comment)
- :value (:who-comment options)}
- [:option {:value "team"} (tr "common.share-link.team-members")]
- [:option {:value "all"} (tr "common.share-link.all-users")]]]]
- [:div.inspect-mode
- [:div.subtitle
- [:span.icon i/code]
- (tr "common.share-link.permissions-can-inspect")]
- [:div.items
- [:select.input-select {:on-change (partial on-who-change :inspect)
- :value (:who-inspect options)}
- [:option {:value "team"} (tr "common.share-link.team-members")]
- [:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]]))
+ :id "view-all"
+ :checked all-selected?
+ :name "pages-mode"
+ :on-change on-toggle-all}]
+ [:label {:for "view-all"} (tr "common.share-link.view-all")]]
+ [:span.count-pages (tr "common.share-link.page-shared" (i18n/c (count selected)))]]
+
+ [:ul.pages-selection
+ (for [{:keys [id name]} pages]
+ [:li.input-checkbox.check-primary {:key (dm/str id)}
+ [:input {:type "checkbox"
+ :id (dm/str "page-" id)
+ :data-page-id (dm/str id)
+ :on-change on-mark-checked-page
+ :checked (contains? selected id)}]
+ (if (= current-page-id id)
+ [:*
+ [:label {:for (dm/str "page-" id)} name]
+ [:span.current-tag (dm/str " " (tr "common.share-link.current-tag"))]]
+ [:label {:for (dm/str "page-" id)} name])])]])]]])
+ [:div.access-mode
+ [:div.subtitle
+ [:span.icon i/chat]
+ (tr "common.share-link.permissions-can-comment")]
+ [:div.items
+ [:select.input-select {:on-change on-comment-change
+ :value (:who-comment options)}
+ [:option {:value "team"} (tr "common.share-link.team-members")]
+ [:option {:value "all"} (tr "common.share-link.all-users")]]]]
+ [:div.inspect-mode
+ [:div.subtitle
+ [:span.icon i/code]
+ (tr "common.share-link.permissions-can-inspect")]
+ [:div.items
+ [:select.input-select {:on-change on-inspect-change
+ :value (:who-inspect options)}
+ [:option {:value "team"} (tr "common.share-link.team-members")]
+ [:option {:value "all"} (tr "common.share-link.all-users")]]]]])]]])))
diff --git a/frontend/src/app/main/ui/viewer/share_link.scss b/frontend/src/app/main/ui/viewer/share_link.scss
new file mode 100644
index 000000000..dc0fbc7b4
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/share_link.scss
@@ -0,0 +1,176 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@import "refactor/common-refactor.scss";
+
+.share-modal {
+ display: block;
+ position: absolute;
+ top: $s-52;
+ right: $s-12;
+ left: calc(100vw - $s-512);
+ z-index: $z-index-modal;
+}
+.share-link-dialog {
+ @extend .modal-container-base;
+ min-height: unset;
+}
+
+.share-link-header {
+ margin-bottom: $s-24;
+}
+
+.share-link-title {
+ @include tabTitleTipography;
+ color: var(--modal-title-foreground-color);
+}
+
+.modal-close-button {
+ @extend .modal-close-btn-base;
+}
+
+.modal-content {
+ @include titleTipography;
+ @include flexColumn;
+ gap: $s-24;
+}
+
+.share-link-section {
+ @include flexColumn;
+ gap: $s-8;
+}
+
+.hint-wrapper {
+ @include flexRow;
+}
+.hint {
+ flex-grow: 1;
+}
+.custon-input-wrapper {
+ @include flexRow;
+ border-radius: $br-8;
+ height: $s-32;
+ width: 100%;
+ background-color: var(--input-background-color);
+}
+
+.input-text {
+ @extend .input-element;
+ color: var(--input-foreground-color-active);
+ padding-left: $s-8;
+ margin: 0;
+ flex-grow: 1;
+ &:focus {
+ outline: none;
+ border: $s-1 solid var(--input-border-color-active);
+ }
+}
+.copy-button {
+ @extend .button-secondary;
+ @include flexRow;
+ gap: $s-8;
+ height: $s-32;
+ width: $s-28;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground-hover);
+ }
+}
+
+.description {
+ @include titleTipography;
+ margin-bottom: $s-24;
+}
+
+.actions {
+ @include flexRow;
+ justify-content: flex-end;
+}
+
+.button-active {
+ @extend .modal-accept-btn;
+}
+.button-cancel {
+ @extend .modal-cancel-btn;
+}
+.button-danger {
+ @extend .modal-danger-btn;
+}
+
+.permissions-section {
+ @include flexColumn;
+ gap: $s-8;
+}
+
+.manage-permissions {
+ @include buttonStyle;
+ @include tabTitleTipography;
+ color: var(--menu-foreground-color-rest);
+ height: $s-32;
+ display: flex;
+ align-items: center;
+ padding: 0;
+}
+
+.icon {
+ @include flexCenter;
+ margin-right: $s-6;
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+ &.rotated {
+ transform: rotate(90deg);
+ }
+}
+.view-mode,
+.access-mode,
+.inspect-mode {
+ display: flex;
+ width: 100%;
+}
+.subtitle {
+ color: var(--modal-text-foreground-color);
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ width: $s-136;
+ height: $s-32;
+}
+
+.items {
+ flex-grow: 1;
+ color: var(--input-foreground-color-active);
+}
+.select-all-row {
+ @include flexRow;
+ justify-content: space-between;
+ height: $s-32;
+ border-bottom: $s-1 solid var(--input-border-color-disabled);
+}
+.select-all-label {
+ color: var(--input-foreground-color-active);
+}
+.pages-selection {
+ margin: 0;
+ li {
+ border-bottom: $s-1 solid var(--input-border-color-disabled);
+ }
+ li:last-child {
+ border-bottom: none;
+ }
+}
+.count-pages,
+.current-tag {
+ @include titleTipography;
+ color: var(--input-foreground-color);
+}
+
+.checkbox-wrapper {
+ @extend .input-checkbox;
+ height: $s-32;
+ padding: 0;
+}
diff --git a/frontend/src/app/main/ui/viewer/thumbnails.cljs b/frontend/src/app/main/ui/viewer/thumbnails.cljs
index 086cbe047..8e95c5727 100644
--- a/frontend/src/app/main/ui/viewer/thumbnails.cljs
+++ b/frontend/src/app/main/ui/viewer/thumbnails.cljs
@@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer.thumbnails
+ (:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@@ -13,6 +14,7 @@
[app.main.data.viewer :as dv]
[app.main.render :as render]
[app.main.store :as st]
+ [app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@@ -22,7 +24,8 @@
(mf/defc thumbnails-content
[{:keys [children expanded? total] :as props}]
- (let [container (mf/use-ref)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ container (mf/use-ref)
width (mf/use-var (.. js/document -documentElement -clientWidth))
element-width (mf/use-var 152)
@@ -56,45 +59,96 @@
(reset! width (obj/get dom "clientWidth"))))]
(mf/use-effect on-mount)
- (if expanded?
- [:div.thumbnails-content
- [:div.thumbnails-list-expanded children]]
- [:div.thumbnails-content
- [:div.left-scroll-handler {:on-click on-left-arrow-click} i/arrow-slide]
- [:div.right-scroll-handler {:on-click on-right-arrow-click} i/arrow-slide]
- [:div.thumbnails-list {:ref container :on-wheel on-scroll}
- [:div.thumbnails-list-inside {:style {:right (str (* @offset 152) "px")}}
- children]]])))
+ (if new-css-system
+ (if expanded?
+ [:div {:class (stl/css :thumbnails-content)}
+ [:div {:class (stl/css :thumbnails-list-expanded)} children]]
+
+ [:div {:class (stl/css :thumbnails-content)}
+ [:button {:class (stl/css :left-scroll-handler)
+ :on-click on-left-arrow-click} i/arrow-refactor]
+ [:button {:class (stl/css :right-scroll-handler)
+ :on-click on-right-arrow-click} i/arrow-refactor]
+
+ [:div {:class (stl/css :thumbnails-list)
+ :ref container
+ :on-wheel on-scroll}
+ [:div {:class (stl/css :thumbnails-list-inside)
+ :style {:right (str (* @offset 152) "px")}}
+ children]]])
+
+
+
+ (if expanded?
+ [:div.thumbnails-content
+ [:div.thumbnails-list-expanded children]]
+
+ [:div.thumbnails-content
+ [:div.left-scroll-handler {:on-click on-left-arrow-click} i/arrow-slide]
+ [:div.right-scroll-handler {:on-click on-right-arrow-click} i/arrow-slide]
+ [:div.thumbnails-list {:ref container :on-wheel on-scroll}
+ [:div.thumbnails-list-inside {:style {:right (str (* @offset 152) "px")}}
+ children]]]))))
(mf/defc thumbnails-summary
[{:keys [on-toggle-expand on-close total] :as props}]
- [:div.thumbnails-summary
- [:span.counter (tr "labels.num-of-frames" (i18n/c total))]
- [:span.buttons
- [:span.btn-expand {:on-click on-toggle-expand} i/arrow-down]
- [:span.btn-close {:on-click on-close} i/close]]])
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)]
+ (if new-css-system
+ [:div {:class (stl/css :thumbnails-summary)}
+ [:span {:class (stl/css :counter)}
+ (tr "labels.num-of-frames" (i18n/c total))]
+ [:span {:class (stl/css :actions)}
+ [:button {:class (stl/css :expand-btn)
+ :on-click on-toggle-expand} i/arrow-refactor]
+ [:button {:class (stl/css :close-btn)
+ :on-click on-close} i/close-refactor]]]
+
+
+ [:div.thumbnails-summary
+ [:span.counter (tr "labels.num-of-frames" (i18n/c total))]
+ [:span.buttons
+ [:span.btn-expand {:on-click on-toggle-expand} i/arrow-down]
+ [:span.btn-close {:on-click on-close} i/close]]])))
(mf/defc thumbnail-item
{::mf/wrap [mf/memo
#(mf/deferred % ts/idle-then-raf)]}
[{:keys [selected? frame on-click index objects page-id thumbnail-data]}]
- (let [children-ids (cfh/get-children-ids objects (:id frame))
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ children-ids (cfh/get-children-ids objects (:id frame))
children-bounds (gsh/shapes->rect (concat [frame] (->> children-ids (keep (d/getf objects)))))]
- [:div.thumbnail-item {:on-click #(on-click % index)}
- [:div.thumbnail-preview
- {:class (dom/classnames :selected selected?)}
- [:& render/frame-svg {:frame (-> frame
- (assoc :thumbnail (get thumbnail-data (dm/str page-id (:id frame))))
- (assoc :children-bounds children-bounds))
- :objects objects
- :use-thumbnails true}]]
- [:div.thumbnail-info
- [:span.name {:title (:name frame)} (:name frame)]]]))
+
+ (if new-css-system
+ [:button {:class (stl/css :thumbnail-item)
+ :on-click #(on-click % index)}
+ [:div {:class (stl/css-case :thumbnail-preview true
+ :selected selected?)}
+ [:& render/frame-svg {:frame (-> frame
+ (assoc :thumbnail (get thumbnail-data (dm/str page-id (:id frame))))
+ (assoc :children-bounds children-bounds))
+ :objects objects
+ :use-thumbnails true}]]
+ [:div {:class (stl/css :thumbnail-info)
+ :title (:name frame)}
+ (:name frame)]]
+
+
+ [:div.thumbnail-item {:on-click #(on-click % index)}
+ [:div.thumbnail-preview
+ {:class (dom/classnames :selected selected?)}
+ [:& render/frame-svg {:frame (-> frame
+ (assoc :thumbnail (get thumbnail-data (dm/str page-id (:id frame))))
+ (assoc :children-bounds children-bounds))
+ :objects objects
+ :use-thumbnails true}]]
+ [:div.thumbnail-info
+ [:span.name {:title (:name frame)} (:name frame)]]])))
(mf/defc thumbnails-panel
[{:keys [frames page index show? thumbnail-data] :as props}]
- (let [expanded? (mf/use-state false)
+ (let [new-css-system (mf/use-ctx ctx/new-css-system)
+ expanded? (mf/use-state false)
container (mf/use-ref)
objects (:objects page)
@@ -109,24 +163,48 @@
(st/emit! (dv/go-to-frame-by-index index))
(when @expanded?
(on-close))))]
+ (if new-css-system
+ [:section
+ {:class (stl/css-case :viewer-thumbnails true
+ :expanded @expanded?)
+ ;; This is better as an inline-style so it won't make a reflow of every frame inside
+ :style {:display (when (not show?) "none")}
+ :ref container}
- [:section.viewer-thumbnails
- {;; This is better as an inline-style so it won't make a reflow of every frame inside
- :style {:display (when (not show?) "none")}
- :class (dom/classnames :expanded @expanded?)
- :ref container}
+ [:& thumbnails-summary {:on-toggle-expand #(swap! expanded? not)
+ :on-close on-close
+ :total (count frames)}]
+ [:& thumbnails-content {:expanded? @expanded?
+ :total (count frames)}
+ (for [[i frame] (d/enumerate frames)]
+ [:& thumbnail-item {:index i
+ :key (dm/str (:id frame) "-" i)
+ :frame frame
+ :page-id (:id page)
+ :objects objects
+ :on-click on-item-click
+ :selected? (= i index)
+ :thumbnail-data thumbnail-data}])]]
- [:& thumbnails-summary {:on-toggle-expand #(swap! expanded? not)
- :on-close on-close
- :total (count frames)}]
- [:& thumbnails-content {:expanded? @expanded?
- :total (count frames)}
- (for [[i frame] (d/enumerate frames)]
- [:& thumbnail-item {:index i
- :key (dm/str (:id frame) "-" i)
- :frame frame
- :page-id (:id page)
- :objects objects
- :on-click on-item-click
- :selected? (= i index)
- :thumbnail-data thumbnail-data}])]]))
+
+
+ [:section.viewer-thumbnails
+ {;; This is better as an inline-style so it won't make a reflow of every frame inside
+ :style {:display (when (not show?) "none")}
+ :class (dom/classnames :expanded @expanded?)
+ :ref container}
+
+ [:& thumbnails-summary {:on-toggle-expand #(swap! expanded? not)
+ :on-close on-close
+ :total (count frames)}]
+ [:& thumbnails-content {:expanded? @expanded?
+ :total (count frames)}
+ (for [[i frame] (d/enumerate frames)]
+ [:& thumbnail-item {:index i
+ :key (dm/str (:id frame) "-" i)
+ :frame frame
+ :page-id (:id page)
+ :objects objects
+ :on-click on-item-click
+ :selected? (= i index)
+ :thumbnail-data thumbnail-data}])]])))
diff --git a/frontend/src/app/main/ui/viewer/thumbnails.scss b/frontend/src/app/main/ui/viewer/thumbnails.scss
new file mode 100644
index 000000000..982a9b468
--- /dev/null
+++ b/frontend/src/app/main/ui/viewer/thumbnails.scss
@@ -0,0 +1,152 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) KALEIDOS INC
+
+@use "common/refactor/common-refactor.scss" as *;
+
+.viewer-thumbnails {
+ background-color: var(--viewer-background-color);
+ grid-row: 1 / span 1;
+ grid-column: 1 / span 1;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ z-index: $z-index-10;
+}
+
+.expanded {
+ grid-row: 1 / span 2;
+
+ .expand-btn svg {
+ transform: rotate(-90deg);
+ }
+}
+
+.thumbnails-summary {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: $s-32;
+ margin: $s-24 $s-24 0 $s-24;
+}
+
+.counter {
+ @include titleTipography;
+ color: var(--viewer-thumbnails-control-foreground-color);
+}
+
+.actions {
+ @include flexRow;
+ width: $s-60;
+}
+
+.expand-btn,
+.close-btn {
+ @extend .button-tertiary;
+ height: $s-32;
+ width: $s-28;
+ svg {
+ @extend .button-icon;
+ }
+}
+
+.expand-btn svg {
+ transform: rotate(90deg);
+}
+
+.thumbnails-content {
+ display: grid;
+ grid-template-columns: $s-40 auto $s-40;
+ grid-template-rows: auto;
+}
+
+.thumbnails-list-expanded {
+ grid-column: 1 / span 3;
+ grid-row: 1 / span 1;
+ display: flex;
+ flex-wrap: wrap;
+ overflow: hidden;
+}
+
+.right-scroll-handler,
+.left-scroll-handler {
+ @extend .button-tertiary;
+ @include flexCenter;
+ grid-column: 3 / span 1;
+ grid-row: 1 / span 1;
+ width: $s-32;
+ height: $s-60;
+ margin: auto 0;
+ z-index: $z-index-10;
+ opacity: 0;
+ &:hover {
+ opacity: 1;
+ }
+ svg {
+ @extend .button-icon;
+ stroke: var(--icon-foreground);
+ }
+}
+
+.left-scroll-handler {
+ grid-column: 1 / span 1;
+ grid-row: 1 / span 1;
+ svg {
+ transform: rotate(180deg);
+ }
+}
+
+.thumbnails-list {
+ grid-column: 1 / span 3;
+ grid-row: 1 / span 1;
+ display: flex;
+ flex-wrap: nowrap;
+ overflow: hidden;
+}
+
+.thumbnails-list-inside {
+ display: flex;
+ position: relative;
+}
+
+.thumbnail-item {
+ @include buttonStyle;
+ display: flex;
+ flex-direction: column;
+ padding: $s-16;
+}
+
+.thumbnail-preview {
+ @include flexCenter;
+ width: $s-132;
+ min-height: $s-132;
+ height: $s-132;
+ padding: $s-4;
+
+ svg {
+ width: 100%;
+ height: 100%;
+ }
+
+ &.selected {
+ background-color: var(--viewer-thumbnail-background-color-selected);
+ border-radius: $br-8;
+ }
+
+ &:hover {
+ border: $s-1 solid var(--viewer-thumbnail-border-color);
+ border-radius: $br-8;
+ }
+}
+
+.thumbnail-info {
+ @include titleTipography;
+ @include textEllipsis;
+ text-align: center;
+ color: var(--viewer-thumbnails-control-foreground-color);
+ padding: $s-8 0;
+ width: 100%;
+ max-width: $s-132;
+}
diff --git a/frontend/src/app/main/ui/workspace/comments.cljs b/frontend/src/app/main/ui/workspace/comments.cljs
index ca7a4d4e8..121ca11d9 100644
--- a/frontend/src/app/main/ui/workspace/comments.cljs
+++ b/frontend/src/app/main/ui/workspace/comments.cljs
@@ -86,12 +86,10 @@
[:li {:class (dom/classnames :selected (= :pending cshow))
:on-click update-show}
[:span.icon i/tick]
- [:span.label (tr "labels.hide-resolved-comments")]]])
-
- ))
+ [:span.label (tr "labels.hide-resolved-comments")]]])))
(mf/defc comments-sidebar
- [{:keys [users threads page-id]}]
+ [{:keys [users threads page-id from-viewer]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
threads-map (mf/deref refs/threads-ref)
profile (mf/deref refs/profile)
@@ -111,8 +109,11 @@
close-section
(mf/use-fn
- (mf/deps)
- #(st/emit! :interrupt (dw/deselect-all true)))
+ (mf/deps from-viewer)
+ (fn []
+ (if from-viewer
+ (st/emit! (dcm/update-options {:show-sidebar? false}))
+ (st/emit! :interrupt (dw/deselect-all true)))))
tgroups (->> threads
(dcm/group-threads-by-page))
@@ -121,7 +122,6 @@
toggle-mode-selector
(mf/use-fn
- (mf/deps)
(fn [event]
(dom/stop-propagation event)
(swap! state* not)))
@@ -147,18 +147,17 @@
:on-click close-section}
i/close-refactor]]
- (when (seq tgroups)
- [:button {:class (stl/css :mode-dropdown-wrapper)
- :on-click toggle-mode-selector}
+ [:button {:class (stl/css :mode-dropdown-wrapper)
+ :on-click toggle-mode-selector}
- [:span {:class (stl/css :mode-label)} (case (:mode local)
- (nil :all) (tr "labels.show-all-comments")
- :yours (tr "labels.show-your-comments"))]
- [:div {:class (stl/css :icon)} i/arrow-refactor]]
+ [:span {:class (stl/css :mode-label)} (case (:mode local)
+ (nil :all) (tr "labels.show-all-comments")
+ :yours (tr "labels.show-your-comments"))]
+ [:div {:class (stl/css :icon)} i/arrow-refactor]]
- [:& dropdown {:show options?
- :on-close #(reset! state* false)}
- [:& sidebar-options {:local local}]])
+ [:& dropdown {:show options?
+ :on-close #(reset! state* false)}
+ [:& sidebar-options {:local local}]]
[:div {:class (stl/css :comments-section-content)}
diff --git a/frontend/src/app/main/ui/workspace/right_header.cljs b/frontend/src/app/main/ui/workspace/right_header.cljs
index 2359cf725..0e46f05ca 100644
--- a/frontend/src/app/main/ui/workspace/right_header.cljs
+++ b/frontend/src/app/main/ui/workspace/right_header.cljs
@@ -126,14 +126,14 @@
(tr "workspace.header.zoom-fit-all")
[:span {:class (stl/css :shortcuts)}
(for [sc (scd/split-sc (sc/get-tooltip :fit-all))]
- [:span {:class (dom/classnames (stl/css :shortcut-key) true)
+ [:span {:class (stl/css :shortcut-key)
:key (str "zoom-fit-" sc)} sc])]]
[:li {:class (stl/css :zoom-option)
:on-click on-zoom-selected}
(tr "workspace.header.zoom-selected")
[:span {:class (stl/css :shortcuts)}
(for [sc (scd/split-sc (sc/get-tooltip :zoom-selected))]
- [:span {:class (dom/classnames (stl/css :shortcut-key) true)
+ [:span {:class (stl/css :shortcut-key)
:key (str "zoom-selected-" sc)} sc])]]]]]))
;; --- Header Component
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs
index 31f7faf2a..948c5228f 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs
@@ -198,6 +198,7 @@
:checked (not hide-fill-on-export?)
:on-change on-change-show-fill-on-export}]]])])]
+ ;; OLD
[:div.element-set
[:div.element-set-title
[:span label]
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index 1c5e97d90..f1206c084 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -1637,6 +1637,9 @@ msgstr "Settings"
msgid "labels.share-prototype"
msgstr "Share prototype"
+msgid "labels.share"
+msgstr "Share"
+
#: src/app/main/ui/dashboard/sidebar.cljs
msgid "labels.shared-libraries"
msgstr "Libraries"
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index 218fdad3c..7b4e5b85e 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -1673,6 +1673,9 @@ msgstr "ConfiguraciĆ³n"
msgid "labels.share-prototype"
msgstr "Compartir prototipo"
+msgid "labels.share"
+msgstr "Compartir"
+
#: src/app/main/ui/dashboard/sidebar.cljs
msgid "labels.shared-libraries"
msgstr "Bibliotecas"